无法在Android OpenGL中启用深度测试

时间:2017-09-06 15:13:23

标签: android opengl-es

我是OpenGL的新手,在Android上工作。在Web中找到了很好的代码示例,可以记录所有内容。但是我发现了一个大问题:深度测试不起作用,所以在我的模型中,即使它们在另一个面后面,所有与相机相对的面都会被点亮: wrong depth test 我认为在这部分代码中可能会出现一些错误:

/**
 * Prepares the off-screen framebuffer.
 */
private void prepareFramebuffer(int width, int height) {
    GlUtil.checkGlError("prepareFramebuffer start");

    int[] values = new int[1];

    // Create a texture object and bind it.  This will be the color buffer.
    GLES20.glGenTextures(1, values, 0);
    GlUtil.checkGlError("glGenTextures");
    mOffscreenTexture = values[0];   // expected > 0
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mOffscreenTexture);
    GlUtil.checkGlError("glBindTexture " + mOffscreenTexture);

    // Create texture storage.
    GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, width, height, 0,
            GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);

    // Set parameters.  We're probably using non-power-of-two dimensions, so
    // some values may not be available for use.
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,
            GLES20.GL_NEAREST);
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER,
            GLES20.GL_LINEAR);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,
            GLES20.GL_CLAMP_TO_EDGE);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,
            GLES20.GL_CLAMP_TO_EDGE);
    GlUtil.checkGlError("glTexParameter");

    // Create framebuffer object and bind it.
    GLES20.glGenFramebuffers(1, values, 0);
    GlUtil.checkGlError("glGenFramebuffers");
    mFramebuffer = values[0];    // expected > 0
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mFramebuffer);
    GlUtil.checkGlError("glBindFramebuffer " + mFramebuffer);

    // Create a depth buffer and bind it.
    GLES20.glGenRenderbuffers(1, values, 0);
    GlUtil.checkGlError("glGenRenderbuffers");
    mDepthBuffer = values[0];    // expected > 0
    GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, mDepthBuffer);
    GlUtil.checkGlError("glBindRenderbuffer " + mDepthBuffer);

    // Allocate storage for the depth buffer.
    GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, GLES20.GL_DEPTH_COMPONENT16,
            width, height);
    GlUtil.checkGlError("glRenderbufferStorage");

    // Attach the depth buffer and the texture (color buffer) to the framebuffer object.
    GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT,
            GLES20.GL_RENDERBUFFER, mDepthBuffer);
    GlUtil.checkGlError("glFramebufferRenderbuffer");
    GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0,
            GLES20.GL_TEXTURE_2D, mOffscreenTexture, 0);
    GlUtil.checkGlError("glFramebufferTexture2D");

    // See if GLES is happy with all this.
    int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER);
    if (status != GLES20.GL_FRAMEBUFFER_COMPLETE) {
        //       throw new RuntimeException("Framebuffer not complete, status=" + status);
    }

    // Switch back to the default framebuffer.
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);

    GlUtil.checkGlError("prepareFramebuffer done");
}

我已经做过的另一件重要事情:

/**
 * Prepares window surface and GL state.
 */
private void prepareGl(Surface surface) {
    Log.d(TAG, "prepareGl");

    EglCore.logCurrent("before creating");

    GlUtil.checkGlError("debug");
    if (mWindowSurface == null)
        mWindowSurface = new WindowSurface(mEglCore, surface, false);

    mWindowSurface.makeCurrent();

    EglCore.logCurrent("after creation");

    glClearColor(0f, 0f, 0f, 1f); //glClearColor(0.15f, 0.15f, 0.15f, 1f);

    GlUtil.checkGlError("debug");
    glEnable(GL_DEPTH_TEST);

    GlUtil.checkGlError("debug");
    glEnable(GL_CULL_FACE);

    GlUtil.checkGlError("debug");
    glCullFace(GL_BACK);

    GlUtil.checkGlError("debug");
    glShadeModel(GL_SMOOTH);

    GlUtil.checkGlError("debug");
    glEnable(GL_BLEND);

    GlUtil.checkGlError("debug");
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

我做错了什么?哪里可能是错误?

添加onDraw代码:

private void draw() {
    GlUtil.checkGlError("draw start");
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glDepthFunc(GL_LESS);
    if (leftEye != null) {
        resetMatrices();
        setModelViewMatrix();
        translateMEyes();

        eyeTextureProgram.useProgram();
        eyeTextureProgram.setViewAndTexture(modelViewProjectionMatrix, textureEye);

        setProgramParams(eyeTextureProgram, textureEye);
        leftEye.bindData(eyeTextureProgram);
        leftEye.draw();
    }

    if (rightEye != null) {
        rightEye.bindData(eyeTextureProgram);
        rightEye.draw();
    }

    glDepthFunc(GL_LEQUAL);

    resetMatrices();
    setModelViewMatrix();

    setProgramParams(faceTextureProgram, textureFace);
    headBase.bindData(faceTextureProgram);
    headBase.draw();

    GlUtil.checkGlError("draw done");
}

1 个答案:

答案 0 :(得分:1)

将深度缓冲区的清除值设置为1.0。深度缓冲区的清除值应该是深度范围的最大值,默认值为0.0 - 1.0。

glClearDepth(1.0)

另外,请确保在绘图前清除深度和颜色缓冲区。

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)