1

我想通过解析一个obj文件来渲染一个对象(android平台,opengl es 1.1)。解析没问题,我将所有数据(v、vn、vt)和索引正确存储在单独的数组中。当我尝试使用 glDrawElements 进行渲染时,对象绘制得很好,但纹理是混合的。我猜这是因为纹理坐标的索引与顶点不同,opengl 只使用顶点索引。我试图使 VBO 不能使用索引。但是这次当我调用 gldrawArrays 时,什么都没有绘制。(黑页)。请告诉我问题的原因是什么以及渲染此类对象的其他方法是什么。

这是我的代码的一些部分。如果您需要其他零件,请告诉我。这是 ObjectArr 类,它保存矩阵并创建 VBO 并绘制对象。

public ObjectArr(float[] positions, float[] textureCoords, float[] normal, short[] faceIndices, short[] texturePointer, short[] normalPointer){
    texture = textureCoords;
    vertexPointer = faceIndices;
    normals = normal;
    vertex = positions;
    ByteBuffer ilbuffer = ByteBuffer.allocate(vertexPointer.length * 8 * 4); // creating interleave
    ilbuffer.order(ByteOrder.nativeOrder());
    interleave = ilbuffer.asFloatBuffer();
    for (int i = 0; i < vertexPointer.length; i++) { 
        for (int j = 0;j < 3; j++) // positions
            interleave.put(vertex[3 * vertexPointer[i] + j]); // three number for position
        for (int j = 0;j < 3; j++) // normals
            interleave.put(normals[3 * normalPointer[i] + j]); // three number for normal
        for (int j = 0; j < 3; j++) 
            interleave.put(texture[3 * texturePointer[i] + j]); // three number for texture
    }
    interleave.position(0);
draw (GL10 gl){    
    GL11 gl11 = (GL11) gl;
    int stride = 9 * 4;
    gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, VBO[0]);
    gl11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
    gl11.glVertexPointer(3, GL11.GL_FLOAT, stride, 0);
    gl11.glEnableClientState(GL11.GL_NORMAL_ARRAY);
    gl11.glNormalPointer(GL11.GL_FLOAT, stride, 3 * 4); // 4 is float size
    gl11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
    gl11.glTexCoordPointer(3,GL11.GL_FLOAT,stride,(3 + 3) * 4);
    gl11.glEnable(GL11.GL_TEXTURE_2D);
    gl11.glBindTexture(GL11.GL_TEXTURE_2D, texturesMatrix[0]);
    gl11.glDrawArrays(GL11.GL_TRIANGLE_STRIP, 0, vertexPointer.length);
    // deactivate arrays with gldisableclient...
    gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, 0);
}
public void createVBO(GL10 gl){ // creates VBO from interleave created before
    GL11 gl11 = (GL11) gl;
    VBO = new int[1];
    gl11.glGenBuffers(1, VBO, 0);
    gl11.glBindBuffer(GLES11.GL_ARRAY_BUFFER, VBO[0]);
    gl11.glBufferData(GLES11.GL_ARRAY_BUFFER, 9 * 4 * vertexPointer.length, interleave, GLES11.GL_STATIC_DRAW); // 9 is stride
}

public void loadGLTexture(GL10 gl, Context context) { // plane is a simple obj and also png file
    GL11 gl11 = (GL11) gl;
    // reading bitmap from raw folder
    gl11.glGenTextures(1, texturesMatrix, 0); // matrix with integer values for binding
    gl11.glBindTexture(GL11.GL_TEXTURE_2D, texturesMatrix[0]);
    GLUtils.texImage2D(GL11.GL_TEXTURE_2D, 0, bitmap, 0);
    bitmap.recycle();
}

这是我的渲染器中的 unSurfaceCreated 和 onDrawFrame 方法。

public void onSurfaceCreated(GL10 gl, EGLConfig config) { 
    GL11 gl11 = (GL11) gl;
    obj.createVBO(gl);
    obj.loadGLTexture(gl, this.context);
    gl11.glEnable(GL10.GL_TEXTURE_2D);
    gl11.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);  // Set color's clear-value to black
    gl11.glClearDepthf(1.0f);            // Set depth's clear-value to farthest
    gl11.glEnable(GL10.GL_DEPTH_TEST);   // Enables depth-buffer for hidden surface removal
    gl11.glDepthFunc(GL10.GL_LEQUAL);    // The type of depth testing to do
    gl11.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);  // nice perspective view
    gl11.glShadeModel(GL10.GL_SMOOTH);   // Enable smooth shading of color
    gl11.glDisable(GL10.GL_DITHER);      // Disable dithering for better performance
}
public void onDrawFrame(GL10 gl){
    GL11 gl11 = (GL11) gl;
    // Clear color and depth buffers
    gl11.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
    gl11.glLoadIdentity();
    gl11.glTranslatef(-8.0f, 0.0f, -16.0f);
    //--- Touch
    gl11.glTranslatef(X, 0.0f, 0.0f);
    gl11.glTranslatef(0.0f, Y, 0.0f);
    //--- Touch
    gl11.glScalef(0.03f * zoomScale, 0.03f * zoomScale, 0.03f * zoomScale);  (NEW)
    obj.draw(gl);
}

我完全困惑和卡住了。我很感激任何帮助。tnx。

4

0 回答 0