我最近学习了适用于 Windows 的 OpenGL,现在我想在 Android 上尝试一下。我检查了一些教程,现在我已经开始破解这个示例:http: //blog.shayanjaved.com/2011/03/13/shaders-android/
在这个应用程序中,您可以在网格之间进行选择,但我想同时绘制其中两个。我做了一个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);
}
两个对象都会被绘制,但问题是,两个不同的对象存在于两个不同的世界中。如果我首先绘制道路,然后在调用 drawCar 函数之后,无论我是否在 Y 轴上将其平移 -100.0,汽车(实际上它是一个立方体)都将始终可见。
对象从网格文件中读取并正确解析为顶点缓冲区和索引缓冲区,并且它们自己完美地显示出来。
如何将两个(或更多)对象放在同一个空间中?