/* OpenGL ES2.0のテクスチャ設定 2017/03/30 創作プログラミングの街 */ package info.gamebatake.android.gltexturetest; import android.graphics.Bitmap; import android.graphics.Color; import android.opengl.GLES20; import android.opengl.GLSurfaceView; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.util.HashMap; import android.opengl.GLUtils; public class TestGLView extends GLSurfaceView implements GLSurfaceView.Renderer { private int _gl_prog; private HashMap _gl_vars; private FloatBuffer _vertex_buffer; private FloatBuffer _texture_buffer; private int _draw_counter; public TestGLView(MainActivity activity) { super(activity); // OpenGL ES 2 setEGLContextClientVersion(2); _draw_counter = 0; setRenderer(this); // 自動で連続描画を行う setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY); } @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { String vs_code = "attribute vec2 A_position;attribute vec2 A_texture_uv;varying vec2 V_texture_uv;void main(void){gl_Position = vec4(A_position, 0.0, 1.0);V_texture_uv = A_texture_uv;}"; String fs_code = "precision mediump float;uniform sampler2D texture0;varying vec2 V_texture_uv; void main() { gl_FragColor = texture2D(texture0, V_texture_uv);}"; int v_shader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER); int f_shader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER); // Vertexシェーダーのコードをコンパイル GLES20.glShaderSource(v_shader, vs_code); GLES20.glCompileShader(v_shader); // Fragmentシェーダーのコードをコンパイル GLES20.glShaderSource(f_shader, fs_code); GLES20.glCompileShader(f_shader); // Programを作成 _gl_prog = GLES20.glCreateProgram(); // Programのシェーダーを設定 GLES20.glAttachShader(_gl_prog, v_shader); GLES20.glAttachShader(_gl_prog, f_shader); GLES20.glLinkProgram(_gl_prog); GLES20.glUseProgram(_gl_prog); _gl_vars = new HashMap(); // gl変数を保存 _gl_vars.put("A_position", GLES20.glGetAttribLocation(_gl_prog, "A_position")); _gl_vars.put("A_texture_uv", GLES20.glGetAttribLocation(_gl_prog, "A_texture_uv")); _gl_vars.put("texture0", GLES20.glGetUniformLocation(_gl_prog, "texture0")); // テクスチャ用Bitmap作成 Bitmap bmp = Bitmap.createBitmap(32, 32, Bitmap.Config.ARGB_8888); // テクスチャ用の画像を描画 for (int y = 0;y < 32;y++) { for (int x = 0;x < 32;x++) { if (x == 0 || x == 31 || y == 0 || y ==31) { bmp.setPixel(x, y, Color.argb(255, 0, y * 8, 255)); } else { bmp.setPixel(x, y, Color.argb(255, 255 - x * 8, y * 4, 0)); } } } // テクスチャ0を有効化 GLES20.glActiveTexture(GLES20.GL_TEXTURE0); int[] textures = new int[1]; // テクスチャ作成しidをtextures[0]に保存 GLES20.glGenTextures(1, textures, 0); // テクスチャ0にtextures[0]をバインド GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]); // 縮小時の補間設定 GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); // 拡大時の補間設定 GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); // bmpをテクスチャ0に設定 GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bmp, 0); bmp.recycle(); bmp = null; // gl変数texture0に0を設定 GLES20.glUniform1i(_gl_vars.get("texture0"), 0); // 「全体」を覆うテクスチャ座標配列を作成 float[] texture_uvs = {0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f}; ByteBuffer tex_bb = ByteBuffer.allocateDirect(texture_uvs.length * 4); tex_bb.order(ByteOrder.nativeOrder()); _texture_buffer = tex_bb.asFloatBuffer(); _texture_buffer.put(texture_uvs); _texture_buffer.position(0); // (-0,9, -0.9)-(0.9, 0.9)の長方形頂点データ作成 float[] vertex_array = {-0.9f, -0.9f, -0.9f, 0.9f, 0.9f, -0.9f, 0.9f, 0.9f}; // 頂点データをバッファに格納 ByteBuffer vt_bb = ByteBuffer.allocateDirect(vertex_array.length * 4); vt_bb.order(ByteOrder.nativeOrder()); _vertex_buffer = vt_bb.asFloatBuffer(); _vertex_buffer.put(vertex_array); _vertex_buffer.position(0); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { // 画面全体を(-1.0, -1.0)-(1.0, 1.0)の座標系に対応させる GLES20.glViewport(0, 0, width, height); } @Override public void onDrawFrame(GL10 gl) { // クリア色設定 float l = (float)(Math.sin(_draw_counter / 100.0) / 2.0 + 0.5); GLES20.glClearColor(l, l, l, 1.0f); // カラーバッファクリア GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); // 長方形のテクスチャ変数設定 GLES20.glEnableVertexAttribArray(_gl_vars.get("A_texture_uv")); GLES20.glVertexAttribPointer(_gl_vars.get("A_texture_uv"), 2, GLES20.GL_FLOAT, false, 0, _texture_buffer); // 長方形の頂点変数設定 GLES20.glEnableVertexAttribArray(_gl_vars.get("A_position")); GLES20.glVertexAttribPointer(_gl_vars.get("A_position"), 2, GLES20.GL_FLOAT, false, 0, _vertex_buffer); // 長方形を描画 GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); // 変数解除 GLES20.glDisableVertexAttribArray(_gl_vars.get("A_texture_uv")); GLES20.glDisableVertexAttribArray(_gl_vars.get("A_position")); _draw_counter++; } }