最近、Windows 用の OpenGL を学びましたが、Android でも試してみたいと思っています。いくつかのチュートリアルを確認したところ、このサンプルのハッキングを開始しました: http://blog.shayanjaved.com/2011/03/13/shaders-android/
このアプリではメッシュを選択できますが、同時に 2 つのメッシュを描画したいと考えています。drawRoad 関数と drawCar 関数を作りました。
private void drawCar(int program){
/*** DRAWING OBJECT **/
// Get buffers from mesh
Object3D ob = this._objects[this.CUBE];
Mesh mesh = ob.getMesh();
FloatBuffer _vb = mesh.get_vb();
ShortBuffer _ib = mesh.get_ib();
short[] _indices = mesh.get_indices();
// Vertex buffer
// the vertex coordinates
_vb.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
GLES20.glVertexAttribPointer(GLES20.glGetAttribLocation(program, "aPosition"), 3, GLES20.GL_FLOAT, false,
TRIANGLE_VERTICES_DATA_STRIDE_BYTES, _vb);
GLES20.glEnableVertexAttribArray(GLES20.glGetAttribLocation(program, "aPosition"));
// the normal info
_vb.position(TRIANGLE_VERTICES_DATA_NOR_OFFSET);
GLES20.glVertexAttribPointer(GLES20.glGetAttribLocation(program, "aNormal"), 3, GLES20.GL_FLOAT, false,
TRIANGLE_VERTICES_DATA_STRIDE_BYTES, _vb);
GLES20.glEnableVertexAttribArray(GLES20.glGetAttribLocation(program, "aNormal"));
// Texture info
// bind textures
if (ob.hasTexture()) {// && enableTexture) {
// number of textures
int[] texIDs = ob.get_texID();
for(int i = 0; i < _texIDs.length; i++) {
GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + i);
Log.d("TEXTURE BIND: ", i + " " + texIDs[i]);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texIDs[i]);
GLES20.glUniform1i(GLES20.glGetUniformLocation(program, "texture" + (i+1)), i);
}
}
// enable texturing? [fix - sending float is waste]
GLES20.glUniform1f(GLES20.glGetUniformLocation(program, "hasTexture")/*shader.hasTextureHandle*/, ob.hasTexture() && enableTexture ? 2.0f : 0.0f);
// texture coordinates
_vb.position(TRIANGLE_VERTICES_DATA_TEX_OFFSET);
GLES20.glVertexAttribPointer(GLES20.glGetAttribLocation(program, "textureCoord")/*shader.maTextureHandle*/, 2, GLES20.GL_FLOAT, false,
TRIANGLE_VERTICES_DATA_STRIDE_BYTES, _vb);
GLES20.glEnableVertexAttribArray(GLES20.glGetAttribLocation(program, "textureCoord"));//GLES20.glEnableVertexAttribArray(shader.maTextureHandle);
// Draw with indices
GLES20.glDrawElements(GLES20.GL_TRIANGLES, _indices.length, GLES20.GL_UNSIGNED_SHORT, _ib);
checkGlError("glDrawElements");
/** END DRAWING OBJECT ***/
}
private void drawRoad(int program){
/*** DRAWING OBJECT **/
// Get buffers from mesh
Object3D ob = this._objects[this.ROAD];
Mesh mesh = ob.getMesh();
FloatBuffer _vb = mesh.get_vb();
ShortBuffer _ib = mesh.get_ib();
short[] _indices = mesh.get_indices();
// Vertex buffer
// the vertex coordinates
_vb.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
GLES20.glVertexAttribPointer(GLES20.glGetAttribLocation(program, "aPosition"), 3, GLES20.GL_FLOAT, false,
TRIANGLE_VERTICES_DATA_STRIDE_BYTES, _vb);
GLES20.glEnableVertexAttribArray(GLES20.glGetAttribLocation(program, "aPosition"));
// the normal info
_vb.position(TRIANGLE_VERTICES_DATA_NOR_OFFSET);
GLES20.glVertexAttribPointer(GLES20.glGetAttribLocation(program, "aNormal"), 3, GLES20.GL_FLOAT, false,
TRIANGLE_VERTICES_DATA_STRIDE_BYTES, _vb);
GLES20.glEnableVertexAttribArray(GLES20.glGetAttribLocation(program, "aNormal"));
// Texture info
// bind textures
if (ob.hasTexture()) {// && enableTexture) {
// number of textures
int[] texIDs = ob.get_texID();
for(int i = 0; i < _texIDs.length; i++) {
GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + i);
//Log.d("TEXTURE BIND: ", i + " " + texIDs[i]);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texIDs[i]);
GLES20.glUniform1i(GLES20.glGetUniformLocation(program, "texture" + (i+1)), i);
}
}
// enable texturing? [fix - sending float is waste]
GLES20.glUniform1f(GLES20.glGetUniformLocation(program, "hasTexture")/*shader.hasTextureHandle*/, ob.hasTexture() && enableTexture ? 2.0f : 0.0f);
// texture coordinates
_vb.position(TRIANGLE_VERTICES_DATA_TEX_OFFSET);
GLES20.glVertexAttribPointer(GLES20.glGetAttribLocation(program, "textureCoord")/*shader.maTextureHandle*/, 2, GLES20.GL_FLOAT, false,
TRIANGLE_VERTICES_DATA_STRIDE_BYTES, _vb);
GLES20.glEnableVertexAttribArray(GLES20.glGetAttribLocation(program, "textureCoord"));//GLES20.glEnableVertexAttribArray(shader.maTextureHandle);
// Draw with indices
GLES20.glDrawElements(GLES20.GL_TRIANGLES, _indices.length, GLES20.GL_UNSIGNED_SHORT, _ib);
checkGlError("glDrawElements");
/** END DRAWING OBJECT ***/
その後、いくつかの基本的な変換を行い、行列を onDrawFrame 関数でシェーダーに送信します。
public void onDrawFrame(GL10 glUnused) {
// Ignore the passed-in GL10 interface, and use the GLES20
// class's static methods instead.
GLES20.glClearColor(.0f, .0f, .0f, 1.0f);
GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glUseProgram(0);
// the current shader
Shader shader = _shaders[this._currentShader]; // PROBLEM!
int program = shader.get_program();
// Start using the shader
GLES20.glUseProgram(program);
checkGlError("glUseProgram");
// eye position
GLES20.glUniform3fv(GLES20.glGetUniformLocation(program, "eyePos")/*shader.eyeHandle*/, 1, eyePos, 0);
setLight(program);
Matrix.setIdentityM(mMMatrix, 0);
Matrix.setIdentityM(mTransMatrix, 0);
Matrix.translateM(mTransMatrix, 0, 2.0f, 5.0f, 5.0f);
Matrix.multiplyMM(mMMatrix, 0, mMMatrix, 0, mTransMatrix, 0); //Translate
Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0); //View
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0); //Proj
// send to the shader
GLES20.glUniformMatrix4fv(GLES20.glGetUniformLocation(program, "uMVPMatrix"), 1, false, mMVPMatrix, 0);
// Create the normal modelview matrix
// Invert + transpose of mvpmatrix
Matrix.invertM(normalMatrix, 0, mMVPMatrix, 0);
Matrix.transposeM(normalMatrix, 0, normalMatrix, 0);
// send to the shader
GLES20.glUniformMatrix4fv(GLES20.glGetUniformLocation(program, "normalMatrix"), 1, false, mMVPMatrix, 0);
drawCar(program);
//**********************************************************************************************************
Matrix.setIdentityM(mMMatrix, 0);
Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0); //View
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0); //Proj
// send to the shader
GLES20.glUniformMatrix4fv(GLES20.glGetUniformLocation(program, "uMVPMatrix"), 1, false, mMVPMatrix, 0);
// Create the normal modelview matrix
// Invert + transpose of mvpmatrix
Matrix.invertM(normalMatrix, 0, mMVPMatrix, 0);
Matrix.transposeM(normalMatrix, 0, normalMatrix, 0);
// send to the shader
GLES20.glUniformMatrix4fv(GLES20.glGetUniformLocation(program, "normalMatrix"), 1, false, mMVPMatrix, 0);
drawRoad(program);
}
両方のオブジェクトが描画されますが、問題は、2 つの異なるオブジェクトが 2 つの異なる世界に存在することです。最初に道路を描画し、drawCar 関数を呼び出した後、Y 軸上で -100.0 に変換しても、車 (実際には立方体です) は常に表示されます。
オブジェクトはメッシュ ファイルから読み取られ、頂点バッファーとインデックス バッファーに正しく解析され、単独で完全に表示されます。
2 つ (またはそれ以上) のオブジェクトを同じスペースに配置するにはどうすればよいですか?