使用DSA(直接状态访问)将OpenGL渲染到立方体Map

z9gpfhce  于 2022-10-18  发布在  其他
关注(0)|答案(1)|浏览(148)

我试着渲染到立方体贴图中,以制作一个动态的天空盒子。我试着用OpenGL 4.5的直接状态访问功能来实现它。
我的想法是用一个简单的2D纹理进行屏幕外渲染。
我是这样做的。我只粘贴最少且有效的代码。

// 1. Initialization code
{
    // FBO (Frame Buffer Object)
    GLuint FBO;
    glCreateFramebuffers(1, &FBO);

    // Texture2D for color buffer
    {
        GLuint colorBuffer;
        glCreateTextures(GL_TEXTURE_2D, 1, &colorBuffer);
        glTextureStorage2D(colorBuffer, 1, GL_RGB8, 1024, 1024);

        glNamedFramebufferTexture(FBO, GL_COLOR_ATTACHMENT0, colorBuffer, 0);
    }

    // RBO (Render Buffer Object) for depth buffer.
    {
        GLuint depthBuffer;
        glCreateRenderbuffers(1, &depthBuffer);
        glNamedRenderbufferStorage(depthBuffer, GL_DEPTH_COMPONENT24, 1024, 1024);

        glNamedFramebufferRenderbuffer(FBO, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer);
    }

    if ( glCheckNamedFramebufferStatus(m_identifier, GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE )
        exit(1);
}

// 2. Drawing code
{
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FBO);

    glClearNamedFramebufferfv(FBO, GL_COLOR, 0, m_clearColor.data());
    glClearNamedFramebufferfv(FBO, GL_DEPTH, 0, &m_clearDepth);

    // Draw stuffs ...

    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
}

因此,要渲染到立方体贴图,我的想法是将“GL_纹理_2D”替换为“GL_纹理_CUBEMAP”。我知道我需要继续使用glTextureStorage2D()来创建存储。
然后,我不知道RBO是否会处理立方图渲染...我想对每一张脸重复使用它。
最后,我完全搞不懂渲染部分。至少,我知道我必须用不同的相机Angular 渲染6次场景才能完成立方体。但我不知道如何告诉OpenGL我实际上正在渲染哪个面。
我的第一个提示之一是使用“glNamedFrameBufferDrawBuffer(FBO,GL_COLOR_ATTACHMENT0+Face)”,但它不起作用。
在使用glNamedFrameBufferTextureLayer()创建帧缓冲区时,我看到了另一种解决方案,但我不确定它是否正确。
我在网上寻找解决方案,但我找到了很多方法,其中一些与DSA不兼容。
有没有人能做到这一点?我只想知道大意。

kqhtkvqz

kqhtkvqz1#

您有两个选择:

渲染缓冲区多遍

不能创建立方体贴图渲染器缓冲区。因此,如果将渲染缓冲区用于深度缓冲区,则必须进行六个渲染过程,每个面一个。若要依次将纹理的每个面附加到颜色缓冲区,请使用glNamedFramebufferTextureLayer

// 1. Initialization code
    // ...
    {
        GLuint colorBuffer;
        glCreateTextures(GL_TEXTURE_CUBE_MAP, 1, &colorBuffer);
        glTextureStorage2D(colorBuffer, 1, GL_SRGB8_ALPHA8, 1024, 1024);
    }

// 2. Drawing code
{
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FBO);

    for(int cube_map_face = 0; cube_map_face < 6; ++cube_map_face)
    {
        glNamedFramebufferTextureLayer(FBO, GL_COLOR_ATTACHMENT0, colorBuffer, 0, cube_map_face);
        glClearNamedFramebufferfv(FBO, GL_COLOR, 0, m_clearColor.data());
        glClearNamedFramebufferfv(FBO, GL_DEPTH, 0, &m_clearDepth);

        // Draw cub_map_face
    }
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
}

几何体着色器的一次传递

或者,可以将深度纹理立方体贴图与几何体着色器一起使用,以将基本体分派到每个(相关)面。

// 1. Initialization code
{
    // FBO (Frame Buffer Object)
    GLuint FBO;
    glCreateFramebuffers(1, &FBO);

    // Texture for color buffer
    {
        GLuint colorBuffer;
        glCreateTextures(GL_TEXTURE_CUBE_MAP, 1, &colorBuffer);
        glTextureStorage2D(colorBuffer, 1, GL_SRGB8_ALPHA8, 1024, 1024);
        glNamedFramebufferTexture(FBO, GL_COLOR_ATTACHMENT0, colorBuffer, 0);
    }

    // Texture for depth buffer.
    {
        GLuint depthBuffer;
        glCreateTextures(GL_TEXTURE_CUBE_MAP, 1, &depthBuffer);
        glTextureStorage2D(depthBuffer, 1, GL_DEPTH24_STENCIL8, 1024, 1024);
        glNamedFramebufferTexture(FBO, GL_DEPTH_ATTACHMENT, depthBuffer, 0);
    }

    if ( glCheckNamedFramebufferStatus(m_identifier, GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE )
        exit(1);
}  

// 2. Drawing code
{
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FBO);

    glClearNamedFramebufferfv(FBO, GL_COLOR, 0, m_clearColor.data());
    glClearNamedFramebufferfv(FBO, GL_DEPTH, 0, &m_clearDepth);

    // Draw stuffs ... (one pass)

    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
}

您需要附加一个几何体着色器,该着色器为每个面复制基本体。看这里。

相关问题