package net.npaka.gl10textureex5; 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.GLSurfaceView; import android.opengl.GLUtils;
//レンダラー 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) { //頂点バッファの有効化 gl10.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl10.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); //テクスチャの有効化 gl10.glEnable(GL10.GL_TEXTURE_2D); //テクスチャの生成 Bitmap bmp=BitmapFactory.decodeResource( activity.getResources(),R.drawable.sample); textureId=makeTexture(gl10,bmp); //ブレンドの指定 gl10.glEnable(GL10.GL_BLEND); gl10.glBlendFunc(GL10.GL_SRC_ALPHA,GL10.GL_ONE_MINUS_SRC_ALPHA); //頂点バッファの生成 vertexBuffer=makeVertexBuffer(); //UVバッファの生成 uvBuffer=makeUVBuffer(); } //画面サイズ変更時に呼ばれる @Override public void onSurfaceChanged(GL10 gl10,int w,int h) { //画面の表示領域の指定 gl10.glViewport(0,0,w,h); screenW=w; screenH=h; } //毎フレーム描画時に呼ばれる @Override public void onDrawFrame(GL10 gl10) { //画面のクリア gl10.glClearColor(1.0f,1.0f,1.0f,1.0f); gl10.glClear(GL10.GL_COLOR_BUFFER_BIT); //テクスチャの指定 gl10.glActiveTexture(GL10.GL_TEXTURE0); gl10.glBindTexture(GL10.GL_TEXTURE_2D,textureId);
//UVバッファの指定 gl10.glTexCoordPointer(2,GL10.GL_FLOAT,0,uvBuffer); //上の四角形の描画 setTextureArea(gl10,256,256,0,0,128,128); drawRect(gl10,50,50,200,200); //下の四角形の描画 setTextureArea(gl10,256,256,0,128,128,128); drawRect(gl10,50,300,300,300); } //テクスチャ領域の指定 private void setTextureArea(GL10 gl10, int textureW,int textureH,int x,int y,int w,int h) { //ウィンドウ座標を正規化デバイス座標に変換 float tw=(float)w/(float)textureW; float th=(float)h/(float)textureH; float tx=(float)x/(float)textureW; float ty=(float)y/(float)textureH; //テクスチャ行列の移動・拡大縮小 gl10.glMatrixMode(GL10.GL_TEXTURE); gl10.glLoadIdentity(); gl10.glTranslatef(tx,ty,0.0f); gl10.glScalef(tw,th,1.0f); } //四角形の描画 private void drawRect(GL10 gl10,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); //モデルビュー行列の移動・拡縮 gl10.glMatrixMode(GL10.GL_MODELVIEW); gl10.glLoadIdentity(); gl10.glTranslatef(sx+sw,-(sy+sh),0.0f); gl10.glScalef(sw,sh,1.0f); //四角形の描画 gl10.glVertexPointer(3,GL10.GL_FLOAT,0,vertexBuffer); gl10.glDrawArrays(GL10.GL_TRIANGLE_STRIP,0,4); } //テクスチャの生成 private int makeTexture(GL10 gl10,Bitmap bmp) { //テクスチャメモリの確保 int[] textureIds=new int[1]; gl10.glGenTextures(1,textureIds,0); //テクスチャへのビットマップ指定 gl10.glActiveTexture(GL10.GL_TEXTURE0); gl10.glBindTexture(GL10.GL_TEXTURE_2D,textureIds[0]); GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0,bmp,0); //テクスチャフィルタの指定 gl10.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST); gl10.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,GL10.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; } }
|