【问题标题】:OpenGL ES 2.0 Not rendering correctlyOpenGL ES 2.0 无法正确渲染
【发布时间】:2013-01-21 17:47:28
【问题描述】:

这应该渲染一个立方体。看起来背面的某些部分在最靠近相机的部分前面渲染。即使我将它设置得更远,也会发生这种情况。这是来自我的渲染器:

public void onDrawFrame(GL10 unused) {

    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

    // Set the camera position
    Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3f, 0f, 0f, 0f, 0f, 1.0f, 0.0f);

    Matrix.setIdentityM(mModelMatrix, 0);
    Matrix.setRotateM(mModelMatrix, 0, mAngle, 0f, 1f, 0.0f);

    Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mModelMatrix, 0);
    Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix,   0);

    // Draw object
    cube.draw(mMVPMatrix, context);

    mAngle++;
}

还有我的对象的绘制方法

public void draw(float[] mvpMatrix, Context context) {
    GLES20.glUseProgram(mProgram);

    GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
                                 GLES20.GL_FLOAT, false,
                                 vertexStride, vertexBuffer);

    GLES20.glVertexAttribPointer(mTexHandle, 2,
                                 GLES20.GL_FLOAT, false,
                                 8, textureBuffer);

    GLES20.glEnableVertexAttribArray(mPositionHandle);
    GLES20.glEnableVertexAttribArray(mTexHandle);

    GLES20.glActiveTexture ( GLES20.GL_TEXTURE0 );
    GLES20.glBindTexture ( GLES20.GL_TEXTURE_2D, mTextureID);
    GLES20.glUniform1i ( mSampler, 0 );

    mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");

    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);

    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);

    GLES20.glDisableVertexAttribArray(mPositionHandle);
    GLES20.glDisableVertexAttribArray(mTexHandle);
}

还有我的着色器:

    String vertexShaderCode =
         "uniform mat4 uMVPMatrix;" +
         "uniform float u_offset;      \n" +
         "attribute vec4 a_position;   \n" +
         "attribute vec2 a_texCoord;   \n" +
         "varying vec2 v_texCoord;     \n" +
         "void main()                  \n" +
         "{                            \n" +
         "   gl_Position = uMVPMatrix *  a_position; \n" +
         "   gl_Position.x += u_offset;\n" +
         "   v_texCoord = a_texCoord;  \n" +
         "}                            \n";




String fragmentShaderCode = 
      "precision mediump float;                            \n" +
      "varying vec2 v_texCoord;                            \n" +
      "uniform sampler2D s_texture;                        \n" +
      "void main()                                         \n" +
      "{                                                   \n" +
      "  gl_FragColor = texture2D(s_texture, v_texCoord);  \n" +
      "}                                                   \n";

结果

图片: http://i.imgur.com/eWI2Uom.png

谢谢

【问题讨论】:

  • 如果您的对象没有正确绘制三角形,您应该做的第一件事是检查立方体的位置数组,您的顶点顺序不正确
  • @L7ColWinters 我正在使用来自 .OBJ 文件的顶点数据。它适用于 OpenGL ES 1.0,我什至使用相同的数组。不过我会研究一下并尝试手动填充顶点缓冲区。谢谢

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


【解决方案1】:

假设您正在使用深度缓冲区,您似乎没有在 onDrawFrame 函数中清除它。试试:

GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT|GLES20.GL_DEPTH_BUFFER_BIT);

【讨论】:

  • 哇...我完全忘了添加深度缓冲区。非常感谢
  • :|我错过了回答这个问题:|
【解决方案2】:

当我在 iOS 上编程时,我不确定 Android 特定的代码,但我从阅读“OpenGL ES 2.0 编程指南”(Munshi 等人的)中了解到几乎没有什么不同。这是我最近的一个小项目中的代码:

在设置好帧缓冲区和颜色渲染缓冲区之后,就像您已经完成的那样,设置深度缓冲区。

GLuint depthRenderbuffer;

GLint backingWidth, backingHeight;

glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth);
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight);

glGenRenderbuffers(1, &depthRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);

glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, backingWidth, backingHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);

使用glGetRenderbufferParameteriv() 包含有关基于颜色渲染缓冲区设置深度缓冲区尺寸的部分是一个好主意,因为它确保无论如何,它们都会匹配。

附带说明,在 iOS 上,建议直接从底层 iOS 绘图层设置颜色渲染缓冲区存储,但是在设置深度渲染缓冲区时,它需要调用 glRenderbufferStorage(),如上所示.

您还需要在绘图例程中包含以下代码行:

glClearDepthf(1.0);
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

如果你不打电话给glEnable(GL_DEPTH_TEST),它似乎一开始会出现故障,然后工作得很好,至少在我在 iOS 中的实现上是这样。 glClearDepthf(1.0) 将其一直清除到远平面,而不是值 0.0 将其清除到前平面。

看起来您可能有一些特定于 Android 的代码,但希望这能让您有一个正确的开始。干杯!

【讨论】: