Extract GLCanvas interface and start testing.
Change-Id: Ice3a4e92ab1cd45e296b9370b2ab97347ad31299
diff --git a/new3d/src/com/android/gallery3d/anim/AlphaAnimation.java b/new3d/src/com/android/gallery3d/anim/AlphaAnimation.java
index d806885..c55d7c2 100644
--- a/new3d/src/com/android/gallery3d/anim/AlphaAnimation.java
+++ b/new3d/src/com/android/gallery3d/anim/AlphaAnimation.java
@@ -23,7 +23,7 @@
@Override
public int getCanvasSaveFlags() {
- return GLCanvas.ALPHA_SAVE_FLAG;
+ return GLCanvas.SAVE_FLAG_ALPHA;
}
@Override
diff --git a/new3d/src/com/android/gallery3d/anim/ScaleAnimation.java b/new3d/src/com/android/gallery3d/anim/ScaleAnimation.java
index f5dca50..f065cf7 100644
--- a/new3d/src/com/android/gallery3d/anim/ScaleAnimation.java
+++ b/new3d/src/com/android/gallery3d/anim/ScaleAnimation.java
@@ -51,7 +51,7 @@
@Override
public int getCanvasSaveFlags() {
- return GLCanvas.MATRIX_SAVE_FLAG;
+ return GLCanvas.SAVE_FLAG_MATRIX;
}
@Override
diff --git a/new3d/src/com/android/gallery3d/ui/DisplayItemPanel.java b/new3d/src/com/android/gallery3d/ui/DisplayItemPanel.java
index ba6ec37..8b9a4bd 100644
--- a/new3d/src/com/android/gallery3d/ui/DisplayItemPanel.java
+++ b/new3d/src/com/android/gallery3d/ui/DisplayItemPanel.java
@@ -19,8 +19,8 @@
// The state of the items that changed position
private static final int STATE_MOVED = 3;
- private static final long NO_ANIMATION = -1;
- private static final long START_ANIMATION = 0;
+ private static final long START_ANIMATION = -1;
+ private static final long NO_ANIMATION = -2;
private ArrayList<DisplayItem> mItems = new ArrayList<DisplayItem>();
@@ -114,7 +114,7 @@
}
private void renderItem(GLCanvas canvas, DisplayItem item) {
- canvas.save(GLCanvas.ALPHA_SAVE_FLAG | GLCanvas.MATRIX_SAVE_FLAG);
+ canvas.save(GLCanvas.SAVE_FLAG_ALPHA | GLCanvas.SAVE_FLAG_MATRIX);
item.mCurrent.apply(canvas);
item.render(canvas);
canvas.restore();
@@ -122,7 +122,7 @@
private void renderItem(
GLCanvas canvas, DisplayItem item, float interpolate) {
- canvas.save(GLCanvas.ALPHA_SAVE_FLAG | GLCanvas.MATRIX_SAVE_FLAG);
+ canvas.save(GLCanvas.SAVE_FLAG_ALPHA | GLCanvas.SAVE_FLAG_MATRIX);
switch (item.mState) {
case STATE_MOVED:
item.updateCurrentPosition(interpolate);
diff --git a/new3d/src/com/android/gallery3d/ui/GLCanvas.java b/new3d/src/com/android/gallery3d/ui/GLCanvas.java
index 770cac4..5560098 100644
--- a/new3d/src/com/android/gallery3d/ui/GLCanvas.java
+++ b/new3d/src/com/android/gallery3d/ui/GLCanvas.java
@@ -2,773 +2,109 @@
import android.graphics.Rect;
import android.graphics.RectF;
-import android.opengl.GLU;
-import android.opengl.Matrix;
+import android.view.animation.Transformation;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.FloatBuffer;
import java.util.Collection;
-import java.util.Stack;
-import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;
-import javax.microedition.khronos.opengles.GL11Ext;
-public class GLCanvas {
+//
+// GLCanvas gives a convenient interface to draw using OpenGL.
+//
+// When a rectangle is specified in this interface, it means the region
+// [x, x+width) * [y, y+height)
+//
+public interface GLCanvas {
+ // Tells GLCanvas the size of the underlying GL surface. This should be
+ // called before first drawing and when the size of GL surface is changed.
+ // This is called by GLRootView and should not be called by the clients
+ // who only want to draw on the GLCanvas.
+ public void setSize(int width, int height);
- public static final int ALL_SAVE_FLAG = 0xFFFFFFFF;
- public static final int CLIP_SAVE_FLAG = 0x01;
- public static final int ALPHA_SAVE_FLAG = 0x02;
- public static final int MATRIX_SAVE_FLAG = 0x04;
+ // Clear the drawing buffers. This should only be used by GLRootView.
+ public void clearBuffer();
- // We need 16 vertices for a normal nine-patch image (the 4x4 vertices)
- private static final int VERTEX_BUFFER_SIZE = 16 * 2;
+ // This is the time value used to calculate the animation in the current
+ // frame. The "set" function should only called by GLRootView, and the
+ // "time" parameter must be nonnegative.
+ public void setCurrentAnimationTimeMillis(long time);
+ public long currentAnimationTimeMillis();
- // We need 22 indices for a normal nine-patch image
- private static final int INDEX_BUFFER_SIZE = 22;
+ // Sets the current drawing color used for drawLine and fillRect.
+ public void setColor(int color);
- private static final float OPAQUE_ALPHA = 0.95f;
+ // Sets and gets the current alpha
+ public void setAlpha(float alpha);
+ public float getAlpha();
- private final GL11 mGL;
+ // (current alpha) = (current alpha) * alpha
+ public void multiplyAlpha(float alpha);
- private final float mMatrixValues[] = new float[16];
+ public void translate(float x, float y, float z);
+ public void scale(float sx, float sy, float sz);
+ public void rotate(float angle, float x, float y, float z);
- private final float mUvBuffer[] = new float[VERTEX_BUFFER_SIZE];
- private final float mXyBuffer[] = new float[VERTEX_BUFFER_SIZE];
- private final byte mIndexBuffer[] = new byte[INDEX_BUFFER_SIZE];
+ // Modifies the current clip with the specified rectangle.
+ // (current clip) = (current clip) intersect (specified rectangle).
+ // Returns true if the result clip is non-empty.
+ public boolean clipRect(int x, int y, int width, int height);
- private final int mNinePatchX[] = new int[4];
- private final int mNinePatchY[] = new int[4];
- private final float mNinePatchU[] = new float[4];
- private final float mNinePatchV[] = new float[4];
- private final float mTextureColor[] = new float[4];
+ // Pushes the configuration state (matrix, alpha, and clip) onto
+ // a private stack.
+ public int save();
- private FloatBuffer mXyPointer;
- private FloatBuffer mUvPointer;
- private ByteBuffer mIndexPointer;
+ // Same as save(), but only save those specified in saveFlags.
+ public int save(int saveFlags);
- private final GLState mGLState;
+ public static final int SAVE_FLAG_ALL = 0xFFFFFFFF;
+ public static final int SAVE_FLAG_CLIP = 0x01;
+ public static final int SAVE_FLAG_ALPHA = 0x02;
+ public static final int SAVE_FLAG_MATRIX = 0x04;
- private long mAnimationTime;
+ // Pops from the top of the stack as current configuration state (matrix,
+ // alpha, and clip). This call balances a previous call to save(), and is
+ // used to remove all modifications to the configuration state since the
+ // last save call.
+ public void restore();
- private float mAlpha;
- private final Rect mClipRect = new Rect();
- private final Stack<ConfigState> mRestoreStack =
- new Stack<ConfigState>();
- private ConfigState mRecycledRestoreAction;
+ // Draws a line using current drawing color from (x1, y1) to (x2, y2).
+ // (Both end points are included).
+ public void drawLine(int x1, int y1, int x2, int y2);
- GLCanvas(GL11 gl) {
- mGL = gl;
- mGLState = new GLState(gl);
- initialize();
- }
+ // Fills the specified rectange with the current drawing color or
+ // the color of texture.
+ public void fillRect(int x, int y, int width, int height);
+ public void fillRect(Rect r);
- public void setSize(int width, int height) {
- GL11 gl = mGL;
- gl.glViewport(0, 0, width, height);
- gl.glMatrixMode(GL11.GL_PROJECTION);
- gl.glLoadIdentity();
- GLU.gluOrtho2D(gl, 0, width, 0, height);
+ // Sets the texture coordinates for fillRect calls.
+ public void setTextureCoords(RectF source);
- gl.glMatrixMode(GL11.GL_MODELVIEW);
- gl.glLoadIdentity();
-
- // The positive direction in Y coordinate in OpenGL is from bottom to
- // top, which is different from the coordinate system in Java. So, we
- // flip it here.
- float matrix[] = mMatrixValues;
- Matrix.setIdentityM(matrix, 0);
- Matrix.translateM(matrix, 0, 0, height, 0);
- Matrix.scaleM(matrix, 0, 1, -1, 1);
-
- mClipRect.set(0, 0, width, height);
- gl.glScissor(0, 0, width, height);
- }
-
- public long currentAnimationTimeMillis() {
- return mAnimationTime;
- }
-
- public void setAlpha(float alpha) {
- mAlpha = alpha;
- }
-
- public void multiplyAlpha(float alpha) {
- mAlpha *= alpha;
- }
-
- public float getAlpha() {
- return mAlpha;
- }
-
- private static ByteBuffer allocateDirectNativeOrderBuffer(int size) {
- return ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder());
- }
-
- private void initialize() {
- int size = VERTEX_BUFFER_SIZE * Float.SIZE / Byte.SIZE;
- mXyPointer = allocateDirectNativeOrderBuffer(size).asFloatBuffer();
- mUvPointer = allocateDirectNativeOrderBuffer(size).asFloatBuffer();
- mIndexPointer = allocateDirectNativeOrderBuffer(INDEX_BUFFER_SIZE);
-
- GL11 gl = mGL;
-
- gl.glVertexPointer(2, GL11.GL_FLOAT, 0, mXyPointer);
- gl.glTexCoordPointer(2, GL11.GL_FLOAT, 0, mUvPointer);
-
- // Enable the texture coordinate array for Texture 1
- gl.glClientActiveTexture(GL11.GL_TEXTURE1);
- gl.glTexCoordPointer(2, GL11.GL_FLOAT, 0, mUvPointer);
- gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
-
- // mMatrixValues will be initialized in setSize()
- mAlpha = 1.0f;
- }
-
- private static void putRectangle(float x, float y,
- float width, float height, float[] buffer, FloatBuffer pointer) {
- buffer[0] = x;
- buffer[1] = y;
- buffer[2] = x + width;
- buffer[3] = y;
- buffer[4] = x;
- buffer[5] = y + height;
- buffer[6] = x + width;
- buffer[7] = y + height;
- pointer.put(buffer, 0, 8).position(0);
- }
-
- public void setColor(int color) {
- float alpha = mAlpha;
- mGLState.setBlendEnabled(!Util.isOpaque(color) || alpha < OPAQUE_ALPHA);
- mGLState.setFragmentColor(color, alpha);
- }
-
- public void drawLine(int x1, int y1, int x2, int y2) {
- GL11 gl = mGL;
- gl.glLoadMatrixf(mMatrixValues, 0);
- float buffer[] = mXyBuffer;
- buffer[0] = x1;
- buffer[1] = y1;
- buffer[2] = x2;
- buffer[3] = y2;
- mXyPointer.put(buffer, 0, 4).position(0);
- gl.glDrawArrays(GL11.GL_LINE_STRIP, 0, 2);
- }
-
- public void fillRect(Rect r) {
- fillRect(r.left, r.top, r.right - r.left, r.bottom - r.top);
- }
-
- public void translate(float x, float y, float z) {
- Matrix.translateM(mMatrixValues, 0, x, y, z);
- }
-
- public void scale(float sx, float sy, float sz) {
- Matrix.scaleM(mMatrixValues, 0, sx, sy, sz);
- }
-
- public void rotate(float angle, float x, float y, float z) {
- Matrix.rotateM(mMatrixValues, 0, angle, x, y, z);
- }
-
- public void fillRect(int x, int y, int width, int height) {
- GL11 gl = mGL;
- gl.glLoadMatrixf(mMatrixValues, 0);
- putRectangle(x, y, width, height, mXyBuffer, mXyPointer);
- gl.glDrawArrays(GL11.GL_TRIANGLE_STRIP, 0, 4);
- }
-
- public void drawNinePatch(
- NinePatchTexture tex, int x, int y, int width, int height) {
- float alpha = mAlpha;
- NinePatchChunk chunk = tex.getNinePatchChunk();
-
- mGLState.setTexture2DEnabled(true);
-
- // The code should be easily extended to handle the general cases by
- // allocating more space for buffers. But let's just handle the only
- // use case.
- if (chunk.mDivX.length != 2 || chunk.mDivY.length != 2) {
- throw new RuntimeException("unsupported nine patch");
- }
- tex.bind(this);
- if (width <= 0 || height <= 0) return ;
-
- int divX[] = mNinePatchX;
- int divY[] = mNinePatchY;
- float divU[] = mNinePatchU;
- float divV[] = mNinePatchV;
-
- int nx = stretch(divX, divU, chunk.mDivX, tex.getWidth(), width);
- int ny = stretch(divY, divV, chunk.mDivY, tex.getHeight(), height);
- mGLState.setBlendEnabled(!tex.isOpaque() || alpha < OPAQUE_ALPHA);
-
- mGLState.setTextureAlpha(alpha);
-
- GL11 gl = mGL;
- gl.glLoadMatrixf(mMatrixValues, 0);
- gl.glTranslatef(x, y, 0);
- drawMesh(divX, divY, divU, divV, nx, ny);
- }
-
- /**
- * Stretches the texture according to the nine-patch rules. It will
- * linearly distribute the strechy parts defined in the nine-patch chunk to
- * the target area.
- *
- * <pre>
- * source
- * /--------------^---------------\
- * u0 u1 u2 u3 u4 u5
- * div ---> |fffff|ssssssss|fff|ssssss|ffff| ---> u
- * | div0 div1 div2 div3 |
- * | | / / / /
- * | | / / / /
- * | | / / / /
- * |fffff|ssss|fff|sss|ffff| ---> x
- * x0 x1 x2 x3 x4 x5
- * \----------v------------/
- * target
- *
- * f: fixed segment
- * s: stretchy segment
- * </pre>
- *
- * @param div the stretch parts defined in nine-patch chunk
- * @param source the length of the texture
- * @param target the length on the drawing plan
- * @param u output, the positions of these dividers in the texture
- * coordinate
- * @param x output, the corresponding position of these dividers on the
- * drawing plan
- * @return the number of these dividers.
- */
- private int stretch(
- int x[], float u[], int div[], int source, int target) {
- int textureSize = Util.nextPowerOf2(source);
- float textureBound = (source - 0.5f) / textureSize;
-
- int stretch = 0;
- for (int i = 0, n = div.length; i < n; i += 2) {
- stretch += div[i + 1] - div[i];
- }
-
- float remaining = target - source + stretch;
-
- int lastX = 0;
- int lastU = 0;
-
- x[0] = 0;
- u[0] = 0;
- for (int i = 0, n = div.length; i < n; i += 2) {
- // fixed segment
- x[i + 1] = lastX + (div[i] - lastU);
- u[i + 1] = Math.min((float) div[i] / textureSize, textureBound);
-
- // stretchy segment
- float partU = div[i + 1] - div[i];
- int partX = (int)(remaining * partU / stretch + 0.5f);
- remaining -= partX;
- stretch -= partU;
-
- lastX = x[i + 1] + partX;
- lastU = div[i + 1];
- x[i + 2] = lastX;
- u[i + 2] = Math.min((float) lastU / textureSize, textureBound);
- }
- // the last fixed segment
- x[div.length + 1] = target;
- u[div.length + 1] = textureBound;
-
- // remove segments with length 0.
- int last = 0;
- for (int i = 1, n = div.length + 2; i < n; ++i) {
- if (x[last] == x[i]) continue;
- x[++last] = x[i];
- u[last] = u[i];
- }
- return last + 1;
- }
-
- private void drawMesh(
- int x[], int y[], float u[], float v[], int nx, int ny) {
- /*
- * Given a 3x3 nine-patch image, the vertex order is defined as the
- * following graph:
- *
- * (0) (1) (2) (3)
- * | /| /| /|
- * | / | / | / |
- * (4) (5) (6) (7)
- * | \ | \ | \ |
- * | \| \| \|
- * (8) (9) (A) (B)
- * | /| /| /|
- * | / | / | / |
- * (C) (D) (E) (F)
- *
- * And we draw the triangle strip in the following index order:
- *
- * index: 04152637B6A5948C9DAEBF
- */
- int pntCount = 0;
- float xy[] = mXyBuffer;
- float uv[] = mUvBuffer;
- for (int j = 0; j < ny; ++j) {
- for (int i = 0; i < nx; ++i) {
- int xIndex = (pntCount++) << 1;
- int yIndex = xIndex + 1;
- xy[xIndex] = x[i];
- xy[yIndex] = y[j];
- uv[xIndex] = u[i];
- uv[yIndex] = v[j];
- }
- }
- mUvPointer.put(uv, 0, pntCount << 1).position(0);
- mXyPointer.put(xy, 0, pntCount << 1).position(0);
-
- int idxCount = 1;
- byte index[] = mIndexBuffer;
- for (int i = 0, bound = nx * (ny - 1); true;) {
- // normal direction
- --idxCount;
- for (int j = 0; j < nx; ++j, ++i) {
- index[idxCount++] = (byte) i;
- index[idxCount++] = (byte) (i + nx);
- }
- if (i >= bound) break;
-
- // reverse direction
- int sum = i + i + nx - 1;
- --idxCount;
- for (int j = 0; j < nx; ++j, ++i) {
- index[idxCount++] = (byte) (sum - i);
- index[idxCount++] = (byte) (sum - i + nx);
- }
- if (i >= bound) break;
- }
- mIndexPointer.put(index, 0, idxCount).position(0);
-
- mGL.glDrawElements(GL11.GL_TRIANGLE_STRIP,
- idxCount, GL11.GL_UNSIGNED_BYTE, mIndexPointer);
- }
-
- private float[] mapPoints(float matrix[], int x1, int y1, int x2, int y2) {
- float[] point = mXyBuffer;
- int srcOffset = 6;
- point[srcOffset] = x1;
- point[srcOffset + 1] = y1;
- point[srcOffset + 2] = 0;
- point[srcOffset + 3] = 1;
-
- int resultOffset = 0;
- Matrix.multiplyMV(point, resultOffset, matrix, 0, point, srcOffset);
- point[resultOffset] /= point[resultOffset + 3];
- point[resultOffset + 1] /= point[resultOffset + 3];
-
- // map the second point
- point[srcOffset] = x2;
- point[srcOffset + 1] = y2;
- resultOffset = 2;
- Matrix.multiplyMV(point, resultOffset, matrix, 0, point, srcOffset);
- point[resultOffset] /= point[resultOffset + 3];
- point[resultOffset + 1] /= point[resultOffset + 3];
-
- return point;
- }
-
-
- public boolean clipRect(int left, int top, int right, int bottom) {
- float point[] = mapPoints(mMatrixValues, left, top, right, bottom);
-
- // mMatrix could be a rotation matrix. In this case, we need to find
- // the boundaries after rotation. (only handle 90 * n degrees)
- if (point[0] > point[2]) {
- left = (int) point[2];
- right = (int) point[0];
- } else {
- left = (int) point[0];
- right = (int) point[2];
- }
- if (point[1] > point[3]) {
- top = (int) point[3];
- bottom = (int) point[1];
- } else {
- top = (int) point[1];
- bottom = (int) point[3];
- }
- Rect clip = mClipRect;
-
- boolean intersect = clip.intersect(left, top, right, bottom);
- if (!intersect) clip.set(0, 0, 0, 0);
- mGL.glScissor(clip.left, clip.top, clip.width(), clip.height());
- return intersect;
- }
-
- public void drawColor(int x, int y, int width, int height, int color) {
- float alpha = mAlpha;
- mGLState.setBlendEnabled(!Util.isOpaque(color) || alpha < OPAQUE_ALPHA);
- mGLState.setFragmentColor(color, alpha);
- fillRect(x, y, width, height);
- }
-
- private void drawBoundTexture(
- BasicTexture texture, int x, int y, int width, int height) {
- // Test whether it has been rotated or flipped, if so, glDrawTexiOES
- // won't work
- if (isMatrixRotatedOrFlipped(mMatrixValues)) {
- putRectangle(0, 0,
- (texture.mWidth - 0.5f) / texture.mTextureWidth,
- (texture.mHeight - 0.5f) / texture.mTextureHeight,
- mUvBuffer, mUvPointer);
- fillRect(x, y, width, height);
- } else {
- // draw the rect from bottom-left to top-right
- float points[] = mapPoints(
- mMatrixValues, x, y + height, x + width, y);
- x = (int) points[0];
- y = (int) points[1];
- width = (int) points[2] - x;
- height = (int) points[3] - y;
- if (width > 0 && height > 0) {
- ((GL11Ext) mGL).glDrawTexiOES(x, y, 0, width, height);
- }
- }
-
- }
-
+ // Draws a texture to the specified rectangle.
public void drawTexture(
- BasicTexture texture, int x, int y, int width, int height) {
- drawTexture(texture, x, y, width, height, mAlpha);
- }
+ BasicTexture texture, int x, int y, int width, int height);
+ public void drawNinePatch(
+ NinePatchTexture tex, int x, int y, int width, int height);
+ // Draws a texture to the specified rectangle. The "alpha" parameter
+ // overrides the current drawing alpha value.
public void drawTexture(BasicTexture texture,
- int x, int y, int width, int height, float alpha) {
- if (width <= 0 || height <= 0) return ;
+ int x, int y, int width, int height, float alpha);
- mGLState.setBlendEnabled(!texture.isOpaque() || alpha < OPAQUE_ALPHA);
- mGLState.setTexture2DEnabled(true);
- texture.bind(this);
- mGLState.setTextureAlpha(alpha);
- drawBoundTexture(texture, x, y, width, height);
- }
+ // Draw two textures to the specified rectange. The actual texture used is
+ // from * (1 - ratio) + to * ratio
+ public void drawMixed(BasicTexture from, BasicTexture to,
+ float ratio, int x, int y, int w, int h);
public void drawMixed(BasicTexture from, BasicTexture to,
- float ratio, int x, int y, int w, int h) {
- drawMixed(from, to, ratio, x, y, w, h, mAlpha);
- }
+ float ratio, int x, int y, int width, int height, float alpha);
- private void setTextureColor(float r, float g, float b, float alpha) {
- float[] color = mTextureColor;
- color[0] = r;
- color[1] = g;
- color[2] = b;
- color[3] = alpha;
- }
-
- public void handleLowMemory() {
- }
-
- public void drawMixed(BasicTexture from, BasicTexture to,
- float ratio, int x, int y, int width, int height, float alpha) {
- if (alpha < OPAQUE_ALPHA) {
- throw new RuntimeException("Cannot support alpha value");
- }
- mGLState.setBlendEnabled(!from.isOpaque() || !to.isOpaque());
- mGLState.setTextureAlpha(1);
- mGLState.setTexture2DEnabled(true);
-
- final GL11 gl = mGL;
- from.bind(this);
-
- gl.glActiveTexture(GL11.GL_TEXTURE1);
- to.bind(this);
- gl.glEnable(GL11.GL_TEXTURE_2D);
-
- // Interpolate the RGB and alpha values between both textures.
- mGLState.setTexEnvMode(GL11.GL_COMBINE);
- gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_COMBINE_RGB, GL11.GL_INTERPOLATE);
- gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_COMBINE_ALPHA, GL11.GL_INTERPOLATE);
-
- // Specify the interpolation factor via the alpha component of
- // GL_TEXTURE_ENV_COLORes.
- setTextureColor(ratio, ratio, ratio, ratio);
- gl.glTexEnvfv(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_COLOR, mTextureColor, 0);
-
- // Wire up the interpolation factor for RGB.
- gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_SRC2_RGB, GL11.GL_CONSTANT);
- gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_OPERAND2_RGB, GL11.GL_SRC_ALPHA);
-
- // Wire up the interpolation factor for alpha.
- gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_SRC2_ALPHA, GL11.GL_CONSTANT);
- gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_OPERAND2_ALPHA, GL11.GL_SRC_ALPHA);
-
- // Draw the combined texture.
- drawBoundTexture(to, x, y, width, height);
-
- // Disable TEXTURE1.
- gl.glDisable(GL11.GL_TEXTURE_2D);
- // Switch back to the default texture unit.
- gl.glActiveTexture(GL11.GL_TEXTURE0);
- }
-
- // TODO: the code only work for 2D should get fixed for 3D or removed
- private static final int MSKEW_X = 4;
- private static final int MSKEW_Y = 1;
- private static final int MSCALE_X = 0;
- private static final int MSCALE_Y = 5;
-
- private static boolean isMatrixRotatedOrFlipped(float matrix[]) {
- return matrix[MSKEW_X] != 0 || matrix[MSKEW_Y] != 0
- || matrix[MSCALE_X] < 0 || matrix[MSCALE_Y] > 0;
- }
-
+ // Copies the specified rectangle to the RawTexture.
public void copyTexture2D(
- RawTexture texture, int x, int y, int width, int height) {
+ RawTexture texture, int x, int y, int width, int height);
- if (isMatrixRotatedOrFlipped(mMatrixValues)) {
- throw new IllegalArgumentException("cannot support rotated matrix");
- }
- float points[] = mapPoints(mMatrixValues, x, y + height, x + width, y);
- x = (int) points[0];
- y = (int) points[1];
- width = (int) points[2] - x;
- height = (int) points[3] - y;
+ // TODO: Remove this or document it.
+ public void releaseTextures(Collection<? extends BasicTexture> c);
- GL11 gl = mGL;
- int newWidth = Util.nextPowerOf2(width);
- int newHeight = Util.nextPowerOf2(height);
- int glError = GL11.GL_NO_ERROR;
-
- gl.glBindTexture(GL11.GL_TEXTURE_2D, texture.getId());
-
- int[] cropRect = {0, 0, width, height};
- gl.glTexParameteriv(GL11.GL_TEXTURE_2D,
- GL11Ext.GL_TEXTURE_CROP_RECT_OES, cropRect, 0);
- gl.glTexParameteri(GL11.GL_TEXTURE_2D,
- GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP_TO_EDGE);
- gl.glTexParameteri(GL11.GL_TEXTURE_2D,
- GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP_TO_EDGE);
- gl.glTexParameterf(GL11.GL_TEXTURE_2D,
- GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
- gl.glTexParameterf(GL11.GL_TEXTURE_2D,
- GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
- gl.glCopyTexImage2D(GL11.GL_TEXTURE_2D, 0,
- GL11.GL_RGBA, x, y, newWidth, newHeight, 0);
- glError = gl.glGetError();
-
- if (glError == GL11.GL_OUT_OF_MEMORY) {
- throw new GLOutOfMemoryException();
- }
-
- if (glError != GL11.GL_NO_ERROR) {
- throw new RuntimeException(
- "Texture copy fail, glError " + glError);
- }
-
- texture.setSize(width, height);
- texture.setTextureSize(newWidth, newHeight);
- }
-
- private static class GLState {
-
- private final GL11 mGL;
-
- private int mTexEnvMode = GL11.GL_REPLACE;
- private float mTextureAlpha = 1.0f;
- private boolean mTexture2DEnabled = true;
- private boolean mBlendEnabled = true;
-
- public GLState(GL11 gl) {
- mGL = gl;
-
- // Disable unused state
- gl.glDisable(GL11.GL_LIGHTING);
-
- // Enable used features
- gl.glEnable(GL11.GL_DITHER);
-
- gl.glEnable(GL11.GL_SCISSOR_TEST);
- gl.glEnable(GL11.GL_STENCIL_TEST);
-
- gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
- gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
- gl.glEnable(GL11.GL_TEXTURE_2D);
-
- gl.glTexEnvf(GL11.GL_TEXTURE_ENV,
- GL11.GL_TEXTURE_ENV_MODE, GL11.GL_REPLACE);
-
- // Set the background color
- gl.glClearColor(0f, 0f, 0f, 0f);
- gl.glClearStencil(0);
-
- gl.glEnable(GL11.GL_BLEND);
- gl.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- }
-
- public void setTexEnvMode(int mode) {
- if (mTexEnvMode == mode) return;
- mTexEnvMode = mode;
- mGL.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, mode);
- }
-
- public void setTextureAlpha(float alpha) {
- if (mTextureAlpha == alpha) return;
- mTextureAlpha = alpha;
- if (alpha >= OPAQUE_ALPHA) {
- // The alpha is need for those texture without alpha channel
- mGL.glColor4f(1, 1, 1, 1);
- setTexEnvMode(GL11.GL_REPLACE);
- } else {
- mGL.glColor4f(alpha, alpha, alpha, alpha);
- setTexEnvMode(GL11.GL_MODULATE);
- }
- }
-
- public void setFragmentColor(int color, float alpha) {
- // Set mTextureAlpha to an invalid value, so that it will reset
- // again in setTextureAlpha(float) later.
- mTextureAlpha = -1.0f;
-
- setTexture2DEnabled(false);
- int prealpha = (int) ((color >>> 24) * alpha + 0.5);
- mGL.glColor4x(
- ((color >> 16) & 0xFF) * prealpha,
- ((color >> 8) & 0xFF) * prealpha,
- (color & 0xFF) * prealpha, prealpha << 8);
- }
-
- public void setTexture2DEnabled(boolean enabled) {
- if (mTexture2DEnabled == enabled) return;
- mTexture2DEnabled = enabled;
- if (enabled) {
- mGL.glEnable(GL11.GL_TEXTURE_2D);
- } else {
- mGL.glDisable(GL11.GL_TEXTURE_2D);
- }
- }
-
- public void setBlendEnabled(boolean enabled) {
- if (mBlendEnabled == enabled) return;
- mBlendEnabled = enabled;
- if (enabled) {
- mGL.glEnable(GL11.GL_BLEND);
- } else {
- mGL.glDisable(GL11.GL_BLEND);
- }
- }
- }
-
- public GL11 getGLInstance() {
- return mGL;
- }
-
- protected void setCurrentTimeMillis(long time) {
- mAnimationTime = time;
- }
-
- public void clearBuffer() {
- mGL.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_STENCIL_BUFFER_BIT);
- }
-
- public void setTextureCoords(RectF source) {
- float buffer[] = mUvBuffer;
- buffer[0] = source.left;
- buffer[1] = source.top;
- buffer[2] = source.right;
- buffer[3] = source.top;
- buffer[4] = source.left;
- buffer[5] = source.bottom;
- buffer[6] = source.right;
- buffer[7] = source.bottom;
- mUvPointer.put(buffer, 0, 8).position(0);
- }
-
- public void releaseTextures(Collection<? extends BasicTexture> c) {
- IntArray array = new IntArray();
- for (BasicTexture t : c) {
- if (t.isLoaded(this)) array.add(t.mId);
- }
- if (array.size() > 0) {
- mGL.glDeleteTextures(array.size(), array.toArray(null), 0);
- }
- }
-
- public int save() {
- return save(ALL_SAVE_FLAG);
- }
-
- public int save(int saveFlags) {
- ConfigState config = obtainRestoreConfig();
-
- if ((saveFlags & ALPHA_SAVE_FLAG) != 0) {
- config.mAlpha = mAlpha;
- } else {
- config.mAlpha = -1;
- }
-
- if ((saveFlags & CLIP_SAVE_FLAG) != 0) {
- config.mRect.set(mClipRect);
- } else {
- config.mRect.left = Integer.MAX_VALUE;
- }
-
- if ((saveFlags & MATRIX_SAVE_FLAG) != 0) {
- System.arraycopy(mMatrixValues, 0, config.mMatrix, 0, 16);
- } else {
- config.mMatrix[0] = Float.NEGATIVE_INFINITY;
- }
-
- mRestoreStack.push(config);
- return mRestoreStack.size() - 1;
- }
-
- public void restore() {
- if (mRestoreStack.isEmpty()) throw new IllegalStateException();
- ConfigState config = mRestoreStack.pop();
- config.restore(this);
- freeRestoreConfig(config);
- }
-
- public void restoreToCount(int saveCount) {
- while (mRestoreStack.size() > saveCount) {
- restore();
- }
- }
-
- private void freeRestoreConfig(ConfigState action) {
- action.mNextFree = mRecycledRestoreAction;
- mRecycledRestoreAction = action;
- }
-
- private ConfigState obtainRestoreConfig() {
- if (mRecycledRestoreAction != null) {
- ConfigState result = mRecycledRestoreAction;
- mRecycledRestoreAction = result.mNextFree;
- return result;
- }
- return new ConfigState();
- }
-
- private static class ConfigState {
- float mAlpha;
- Rect mRect = new Rect();
- float mMatrix[] = new float[16];
- ConfigState mNextFree;
-
- public void restore(GLCanvas canvas) {
- if (mAlpha >= 0) canvas.setAlpha(mAlpha);
- if (mRect.left != Integer.MAX_VALUE) {
- Rect rect = mRect;
- canvas.mClipRect.set(rect);
- canvas.mGL.glScissor(
- rect.left, rect.top, rect.width(), rect.height());
- }
- if (mMatrix[0] != Float.NEGATIVE_INFINITY) {
- System.arraycopy(mMatrix, 0, canvas.mMatrixValues, 0, 16);
- }
- }
- }
+ // Gets the underlying GL instance. This is used when
+ public GL11 getGLInstance();
}
diff --git a/new3d/src/com/android/gallery3d/ui/GLCanvasImp.java b/new3d/src/com/android/gallery3d/ui/GLCanvasImp.java
new file mode 100644
index 0000000..33796f1
--- /dev/null
+++ b/new3d/src/com/android/gallery3d/ui/GLCanvasImp.java
@@ -0,0 +1,770 @@
+package com.android.gallery3d.ui;
+
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.opengl.GLU;
+import android.opengl.Matrix;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.util.Collection;
+import java.util.Stack;
+
+import javax.microedition.khronos.opengles.GL10;
+import javax.microedition.khronos.opengles.GL11;
+import javax.microedition.khronos.opengles.GL11Ext;
+
+public class GLCanvasImp implements GLCanvas {
+
+ // We need 16 vertices for a normal nine-patch image (the 4x4 vertices)
+ private static final int VERTEX_BUFFER_SIZE = 16 * 2;
+
+ // We need 22 indices for a normal nine-patch image
+ private static final int INDEX_BUFFER_SIZE = 22;
+
+ private static final float OPAQUE_ALPHA = 0.95f;
+
+ private final GL11 mGL;
+
+ private final float mMatrixValues[] = new float[16];
+
+ private final float mUvBuffer[] = new float[VERTEX_BUFFER_SIZE];
+ private final float mXyBuffer[] = new float[VERTEX_BUFFER_SIZE];
+ private final byte mIndexBuffer[] = new byte[INDEX_BUFFER_SIZE];
+
+ private final int mNinePatchX[] = new int[4];
+ private final int mNinePatchY[] = new int[4];
+ private final float mNinePatchU[] = new float[4];
+ private final float mNinePatchV[] = new float[4];
+ private final float mTextureColor[] = new float[4];
+
+ private FloatBuffer mXyPointer;
+ private FloatBuffer mUvPointer;
+ private ByteBuffer mIndexPointer;
+
+ private final GLState mGLState;
+
+ private long mAnimationTime;
+
+ private float mAlpha;
+ private final Rect mClipRect = new Rect();
+ private final Stack<ConfigState> mRestoreStack =
+ new Stack<ConfigState>();
+ private ConfigState mRecycledRestoreAction;
+
+ GLCanvasImp(GL11 gl) {
+ mGL = gl;
+ mGLState = new GLState(gl);
+ initialize();
+ }
+
+ public void setSize(int width, int height) {
+ GL11 gl = mGL;
+ gl.glViewport(0, 0, width, height);
+ gl.glMatrixMode(GL11.GL_PROJECTION);
+ gl.glLoadIdentity();
+ GLU.gluOrtho2D(gl, 0, width, 0, height);
+
+ gl.glMatrixMode(GL11.GL_MODELVIEW);
+ gl.glLoadIdentity();
+
+ // The positive direction in Y coordinate in OpenGL is from bottom to
+ // top, which is different from the coordinate system in Java. So, we
+ // flip it here.
+ float matrix[] = mMatrixValues;
+ Matrix.setIdentityM(matrix, 0);
+ Matrix.translateM(matrix, 0, 0, height, 0);
+ Matrix.scaleM(matrix, 0, 1, -1, 1);
+
+ mClipRect.set(0, 0, width, height);
+ gl.glScissor(0, 0, width, height);
+ }
+
+ public long currentAnimationTimeMillis() {
+ return mAnimationTime;
+ }
+
+ public void setAlpha(float alpha) {
+ mAlpha = alpha;
+ }
+
+ public void multiplyAlpha(float alpha) {
+ mAlpha *= alpha;
+ }
+
+ public float getAlpha() {
+ return mAlpha;
+ }
+
+ private static ByteBuffer allocateDirectNativeOrderBuffer(int size) {
+ return ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder());
+ }
+
+ private void initialize() {
+ int size = VERTEX_BUFFER_SIZE * Float.SIZE / Byte.SIZE;
+ mXyPointer = allocateDirectNativeOrderBuffer(size).asFloatBuffer();
+ mUvPointer = allocateDirectNativeOrderBuffer(size).asFloatBuffer();
+ mIndexPointer = allocateDirectNativeOrderBuffer(INDEX_BUFFER_SIZE);
+
+ GL11 gl = mGL;
+
+ gl.glVertexPointer(2, GL11.GL_FLOAT, 0, mXyPointer);
+ gl.glTexCoordPointer(2, GL11.GL_FLOAT, 0, mUvPointer);
+
+ // Enable the texture coordinate array for Texture 1
+ gl.glClientActiveTexture(GL11.GL_TEXTURE1);
+ gl.glTexCoordPointer(2, GL11.GL_FLOAT, 0, mUvPointer);
+ gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
+
+ // mMatrixValues will be initialized in setSize()
+ mAlpha = 1.0f;
+ }
+
+ private static void putRectangle(float x, float y,
+ float width, float height, float[] buffer, FloatBuffer pointer) {
+ buffer[0] = x;
+ buffer[1] = y;
+ buffer[2] = x + width;
+ buffer[3] = y;
+ buffer[4] = x;
+ buffer[5] = y + height;
+ buffer[6] = x + width;
+ buffer[7] = y + height;
+ pointer.put(buffer, 0, 8).position(0);
+ }
+
+ public void setColor(int color) {
+ float alpha = mAlpha;
+ mGLState.setBlendEnabled(!Util.isOpaque(color) || alpha < OPAQUE_ALPHA);
+ mGLState.setFragmentColor(color, alpha);
+ }
+
+ public void drawLine(int x1, int y1, int x2, int y2) {
+ GL11 gl = mGL;
+ gl.glLoadMatrixf(mMatrixValues, 0);
+ float buffer[] = mXyBuffer;
+ buffer[0] = x1;
+ buffer[1] = y1;
+ buffer[2] = x2;
+ buffer[3] = y2;
+ mXyPointer.put(buffer, 0, 4).position(0);
+ gl.glDrawArrays(GL11.GL_LINE_STRIP, 0, 2);
+ }
+
+ public void fillRect(Rect r) {
+ fillRect(r.left, r.top, r.right - r.left, r.bottom - r.top);
+ }
+
+ public void translate(float x, float y, float z) {
+ Matrix.translateM(mMatrixValues, 0, x, y, z);
+ }
+
+ public void scale(float sx, float sy, float sz) {
+ Matrix.scaleM(mMatrixValues, 0, sx, sy, sz);
+ }
+
+ public void rotate(float angle, float x, float y, float z) {
+ Matrix.rotateM(mMatrixValues, 0, angle, x, y, z);
+ }
+
+ public void fillRect(int x, int y, int width, int height) {
+ GL11 gl = mGL;
+ gl.glLoadMatrixf(mMatrixValues, 0);
+ putRectangle(x, y, width, height, mXyBuffer, mXyPointer);
+ gl.glDrawArrays(GL11.GL_TRIANGLE_STRIP, 0, 4);
+ }
+
+ public void drawNinePatch(
+ NinePatchTexture tex, int x, int y, int width, int height) {
+ float alpha = mAlpha;
+ NinePatchChunk chunk = tex.getNinePatchChunk();
+
+ mGLState.setTexture2DEnabled(true);
+
+ // The code should be easily extended to handle the general cases by
+ // allocating more space for buffers. But let's just handle the only
+ // use case.
+ if (chunk.mDivX.length != 2 || chunk.mDivY.length != 2) {
+ throw new RuntimeException("unsupported nine patch");
+ }
+ tex.bind(this);
+ if (width <= 0 || height <= 0) return ;
+
+ int divX[] = mNinePatchX;
+ int divY[] = mNinePatchY;
+ float divU[] = mNinePatchU;
+ float divV[] = mNinePatchV;
+
+ int nx = stretch(divX, divU, chunk.mDivX, tex.getWidth(), width);
+ int ny = stretch(divY, divV, chunk.mDivY, tex.getHeight(), height);
+ mGLState.setBlendEnabled(!tex.isOpaque() || alpha < OPAQUE_ALPHA);
+
+ mGLState.setTextureAlpha(alpha);
+
+ GL11 gl = mGL;
+ gl.glLoadMatrixf(mMatrixValues, 0);
+ gl.glTranslatef(x, y, 0);
+ drawMesh(divX, divY, divU, divV, nx, ny);
+ }
+
+ /**
+ * Stretches the texture according to the nine-patch rules. It will
+ * linearly distribute the strechy parts defined in the nine-patch chunk to
+ * the target area.
+ *
+ * <pre>
+ * source
+ * /--------------^---------------\
+ * u0 u1 u2 u3 u4 u5
+ * div ---> |fffff|ssssssss|fff|ssssss|ffff| ---> u
+ * | div0 div1 div2 div3 |
+ * | | / / / /
+ * | | / / / /
+ * | | / / / /
+ * |fffff|ssss|fff|sss|ffff| ---> x
+ * x0 x1 x2 x3 x4 x5
+ * \----------v------------/
+ * target
+ *
+ * f: fixed segment
+ * s: stretchy segment
+ * </pre>
+ *
+ * @param div the stretch parts defined in nine-patch chunk
+ * @param source the length of the texture
+ * @param target the length on the drawing plan
+ * @param u output, the positions of these dividers in the texture
+ * coordinate
+ * @param x output, the corresponding position of these dividers on the
+ * drawing plan
+ * @return the number of these dividers.
+ */
+ private int stretch(
+ int x[], float u[], int div[], int source, int target) {
+ int textureSize = Util.nextPowerOf2(source);
+ float textureBound = (source - 0.5f) / textureSize;
+
+ int stretch = 0;
+ for (int i = 0, n = div.length; i < n; i += 2) {
+ stretch += div[i + 1] - div[i];
+ }
+
+ float remaining = target - source + stretch;
+
+ int lastX = 0;
+ int lastU = 0;
+
+ x[0] = 0;
+ u[0] = 0;
+ for (int i = 0, n = div.length; i < n; i += 2) {
+ // fixed segment
+ x[i + 1] = lastX + (div[i] - lastU);
+ u[i + 1] = Math.min((float) div[i] / textureSize, textureBound);
+
+ // stretchy segment
+ float partU = div[i + 1] - div[i];
+ int partX = (int)(remaining * partU / stretch + 0.5f);
+ remaining -= partX;
+ stretch -= partU;
+
+ lastX = x[i + 1] + partX;
+ lastU = div[i + 1];
+ x[i + 2] = lastX;
+ u[i + 2] = Math.min((float) lastU / textureSize, textureBound);
+ }
+ // the last fixed segment
+ x[div.length + 1] = target;
+ u[div.length + 1] = textureBound;
+
+ // remove segments with length 0.
+ int last = 0;
+ for (int i = 1, n = div.length + 2; i < n; ++i) {
+ if (x[last] == x[i]) continue;
+ x[++last] = x[i];
+ u[last] = u[i];
+ }
+ return last + 1;
+ }
+
+ private void drawMesh(
+ int x[], int y[], float u[], float v[], int nx, int ny) {
+ /*
+ * Given a 3x3 nine-patch image, the vertex order is defined as the
+ * following graph:
+ *
+ * (0) (1) (2) (3)
+ * | /| /| /|
+ * | / | / | / |
+ * (4) (5) (6) (7)
+ * | \ | \ | \ |
+ * | \| \| \|
+ * (8) (9) (A) (B)
+ * | /| /| /|
+ * | / | / | / |
+ * (C) (D) (E) (F)
+ *
+ * And we draw the triangle strip in the following index order:
+ *
+ * index: 04152637B6A5948C9DAEBF
+ */
+ int pntCount = 0;
+ float xy[] = mXyBuffer;
+ float uv[] = mUvBuffer;
+ for (int j = 0; j < ny; ++j) {
+ for (int i = 0; i < nx; ++i) {
+ int xIndex = (pntCount++) << 1;
+ int yIndex = xIndex + 1;
+ xy[xIndex] = x[i];
+ xy[yIndex] = y[j];
+ uv[xIndex] = u[i];
+ uv[yIndex] = v[j];
+ }
+ }
+ mUvPointer.put(uv, 0, pntCount << 1).position(0);
+ mXyPointer.put(xy, 0, pntCount << 1).position(0);
+
+ int idxCount = 1;
+ byte index[] = mIndexBuffer;
+ for (int i = 0, bound = nx * (ny - 1); true;) {
+ // normal direction
+ --idxCount;
+ for (int j = 0; j < nx; ++j, ++i) {
+ index[idxCount++] = (byte) i;
+ index[idxCount++] = (byte) (i + nx);
+ }
+ if (i >= bound) break;
+
+ // reverse direction
+ int sum = i + i + nx - 1;
+ --idxCount;
+ for (int j = 0; j < nx; ++j, ++i) {
+ index[idxCount++] = (byte) (sum - i);
+ index[idxCount++] = (byte) (sum - i + nx);
+ }
+ if (i >= bound) break;
+ }
+ mIndexPointer.put(index, 0, idxCount).position(0);
+
+ mGL.glDrawElements(GL11.GL_TRIANGLE_STRIP,
+ idxCount, GL11.GL_UNSIGNED_BYTE, mIndexPointer);
+ }
+
+ private float[] mapPoints(float matrix[], int x1, int y1, int x2, int y2) {
+ float[] point = mXyBuffer;
+ int srcOffset = 6;
+ point[srcOffset] = x1;
+ point[srcOffset + 1] = y1;
+ point[srcOffset + 2] = 0;
+ point[srcOffset + 3] = 1;
+
+ int resultOffset = 0;
+ Matrix.multiplyMV(point, resultOffset, matrix, 0, point, srcOffset);
+ point[resultOffset] /= point[resultOffset + 3];
+ point[resultOffset + 1] /= point[resultOffset + 3];
+
+ // map the second point
+ point[srcOffset] = x2;
+ point[srcOffset + 1] = y2;
+ resultOffset = 2;
+ Matrix.multiplyMV(point, resultOffset, matrix, 0, point, srcOffset);
+ point[resultOffset] /= point[resultOffset + 3];
+ point[resultOffset + 1] /= point[resultOffset + 3];
+
+ return point;
+ }
+
+
+ public boolean clipRect(int left, int top, int right, int bottom) {
+ float point[] = mapPoints(mMatrixValues, left, top, right, bottom);
+
+ // mMatrix could be a rotation matrix. In this case, we need to find
+ // the boundaries after rotation. (only handle 90 * n degrees)
+ if (point[0] > point[2]) {
+ left = (int) point[2];
+ right = (int) point[0];
+ } else {
+ left = (int) point[0];
+ right = (int) point[2];
+ }
+ if (point[1] > point[3]) {
+ top = (int) point[3];
+ bottom = (int) point[1];
+ } else {
+ top = (int) point[1];
+ bottom = (int) point[3];
+ }
+ Rect clip = mClipRect;
+
+ boolean intersect = clip.intersect(left, top, right, bottom);
+ if (!intersect) clip.set(0, 0, 0, 0);
+ mGL.glScissor(clip.left, clip.top, clip.width(), clip.height());
+ return intersect;
+ }
+
+ public void drawColor(int x, int y, int width, int height, int color) {
+ float alpha = mAlpha;
+ mGLState.setBlendEnabled(!Util.isOpaque(color) || alpha < OPAQUE_ALPHA);
+ mGLState.setFragmentColor(color, alpha);
+ fillRect(x, y, width, height);
+ }
+
+ private void drawBoundTexture(
+ BasicTexture texture, int x, int y, int width, int height) {
+ // Test whether it has been rotated or flipped, if so, glDrawTexiOES
+ // won't work
+ if (isMatrixRotatedOrFlipped(mMatrixValues)) {
+ putRectangle(0, 0,
+ (texture.mWidth - 0.5f) / texture.mTextureWidth,
+ (texture.mHeight - 0.5f) / texture.mTextureHeight,
+ mUvBuffer, mUvPointer);
+ fillRect(x, y, width, height);
+ } else {
+ // draw the rect from bottom-left to top-right
+ float points[] = mapPoints(
+ mMatrixValues, x, y + height, x + width, y);
+ x = (int) points[0];
+ y = (int) points[1];
+ width = (int) points[2] - x;
+ height = (int) points[3] - y;
+ if (width > 0 && height > 0) {
+ ((GL11Ext) mGL).glDrawTexiOES(x, y, 0, width, height);
+ }
+ }
+
+ }
+
+ public void drawTexture(
+ BasicTexture texture, int x, int y, int width, int height) {
+ drawTexture(texture, x, y, width, height, mAlpha);
+ }
+
+ public void drawTexture(BasicTexture texture,
+ int x, int y, int width, int height, float alpha) {
+ if (width <= 0 || height <= 0) return ;
+
+ mGLState.setBlendEnabled(!texture.isOpaque() || alpha < OPAQUE_ALPHA);
+ mGLState.setTexture2DEnabled(true);
+ texture.bind(this);
+ mGLState.setTextureAlpha(alpha);
+ drawBoundTexture(texture, x, y, width, height);
+ }
+
+ public void drawMixed(BasicTexture from, BasicTexture to,
+ float ratio, int x, int y, int w, int h) {
+ drawMixed(from, to, ratio, x, y, w, h, mAlpha);
+ }
+
+ private void setTextureColor(float r, float g, float b, float alpha) {
+ float[] color = mTextureColor;
+ color[0] = r;
+ color[1] = g;
+ color[2] = b;
+ color[3] = alpha;
+ }
+
+ public void handleLowMemory() {
+ }
+
+ public void drawMixed(BasicTexture from, BasicTexture to,
+ float ratio, int x, int y, int width, int height, float alpha) {
+ if (alpha < OPAQUE_ALPHA) {
+ throw new RuntimeException("Cannot support alpha value");
+ }
+ mGLState.setBlendEnabled(!from.isOpaque() || !to.isOpaque());
+ mGLState.setTextureAlpha(1);
+ mGLState.setTexture2DEnabled(true);
+
+ final GL11 gl = mGL;
+ from.bind(this);
+
+ gl.glActiveTexture(GL11.GL_TEXTURE1);
+ to.bind(this);
+ gl.glEnable(GL11.GL_TEXTURE_2D);
+
+ // Interpolate the RGB and alpha values between both textures.
+ mGLState.setTexEnvMode(GL11.GL_COMBINE);
+ gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_COMBINE_RGB, GL11.GL_INTERPOLATE);
+ gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_COMBINE_ALPHA, GL11.GL_INTERPOLATE);
+
+ // Specify the interpolation factor via the alpha component of
+ // GL_TEXTURE_ENV_COLORes.
+ setTextureColor(ratio, ratio, ratio, ratio);
+ gl.glTexEnvfv(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_COLOR, mTextureColor, 0);
+
+ // Wire up the interpolation factor for RGB.
+ gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_SRC2_RGB, GL11.GL_CONSTANT);
+ gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_OPERAND2_RGB, GL11.GL_SRC_ALPHA);
+
+ // Wire up the interpolation factor for alpha.
+ gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_SRC2_ALPHA, GL11.GL_CONSTANT);
+ gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_OPERAND2_ALPHA, GL11.GL_SRC_ALPHA);
+
+ // Draw the combined texture.
+ drawBoundTexture(to, x, y, width, height);
+
+ // Disable TEXTURE1.
+ gl.glDisable(GL11.GL_TEXTURE_2D);
+ // Switch back to the default texture unit.
+ gl.glActiveTexture(GL11.GL_TEXTURE0);
+ }
+
+ // TODO: the code only work for 2D should get fixed for 3D or removed
+ private static final int MSKEW_X = 4;
+ private static final int MSKEW_Y = 1;
+ private static final int MSCALE_X = 0;
+ private static final int MSCALE_Y = 5;
+
+ private static boolean isMatrixRotatedOrFlipped(float matrix[]) {
+ return matrix[MSKEW_X] != 0 || matrix[MSKEW_Y] != 0
+ || matrix[MSCALE_X] < 0 || matrix[MSCALE_Y] > 0;
+ }
+
+ public void copyTexture2D(
+ RawTexture texture, int x, int y, int width, int height) {
+
+ if (isMatrixRotatedOrFlipped(mMatrixValues)) {
+ throw new IllegalArgumentException("cannot support rotated matrix");
+ }
+ float points[] = mapPoints(mMatrixValues, x, y + height, x + width, y);
+ x = (int) points[0];
+ y = (int) points[1];
+ width = (int) points[2] - x;
+ height = (int) points[3] - y;
+
+ GL11 gl = mGL;
+ int newWidth = Util.nextPowerOf2(width);
+ int newHeight = Util.nextPowerOf2(height);
+ int glError = GL11.GL_NO_ERROR;
+
+ gl.glBindTexture(GL11.GL_TEXTURE_2D, texture.getId());
+
+ int[] cropRect = {0, 0, width, height};
+ gl.glTexParameteriv(GL11.GL_TEXTURE_2D,
+ GL11Ext.GL_TEXTURE_CROP_RECT_OES, cropRect, 0);
+ gl.glTexParameteri(GL11.GL_TEXTURE_2D,
+ GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP_TO_EDGE);
+ gl.glTexParameteri(GL11.GL_TEXTURE_2D,
+ GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP_TO_EDGE);
+ gl.glTexParameterf(GL11.GL_TEXTURE_2D,
+ GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
+ gl.glTexParameterf(GL11.GL_TEXTURE_2D,
+ GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
+ gl.glCopyTexImage2D(GL11.GL_TEXTURE_2D, 0,
+ GL11.GL_RGBA, x, y, newWidth, newHeight, 0);
+ glError = gl.glGetError();
+
+ if (glError == GL11.GL_OUT_OF_MEMORY) {
+ throw new GLOutOfMemoryException();
+ }
+
+ if (glError != GL11.GL_NO_ERROR) {
+ throw new RuntimeException(
+ "Texture copy fail, glError " + glError);
+ }
+
+ texture.setSize(width, height);
+ texture.setTextureSize(newWidth, newHeight);
+ }
+
+ private static class GLState {
+
+ private final GL11 mGL;
+
+ private int mTexEnvMode = GL11.GL_REPLACE;
+ private float mTextureAlpha = 1.0f;
+ private boolean mTexture2DEnabled = true;
+ private boolean mBlendEnabled = true;
+
+ public GLState(GL11 gl) {
+ mGL = gl;
+
+ // Disable unused state
+ gl.glDisable(GL11.GL_LIGHTING);
+
+ // Enable used features
+ gl.glEnable(GL11.GL_DITHER);
+
+ gl.glEnable(GL11.GL_SCISSOR_TEST);
+ gl.glEnable(GL11.GL_STENCIL_TEST);
+
+ gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
+ gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
+ gl.glEnable(GL11.GL_TEXTURE_2D);
+
+ gl.glTexEnvf(GL11.GL_TEXTURE_ENV,
+ GL11.GL_TEXTURE_ENV_MODE, GL11.GL_REPLACE);
+
+ // Set the background color
+ gl.glClearColor(0f, 0f, 0f, 0f);
+ gl.glClearStencil(0);
+
+ gl.glEnable(GL11.GL_BLEND);
+ gl.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ }
+
+ public void setTexEnvMode(int mode) {
+ if (mTexEnvMode == mode) return;
+ mTexEnvMode = mode;
+ mGL.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, mode);
+ }
+
+ public void setTextureAlpha(float alpha) {
+ if (mTextureAlpha == alpha) return;
+ mTextureAlpha = alpha;
+ if (alpha >= OPAQUE_ALPHA) {
+ // The alpha is need for those texture without alpha channel
+ mGL.glColor4f(1, 1, 1, 1);
+ setTexEnvMode(GL11.GL_REPLACE);
+ } else {
+ mGL.glColor4f(alpha, alpha, alpha, alpha);
+ setTexEnvMode(GL11.GL_MODULATE);
+ }
+ }
+
+ public void setFragmentColor(int color, float alpha) {
+ // Set mTextureAlpha to an invalid value, so that it will reset
+ // again in setTextureAlpha(float) later.
+ mTextureAlpha = -1.0f;
+
+ setTexture2DEnabled(false);
+ int prealpha = (int) ((color >>> 24) * alpha + 0.5);
+ mGL.glColor4x(
+ ((color >> 16) & 0xFF) * prealpha,
+ ((color >> 8) & 0xFF) * prealpha,
+ (color & 0xFF) * prealpha, prealpha << 8);
+ }
+
+ public void setTexture2DEnabled(boolean enabled) {
+ if (mTexture2DEnabled == enabled) return;
+ mTexture2DEnabled = enabled;
+ if (enabled) {
+ mGL.glEnable(GL11.GL_TEXTURE_2D);
+ } else {
+ mGL.glDisable(GL11.GL_TEXTURE_2D);
+ }
+ }
+
+ public void setBlendEnabled(boolean enabled) {
+ if (mBlendEnabled == enabled) return;
+ mBlendEnabled = enabled;
+ if (enabled) {
+ mGL.glEnable(GL11.GL_BLEND);
+ } else {
+ mGL.glDisable(GL11.GL_BLEND);
+ }
+ }
+ }
+
+ public GL11 getGLInstance() {
+ return mGL;
+ }
+
+ public void setCurrentAnimationTimeMillis(long time) {
+ if (time < 0) throw new IllegalArgumentException("time must be nonnegative");
+ mAnimationTime = time;
+ }
+
+ public void clearBuffer() {
+ mGL.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_STENCIL_BUFFER_BIT);
+ }
+
+ public void setTextureCoords(RectF source) {
+ float buffer[] = mUvBuffer;
+ buffer[0] = source.left;
+ buffer[1] = source.top;
+ buffer[2] = source.right;
+ buffer[3] = source.top;
+ buffer[4] = source.left;
+ buffer[5] = source.bottom;
+ buffer[6] = source.right;
+ buffer[7] = source.bottom;
+ mUvPointer.put(buffer, 0, 8).position(0);
+ }
+
+ public void releaseTextures(Collection<? extends BasicTexture> c) {
+ IntArray array = new IntArray();
+ for (BasicTexture t : c) {
+ if (t.isLoaded(this)) array.add(t.mId);
+ }
+ if (array.size() > 0) {
+ mGL.glDeleteTextures(array.size(), array.toArray(null), 0);
+ }
+ }
+
+ public int save() {
+ return save(SAVE_FLAG_ALL);
+ }
+
+ public int save(int saveFlags) {
+ ConfigState config = obtainRestoreConfig();
+
+ if ((saveFlags & SAVE_FLAG_ALPHA) != 0) {
+ config.mAlpha = mAlpha;
+ } else {
+ config.mAlpha = -1;
+ }
+
+ if ((saveFlags & SAVE_FLAG_CLIP) != 0) {
+ config.mRect.set(mClipRect);
+ } else {
+ config.mRect.left = Integer.MAX_VALUE;
+ }
+
+ if ((saveFlags & SAVE_FLAG_MATRIX) != 0) {
+ System.arraycopy(mMatrixValues, 0, config.mMatrix, 0, 16);
+ } else {
+ config.mMatrix[0] = Float.NEGATIVE_INFINITY;
+ }
+
+ mRestoreStack.push(config);
+ return mRestoreStack.size() - 1;
+ }
+
+ public void restore() {
+ if (mRestoreStack.isEmpty()) throw new IllegalStateException();
+ ConfigState config = mRestoreStack.pop();
+ config.restore(this);
+ freeRestoreConfig(config);
+ }
+
+ public void restoreToCount(int saveCount) {
+ while (mRestoreStack.size() > saveCount) {
+ restore();
+ }
+ }
+
+ private void freeRestoreConfig(ConfigState action) {
+ action.mNextFree = mRecycledRestoreAction;
+ mRecycledRestoreAction = action;
+ }
+
+ private ConfigState obtainRestoreConfig() {
+ if (mRecycledRestoreAction != null) {
+ ConfigState result = mRecycledRestoreAction;
+ mRecycledRestoreAction = result.mNextFree;
+ return result;
+ }
+ return new ConfigState();
+ }
+
+ private static class ConfigState {
+ float mAlpha;
+ Rect mRect = new Rect();
+ float mMatrix[] = new float[16];
+ ConfigState mNextFree;
+
+ public void restore(GLCanvasImp canvas) {
+ if (mAlpha >= 0) canvas.setAlpha(mAlpha);
+ if (mRect.left != Integer.MAX_VALUE) {
+ Rect rect = mRect;
+ canvas.mClipRect.set(rect);
+ canvas.mGL.glScissor(
+ rect.left, rect.top, rect.width(), rect.height());
+ }
+ if (mMatrix[0] != Float.NEGATIVE_INFINITY) {
+ System.arraycopy(mMatrix, 0, canvas.mMatrixValues, 0, 16);
+ }
+ }
+ }
+}
diff --git a/new3d/src/com/android/gallery3d/ui/GLListView.java b/new3d/src/com/android/gallery3d/ui/GLListView.java
index b2042c5..edc1627 100644
--- a/new3d/src/com/android/gallery3d/ui/GLListView.java
+++ b/new3d/src/com/android/gallery3d/ui/GLListView.java
@@ -132,7 +132,7 @@
@Override
protected void render(GLCanvas canvas) {
- canvas.save(GLCanvas.CLIP_SAVE_FLAG);
+ canvas.save(GLCanvas.SAVE_FLAG_CLIP);
canvas.clipRect(0, 0, getWidth(), getHeight());
if (mHighlightIndex != INDEX_NONE) {
GLView view = mModel.getView(mHighlightIndex);
diff --git a/new3d/src/com/android/gallery3d/ui/GLRootView.java b/new3d/src/com/android/gallery3d/ui/GLRootView.java
index 659a4be..81cc256 100644
--- a/new3d/src/com/android/gallery3d/ui/GLRootView.java
+++ b/new3d/src/com/android/gallery3d/ui/GLRootView.java
@@ -167,7 +167,7 @@
Log.i(TAG, "GLObject has changed from " + mGL + " to " + gl);
}
mGL = gl;
- mCanvas = new GLCanvas(gl);
+ mCanvas = new GLCanvasImp(gl);
if (!ENABLE_FPS_TEST) {
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
} else {
@@ -207,7 +207,7 @@
if ((mFlags & FLAG_NEED_LAYOUT) != 0) layoutContentPane();
mCanvas.clearBuffer();
- mCanvas.setCurrentTimeMillis(SystemClock.uptimeMillis());
+ mCanvas.setCurrentAnimationTimeMillis(SystemClock.uptimeMillis());
if (mContentView != null) {
mContentView.render(mCanvas);
}
diff --git a/new3d/src/com/android/gallery3d/ui/Pathbar.java b/new3d/src/com/android/gallery3d/ui/Pathbar.java
index 06cf4e0..b92f1da 100644
--- a/new3d/src/com/android/gallery3d/ui/Pathbar.java
+++ b/new3d/src/com/android/gallery3d/ui/Pathbar.java
@@ -251,7 +251,7 @@
int degrees = mProgressStep * 360 / PROGRESS_STEP_COUNT;
int pivotX = offsetX + icon.getWidth() / 2;
int pivotY = offsetY + icon.getHeight() / 2;
- canvas.save(GLCanvas.MATRIX_SAVE_FLAG);
+ canvas.save(GLCanvas.SAVE_FLAG_MATRIX);
canvas.translate(pivotX, pivotY, 0);
canvas.rotate(degrees, 0, 0, 1);
canvas.translate(-pivotX, -pivotY, 0);
diff --git a/new3d/src/com/android/gallery3d/ui/ScrollerHelper.java b/new3d/src/com/android/gallery3d/ui/ScrollerHelper.java
index 916a637..a14de7d 100644
--- a/new3d/src/com/android/gallery3d/ui/ScrollerHelper.java
+++ b/new3d/src/com/android/gallery3d/ui/ScrollerHelper.java
@@ -6,7 +6,7 @@
import android.view.animation.Interpolator;
public class ScrollerHelper {
- private static final long ANIMATION_START = 0;
+ private static final long START_ANIMATION = -1;
private final float mDeceleration;
@@ -38,7 +38,7 @@
*/
public boolean computeScrollOffset(long currentTimeMillis) {
if (mFinished) return false;
- if (mStartTime == ANIMATION_START) mStartTime = currentTimeMillis;
+ if (mStartTime == START_ANIMATION) mStartTime = currentTimeMillis;
int timePassed = (int)(currentTimeMillis - mStartTime);
if (timePassed < mDuration) {
@@ -70,7 +70,7 @@
mVelocity = Math.abs(velocity);
mDirection = velocity >= 0 ? 1 : -1;
mDuration = (int) (1000 * mVelocity / mDeceleration);
- mStartTime = ANIMATION_START;
+ mStartTime = START_ANIMATION;
mStart = start;
mMin = min;
mMax = max;
diff --git a/new3d/tests/src/com/android/gallery3d/ui/GLCanvasTest.java b/new3d/tests/src/com/android/gallery3d/ui/GLCanvasTest.java
new file mode 100644
index 0000000..597ca7b
--- /dev/null
+++ b/new3d/tests/src/com/android/gallery3d/ui/GLCanvasTest.java
@@ -0,0 +1,41 @@
+package com.android.gallery3d.ui;
+
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Log;
+
+import java.util.Arrays;
+import javax.microedition.khronos.opengles.GL11;
+import junit.framework.TestCase;
+
+@SmallTest
+public class GLCanvasTest extends TestCase {
+ private static final String TAG = "GLCanvasTest";
+
+ GL11 mGlStub;
+ GLCanvas mCanvas;
+
+ public void setUp() {
+ mGlStub = new GLStub();
+ mCanvas = new GLCanvasImp(mGlStub);
+ }
+
+ public void testGetGLInstance() {
+ assertSame(mGlStub, mCanvas.getGLInstance());
+ }
+
+ public void testAnimationTime() {
+ long[] testData = {0, 1, 2, 1000, 10000, Long.MAX_VALUE};
+
+ for (long v : testData) {
+ mCanvas.setCurrentAnimationTimeMillis(v);
+ assertEquals(v, mCanvas.currentAnimationTimeMillis());
+ }
+
+ try {
+ mCanvas.setCurrentAnimationTimeMillis(-1);
+ fail();
+ } catch (IllegalArgumentException ex) {
+ // expected.
+ }
+ }
+}
diff --git a/new3d/tests/src/com/android/gallery3d/ui/GLStub.java b/new3d/tests/src/com/android/gallery3d/ui/GLStub.java
new file mode 100644
index 0000000..3b4d7d6
--- /dev/null
+++ b/new3d/tests/src/com/android/gallery3d/ui/GLStub.java
@@ -0,0 +1,1476 @@
+package com.android.gallery3d.ui;
+
+import android.util.Log;
+
+import javax.microedition.khronos.opengles.GL;
+import javax.microedition.khronos.opengles.GL10;
+import javax.microedition.khronos.opengles.GL10Ext;
+import javax.microedition.khronos.opengles.GL11;
+import javax.microedition.khronos.opengles.GL11Ext;
+import javax.microedition.khronos.opengles.GL11ExtensionPack;
+
+public class GLStub implements GL, GL10, GL10Ext, GL11, GL11Ext {
+ private static final String TAG = "GLStub";
+
+ public void glActiveTexture(
+ int texture
+ ){}
+
+ public void glAlphaFunc(
+ int func,
+ float ref
+ ){}
+
+ public void glAlphaFuncx(
+ int func,
+ int ref
+ ){}
+
+ public void glBindTexture(
+ int target,
+ int texture
+ ){}
+
+ public void glBlendFunc(
+ int sfactor,
+ int dfactor
+ ){}
+
+ public void glClear(
+ int mask
+ ){}
+
+ public void glClearColor(
+ float red,
+ float green,
+ float blue,
+ float alpha
+ ){}
+
+ public void glClearColorx(
+ int red,
+ int green,
+ int blue,
+ int alpha
+ ){}
+
+ public void glClearDepthf(
+ float depth
+ ){}
+
+ public void glClearDepthx(
+ int depth
+ ){}
+
+ public void glClearStencil(
+ int s
+ ){}
+
+ public void glClientActiveTexture(
+ int texture
+ ){}
+
+ public void glColor4f(
+ float red,
+ float green,
+ float blue,
+ float alpha
+ ){}
+
+ public void glColor4x(
+ int red,
+ int green,
+ int blue,
+ int alpha
+ ){}
+
+ public void glColorMask(
+ boolean red,
+ boolean green,
+ boolean blue,
+ boolean alpha
+ ){}
+
+ public void glColorPointer(
+ int size,
+ int type,
+ int stride,
+ java.nio.Buffer pointer
+ ){}
+
+ public void glCompressedTexImage2D(
+ int target,
+ int level,
+ int internalformat,
+ int width,
+ int height,
+ int border,
+ int imageSize,
+ java.nio.Buffer data
+ ){}
+
+ public void glCompressedTexSubImage2D(
+ int target,
+ int level,
+ int xoffset,
+ int yoffset,
+ int width,
+ int height,
+ int format,
+ int imageSize,
+ java.nio.Buffer data
+ ){}
+
+ public void glCopyTexImage2D(
+ int target,
+ int level,
+ int internalformat,
+ int x,
+ int y,
+ int width,
+ int height,
+ int border
+ ){}
+
+ public void glCopyTexSubImage2D(
+ int target,
+ int level,
+ int xoffset,
+ int yoffset,
+ int x,
+ int y,
+ int width,
+ int height
+ ){}
+
+ public void glCullFace(
+ int mode
+ ){}
+
+ public void glDeleteTextures(
+ int n,
+ int[] textures,
+ int offset
+ ){}
+
+ public void glDeleteTextures(
+ int n,
+ java.nio.IntBuffer textures
+ ){}
+
+ public void glDepthFunc(
+ int func
+ ){}
+
+ public void glDepthMask(
+ boolean flag
+ ){}
+
+ public void glDepthRangef(
+ float zNear,
+ float zFar
+ ){}
+
+ public void glDepthRangex(
+ int zNear,
+ int zFar
+ ){}
+
+ public void glDisable(
+ int cap
+ ){}
+
+ public void glDisableClientState(
+ int array
+ ){}
+
+ public void glDrawArrays(
+ int mode,
+ int first,
+ int count
+ ){}
+
+ public void glDrawElements(
+ int mode,
+ int count,
+ int type,
+ java.nio.Buffer indices
+ ){}
+
+ public void glEnable(
+ int cap
+ ){}
+
+ public void glEnableClientState(
+ int array
+ ){}
+
+ public void glFinish(
+ ){}
+
+ public void glFlush(
+ ){}
+
+ public void glFogf(
+ int pname,
+ float param
+ ){}
+
+ public void glFogfv(
+ int pname,
+ float[] params,
+ int offset
+ ){}
+
+ public void glFogfv(
+ int pname,
+ java.nio.FloatBuffer params
+ ){}
+
+ public void glFogx(
+ int pname,
+ int param
+ ){}
+
+ public void glFogxv(
+ int pname,
+ int[] params,
+ int offset
+ ){}
+
+ public void glFogxv(
+ int pname,
+ java.nio.IntBuffer params
+ ){}
+
+ public void glFrontFace(
+ int mode
+ ){}
+
+ public void glFrustumf(
+ float left,
+ float right,
+ float bottom,
+ float top,
+ float zNear,
+ float zFar
+ ){}
+
+ public void glFrustumx(
+ int left,
+ int right,
+ int bottom,
+ int top,
+ int zNear,
+ int zFar
+ ){}
+
+ public void glGenTextures(
+ int n,
+ int[] textures,
+ int offset
+ ){}
+
+ public void glGenTextures(
+ int n,
+ java.nio.IntBuffer textures
+ ){}
+
+ public int glGetError(
+ ){ throw new UnsupportedOperationException(); }
+
+ public void glGetIntegerv(
+ int pname,
+ int[] params,
+ int offset
+ ){}
+
+ public void glGetIntegerv(
+ int pname,
+ java.nio.IntBuffer params
+ ){}
+
+ public String glGetString(
+ int name
+ ){ throw new UnsupportedOperationException(); }
+
+ public void glHint(
+ int target,
+ int mode
+ ){}
+
+ public void glLightModelf(
+ int pname,
+ float param
+ ){}
+
+ public void glLightModelfv(
+ int pname,
+ float[] params,
+ int offset
+ ){}
+
+ public void glLightModelfv(
+ int pname,
+ java.nio.FloatBuffer params
+ ){}
+
+ public void glLightModelx(
+ int pname,
+ int param
+ ){}
+
+ public void glLightModelxv(
+ int pname,
+ int[] params,
+ int offset
+ ){}
+
+ public void glLightModelxv(
+ int pname,
+ java.nio.IntBuffer params
+ ){}
+
+ public void glLightf(
+ int light,
+ int pname,
+ float param
+ ){}
+
+ public void glLightfv(
+ int light,
+ int pname,
+ float[] params,
+ int offset
+ ){}
+
+ public void glLightfv(
+ int light,
+ int pname,
+ java.nio.FloatBuffer params
+ ){}
+
+ public void glLightx(
+ int light,
+ int pname,
+ int param
+ ){}
+
+ public void glLightxv(
+ int light,
+ int pname,
+ int[] params,
+ int offset
+ ){}
+
+ public void glLightxv(
+ int light,
+ int pname,
+ java.nio.IntBuffer params
+ ){}
+
+ public void glLineWidth(
+ float width
+ ){}
+
+ public void glLineWidthx(
+ int width
+ ){}
+
+ public void glLoadIdentity(
+ ){}
+
+ public void glLoadMatrixf(
+ float[] m,
+ int offset
+ ){}
+
+ public void glLoadMatrixf(
+ java.nio.FloatBuffer m
+ ){}
+
+ public void glLoadMatrixx(
+ int[] m,
+ int offset
+ ){}
+
+ public void glLoadMatrixx(
+ java.nio.IntBuffer m
+ ){}
+
+ public void glLogicOp(
+ int opcode
+ ){}
+
+ public void glMaterialf(
+ int face,
+ int pname,
+ float param
+ ){}
+
+ public void glMaterialfv(
+ int face,
+ int pname,
+ float[] params,
+ int offset
+ ){}
+
+ public void glMaterialfv(
+ int face,
+ int pname,
+ java.nio.FloatBuffer params
+ ){}
+
+ public void glMaterialx(
+ int face,
+ int pname,
+ int param
+ ){}
+
+ public void glMaterialxv(
+ int face,
+ int pname,
+ int[] params,
+ int offset
+ ){}
+
+ public void glMaterialxv(
+ int face,
+ int pname,
+ java.nio.IntBuffer params
+ ){}
+
+ public void glMatrixMode(
+ int mode
+ ){}
+
+ public void glMultMatrixf(
+ float[] m,
+ int offset
+ ){}
+
+ public void glMultMatrixf(
+ java.nio.FloatBuffer m
+ ){}
+
+ public void glMultMatrixx(
+ int[] m,
+ int offset
+ ){}
+
+ public void glMultMatrixx(
+ java.nio.IntBuffer m
+ ){}
+
+ public void glMultiTexCoord4f(
+ int target,
+ float s,
+ float t,
+ float r,
+ float q
+ ){}
+
+ public void glMultiTexCoord4x(
+ int target,
+ int s,
+ int t,
+ int r,
+ int q
+ ){}
+
+ public void glNormal3f(
+ float nx,
+ float ny,
+ float nz
+ ){}
+
+ public void glNormal3x(
+ int nx,
+ int ny,
+ int nz
+ ){}
+
+ public void glNormalPointer(
+ int type,
+ int stride,
+ java.nio.Buffer pointer
+ ){}
+
+ public void glOrthof(
+ float left,
+ float right,
+ float bottom,
+ float top,
+ float zNear,
+ float zFar
+ ){}
+
+ public void glOrthox(
+ int left,
+ int right,
+ int bottom,
+ int top,
+ int zNear,
+ int zFar
+ ){}
+
+ public void glPixelStorei(
+ int pname,
+ int param
+ ){}
+
+ public void glPointSize(
+ float size
+ ){}
+
+ public void glPointSizex(
+ int size
+ ){}
+
+ public void glPolygonOffset(
+ float factor,
+ float units
+ ){}
+
+ public void glPolygonOffsetx(
+ int factor,
+ int units
+ ){}
+
+ public void glPopMatrix(
+ ){}
+
+ public void glPushMatrix(
+ ){}
+
+ public void glReadPixels(
+ int x,
+ int y,
+ int width,
+ int height,
+ int format,
+ int type,
+ java.nio.Buffer pixels
+ ){}
+
+ public void glRotatef(
+ float angle,
+ float x,
+ float y,
+ float z
+ ){}
+
+ public void glRotatex(
+ int angle,
+ int x,
+ int y,
+ int z
+ ){}
+
+ public void glSampleCoverage(
+ float value,
+ boolean invert
+ ){}
+
+ public void glSampleCoveragex(
+ int value,
+ boolean invert
+ ){}
+
+ public void glScalef(
+ float x,
+ float y,
+ float z
+ ){}
+
+ public void glScalex(
+ int x,
+ int y,
+ int z
+ ){}
+
+ public void glScissor(
+ int x,
+ int y,
+ int width,
+ int height
+ ){}
+
+ public void glShadeModel(
+ int mode
+ ){}
+
+ public void glStencilFunc(
+ int func,
+ int ref,
+ int mask
+ ){}
+
+ public void glStencilMask(
+ int mask
+ ){}
+
+ public void glStencilOp(
+ int fail,
+ int zfail,
+ int zpass
+ ){}
+
+ public void glTexCoordPointer(
+ int size,
+ int type,
+ int stride,
+ java.nio.Buffer pointer
+ ){}
+
+ public void glTexEnvf(
+ int target,
+ int pname,
+ float param
+ ){}
+
+ public void glTexEnvfv(
+ int target,
+ int pname,
+ float[] params,
+ int offset
+ ){}
+
+ public void glTexEnvfv(
+ int target,
+ int pname,
+ java.nio.FloatBuffer params
+ ){}
+
+ public void glTexEnvx(
+ int target,
+ int pname,
+ int param
+ ){}
+
+ public void glTexEnvxv(
+ int target,
+ int pname,
+ int[] params,
+ int offset
+ ){}
+
+ public void glTexEnvxv(
+ int target,
+ int pname,
+ java.nio.IntBuffer params
+ ){}
+
+ public void glTexImage2D(
+ int target,
+ int level,
+ int internalformat,
+ int width,
+ int height,
+ int border,
+ int format,
+ int type,
+ java.nio.Buffer pixels
+ ){}
+
+ public void glTexParameterf(
+ int target,
+ int pname,
+ float param
+ ){}
+
+ public void glTexParameterx(
+ int target,
+ int pname,
+ int param
+ ){}
+
+ public void glTexSubImage2D(
+ int target,
+ int level,
+ int xoffset,
+ int yoffset,
+ int width,
+ int height,
+ int format,
+ int type,
+ java.nio.Buffer pixels
+ ){}
+
+ public void glTranslatef(
+ float x,
+ float y,
+ float z
+ ){}
+
+ public void glTranslatex(
+ int x,
+ int y,
+ int z
+ ){}
+
+ public void glVertexPointer(
+ int size,
+ int type,
+ int stride,
+ java.nio.Buffer pointer
+ ){}
+
+ public void glViewport(
+ int x,
+ int y,
+ int width,
+ int height
+ ){}
+
+ public int glQueryMatrixxOES(
+ int[] mantissa,
+ int mantissaOffset,
+ int[] exponent,
+ int exponentOffset
+ ){ throw new UnsupportedOperationException(); }
+
+ public int glQueryMatrixxOES(
+ java.nio.IntBuffer mantissa,
+ java.nio.IntBuffer exponent
+ ){ throw new UnsupportedOperationException(); }
+
+ public void glGetPointerv(int pname, java.nio.Buffer[] params){}
+ public void glBindBuffer(
+ int target,
+ int buffer
+ ){}
+
+ public void glBufferData(
+ int target,
+ int size,
+ java.nio.Buffer data,
+ int usage
+ ){}
+
+ public void glBufferSubData(
+ int target,
+ int offset,
+ int size,
+ java.nio.Buffer data
+ ){}
+
+ public void glClipPlanef(
+ int plane,
+ float[] equation,
+ int offset
+ ){}
+
+ public void glClipPlanef(
+ int plane,
+ java.nio.FloatBuffer equation
+ ){}
+
+ public void glClipPlanex(
+ int plane,
+ int[] equation,
+ int offset
+ ){}
+
+ public void glClipPlanex(
+ int plane,
+ java.nio.IntBuffer equation
+ ){}
+
+ public void glColor4ub(
+ byte red,
+ byte green,
+ byte blue,
+ byte alpha
+ ){}
+
+ public void glColorPointer(
+ int size,
+ int type,
+ int stride,
+ int offset
+ ){}
+
+ public void glDeleteBuffers(
+ int n,
+ int[] buffers,
+ int offset
+ ){}
+
+ public void glDeleteBuffers(
+ int n,
+ java.nio.IntBuffer buffers
+ ){}
+
+ public void glDrawElements(
+ int mode,
+ int count,
+ int type,
+ int offset
+ ){}
+
+ public void glGenBuffers(
+ int n,
+ int[] buffers,
+ int offset
+ ){}
+
+ public void glGenBuffers(
+ int n,
+ java.nio.IntBuffer buffers
+ ){}
+
+ public void glGetBooleanv(
+ int pname,
+ boolean[] params,
+ int offset
+ ){}
+
+ public void glGetBooleanv(
+ int pname,
+ java.nio.IntBuffer params
+ ){}
+
+ public void glGetBufferParameteriv(
+ int target,
+ int pname,
+ int[] params,
+ int offset
+ ){}
+
+ public void glGetBufferParameteriv(
+ int target,
+ int pname,
+ java.nio.IntBuffer params
+ ){}
+
+ public void glGetClipPlanef(
+ int pname,
+ float[] eqn,
+ int offset
+ ){}
+
+ public void glGetClipPlanef(
+ int pname,
+ java.nio.FloatBuffer eqn
+ ){}
+
+ public void glGetClipPlanex(
+ int pname,
+ int[] eqn,
+ int offset
+ ){}
+
+ public void glGetClipPlanex(
+ int pname,
+ java.nio.IntBuffer eqn
+ ){}
+
+ public void glGetFixedv(
+ int pname,
+ int[] params,
+ int offset
+ ){}
+
+ public void glGetFixedv(
+ int pname,
+ java.nio.IntBuffer params
+ ){}
+
+ public void glGetFloatv(
+ int pname,
+ float[] params,
+ int offset
+ ){}
+
+ public void glGetFloatv(
+ int pname,
+ java.nio.FloatBuffer params
+ ){}
+
+ public void glGetLightfv(
+ int light,
+ int pname,
+ float[] params,
+ int offset
+ ){}
+
+ public void glGetLightfv(
+ int light,
+ int pname,
+ java.nio.FloatBuffer params
+ ){}
+
+ public void glGetLightxv(
+ int light,
+ int pname,
+ int[] params,
+ int offset
+ ){}
+
+ public void glGetLightxv(
+ int light,
+ int pname,
+ java.nio.IntBuffer params
+ ){}
+
+ public void glGetMaterialfv(
+ int face,
+ int pname,
+ float[] params,
+ int offset
+ ){}
+
+ public void glGetMaterialfv(
+ int face,
+ int pname,
+ java.nio.FloatBuffer params
+ ){}
+
+ public void glGetMaterialxv(
+ int face,
+ int pname,
+ int[] params,
+ int offset
+ ){}
+
+ public void glGetMaterialxv(
+ int face,
+ int pname,
+ java.nio.IntBuffer params
+ ){}
+
+ public void glGetTexEnviv(
+ int env,
+ int pname,
+ int[] params,
+ int offset
+ ){}
+
+ public void glGetTexEnviv(
+ int env,
+ int pname,
+ java.nio.IntBuffer params
+ ){}
+
+ public void glGetTexEnvxv(
+ int env,
+ int pname,
+ int[] params,
+ int offset
+ ){}
+
+ public void glGetTexEnvxv(
+ int env,
+ int pname,
+ java.nio.IntBuffer params
+ ){}
+
+ public void glGetTexParameterfv(
+ int target,
+ int pname,
+ float[] params,
+ int offset
+ ){}
+
+ public void glGetTexParameterfv(
+ int target,
+ int pname,
+ java.nio.FloatBuffer params
+ ){}
+
+ public void glGetTexParameteriv(
+ int target,
+ int pname,
+ int[] params,
+ int offset
+ ){}
+
+ public void glGetTexParameteriv(
+ int target,
+ int pname,
+ java.nio.IntBuffer params
+ ){}
+
+ public void glGetTexParameterxv(
+ int target,
+ int pname,
+ int[] params,
+ int offset
+ ){}
+
+ public void glGetTexParameterxv(
+ int target,
+ int pname,
+ java.nio.IntBuffer params
+ ){}
+
+ public boolean glIsBuffer(
+ int buffer
+ ){ throw new UnsupportedOperationException(); }
+
+ public boolean glIsEnabled(
+ int cap
+ ){ throw new UnsupportedOperationException(); }
+
+ public boolean glIsTexture(
+ int texture
+ ){ throw new UnsupportedOperationException(); }
+
+ public void glNormalPointer(
+ int type,
+ int stride,
+ int offset
+ ){}
+
+ public void glPointParameterf(
+ int pname,
+ float param
+ ){}
+
+ public void glPointParameterfv(
+ int pname,
+ float[] params,
+ int offset
+ ){}
+
+ public void glPointParameterfv(
+ int pname,
+ java.nio.FloatBuffer params
+ ){}
+
+ public void glPointParameterx(
+ int pname,
+ int param
+ ){}
+
+ public void glPointParameterxv(
+ int pname,
+ int[] params,
+ int offset
+ ){}
+
+ public void glPointParameterxv(
+ int pname,
+ java.nio.IntBuffer params
+ ){}
+
+ public void glPointSizePointerOES(
+ int type,
+ int stride,
+ java.nio.Buffer pointer
+ ){}
+
+ public void glTexCoordPointer(
+ int size,
+ int type,
+ int stride,
+ int offset
+ ){}
+
+ public void glTexEnvi(
+ int target,
+ int pname,
+ int param
+ ){}
+
+ public void glTexEnviv(
+ int target,
+ int pname,
+ int[] params,
+ int offset
+ ){}
+
+ public void glTexEnviv(
+ int target,
+ int pname,
+ java.nio.IntBuffer params
+ ){}
+
+ public void glTexParameterfv(
+ int target,
+ int pname,
+ float[] params,
+ int offset
+ ){}
+
+ public void glTexParameterfv(
+ int target,
+ int pname,
+ java.nio.FloatBuffer params
+ ){}
+
+ public void glTexParameteri(
+ int target,
+ int pname,
+ int param
+ ){}
+
+ public void glTexParameteriv(
+ int target,
+ int pname,
+ int[] params,
+ int offset
+ ){}
+
+ public void glTexParameteriv(
+ int target,
+ int pname,
+ java.nio.IntBuffer params
+ ){}
+
+ public void glTexParameterxv(
+ int target,
+ int pname,
+ int[] params,
+ int offset
+ ){}
+
+ public void glTexParameterxv(
+ int target,
+ int pname,
+ java.nio.IntBuffer params
+ ){}
+
+ public void glVertexPointer(
+ int size,
+ int type,
+ int stride,
+ int offset
+ ){}
+
+ public void glCurrentPaletteMatrixOES(
+ int matrixpaletteindex
+ ){}
+
+ public void glDrawTexfOES(
+ float x,
+ float y,
+ float z,
+ float width,
+ float height
+ ){}
+
+ public void glDrawTexfvOES(
+ float[] coords,
+ int offset
+ ){}
+
+ public void glDrawTexfvOES(
+ java.nio.FloatBuffer coords
+ ){}
+
+ public void glDrawTexiOES(
+ int x,
+ int y,
+ int z,
+ int width,
+ int height
+ ){}
+
+ public void glDrawTexivOES(
+ int[] coords,
+ int offset
+ ){}
+
+ public void glDrawTexivOES(
+ java.nio.IntBuffer coords
+ ){}
+
+ public void glDrawTexsOES(
+ short x,
+ short y,
+ short z,
+ short width,
+ short height
+ ){}
+
+ public void glDrawTexsvOES(
+ short[] coords,
+ int offset
+ ){}
+
+ public void glDrawTexsvOES(
+ java.nio.ShortBuffer coords
+ ){}
+
+ public void glDrawTexxOES(
+ int x,
+ int y,
+ int z,
+ int width,
+ int height
+ ){}
+
+ public void glDrawTexxvOES(
+ int[] coords,
+ int offset
+ ){}
+
+ public void glDrawTexxvOES(
+ java.nio.IntBuffer coords
+ ){}
+
+ public void glLoadPaletteFromModelViewMatrixOES(
+ ){}
+
+ public void glMatrixIndexPointerOES(
+ int size,
+ int type,
+ int stride,
+ java.nio.Buffer pointer
+ ){}
+
+ public void glMatrixIndexPointerOES(
+ int size,
+ int type,
+ int stride,
+ int offset
+ ){}
+
+ public void glWeightPointerOES(
+ int size,
+ int type,
+ int stride,
+ java.nio.Buffer pointer
+ ){}
+
+ public void glWeightPointerOES(
+ int size,
+ int type,
+ int stride,
+ int offset
+ ){}
+
+ public void glBindFramebufferOES(
+ int target,
+ int framebuffer
+ ){}
+
+ public void glBindRenderbufferOES(
+ int target,
+ int renderbuffer
+ ){}
+
+ public void glBlendEquation(
+ int mode
+ ){}
+
+ public void glBlendEquationSeparate(
+ int modeRGB,
+ int modeAlpha
+ ){}
+
+ public void glBlendFuncSeparate(
+ int srcRGB,
+ int dstRGB,
+ int srcAlpha,
+ int dstAlpha
+ ){}
+
+ public int glCheckFramebufferStatusOES(
+ int target
+ ){ throw new UnsupportedOperationException(); }
+
+ public void glDeleteFramebuffersOES(
+ int n,
+ int[] framebuffers,
+ int offset
+ ){}
+
+ public void glDeleteFramebuffersOES(
+ int n,
+ java.nio.IntBuffer framebuffers
+ ){}
+
+ public void glDeleteRenderbuffersOES(
+ int n,
+ int[] renderbuffers,
+ int offset
+ ){}
+
+ public void glDeleteRenderbuffersOES(
+ int n,
+ java.nio.IntBuffer renderbuffers
+ ){}
+
+ public void glFramebufferRenderbufferOES(
+ int target,
+ int attachment,
+ int renderbuffertarget,
+ int renderbuffer
+ ){}
+
+ public void glFramebufferTexture2DOES(
+ int target,
+ int attachment,
+ int textarget,
+ int texture,
+ int level
+ ){}
+
+ public void glGenerateMipmapOES(
+ int target
+ ){}
+
+ public void glGenFramebuffersOES(
+ int n,
+ int[] framebuffers,
+ int offset
+ ){}
+
+ public void glGenFramebuffersOES(
+ int n,
+ java.nio.IntBuffer framebuffers
+ ){}
+
+ public void glGenRenderbuffersOES(
+ int n,
+ int[] renderbuffers,
+ int offset
+ ){}
+
+ public void glGenRenderbuffersOES(
+ int n,
+ java.nio.IntBuffer renderbuffers
+ ){}
+
+ public void glGetFramebufferAttachmentParameterivOES(
+ int target,
+ int attachment,
+ int pname,
+ int[] params,
+ int offset
+ ){}
+
+ public void glGetFramebufferAttachmentParameterivOES(
+ int target,
+ int attachment,
+ int pname,
+ java.nio.IntBuffer params
+ ){}
+
+ public void glGetRenderbufferParameterivOES(
+ int target,
+ int pname,
+ int[] params,
+ int offset
+ ){}
+
+ public void glGetRenderbufferParameterivOES(
+ int target,
+ int pname,
+ java.nio.IntBuffer params
+ ){}
+
+ public void glGetTexGenfv(
+ int coord,
+ int pname,
+ float[] params,
+ int offset
+ ){}
+
+ public void glGetTexGenfv(
+ int coord,
+ int pname,
+ java.nio.FloatBuffer params
+ ){}
+
+ public void glGetTexGeniv(
+ int coord,
+ int pname,
+ int[] params,
+ int offset
+ ){}
+
+ public void glGetTexGeniv(
+ int coord,
+ int pname,
+ java.nio.IntBuffer params
+ ){}
+
+ public void glGetTexGenxv(
+ int coord,
+ int pname,
+ int[] params,
+ int offset
+ ){}
+
+ public void glGetTexGenxv(
+ int coord,
+ int pname,
+ java.nio.IntBuffer params
+ ){}
+
+ public boolean glIsFramebufferOES(
+ int framebuffer
+ ){ throw new UnsupportedOperationException(); }
+
+ public boolean glIsRenderbufferOES(
+ int renderbuffer
+ ){ throw new UnsupportedOperationException(); }
+
+ public void glRenderbufferStorageOES(
+ int target,
+ int internalformat,
+ int width,
+ int height
+ ){}
+
+ public void glTexGenf(
+ int coord,
+ int pname,
+ float param
+ ){}
+
+ public void glTexGenfv(
+ int coord,
+ int pname,
+ float[] params,
+ int offset
+ ){}
+
+ public void glTexGenfv(
+ int coord,
+ int pname,
+ java.nio.FloatBuffer params
+ ){}
+
+ public void glTexGeni(
+ int coord,
+ int pname,
+ int param
+ ){}
+
+ public void glTexGeniv(
+ int coord,
+ int pname,
+ int[] params,
+ int offset
+ ){}
+
+ public void glTexGeniv(
+ int coord,
+ int pname,
+ java.nio.IntBuffer params
+ ){}
+
+ public void glTexGenx(
+ int coord,
+ int pname,
+ int param
+ ){}
+
+ public void glTexGenxv(
+ int coord,
+ int pname,
+ int[] params,
+ int offset
+ ){}
+
+ public void glTexGenxv(
+ int coord,
+ int pname,
+ java.nio.IntBuffer params
+ ){}
+}