androidのOpenGL ESでテクスチャを貼る
■画像
以下のようにして画像をテクスチャとして貼ることができる。
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で作業をする感じにも似ている。
TrackBack URL :
Comments (1)