1 package com.cooliris.media;
3 import javax.microedition.khronos.opengles.GL11;
4 import javax.microedition.khronos.opengles.GL11Ext;
6 import android.graphics.Bitmap;
7 import android.graphics.Canvas;
8 import android.opengl.GLUtils;
10 public abstract class CanvasTexture {
13 private int mTextureId;
14 private int mTextureWidth;
15 private int mTextureHeight;
16 private float mNormalizedWidth;
17 private float mNormalizedHeight;
19 private final Canvas mCanvas = new Canvas();
20 private final Bitmap.Config mBitmapConfig;
21 private Bitmap mBitmap = null;
22 private boolean mNeedsDraw = false;
23 private boolean mNeedsResize = false;
24 private GL11 mCachedGL = null;
26 public CanvasTexture(Bitmap.Config bitmapConfig) {
27 mBitmapConfig = bitmapConfig;
30 public final void setNeedsDraw() {
34 public final int getWidth() {
38 public final int getHeight() {
42 public final float getNormalizedWidth() {
43 return mNormalizedWidth;
46 public final float getNormalizedHeight() {
47 return mNormalizedHeight;
50 public final void setSize(int width, int height) {
59 public void resetTexture() {
60 // Happens when restoring the scene. Need to manage this more automatically.
65 // This code seems largely a dup of CanvasLayer.
66 public boolean bind(GL11 gl) {
67 if (mCachedGL != gl) {
71 int width = (int) mWidth;
72 int height = (int) mHeight;
73 int textureId = mTextureId;
74 int textureWidth = mTextureWidth;
75 int textureHeight = mTextureHeight;
76 Canvas canvas = mCanvas;
77 Bitmap bitmap = mBitmap;
79 if (mNeedsResize || mTextureId == 0) {
80 // Clear the resize flag and mark as needing draw.
83 // Compute the power-of-2 padded size for the texture.
84 int newTextureWidth = Shared.nextPowerOf2(width);
85 int newTextureHeight = Shared.nextPowerOf2(height);
87 // Reallocate the bitmap only if the padded size has changed.
88 // TODO: reuse same texture if it is already large enough, just
90 if (textureWidth != newTextureWidth || textureHeight != newTextureHeight || mTextureId == 0) {
91 // Allocate a texture if needed.
93 int[] textureIdOut = new int[1];
94 gl.glGenTextures(1, textureIdOut, 0);
95 textureId = textureIdOut[0];
97 mTextureId = textureId;
99 // Set texture parameters.
100 gl.glBindTexture(GL11.GL_TEXTURE_2D, textureId);
101 gl.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP_TO_EDGE);
102 gl.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP_TO_EDGE);
103 gl.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
104 gl.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
107 // Set the new texture width and height.
108 textureWidth = newTextureWidth;
109 textureHeight = newTextureHeight;
110 mTextureWidth = newTextureWidth;
111 mTextureHeight = newTextureHeight;
112 mNormalizedWidth = (float) width / textureWidth;
113 mNormalizedHeight = (float) height / textureHeight;
115 // Recycle the existing bitmap and create a new one.
118 if (textureWidth > 0 && textureHeight > 0) {
119 bitmap = Bitmap.createBitmap(textureWidth, textureHeight, mBitmapConfig);
120 canvas.setBitmap(bitmap);
126 // Bind the texture to the context.
127 if (textureId == 0) {
130 gl.glBindTexture(GL11.GL_TEXTURE_2D, textureId);
132 // Redraw the contents of the texture if needed.
135 renderCanvas(canvas, bitmap, width, height);
136 int[] cropRect = { 0, height, width, -height };
137 gl.glTexParameteriv(GL11.GL_TEXTURE_2D, GL11Ext.GL_TEXTURE_CROP_RECT_OES, cropRect, 0);
138 GLUtils.texImage2D(GL11.GL_TEXTURE_2D, 0, bitmap, 0);
145 public void draw(RenderView view, GL11 gl, int x, int y) {
147 view.draw2D(x, y, 0, mWidth, mHeight);
151 public void drawWithEffect(RenderView view, GL11 gl, float x, float y, float anchorX, float anchorY, float alpha, float scale) {
153 float width = mWidth;
154 float height = mHeight;
156 // Apply scale transform if not identity.
157 if (scale != 1) { // CR: 1.0f
158 float originX = x + anchorX * width;
159 float originY = y + anchorY * height;
162 x = originX - anchorX * width;
163 y = originY - anchorY * height;
166 // Set alpha if needed.
167 if (alpha != 1f) { // CR: 1.0f
168 view.setAlpha(alpha);
170 view.draw2D(x, y, 0, width, height);
177 protected abstract void onSizeChanged();
179 protected abstract void renderCanvas(Canvas canvas, Bitmap backing, int width, int height);
181 } // CR: superfluous newline above.