当前位置: 首页 > 知识库问答 >
问题:

启用GL_DEPTH_TEST时,帧缓冲区中的渲染不起作用

何海
2023-03-14

我试图在帧缓冲区中渲染所有内容。

所以我做了一个带有深度纹理和颜色纹理的帧缓冲器,如下所示:http://www.opengl.org/wiki/Framebuffer_Object_Examples#Color_texture.2C_Depth_texture

但是,如果启用GL_DEPTH_TEST,则不会呈现任何内容。我做错了什么?

整个代码太长...

帧缓冲器类:

class FrameBuffer {
    GLuint id;
    size_t width, height, nColorAttachMents;
    GLuint colorTexture[GL_MAX_COLOR_ATTACHMENTS_EXT];
    GLuint depthTexture;
private:
    void attachDepthTexture();
    void attachColorTexture(GLuint);
public:
    void create(size_t, size_t, size_t);
    void bindDepthTexture() const;
    void bindColorTexture(GLuint) const;
    void bind() const;
    void unbind() const;
    size_t getWidth() const;
    size_t getHeight() const;
};
void FrameBuffer::attachDepthTexture() {
    glGenTextures(1, &depthTexture);
    glBindTexture(GL_TEXTURE_2D, depthTexture);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
    glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY); 

    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
    glBindTexture(GL_TEXTURE_2D, 0);

    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, depthTexture, 0);
}
void FrameBuffer::attachColorTexture(GLuint i) {
    i=clamp(i, 0, GL_MAX_COLOR_ATTACHMENTS_EXT-1);

    glGenTextures(1, &colorTexture[i]);
    glBindTexture(GL_TEXTURE_2D, colorTexture[i]);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
    glBindTexture(GL_TEXTURE_2D, 0);

    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT+i, GL_TEXTURE_2D, colorTexture[i], 0);
}
void FrameBuffer::create(size_t width, size_t height, size_t nColorAttachMents=1) {
    this->width=width;
    this->height=height;
    nColorAttachMents=clamp(nColorAttachMents, 0, GL_MAX_COLOR_ATTACHMENTS_EXT);
    this->nColorAttachMents=nColorAttachMents;

    GLenum FBOstatus;

    glGenFramebuffersEXT(1, &id);
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, id);

    if(nColorAttachMents==0) {
        glDrawBuffer(GL_NONE);
        glReadBuffer(GL_NONE);
    }

    attachDepthTexture();
    for(int i=0; i<nColorAttachMents; i++)
        attachColorTexture(i);

    FBOstatus = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
    if(FBOstatus != GL_FRAMEBUFFER_COMPLETE_EXT)
        showMessage("GL_FRAMEBUFFER_COMPLETE_EXT failed, CANNOT use FBO", "FBO Create error");
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
void FrameBuffer::bindDepthTexture() const {
    glBindTexture(GL_TEXTURE_2D, depthTexture);
}
void FrameBuffer::bindColorTexture(GLuint i=0) const {
    i=clamp(i, 0, GL_MAX_COLOR_ATTACHMENTS_EXT-1);
    glBindTexture(GL_TEXTURE_2D, colorTexture[i]);
}
void FrameBuffer::bind() const {
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, id);
}
void FrameBuffer::unbind() const {
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
size_t FrameBuffer::getWidth() const {
    return width;
}
size_t FrameBuffer::getHeight() const {
    return height;
}   

此处使用:

void Game::init() {
    if(loaded) {
        Terrain::init();

        mainFrameBuffer.create(Settings::screenWidth, Settings::screenHeight, 1);
    ...
}
void Game::render() {
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    gluPerspective(45.0, (float)Game::Settings::screenWidth/Game::Settings::screenHeight, 0.1, 1000.0);

    glMatrixMode(GL_MODELVIEW);
    glPushMatrix(); 
    glLoadIdentity();
    setCamera();
    frustum.updateFrustum();

    if(Settings::shadowOn) makeShadow();

    mainFrameBuffer.bind();
    if(Settings::renderSkyOn) renderSky();
    if(Settings::reflectionOn) renderReflection(Settings::terrainShaderOn, Settings::objectShaderOn);
    if(Settings::renderTerrainOn) renderTerrain(Settings::terrainShaderOn, Settings::shadowOn);
    if(Settings::renderObjectsOn) renderObjectsUnderwater();
    if(Settings::renderWaterOn) renderWater(true);
    drawCursor();
    if(Settings::renderObjectsOn) renderObjects(Settings::objectShaderOn);
    drawMarkers();
    renderProjectiles();
    renderParticles();
    mainFrameBuffer.unbind();

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-1, 1, -1, 1, 1, -1);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glEnable(GL_TEXTURE_2D);
    mainFrameBuffer.bindColorTexture();
    glDrawRectangle(-1, 1, 1, -1);
    Texture2D::bindNone();
    glDisable(GL_TEXTURE_2D);

    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();

    glMatrixMode(GL_PROJECTION);
    glPopMatrix();

}

关闭深度测试时会渲染倒影。这只出现在。

共有1个答案

方夜洛
2023-03-14

对不起,我忘了清除新的帧缓冲区。

 类似资料:
  • 我正在使用JOGL,但这个问题一般适用于OpenGL。似乎存在类似的问题,但它们要么针对GLSL代码,要么与复制帧缓冲区的内容有关,要么是一般建议-使用帧缓冲区对象,而不是。 我正在做一些阴影映射。如何使用帧缓冲对象将深度通道直接渲染到纹理? 能否请你贴一段初始化纹理和帧缓冲对象的代码,以及渲染场景前初始化一切的代码? 目前,我使用<code>glCopyTexSubImage2D<code>。我

  • 我做了一个在上面渲染天空盒和粒子的应用程序。我想添加一些效果,我需要使用帧缓冲区来渲染天空盒、粒子颜色、深度和位置以分离纹理。然后我想使用简单的着色器来使用这些纹理中的值并以适当的方式混合它们。我为纹理、帧缓冲区和屏幕四边形(渲染简单的矩形)编写了辅助类,但不幸的是——当我尝试使用它时没有任何渲染。 当绑定帧缓冲区被注释掉时,我的场景如下所示: 修改着色器表明深度和位置值计算正确。因此问题在于纹理

  • 我是OpenGL的新手。我想使用帧缓冲区读取并保存渲染场景中的所有深度值。我设法将其设置为附加到深度组件的帧缓冲区。但是当我将深度纹理渲染到默认帧缓冲区(显示窗口)时,它只显示白色,即使我线性化了深度值(教程从https://learnopengl.com/开始)。当我在默认帧缓冲区片段着色器中从gl_FragCoord. z访问深度值时,我会得到一个深度图,并且绘图也可以,但是当将深度作为纹理从

  • 这是更大项目的一部分,基本上,我用以下方式创建带有颜色、深度和模具缓冲区的帧缓冲区: 我用以下方法将其绑定: 当我转储附加的纹理: 我收到主帧缓冲区(0)的内容。 知道我哪里错了吗?先谢谢你。

  • 这是我试图执行的主要程序: 但是,我看到的不是纹理而是白色矩形。如果我在屏幕上渲染,我会得到预期的结果(因此渲染代码应该没有问题)。这是FrameBuffer类: 其他一切都经过测试,所以问题应该在主程序的逻辑或帧缓冲区中。 顺便说一下,视口大小iz与窗口大小完全相同。

  • 在DirectX中,您可以有单独的渲染目标和深度缓冲区,因此可以绑定渲染目标和一个深度缓冲区、执行一些渲染、移除深度缓冲区然后使用旧的深度缓冲区作为纹理进行更多渲染。 你会如何在opengl中做到这一点?根据我的理解,您有一个帧缓冲区对象,其中包含颜色缓冲区和可选的深度缓冲区。我不认为我可以同时绑定多个帧缓冲器对象,我是否必须在每次更改时(可能一帧几次)重新创建帧缓冲器对象?普通的 opengl