▼Androidメモ▼
カメラの設定


OpenGL ES 2.0でカメラの設定を行うプログラムを作成する。
HelloGL20_12.png

ソースコード
GL20GeometryEx1.java
package net.npaka.gl20geometryex1;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;

//カメラの設定
public class GL20GeometryEx1 extends Activity {
private GLSurfaceView glView;

//アクティビティ生成時に呼ばれる
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);

//GLサーフェイスビュー
glView=new GLSurfaceView(this);
glView.setEGLContextClientVersion(2);
glView.setRenderer(new GLRenderer());
setContentView(glView);
}

//アクティビティレジューム時に呼ばれる
@Override
public void onResume() {
super.onResume();
glView.onResume();
}

//アクティビティポーズ時に呼ばれる
@Override
public void onPause() {
super.onPause();
glView.onPause();
}
}

GLRenderer.java
package net.npaka.gl20geometryex1;
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.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;

//レンダラー
public class GLRenderer implements
GLSurfaceView.Renderer {
//システム
private float aspect;//アスペクト比

//バッファ
private FloatBuffer vertexBuffer;//頂点バッファ

//サーフェイス生成時に呼ばれる
@Override
public void onSurfaceCreated(GL10 gl10,EGLConfig eglConfig) {
//プログラムの生成
GLES.makeProgram();

//頂点配列の有効化
GLES20.glEnableVertexAttribArray(GLES.positionHandle);

//頂点バッファの生成
float[] vertexs={
0.0f,1.0f,0.0f,//頂点0
0.0f,0.0f,0.0f,//頂点1
1.0f,1.0f,0.0f,//頂点2
};
vertexBuffer=makeFloatBuffer(vertexs);
}

//画面サイズ変更時に呼ばれる
@Override
public void onSurfaceChanged(GL10 gl10,int w,int h) {
//ビューポート変換
GLES20.glViewport(0,0,w,h);
aspect=(float)w/(float)h;
}

//毎フレーム描画時に呼ばれる
@Override
public void onDrawFrame(GL10 gl10) {
//画面のクリア
GLES20.glClearColor(1.0f,1.0f,1.0f,1.0f);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

//射影変換
Matrix.setIdentityM(GLES.pMatrix,0);
GLES.gluPerspective(GLES.pMatrix,
45.0f, //Y方向の画角
aspect, //アスペクト比
1.0f, //ニアクリップ
100.0f);//ファークリップ

//ビュー変換
Matrix.setIdentityM(GLES.mMatrix,0);
GLES.gluLookAt(GLES.mMatrix,
0.0f,0.0f,10.0f,//カメラの視点
0.0f,0.0f,0.0f, //カメラの焦点
0.0f,1.0f,0.0f);//カメラの上方向

//モデル変換
Matrix.translateM(GLES.mMatrix,0,-0.5f,-0.5f,0.0f);

//行列をシェーダに指定
GLES20.glUniformMatrix4fv(GLES.pMatrixHandle,1,false,GLES.pMatrix,0);
GLES20.glUniformMatrix4fv(GLES.mMatrixHandle,1,false,GLES.mMatrix,0);

//三角形の描画
GLES20.glUniform4f(GLES.colorHandle,1.0f,0.0f,0.0f,1.0f);
GLES20.glVertexAttribPointer(GLES.positionHandle,3,
GLES20.GL_FLOAT,false,0,vertexBuffer);
GLES20.glDrawArrays(GLES20.GL_TRIANGLES,0,3);
}

//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;
}
}

GLES.java
package net.npaka.gl20geometryex1;
import android.opengl.GLES20;
import android.opengl.Matrix;

//シェーダ操作
public class GLES {
//頂点シェーダのコード
private final static String VERTEX_CODE=
"uniform mat4 u_MMatrix;"+
"uniform mat4 u_PMatrix;"+
"attribute vec4 a_Position;"+
"void main(){"+
"gl_Position=u_PMatrix*u_MMatrix*a_Position;"+
"}";

//フラグメントシェーダのコード
private final static String FRAGMENT_CODE=
"precision mediump float;"+
"uniform vec4 u_Color;"+
"void main(){"+
"gl_FragColor=u_Color;"+
"}";

//システム
private static int program;//プログラムオブジェクト

//ハンドル
public static int mMatrixHandle; //モデルビュー行列ハンドル
public static int pMatrixHandle; //射影行列ハンドル
public static int positionHandle;//位置ハンドル
public static int colorHandle; //色ハンドル

//行列
public static float[] mMatrix=new float[16];//モデルビュー行列
public static float[] pMatrix=new float[16];//射影行列

//プログラムの生成
public static void makeProgram() {
//シェーダーオブジェクトの生成
int vertexShader=loadShader(GLES20.GL_VERTEX_SHADER,VERTEX_CODE);
int fragmentShader=loadShader(GLES20.GL_FRAGMENT_SHADER,FRAGMENT_CODE);

//プログラムオブジェクトの生成
program=GLES20.glCreateProgram();
GLES20.glAttachShader(program,vertexShader);
GLES20.glAttachShader(program,fragmentShader);
GLES20.glLinkProgram(program);

//ハンドルの取得
mMatrixHandle=GLES20.glGetUniformLocation(program,"u_MMatrix");
pMatrixHandle=GLES20.glGetUniformLocation(program,"u_PMatrix");
positionHandle=GLES20.glGetAttribLocation(program,"a_Position");
colorHandle=GLES20.glGetUniformLocation(program,"u_Color");

//プログラムオブジェクトの利用開始
GLES20.glUseProgram(program);
}

//シェーダーオブジェクトの生成
private static int loadShader(int type,String shaderCode) {
int shader=GLES20.glCreateShader(type);
GLES20.glShaderSource(shader,shaderCode);
GLES20.glCompileShader(shader);
return shader;
}

//透視変換の指定
public static void gluPerspective(float[] m,
float angle,float aspect,float near,float far) {
float top=near*(float)Math.tan(angle*(Math.PI/360.0));
float bottom=-top;
float left=bottom*aspect;
float right=top*aspect;
float[] frustumM=new float[16];
float[] resultM=new float[16];
Matrix.frustumM(frustumM,0,left,right,bottom,top,near,far);
Matrix.multiplyMM(resultM,0,m,0,frustumM,0);
System.arraycopy(resultM,0,m,0,16);
}

//ビュー変換の指定
public static void gluLookAt(float[] m,float eyeX,float eyeY,float eyeZ,
float focusX,float focusY,float focusZ,
float upX,float upY,float upZ) {
float[] lookAtM=new float[16];
float[] resultM=new float[16];
Matrix.setLookAtM(lookAtM,0,
eyeX,eyeY,eyeZ,focusX,focusY,focusZ,upX,upY,upZ);
Matrix.multiplyMM(resultM,0,m,0,lookAtM,0);
System.arraycopy(resultM,0,m,0,16);
}
}

−戻る−