使用DSA(直接状态访问)将OpenGL渲染到cubemap
我尝试渲染成立方体贴图来制作动态天空盒。我尝试使用OpenGL4.5中的直接状态访问功能来实现它 我的想法是使用一个简单的2D纹理进行屏幕外渲染 我是这样做的。我只粘贴最小且有效的代码使用DSA(直接状态访问)将OpenGL渲染到cubemap,c,opengl,rendering,C,Opengl,Rendering,我尝试渲染成立方体贴图来制作动态天空盒。我尝试使用OpenGL4.5中的直接状态访问功能来实现它 我的想法是使用一个简单的2D纹理进行屏幕外渲染 我是这样做的。我只粘贴最小且有效的代码 // 1. Initialization code { // FBO (Frame Buffer Object) GLuint FBO; glCreateFramebuffers(1, &FBO); // Texture2D for color buffer {
// 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_纹理_立方体贴图”替换“GL_纹理_2D”。我知道我需要继续使用glTextureStorage2D()来创建存储
然后,我不知道RBO是否会处理立方体贴图渲染。。。我想对每一张脸都重复使用它
最后,我对渲染部分完全不知所措。至少,我知道我必须以不同的摄影机角度渲染6次场景才能完成立方体。但我不知道如何告诉OpenGL wich face我实际上正在渲染
我的第一条线索是使用“glNamedFramebufferDrawBuffer(FBO,GL_COLOR_ATTACHMENT0+face)”,但它不起作用
在使用glNamedFramebufferTextureLayer()创建帧缓冲区时,我看到了另一种解决方案,但我不确定它是否正确
我在网上寻找解决方案,但我找到了很多方法,有些方法与DSA不兼容
有人能做到这一点吗?我只需要要点。您有两个选择:
使用renderbuffer的多个过程
无法创建立方体贴图renderbuffer。因此,如果使用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);
}
您需要附加一个几何体着色器,用于为每个面复制基本体 现在还不清楚这和DSA到底有什么关系。在我看来,无论如何创建或访问这些对象,您通常都不确定如何渲染到立方体贴图。更具体地说,不清楚如何渲染立方体贴图的面。DSA的问题是调用函数时存在一些差异,有些完全不同。所以我想我可能走错了方向。“DSA的问题是调用函数时有些不同,有些完全不同。”我不记得任何形式为
gl
的DSA函数与非DSAgl
的DSA函数行为不同的实例。在某些情况下,没有与DSA等效的功能(但在这些情况下,您确实不应该首先使用该功能)。在第一个示例中,每次渲染时都重新连接RBO。对吗?无论如何,我更喜欢第二种方式,我会用你给我的链接挖掘更多信息,谢谢。@SébastienBémelmans:不,我只重新附加纹理层。用于深度缓冲区的RBO只连接了一次。是的,我误读了代码。顺便说一句,我已经用第一个示例中的glNamedFramebufferTextureLayer()完成了工作!对于第一个示例。如果我没有放入glNamedFramebufferTexture
,FBO将无法完成。@iaomw:已经有一个glNamedFramebufferTextureLayer
。
// 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);
}