我尝试渲染到一个立方体贴图中以创建一个动态天空盒。而且,我尝试使用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_TEXTURE_2D”替换为“ GL_TEXTURE_CUBEMAP”。我知道我需要继续使用glTextureStorage2D()创建存储。
然后,我不知道RBO是否会处理立方体贴图渲染...我想为每个面重复使用它。
最后,我完全迷失了渲染部分。至少,我知道我必须使用不同的摄像机角度渲染6倍的场景才能完成立方体。但是我不知道如何告诉我实际上正在渲染的OpenGL夹层。
我的第一个线索是使用“ glNamedFramebufferDrawBuffer(FBO,GL_COLOR_ATTACHMENT0 +人脸)”,但这是行不通的。
在使用glNamedFramebufferTextureLayer()创建帧缓冲区时,我看到了另一种解决方案,但是我不确定它是否正确。
我在网络上挖掘解决方案,但是我发现了很多解决方法,有些与DSA不兼容。
有没有实现这一目标的人?我只需要主要思想。
答案 0 :(得分:1)
您有两个选择:
您无法创建立方体贴图渲染缓冲区。因此,如果将renderbuffers用作深度缓冲区,则必须进行六次渲染通道,每个面一次。要将纹理的每个面依次附加到颜色缓冲区,请使用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);
}
您需要附加一个几何着色器,该着色器可为每个面复制图元。 See here。