package net.npaka.gl20textureex5; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.opengl.GLES20; import android.opengl.GLSurfaceView; import android.opengl.GLUtils; import android.opengl.Matrix;
//レンダラー public class GLRenderer implements GLSurfaceView.Renderer { //システム private Activity activity;//アクティビティ private int screenW; //画面幅 private int screenH; //画面高さ //バッファ private FloatBuffer vertexBuffer;//頂点バッファ private FloatBuffer uvBuffer; //UVバッファ //テクスチャ private int textureId;//テクスチャID //コンストラクタ public GLRenderer(Activity activity) { this.activity=activity; } //サーフェイス生成時に呼ばれる @Override public void onSurfaceCreated(GL10 gl10,EGLConfig eglConfig) { //プログラムの生成 GLES.makeProgram(); //頂点バッファの有効化 GLES20.glEnableVertexAttribArray(GLES.positionHandle); GLES20.glEnableVertexAttribArray(GLES.uvHandle); //テクスチャの有効化 GLES20.glEnable(GLES20.GL_TEXTURE_2D); //テクスチャの生成 Bitmap bmp=BitmapFactory.decodeResource( activity.getResources(),R.drawable.sample); textureId=makeTexture(bmp); //ブレンドの指定 GLES20.glEnable(GLES20.GL_BLEND); GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA,GLES20.GL_ONE_MINUS_SRC_ALPHA); //頂点バッファの生成と設定 vertexBuffer=makeVertexBuffer(); //UVバッファの生成 uvBuffer=makeUVBuffer(); } //画面サイズ変更時に呼ばれる @Override public void onSurfaceChanged(GL10 gl10,int w,int h) { //画面の表示領域の指定 GLES20.glViewport(0,0,w,h); screenW=w; screenH=h; } //毎フレーム描画時に呼ばれる @Override public void onDrawFrame(GL10 gl10) { //画面のクリア GLES20.glClearColor(1.0f,1.0f,1.0f,1.0f); GLES20.glClear(GL10.GL_COLOR_BUFFER_BIT); //テクスチャの指定 GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,textureId); GLES20.glUniform1i(GLES.texHandle,0); //UVバッファの指定 GLES20.glVertexAttribPointer(GLES.uvHandle,2, GLES20.GL_FLOAT,false,0,uvBuffer); //上の四角形の描画 setTextureArea(256,256,0,0,128,128); drawRect(50,50,200,200); //下の四角形の描画 setTextureArea(256,256,0,128,128,128); drawRect(50,300,300,300); } //テクスチャ領域の指定 private void setTextureArea( int textureW,int textureH,int x,int y,int w,int h) { //ピクセル座標をUV座標に変換 float tw=(float)w/(float)textureW; float th=(float)h/(float)textureH; float tx=(float)x/(float)textureW; float ty=(float)y/(float)textureH; //テクスチャ行列の移動・拡大縮小 Matrix.setIdentityM(GLES.texMatrix,0); Matrix.translateM(GLES.texMatrix,0,tx,ty,0.0f); Matrix.scaleM(GLES.texMatrix,0,tw,th,1.0f); } //四角形の描画 private void drawRect(int x,int y,int w,int h) { //ウィンドウ座標を正規化デバイス座標に変換 float sx=((float)x/(float)screenW)*2.0f-1.0f; float sy=((float)y/(float)screenH)*2.0f-1.0f; float sw=((float)w/(float)screenW); float sh=((float)h/(float)screenH); //モデルビュー行列の移動・拡縮 Matrix.setIdentityM(GLES.mMatrix,0); Matrix.translateM(GLES.mMatrix,0,sx+sw,-(sy+sh),0.0f); Matrix.scaleM(GLES.mMatrix,0,sw,sh,1.0f); //行列をシェーダに指定 GLES.updateMatrix(); //四角形の描画 GLES20.glVertexAttribPointer(GLES.positionHandle,3, GLES20.GL_FLOAT,false,0,vertexBuffer); GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP,0,4); } //テクスチャの生成 private int makeTexture(Bitmap bmp) { //テクスチャメモリの確保 int[] textureIds=new int[1]; GLES20.glGenTextures(1,textureIds,0); //テクスチャへのビットマップ指定 GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,textureIds[0]); GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0,bmp,0); //テクスチャフィルタの指定 GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,GLES20.GL_NEAREST); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER,GLES20.GL_NEAREST); return textureIds[0]; }
//UVバッファの生成と設定 private FloatBuffer makeUVBuffer() { float[] uvs={ 0.0f,0.0f,//左上 0.0f,1.0f,//左下 1.0f,0.0f,//右上 1.0f,1.0f,//右下 }; return makeFloatBuffer(uvs); } //頂点バッファの生成と設定 private FloatBuffer makeVertexBuffer() { float[] vertexs={ -1.0f, 1.0f,0.0f,//頂点0 -1.0f,-1.0f,0.0f,//頂点1 1.0f, 1.0f,0.0f,//頂点2 1.0f,-1.0f,0.0f,//頂点3 }; return makeFloatBuffer(vertexs); } //float配列をFloatBufferに変換 private FloatBuffer makeFloatBuffer(float[] array){ FloatBuffer fb=ByteBuffer.allocateDirect(array.length*4).order( ByteOrder.nativeOrder()).asFloatBuffer(); fb.put(array).position(0); return fb; } }
|