我正在使用OpenGL Es。我已经成功加载了obj文件(网格)并且显示效果很好但是当我应用纹理时它没有显示。
我已添加以下代码。
public void draw(GL10 gl) {
// bind the previously generated texture
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// Set the face rotation
gl.glFrontFace(GL10.GL_CW);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
for(int i=0; i<parts.size(); i++){
TDModelPart t=parts.get(i);
gl.glNormalPointer(GL10.GL_FLOAT, 0, t.getNormalBuffer());
gl.glDrawElements(GL10.GL_TRIANGLES,t.getFacesCount(),GL10.GL_UNSIGNED_SHORT,t.getFaceBuffer());
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
}
public void buildVertexBuffer(){
ByteBuffer vBuf = ByteBuffer.allocateDirect(v.size() * 4);
vBuf.order(ByteOrder.nativeOrder());
vertexBuffer = vBuf.asFloatBuffer();
vertexBuffer.put(toPrimitiveArrayF(v));
vertexBuffer.position(0);
vBuf = ByteBuffer.allocateDirect(texture.length * 4);
vBuf.order(ByteOrder.nativeOrder());
textureBuffer = vBuf.asFloatBuffer();
textureBuffer.put(texture);
textureBuffer.position(0);
}
private static float[] toPrimitiveArrayF(Vector<Float> vector){
float[] f;
f=new float[vector.size()];
for (int i=0; i<vector.size(); i++){
f[i]=vector.get(i);
}
return f;
}
/**
* Load the texture for the square
* @param gl
* @param context
*/
public void loadGLTexture(GL10 gl, Context context) {
// loading texture
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),
R.drawable.nehe);
// generate one texture pointer
gl.glGenTextures(1, textures, 0);
// ...and bind it to our array
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
// create nearest filtered texture
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
//Different possible texture parameters, e.g. GL10.GL_CLAMP_TO_EDGE
//gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
//gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);
// Use Android GLUtils to specify a two-dimensional texture image from our bitmap
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
// Clean up
bitmap.recycle();
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, lightAmbientBuffer);
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, lightDiffuseBuffer);
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPositionBuffer);
gl.glEnable(GL10.GL_LIGHT0);
model.loadGLTexture(gl, context);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
gl.glClearDepthf(1.0f);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthFunc(GL10.GL_LEQUAL);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
}
答案 0 :(得分:1)
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
for(int i=0; i<parts.size(); i++) {
TDModelPart t=parts.get(i);
gl.glNormalPointer(GL10.GL_FLOAT, 0, t.getNormalBuffer());
gl.glDrawElements(GL10.GL_TRIANGLES,t.getFacesCount(),GL10.GL_UNSIGNED_SHORT,t.getFaceBuffer());
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
当然在绘制任何内容之前禁用texCoord数组并不是一个好主意,因为这会导致你的对象没有任何有效的纹理坐标(严格来说,严格来说它的所有顶点都有当前默认值纹理坐标)。同样,您也不应在循环结束时禁用GL_VERTEX_ARRAY
,因为这会使您的对象不具有以下所有循环迭代的任何有效位置数据。所以你的代码可能应该是这样的:
// bind the previously generated texture
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// Set the face rotation
gl.glFrontFace(GL10.GL_CW);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
for(int i=0; i<parts.size(); i++){
TDModelPart t=parts.get(i);
gl.glNormalPointer(GL10.GL_FLOAT, 0, t.getNormalBuffer());
gl.glDrawElements(GL10.GL_TRIANGLES,t.getFacesCount(),GL10.GL_UNSIGNED_SHORT,t.getFaceBuffer());
}
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
(现在我忽略你设置了glNormalPointer
而没有启用GL_NORMAL_ARRAY
。)
请记住,OpenGL是一个状态机,所有操作,尤其是绘制调用,都会在调用它们的当前状态下运行,除非你更改,否则状态不会改变它你自己(用“你”表示这里的应用程序代码,包括使用相同OpenGL上下文的任何其他第三方组件。)