2011年5月18日水曜日

OpenGLES入門 その3 テクスチャの表示

今回はテクスチャを表示させます。
今回は表示させる画像にこのimage.pngを使用します。


そしてOpenGL入門その2で使用したソースコードを流用します。

MyApplication.javaはそのままで、Renderer.javaとScene.javaの中身を少し変更します。

■Renderer.java■
package test.sample;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.view.Display;

public class GLRenderer implements GLSurfaceView.Renderer {

 private Scene mScene;
 private boolean mOnce = true;
 private Activity mActivity;
 public GLRenderer(Activity activity, Display display) {
  mScene = new Scene(display);
  mActivity = activity;
 }

 @Override
 public void onDrawFrame(GL10 gl) {//毎フレーム呼ばれるメインループ

  if (mOnce) {
   mScene.setTexture(gl, mActivity.getResources().openRawResource(R.drawable.image));
   mOnce = false;
  }
  mScene.draw(gl);
 }

 @Override
 public void onSurfaceChanged(GL10 arg0, int arg1, int arg2) {
 }

 @Override
 public void onSurfaceCreated(GL10 gl, EGLConfig config) {
 }
}

■Scene.java■
package test.sample;

import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.opengles.GL10;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLU;
import android.opengl.GLUtils;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;

public class Scene implements View.OnTouchListener{

 private FloatBuffer vertexBuffer;
 private FloatBuffer textureBuffer;


 private int mTextureNumber;
 private int mWidth;
 private int mHeight;

 public Scene(Display display) {
  mWidth = display.getWidth();
  mHeight = display.getHeight();

  float x = 0.0f;
  float y = 0.0f;
  float z = 0.0f;
  float sizeX = 10.0f;
  float sizeY = 10.0f;
  float sizeZ = 0.0f;
  float[] vertex = {
    //左側の三角形
    x + sizeX, y + sizeY, z + sizeZ,//右下
    x - sizeX, y - sizeY, z + sizeZ,//左上
    x - sizeX, y + sizeY, z + sizeZ,//左下
    //右側の三角形
    x + sizeX, y + sizeY, z + sizeZ,//右下
    x + sizeX, y - sizeY, z + sizeZ,//右上
    x - sizeX, y - sizeY, z + sizeZ,//左上
  };
  ByteBuffer vb = ByteBuffer.allocateDirect(6 * 3 * 4);
  vb.order(ByteOrder.nativeOrder()); //ビッグエンディアンかリトルエンディアンにあわせてくれる
  vertexBuffer = vb.asFloatBuffer();
  vertexBuffer.put(vertex);
  vertexBuffer.position(0);

  float[] texture = {
    1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, //左側の三角形に貼る
    1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f //右側の三角形に貼る
  };
  ByteBuffer tb = ByteBuffer.allocateDirect(2 * 3 * 2 * 4);
  tb.order(ByteOrder.nativeOrder()); //ビッグエンディアンかリトルエンディアンにあわせてくれる
  textureBuffer = tb.asFloatBuffer();
  textureBuffer.put(texture);
  textureBuffer.position(0);

 }


    public void setTexture(GL10 gl, InputStream is)
    {
     Bitmap bitmap;
     try {
      bitmap = BitmapFactory.decodeStream(is);
     } finally {
      try {
       is.close();
      } catch(IOException e) {}
     }
     int[] textureNumber = new int[1];
     gl.glGenTextures(1, textureNumber, 0);
     mTextureNumber = textureNumber[0];
     gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureNumber);
     GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

     gl.glTexParameterx( GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT );
     gl.glTexParameterx( GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT );
     gl.glTexParameterx( GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR );
     gl.glTexParameterx( GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR );

    }

 public void draw(GL10 gl) {
  gl.glClearColor(1.0f, 0.0f, 0.0f, 1.0f);

     gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

  //ビューポート行列(ウィンドウへの出力領域)設定
  gl.glViewport(0,0,mWidth,mHeight);

  //射影行列設定
  gl.glMatrixMode(GL10.GL_PROJECTION);
  gl.glLoadIdentity();
  //視界(視野角、画面のアスペクト、比近視点、遠視点)の設定
  float aspect = (float)mWidth / (float)mHeight;
  GLU.gluPerspective(gl, 45.0f, aspect, 0.1f, 3000.0f);

     GLU.gluLookAt(
              gl,
        0.0f, 0.0f, 100.0f,  //位置(視点)
       0.0f, 0.0f, 0.0f,  //見つめているところ
       0.0f, 1.0f, 0.0f //水平
     );
     gl.glMatrixMode(GL10.GL_MODELVIEW);
     gl.glLoadIdentity();

  gl.glEnable(GL10.GL_TEXTURE_2D);
  gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
  gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

  gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
  gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);

  int triangleNum = 2;
  gl.glDrawArrays(GL10.GL_TRIANGLES, 0, triangleNum * 3);
 }

 @Override
 public boolean onTouch(View arg0, MotionEvent arg1) {
  // TODO 自動生成されたメソッド・スタブ
  return false;
 }

}


画像をdrawable-hdpiに登録してから実行すると下のように表示されます。