928 lines
30 KiB
Java
928 lines
30 KiB
Java
/*
|
|
* Copyright (C) 2006 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package com.android.globaltime;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.HashMap;
|
|
import javax.microedition.khronos.opengles.GL10;
|
|
|
|
import android.graphics.Canvas;
|
|
import android.graphics.Paint;
|
|
import android.view.KeyEvent;
|
|
|
|
class Message {
|
|
|
|
private String mText;
|
|
private long mExpirationTime;
|
|
|
|
public Message(String text, long expirationTime) {
|
|
this.mText = text;
|
|
this.mExpirationTime = expirationTime;
|
|
}
|
|
|
|
public String getText() {
|
|
return mText;
|
|
}
|
|
|
|
public long getExpirationTime() {
|
|
return mExpirationTime;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* A helper class to simplify writing an Activity that renders using
|
|
* OpenGL ES.
|
|
*
|
|
* <p> A GLView object stores common elements of GL state and allows
|
|
* them to be modified interactively. This is particularly useful for
|
|
* determining the proper settings of parameters such as the view
|
|
* frustum and light intensities during application development.
|
|
*
|
|
* <p> A GLView is not an actual View; instead, it is meant to be
|
|
* called from within a View to perform event processing on behalf of the
|
|
* actual View.
|
|
*
|
|
* <p> By passing key events to the GLView object from the View,
|
|
* the application can automatically allow certain parameters to
|
|
* be user-controlled from the keyboard. Key events may be passed as
|
|
* shown below:
|
|
*
|
|
* <pre>
|
|
* GLView mGlView = new GLView();
|
|
*
|
|
* public boolean onKeyDown(int keyCode, KeyEvent event) {
|
|
* // Hand the key to the GLView object first
|
|
* if (mGlView.processKey(keyCode)) {
|
|
* return;
|
|
* }
|
|
*
|
|
* switch (keyCode) {
|
|
* case KeyEvent.KEY_CODE_X:
|
|
* // perform app processing
|
|
* break;
|
|
*
|
|
* default:
|
|
* super.onKeyDown(keyCode, event);
|
|
* break;
|
|
* }
|
|
* }
|
|
* </pre>
|
|
*
|
|
* <p> During drawing of a frame, the GLView object should be given the
|
|
* opportunity to manage GL parameters as shown below:
|
|
*
|
|
* OpenGLContext mGLContext; // initialization not shown
|
|
* int mNumTrianglesDrawn = 0;
|
|
*
|
|
* protected void onDraw(Canvas canvas) {
|
|
* int w = getWidth();
|
|
* int h = getHeight();
|
|
*
|
|
* float ratio = (float) w / h;
|
|
* mGLView.setAspectRatio(ratio);
|
|
*
|
|
* GL10 gl = (GL10) mGLContext.getGL();
|
|
* mGLContext.waitNative(canvas, this);
|
|
*
|
|
* // Enable a light for the GLView to manipulate
|
|
* gl.glEnable(GL10.GL_LIGHTING);
|
|
* gl.glEnable(GL10.GL_LIGHT0);
|
|
*
|
|
* // Allow the GLView to set GL parameters
|
|
* mGLView.setTextureParameters(gl);
|
|
* mGLView.setProjection(gl);
|
|
* mGLView.setView(gl);
|
|
* mGLView.setLights(gl, GL10.GL_LIGHT0);
|
|
*
|
|
* // Draw some stuff (not shown)
|
|
* mNumTrianglesDrawn += <num triangles just drawn>;
|
|
*
|
|
* // Wait for GL drawing to complete
|
|
* mGLContext.waitGL();
|
|
*
|
|
* // Inform the GLView of what was drawn, and ask it to display statistics
|
|
* mGLView.setNumTriangles(mNumTrianglesDrawn);
|
|
* mGLView.showMessages(canvas);
|
|
* mGLView.showStatistics(canvas, w);
|
|
* }
|
|
* </pre>
|
|
*
|
|
* <p> At the end of each frame, following the call to
|
|
* GLContext.waitGL, the showStatistics and showMessages methods
|
|
* will cause additional information to be displayed.
|
|
*
|
|
* <p> To enter the interactive command mode, the 'tab' key must be
|
|
* pressed twice in succession. A subsequent press of the 'tab' key
|
|
* exits the interactive command mode. Entering a multi-letter code
|
|
* sets the parameter to be modified. The 'newline' key erases the
|
|
* current code, and the 'del' key deletes the last letter of
|
|
* the code. The parameter value may be modified by pressing the
|
|
* keypad left or up to decrement the value and right or down to
|
|
* increment the value. The current value will be displayed as an
|
|
* overlay above the GL rendered content.
|
|
*
|
|
* <p> The supported keyboard commands are as follows:
|
|
*
|
|
* <ul>
|
|
* <li> h - display a list of commands
|
|
* <li> fn - near frustum
|
|
* <li> ff - far frustum
|
|
* <li> tx - translate x
|
|
* <li> ty - translate y
|
|
* <li> tz - translate z
|
|
* <li> z - zoom (frustum size)
|
|
* <li> la - ambient light (all RGB channels)
|
|
* <li> lar - ambient light red channel
|
|
* <li> lag - ambient light green channel
|
|
* <li> lab - ambient light blue channel
|
|
* <li> ld - diffuse light (all RGB channels)
|
|
* <li> ldr - diffuse light red channel
|
|
* <li> ldg - diffuse light green channel
|
|
* <li> ldb - diffuse light blue channel
|
|
* <li> ls - specular light (all RGB channels)
|
|
* <li> lsr - specular light red channel
|
|
* <li> lsg - specular light green channel
|
|
* <li> lsb - specular light blue channel
|
|
* <li> lma - light model ambient (all RGB channels)
|
|
* <li> lmar - light model ambient light red channel
|
|
* <li> lmag - light model ambient green channel
|
|
* <li> lmab - light model ambient blue channel
|
|
* <li> tmin - texture min filter
|
|
* <li> tmag - texture mag filter
|
|
* <li> tper - texture perspective correction
|
|
* </ul>
|
|
*
|
|
* {@hide}
|
|
*/
|
|
public class GLView {
|
|
|
|
private static final int DEFAULT_DURATION_MILLIS = 1000;
|
|
private static final int STATE_KEY = KeyEvent.KEYCODE_TAB;
|
|
private static final int HAVE_NONE = 0;
|
|
private static final int HAVE_ONE = 1;
|
|
private static final int HAVE_TWO = 2;
|
|
|
|
private static final float MESSAGE_Y_SPACING = 12.0f;
|
|
|
|
private int mState = HAVE_NONE;
|
|
|
|
private static final int NEAR_FRUSTUM = 0;
|
|
private static final int FAR_FRUSTUM = 1;
|
|
private static final int TRANSLATE_X = 2;
|
|
private static final int TRANSLATE_Y = 3;
|
|
private static final int TRANSLATE_Z = 4;
|
|
private static final int ZOOM_EXPONENT = 5;
|
|
|
|
private static final int AMBIENT_INTENSITY = 6;
|
|
private static final int AMBIENT_RED = 7;
|
|
private static final int AMBIENT_GREEN = 8;
|
|
private static final int AMBIENT_BLUE = 9;
|
|
|
|
private static final int DIFFUSE_INTENSITY = 10;
|
|
private static final int DIFFUSE_RED = 11;
|
|
private static final int DIFFUSE_GREEN = 12;
|
|
private static final int DIFFUSE_BLUE = 13;
|
|
|
|
private static final int SPECULAR_INTENSITY = 14;
|
|
private static final int SPECULAR_RED = 15;
|
|
private static final int SPECULAR_GREEN = 16;
|
|
private static final int SPECULAR_BLUE = 17;
|
|
|
|
private static final int LIGHT_MODEL_AMBIENT_INTENSITY = 18;
|
|
private static final int LIGHT_MODEL_AMBIENT_RED = 19;
|
|
private static final int LIGHT_MODEL_AMBIENT_GREEN = 20;
|
|
private static final int LIGHT_MODEL_AMBIENT_BLUE = 21;
|
|
|
|
private static final int TEXTURE_MIN_FILTER = 22;
|
|
private static final int TEXTURE_MAG_FILTER = 23;
|
|
private static final int TEXTURE_PERSPECTIVE_CORRECTION = 24;
|
|
|
|
private static final String[] commands = {
|
|
"fn",
|
|
"ff",
|
|
"tx",
|
|
"ty",
|
|
"tz",
|
|
"z",
|
|
"la", "lar", "lag", "lab",
|
|
"ld", "ldr", "ldg", "ldb",
|
|
"ls", "lsr", "lsg", "lsb",
|
|
"lma", "lmar", "lmag", "lmab",
|
|
"tmin", "tmag", "tper"
|
|
};
|
|
|
|
private static final String[] labels = {
|
|
"Near Frustum",
|
|
"Far Frustum",
|
|
"Translate X",
|
|
"Translate Y",
|
|
"Translate Z",
|
|
"Zoom",
|
|
"Ambient Intensity",
|
|
"Ambient Red",
|
|
"Ambient Green",
|
|
"Ambient Blue",
|
|
"Diffuse Intensity",
|
|
"Diffuse Red",
|
|
"Diffuse Green",
|
|
"Diffuse Blue",
|
|
"Specular Intenstity",
|
|
"Specular Red",
|
|
"Specular Green",
|
|
"Specular Blue",
|
|
"Light Model Ambient Intensity",
|
|
"Light Model Ambient Red",
|
|
"Light Model Ambient Green",
|
|
"Light Model Ambient Blue",
|
|
"Texture Min Filter",
|
|
"Texture Mag Filter",
|
|
"Texture Perspective Correction",
|
|
};
|
|
|
|
private static final float[] defaults = {
|
|
5.0f, 100.0f,
|
|
0.0f, 0.0f, -50.0f,
|
|
0,
|
|
0.125f, 1.0f, 1.0f, 1.0f,
|
|
0.125f, 1.0f, 1.0f, 1.0f,
|
|
0.125f, 1.0f, 1.0f, 1.0f,
|
|
0.125f, 1.0f, 1.0f, 1.0f,
|
|
GL10.GL_NEAREST, GL10.GL_NEAREST,
|
|
GL10.GL_FASTEST
|
|
};
|
|
|
|
private static final float[] increments = {
|
|
0.01f, 0.5f,
|
|
0.125f, 0.125f, 0.125f,
|
|
1.0f,
|
|
0.03125f, 0.1f, 0.1f, 0.1f,
|
|
0.03125f, 0.1f, 0.1f, 0.1f,
|
|
0.03125f, 0.1f, 0.1f, 0.1f,
|
|
0.03125f, 0.1f, 0.1f, 0.1f,
|
|
0, 0, 0
|
|
};
|
|
|
|
private float[] params = new float[commands.length];
|
|
|
|
private static final float mZoomScale = 0.109f;
|
|
private static final float mZoomBase = 1.01f;
|
|
|
|
private int mParam = -1;
|
|
private float mIncr = 0;
|
|
|
|
private Paint mPaint = new Paint();
|
|
|
|
private float mAspectRatio = 1.0f;
|
|
|
|
private float mZoom;
|
|
|
|
// private boolean mPerspectiveCorrection = false;
|
|
// private int mTextureMinFilter = GL10.GL_NEAREST;
|
|
// private int mTextureMagFilter = GL10.GL_NEAREST;
|
|
|
|
// Counters for FPS calculation
|
|
private boolean mDisplayFPS = false;
|
|
private boolean mDisplayCounts = false;
|
|
private int mFramesFPS = 10;
|
|
private long[] mTimes = new long[mFramesFPS];
|
|
private int mTimesIdx = 0;
|
|
|
|
private Map<String,Message> mMessages = new HashMap<String,Message>();
|
|
|
|
/**
|
|
* Constructs a new GLView.
|
|
*/
|
|
public GLView() {
|
|
mPaint.setColor(0xffffffff);
|
|
reset();
|
|
}
|
|
|
|
/**
|
|
* Sets the aspect ratio (width/height) of the screen.
|
|
*
|
|
* @param aspectRatio the screen width divided by the screen height
|
|
*/
|
|
public void setAspectRatio(float aspectRatio) {
|
|
this.mAspectRatio = aspectRatio;
|
|
}
|
|
|
|
/**
|
|
* Sets the overall ambient light intensity. This intensity will
|
|
* be used to modify the ambient light value for each of the red,
|
|
* green, and blue channels passed to glLightfv(...GL_AMBIENT...).
|
|
* The default value is 0.125f.
|
|
*
|
|
* @param intensity a floating-point value controlling the overall
|
|
* ambient light intensity.
|
|
*/
|
|
public void setAmbientIntensity(float intensity) {
|
|
params[AMBIENT_INTENSITY] = intensity;
|
|
}
|
|
|
|
/**
|
|
* Sets the light model ambient intensity. This intensity will be
|
|
* used to modify the ambient light value for each of the red,
|
|
* green, and blue channels passed to
|
|
* glLightModelfv(GL_LIGHT_MODEL_AMBIENT...). The default value
|
|
* is 0.125f.
|
|
*
|
|
* @param intensity a floating-point value controlling the overall
|
|
* light model ambient intensity.
|
|
*/
|
|
public void setLightModelAmbientIntensity(float intensity) {
|
|
params[LIGHT_MODEL_AMBIENT_INTENSITY] = intensity;
|
|
}
|
|
|
|
/**
|
|
* Sets the ambient color for the red, green, and blue channels
|
|
* that will be multiplied by the value of setAmbientIntensity and
|
|
* passed to glLightfv(...GL_AMBIENT...). The default values are
|
|
* {1, 1, 1}.
|
|
*
|
|
* @param ambient an arry of three floats containing ambient
|
|
* red, green, and blue intensity values.
|
|
*/
|
|
public void setAmbientColor(float[] ambient) {
|
|
params[AMBIENT_RED] = ambient[0];
|
|
params[AMBIENT_GREEN] = ambient[1];
|
|
params[AMBIENT_BLUE] = ambient[2];
|
|
}
|
|
|
|
/**
|
|
* Sets the overall diffuse light intensity. This intensity will
|
|
* be used to modify the diffuse light value for each of the red,
|
|
* green, and blue channels passed to glLightfv(...GL_DIFFUSE...).
|
|
* The default value is 0.125f.
|
|
*
|
|
* @param intensity a floating-point value controlling the overall
|
|
* ambient light intensity.
|
|
*/
|
|
public void setDiffuseIntensity(float intensity) {
|
|
params[DIFFUSE_INTENSITY] = intensity;
|
|
}
|
|
|
|
/**
|
|
* Sets the diffuse color for the red, green, and blue channels
|
|
* that will be multiplied by the value of setDiffuseIntensity and
|
|
* passed to glLightfv(...GL_DIFFUSE...). The default values are
|
|
* {1, 1, 1}.
|
|
*
|
|
* @param diffuse an array of three floats containing diffuse
|
|
* red, green, and blue intensity values.
|
|
*/
|
|
public void setDiffuseColor(float[] diffuse) {
|
|
params[DIFFUSE_RED] = diffuse[0];
|
|
params[DIFFUSE_GREEN] = diffuse[1];
|
|
params[DIFFUSE_BLUE] = diffuse[2];
|
|
}
|
|
|
|
/**
|
|
* Sets the overall specular light intensity. This intensity will
|
|
* be used to modify the diffuse light value for each of the red,
|
|
* green, and blue channels passed to glLightfv(...GL_SPECULAR...).
|
|
* The default value is 0.125f.
|
|
*
|
|
* @param intensity a floating-point value controlling the overall
|
|
* ambient light intensity.
|
|
*/
|
|
public void setSpecularIntensity(float intensity) {
|
|
params[SPECULAR_INTENSITY] = intensity;
|
|
}
|
|
|
|
/**
|
|
* Sets the specular color for the red, green, and blue channels
|
|
* that will be multiplied by the value of setSpecularIntensity and
|
|
* passed to glLightfv(...GL_SPECULAR...). The default values are
|
|
* {1, 1, 1}.
|
|
*
|
|
* @param specular an array of three floats containing specular
|
|
* red, green, and blue intensity values.
|
|
*/
|
|
public void setSpecularColor(float[] specular) {
|
|
params[SPECULAR_RED] = specular[0];
|
|
params[SPECULAR_GREEN] = specular[1];
|
|
params[SPECULAR_BLUE] = specular[2];
|
|
}
|
|
|
|
/**
|
|
* Returns the current X translation of the modelview
|
|
* transformation as passed to glTranslatef. The default value is
|
|
* 0.0f.
|
|
*
|
|
* @return the X modelview translation as a float.
|
|
*/
|
|
public float getTranslateX() {
|
|
return params[TRANSLATE_X];
|
|
}
|
|
|
|
/**
|
|
* Returns the current Y translation of the modelview
|
|
* transformation as passed to glTranslatef. The default value is
|
|
* 0.0f.
|
|
*
|
|
* @return the Y modelview translation as a float.
|
|
*/
|
|
public float getTranslateY() {
|
|
return params[TRANSLATE_Y];
|
|
}
|
|
|
|
/**
|
|
* Returns the current Z translation of the modelview
|
|
* transformation as passed to glTranslatef. The default value is
|
|
* -50.0f.
|
|
*
|
|
* @return the Z modelview translation as a float.
|
|
*/
|
|
public float getTranslateZ() {
|
|
return params[TRANSLATE_Z];
|
|
}
|
|
|
|
/**
|
|
* Sets the position of the near frustum clipping plane as passed
|
|
* to glFrustumf. The default value is 5.0f;
|
|
*
|
|
* @param nearFrustum the near frustum clipping plane distance as
|
|
* a float.
|
|
*/
|
|
public void setNearFrustum(float nearFrustum) {
|
|
params[NEAR_FRUSTUM] = nearFrustum;
|
|
}
|
|
|
|
/**
|
|
* Sets the position of the far frustum clipping plane as passed
|
|
* to glFrustumf. The default value is 100.0f;
|
|
*
|
|
* @param farFrustum the far frustum clipping plane distance as a
|
|
* float.
|
|
*/
|
|
public void setFarFrustum(float farFrustum) {
|
|
params[FAR_FRUSTUM] = farFrustum;
|
|
}
|
|
|
|
private void computeZoom() {
|
|
mZoom = mZoomScale*(float)Math.pow(mZoomBase, -params[ZOOM_EXPONENT]);
|
|
}
|
|
|
|
/**
|
|
* Resets all parameters to their default values.
|
|
*/
|
|
public void reset() {
|
|
for (int i = 0; i < params.length; i++) {
|
|
params[i] = defaults[i];
|
|
}
|
|
computeZoom();
|
|
}
|
|
|
|
private void removeExpiredMessages() {
|
|
long now = System.currentTimeMillis();
|
|
|
|
List<String> toBeRemoved = new ArrayList<String>();
|
|
|
|
Iterator<String> keyIter = mMessages.keySet().iterator();
|
|
while (keyIter.hasNext()) {
|
|
String key = keyIter.next();
|
|
Message msg = mMessages.get(key);
|
|
if (msg.getExpirationTime() < now) {
|
|
toBeRemoved.add(key);
|
|
}
|
|
}
|
|
|
|
Iterator<String> tbrIter = toBeRemoved.iterator();
|
|
while (tbrIter.hasNext()) {
|
|
String key = tbrIter.next();
|
|
mMessages.remove(key);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Displays the message overlay on the given Canvas. The
|
|
* GLContext.waitGL method should be called prior to calling this
|
|
* method. The interactive command display is drawn by this
|
|
* method.
|
|
*
|
|
* @param canvas the Canvas on which messages are to appear.
|
|
*/
|
|
public void showMessages(Canvas canvas) {
|
|
removeExpiredMessages();
|
|
|
|
float y = 10.0f;
|
|
|
|
List<String> l = new ArrayList<String>();
|
|
l.addAll(mMessages.keySet());
|
|
Collections.sort(l);
|
|
|
|
Iterator<String> iter = l.iterator();
|
|
while (iter.hasNext()) {
|
|
String key = iter.next();
|
|
String text = mMessages.get(key).getText();
|
|
canvas.drawText(text, 10.0f, y, mPaint);
|
|
y += MESSAGE_Y_SPACING;
|
|
}
|
|
}
|
|
|
|
private int mTriangles;
|
|
|
|
/**
|
|
* Sets the number of triangles drawn in the previous frame for
|
|
* display by the showStatistics method. The number of triangles
|
|
* is not computed by GLView but must be supplied by the
|
|
* calling Activity.
|
|
*
|
|
* @param triangles an Activity-supplied estimate of the number of
|
|
* triangles drawn in the previous frame.
|
|
*/
|
|
public void setNumTriangles(int triangles) {
|
|
this.mTriangles = triangles;
|
|
}
|
|
|
|
/**
|
|
* Displays statistics on frames and triangles per second. The
|
|
* GLContext.waitGL method should be called prior to calling this
|
|
* method.
|
|
*
|
|
* @param canvas the Canvas on which statistics are to appear.
|
|
* @param width the width of the Canvas.
|
|
*/
|
|
public void showStatistics(Canvas canvas, int width) {
|
|
long endTime = mTimes[mTimesIdx] = System.currentTimeMillis();
|
|
mTimesIdx = (mTimesIdx + 1) % mFramesFPS;
|
|
|
|
float th = mPaint.getTextSize();
|
|
|
|
if (mDisplayFPS) {
|
|
// Use end time from mFramesFPS frames ago
|
|
long startTime = mTimes[mTimesIdx];
|
|
String fps = "" + (1000.0f*mFramesFPS/(endTime - startTime));
|
|
|
|
// Normalize fps to XX.XX format
|
|
if (fps.indexOf(".") == 1) {
|
|
fps = " " + fps;
|
|
}
|
|
int len = fps.length();
|
|
if (len == 2) {
|
|
fps += ".00";
|
|
} else if (len == 4) {
|
|
fps += "0";
|
|
} else if (len > 5) {
|
|
fps = fps.substring(0, 5);
|
|
}
|
|
|
|
canvas.drawText(fps + " fps", width - 60.0f, 10.0f, mPaint);
|
|
}
|
|
|
|
if (mDisplayCounts) {
|
|
canvas.drawText(mTriangles + " triangles",
|
|
width - 100.0f, 10.0f + th + 5, mPaint);
|
|
}
|
|
}
|
|
|
|
private void addMessage(String key, String text, int durationMillis) {
|
|
long expirationTime = System.currentTimeMillis() + durationMillis;
|
|
|
|
mMessages.put(key, new Message(text, expirationTime));
|
|
}
|
|
|
|
private void addMessage(String key, String text) {
|
|
addMessage(key, text, DEFAULT_DURATION_MILLIS);
|
|
}
|
|
|
|
private void addMessage(String text) {
|
|
addMessage(text, text, DEFAULT_DURATION_MILLIS);
|
|
}
|
|
|
|
private void clearMessages() {
|
|
mMessages.clear();
|
|
}
|
|
|
|
String command = "";
|
|
|
|
private void toggleFilter() {
|
|
if (params[mParam] == GL10.GL_NEAREST) {
|
|
params[mParam] = GL10.GL_LINEAR;
|
|
} else {
|
|
params[mParam] = GL10.GL_NEAREST;
|
|
}
|
|
addMessage(commands[mParam],
|
|
"Texture " +
|
|
(mParam == TEXTURE_MIN_FILTER ? "min" : "mag") +
|
|
" filter = " +
|
|
(params[mParam] == GL10.GL_NEAREST ?
|
|
"nearest" : "linear"));
|
|
}
|
|
|
|
private void togglePerspectiveCorrection() {
|
|
if (params[mParam] == GL10.GL_NICEST) {
|
|
params[mParam] = GL10.GL_FASTEST;
|
|
} else {
|
|
params[mParam] = GL10.GL_NICEST;
|
|
}
|
|
addMessage(commands[mParam],
|
|
"Texture perspective correction = " +
|
|
(params[mParam] == GL10.GL_FASTEST ?
|
|
"fastest" : "nicest"));
|
|
}
|
|
|
|
private String valueString() {
|
|
if (mParam == TEXTURE_MIN_FILTER ||
|
|
mParam == TEXTURE_MAG_FILTER) {
|
|
if (params[mParam] == GL10.GL_NEAREST) {
|
|
return "nearest";
|
|
}
|
|
if (params[mParam] == GL10.GL_LINEAR) {
|
|
return "linear";
|
|
}
|
|
}
|
|
if (mParam == TEXTURE_PERSPECTIVE_CORRECTION) {
|
|
if (params[mParam] == GL10.GL_FASTEST) {
|
|
return "fastest";
|
|
}
|
|
if (params[mParam] == GL10.GL_NICEST) {
|
|
return "nicest";
|
|
}
|
|
}
|
|
return "" + params[mParam];
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @return true if the view
|
|
*/
|
|
public boolean hasMessages() {
|
|
return mState == HAVE_TWO || mDisplayFPS || mDisplayCounts;
|
|
}
|
|
|
|
/**
|
|
* Process a key stroke. The calling Activity should pass all
|
|
* keys from its onKeyDown method to this method. If the key is
|
|
* part of a GLView command, true is returned and the calling
|
|
* Activity should ignore the key event. Otherwise, false is
|
|
* returned and the calling Activity may process the key event
|
|
* normally.
|
|
*
|
|
* @param keyCode the key code as passed to Activity.onKeyDown.
|
|
*
|
|
* @return true if the key is part of a GLView command sequence,
|
|
* false otherwise.
|
|
*/
|
|
public boolean processKey(int keyCode) {
|
|
// Pressing the state key twice enters the UI
|
|
// Pressing it again exits the UI
|
|
if ((keyCode == STATE_KEY) ||
|
|
(keyCode == KeyEvent.KEYCODE_SLASH) ||
|
|
(keyCode == KeyEvent.KEYCODE_PERIOD))
|
|
{
|
|
mState = (mState + 1) % 3;
|
|
if (mState == HAVE_NONE) {
|
|
clearMessages();
|
|
}
|
|
if (mState == HAVE_TWO) {
|
|
clearMessages();
|
|
addMessage("aaaa", "GL", Integer.MAX_VALUE);
|
|
addMessage("aaab", "", Integer.MAX_VALUE);
|
|
command = "";
|
|
}
|
|
return true;
|
|
} else {
|
|
if (mState == HAVE_ONE) {
|
|
mState = HAVE_NONE;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// If we're not in the UI, exit without handling the key
|
|
if (mState != HAVE_TWO) {
|
|
return false;
|
|
}
|
|
|
|
if (keyCode == KeyEvent.KEYCODE_ENTER) {
|
|
command = "";
|
|
} else if (keyCode == KeyEvent.KEYCODE_DEL) {
|
|
if (command.length() > 0) {
|
|
command = command.substring(0, command.length() - 1);
|
|
}
|
|
|
|
} else if (keyCode >= KeyEvent.KEYCODE_A &&
|
|
keyCode <= KeyEvent.KEYCODE_Z) {
|
|
command += "" + (char)(keyCode - KeyEvent.KEYCODE_A + 'a');
|
|
}
|
|
|
|
addMessage("aaaa", "GL " + command, Integer.MAX_VALUE);
|
|
|
|
if (command.equals("h")) {
|
|
addMessage("aaaa", "GL", Integer.MAX_VALUE);
|
|
addMessage("h - help");
|
|
addMessage("fn/ff - frustum near/far clip Z");
|
|
addMessage("la/lar/lag/lab - abmient intensity/r/g/b");
|
|
addMessage("ld/ldr/ldg/ldb - diffuse intensity/r/g/b");
|
|
addMessage("ls/lsr/lsg/lsb - specular intensity/r/g/b");
|
|
addMessage("s - toggle statistics display");
|
|
addMessage("tmin/tmag - texture min/mag filter");
|
|
addMessage("tpersp - texture perspective correction");
|
|
addMessage("tx/ty/tz - view translate x/y/z");
|
|
addMessage("z - zoom");
|
|
command = "";
|
|
return true;
|
|
} else if (command.equals("s")) {
|
|
mDisplayCounts = !mDisplayCounts;
|
|
mDisplayFPS = !mDisplayFPS;
|
|
command = "";
|
|
return true;
|
|
}
|
|
|
|
mParam = -1;
|
|
for (int i = 0; i < commands.length; i++) {
|
|
if (command.equals(commands[i])) {
|
|
mParam = i;
|
|
mIncr = increments[i];
|
|
}
|
|
}
|
|
if (mParam == -1) {
|
|
return true;
|
|
}
|
|
|
|
boolean addMessage = true;
|
|
|
|
// Increment or decrement
|
|
if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT ||
|
|
keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
|
|
if (mParam == ZOOM_EXPONENT) {
|
|
params[mParam] += mIncr;
|
|
computeZoom();
|
|
} else if ((mParam == TEXTURE_MIN_FILTER) ||
|
|
(mParam == TEXTURE_MAG_FILTER)) {
|
|
toggleFilter();
|
|
} else if (mParam == TEXTURE_PERSPECTIVE_CORRECTION) {
|
|
togglePerspectiveCorrection();
|
|
} else {
|
|
params[mParam] += mIncr;
|
|
}
|
|
} else if (keyCode == KeyEvent.KEYCODE_DPAD_UP ||
|
|
keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
|
|
if (mParam == ZOOM_EXPONENT) {
|
|
params[mParam] -= mIncr;
|
|
computeZoom();
|
|
} else if ((mParam == TEXTURE_MIN_FILTER) ||
|
|
(mParam == TEXTURE_MAG_FILTER)) {
|
|
toggleFilter();
|
|
} else if (mParam == TEXTURE_PERSPECTIVE_CORRECTION) {
|
|
togglePerspectiveCorrection();
|
|
} else {
|
|
params[mParam] -= mIncr;
|
|
}
|
|
}
|
|
|
|
if (addMessage) {
|
|
addMessage(commands[mParam],
|
|
labels[mParam] + ": " + valueString());
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Zoom in by a given number of steps. A negative value of steps
|
|
* zooms out. Each step zooms in by 1%.
|
|
*
|
|
* @param steps the number of steps to zoom by.
|
|
*/
|
|
public void zoom(int steps) {
|
|
params[ZOOM_EXPONENT] += steps;
|
|
computeZoom();
|
|
}
|
|
|
|
/**
|
|
* Set the projection matrix using glFrustumf. The left and right
|
|
* clipping planes are set at -+(aspectRatio*zoom), the bottom and
|
|
* top clipping planes are set at -+zoom, and the near and far
|
|
* clipping planes are set to the values set by setNearFrustum and
|
|
* setFarFrustum or interactively.
|
|
*
|
|
* <p> GL side effects:
|
|
* <ul>
|
|
* <li>overwrites the matrix mode</li>
|
|
* <li>overwrites the projection matrix</li>
|
|
* </ul>
|
|
*
|
|
* @param gl a GL10 instance whose projection matrix is to be modified.
|
|
*/
|
|
public void setProjection(GL10 gl) {
|
|
gl.glMatrixMode(GL10.GL_PROJECTION);
|
|
gl.glLoadIdentity();
|
|
|
|
if (mAspectRatio >= 1.0f) {
|
|
gl.glFrustumf(-mAspectRatio*mZoom, mAspectRatio*mZoom,
|
|
-mZoom, mZoom,
|
|
params[NEAR_FRUSTUM], params[FAR_FRUSTUM]);
|
|
} else {
|
|
gl.glFrustumf(-mZoom, mZoom,
|
|
-mZoom / mAspectRatio, mZoom / mAspectRatio,
|
|
params[NEAR_FRUSTUM], params[FAR_FRUSTUM]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set the modelview matrix using glLoadIdentity and glTranslatef.
|
|
* The translation values are set interactively.
|
|
*
|
|
* <p> GL side effects:
|
|
* <ul>
|
|
* <li>overwrites the matrix mode</li>
|
|
* <li>overwrites the modelview matrix</li>
|
|
* </ul>
|
|
*
|
|
* @param gl a GL10 instance whose modelview matrix is to be modified.
|
|
*/
|
|
public void setView(GL10 gl) {
|
|
gl.glMatrixMode(GL10.GL_MODELVIEW);
|
|
gl.glLoadIdentity();
|
|
|
|
// Move the viewpoint backwards
|
|
gl.glTranslatef(params[TRANSLATE_X],
|
|
params[TRANSLATE_Y],
|
|
params[TRANSLATE_Z]);
|
|
}
|
|
|
|
/**
|
|
* Sets texture parameters.
|
|
*
|
|
* <p> GL side effects:
|
|
* <ul>
|
|
* <li>sets the GL_PERSPECTIVE_CORRECTION_HINT</li>
|
|
* <li>sets the GL_TEXTURE_MIN_FILTER texture parameter</li>
|
|
* <li>sets the GL_TEXTURE_MAX_FILTER texture parameter</li>
|
|
* </ul>
|
|
*
|
|
* @param gl a GL10 instance whose texture parameters are to be modified.
|
|
*/
|
|
public void setTextureParameters(GL10 gl) {
|
|
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
|
|
(int)params[TEXTURE_PERSPECTIVE_CORRECTION]);
|
|
gl.glTexParameterf(GL10.GL_TEXTURE_2D,
|
|
GL10.GL_TEXTURE_MIN_FILTER,
|
|
params[TEXTURE_MIN_FILTER]);
|
|
gl.glTexParameterf(GL10.GL_TEXTURE_2D,
|
|
GL10.GL_TEXTURE_MAG_FILTER,
|
|
params[TEXTURE_MAG_FILTER]);
|
|
}
|
|
|
|
/**
|
|
* Sets the lighting parameters for the given light.
|
|
*
|
|
* <p> GL side effects:
|
|
* <ul>
|
|
* <li>sets the GL_LIGHT_MODEL_AMBIENT intensities
|
|
* <li>sets the GL_AMBIENT intensities for the given light</li>
|
|
* <li>sets the GL_DIFFUSE intensities for the given light</li>
|
|
* <li>sets the GL_SPECULAR intensities for the given light</li>
|
|
* </ul>
|
|
*
|
|
* @param gl a GL10 instance whose texture parameters are to be modified.
|
|
*/
|
|
public void setLights(GL10 gl, int lightNum) {
|
|
float[] light = new float[4];
|
|
light[3] = 1.0f;
|
|
|
|
float lmi = params[LIGHT_MODEL_AMBIENT_INTENSITY];
|
|
light[0] = params[LIGHT_MODEL_AMBIENT_RED]*lmi;
|
|
light[1] = params[LIGHT_MODEL_AMBIENT_GREEN]*lmi;
|
|
light[2] = params[LIGHT_MODEL_AMBIENT_BLUE]*lmi;
|
|
gl.glLightModelfv(GL10.GL_LIGHT_MODEL_AMBIENT, light, 0);
|
|
|
|
float ai = params[AMBIENT_INTENSITY];
|
|
light[0] = params[AMBIENT_RED]*ai;
|
|
light[1] = params[AMBIENT_GREEN]*ai;
|
|
light[2] = params[AMBIENT_BLUE]*ai;
|
|
gl.glLightfv(lightNum, GL10.GL_AMBIENT, light, 0);
|
|
|
|
float di = params[DIFFUSE_INTENSITY];
|
|
light[0] = params[DIFFUSE_RED]*di;
|
|
light[1] = params[DIFFUSE_GREEN]*di;
|
|
light[2] = params[DIFFUSE_BLUE]*di;
|
|
gl.glLightfv(lightNum, GL10.GL_DIFFUSE, light, 0);
|
|
|
|
float si = params[SPECULAR_INTENSITY];
|
|
light[0] = params[SPECULAR_RED]*si;
|
|
light[1] = params[SPECULAR_GREEN]*si;
|
|
light[2] = params[SPECULAR_BLUE]*si;
|
|
gl.glLightfv(lightNum, GL10.GL_SPECULAR, light, 0);
|
|
}
|
|
}
|