纹理不适用于网格 - OpenGL

时间:2013-07-11 11:59:09

标签: android opengl-es opengl-es-2.0

我正在使用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); 
}

1 个答案:

答案 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上下文的任何其他第三方组件。)