■画像
以下のようにして画像をテクスチャとして貼ることができる。
public class MainActivity extends Activity { private GLSurfaceView gLSurfaceView; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); gLSurfaceView = new GLSurfaceView(this); gLSurfaceView.setRenderer(new Renderer()); setContentView(gLSurfaceView); } @Override public void onPause() { super.onPause(); gLSurfaceView.onPause(); } @Override public void onResume() { super.onResume(); gLSurfaceView.onResume(); } private class Renderer implements GLSurfaceView.Renderer { @Override public void onDrawFrame(GL10 gl) { gl.glClearColor(0.0f, 1.0f, 1.0f, 1.0f); gl.glClear(GL10.GL_COLOR_BUFFER_BIT); float left = -0.9f; float top = 0.9f; float right = 0.9f; float bottom = -0.9f; // テクスチャの描画設定=>次の描画オブジェクトに適用される { float[] uv = { left, top, left, bottom, right, top, right, bottom, }; // Java => OpenGL にあたっての変換 ByteBuffer bb = ByteBuffer.allocateDirect(uv.length * 4); bb.order(ByteOrder.nativeOrder()); FloatBuffer fb = bb.asFloatBuffer(); fb.put(uv); fb.position(0); gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, fb);// UV配列をOpen GLに紐付け } // ポリゴンの描画 { top = -top; bottom = -bottom; float[] vertexes = { left, top, 0.0f, left, bottom, 0.0f, right, top, 0.0f, right, bottom, 0.0f }; // Java => OpenGL にあたっての変換 ByteBuffer bb = ByteBuffer.allocateDirect(vertexes.length * 4); bb.order(ByteOrder.nativeOrder()); FloatBuffer fb = bb.asFloatBuffer(); fb.put(vertexes); fb.position(0); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);// 頂点バッファの有効化 gl.glVertexPointer(3, GL10.GL_FLOAT, 0, fb);// 頂点バッファをOpen GLに紐付け gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);// 描画する } } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { gl.glViewport(0, 0, width, height);// 描画領域を指定 gl.glColor4f(1.0f, 0.9f, 0.9f, 1.0f);// 短形の描画色を指定 gl.glEnable(GL10.GL_TEXTURE_2D);// テクスチャを有効にする // テクスチャ用メモリの確保 int[] buffers = new int[1];// テクスチャ管理IDの配列 gl.glGenTextures(1, buffers, 0);// 1枚分のメモリを確保 gl.glBindTexture(GL10.GL_TEXTURE_2D, buffers[0]);// 1枚目を使う指定 Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.chrome); GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);// 縮小時のフィルタ gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST);// 拡大時のフィルタ bitmap.recycle();// bitmapを破棄 } @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { } } }
■文字列
以下のようにcanvasを利用してして文字列を貼り付けることができる。
public class MainActivity extends Activity { private GLSurfaceView gLSurfaceView; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); gLSurfaceView = new GLSurfaceView(this); gLSurfaceView.setRenderer(new Renderer()); setContentView(gLSurfaceView); } @Override public void onPause() { super.onPause(); gLSurfaceView.onPause(); } @Override public void onResume() { super.onResume(); gLSurfaceView.onResume(); } private class Renderer implements GLSurfaceView.Renderer { private int textureName; @Override public void onDrawFrame(GL10 gl) { gl.glClearColor(0.0f, 1.0f, 1.0f, 1.0f); gl.glClear(GL10.GL_COLOR_BUFFER_BIT); float left = -0.9f; float top = 0.9f; float right = 0.9f; float bottom = -0.9f; // テクスチャの描画設定=>次の描画オブジェクトに適用される { float[] uv = { left, top, left, bottom, right, top, right, bottom, }; ByteBuffer bb = ByteBuffer.allocateDirect(uv.length * 4); bb.order(ByteOrder.nativeOrder()); FloatBuffer fb = bb.asFloatBuffer(); fb.put(uv); fb.position(0); gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, fb); } // ポリゴンの描画 { top = -top; bottom = -bottom; float[] vertexes = { left, top, 0.0f, left, bottom, 0.0f, right, top, 0.0f, right, bottom, 0.0f }; ByteBuffer bb = ByteBuffer.allocateDirect(vertexes.length * 4); bb.order(ByteOrder.nativeOrder()); FloatBuffer fb = bb.asFloatBuffer(); fb.put(vertexes); fb.position(0); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, fb); gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); } } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { gl.glViewport(0, 0, width, height); gl.glColor4f(1.0f, 0.9f, 0.9f, 1.0f); Bitmap bitmap = Bitmap.createBitmap(256, 256, Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); Paint paint = new Paint(); paint.setColor(Color.WHITE); paint.setStyle(Style.FILL); canvas.drawColor(0); canvas.drawText("hogehogehogehogehogehogehogehogehogehoge", 0, 15, paint); gl.glEnable(GL10.GL_TEXTURE_2D);// テクスチャを有効にする int[] buffers = new int[1]; gl.glGenTextures(1, buffers, 0); textureName = buffers[0]; gl.glBindTexture(GL10.GL_TEXTURE_2D, textureName); GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST); bitmap.recycle(); } @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { } } }
■座標
右上が(x, y) = (1.0, 1.0)で、左下が(x, y) = (-1.0, -1.0)となっていると非常に扱いにくい場合もある。以下のようにすることでピクセルに変換できる。
@Override public void onDrawFrame(GL10 gl) { gl.glClearColor(0.0f, 1.0f, 1.0f, 1.0f); gl.glClear(GL10.GL_COLOR_BUFFER_BIT); int x = 0; int y = 0; int width = 512; int height = 512; { float left = ((float) x / (float) textureWidth); float top = ((float) y / (float) textureHeight); float right = left + ((float) width / (float) textureWidth); float bottom = top + ((float) height / (float) textureHeight); float[] uv = { left, top, left, bottom, right, top, right, bottom, }; ByteBuffer bb = ByteBuffer.allocateDirect(uv.length * 4); bb.order(ByteOrder.nativeOrder()); FloatBuffer fb = bb.asFloatBuffer(); fb.put(uv); fb.position(0); gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, fb); } { float left = ((float) x / (float) screenWidth) * 2.0f - 1.0f; float top = ((float) y / (float) screenHeight) * 2.0f - 1.0f; float right = left + ((float) width / (float) screenWidth) * 2.0f; float bottom = top + ((float) height / (float) screenHeight) * 2.0f; top = -top; bottom = -bottom; float[] positions = { left, top, 0.0f, left, bottom, 0.0f, right, top, 0.0f, right, bottom, 0.0f }; ByteBuffer bb = ByteBuffer.allocateDirect(positions.length * 4); bb.order(ByteOrder.nativeOrder()); FloatBuffer fb = bb.asFloatBuffer(); fb.put(positions); fb.position(0); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, fb); gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); } counter++; }
■まとめ
JavaScriptでCanvasを操作してアニメーションする感じに似ている。もっと言うとPhotoshopで作業をする感じにも似ている。
なんか詳しいそうなので、書き込みしてしまいました。
ちょっと、ここの記事に直接関係ないのですが、2.0の環境に対応させて実装したらでできますかねえ?
最近(2011年秋)試していないのですが、2011年の春までいろいろ調べていたのですが、どうやってもシェーダーのコンパイルが通らなかったもんで。