我正在尝试将多采样场景渲染为纹理,这是我正在使用的代码。我黑屏了。我在初始化结束时检查了fbo的完整性,他们报告说两个fbo都是完整的。
void init_rendered_FBO() {
glGenFramebuffers(1,&fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glGenTextures(1,&fbo_tex);
glBindTexture(GL_TEXTURE_2D, fbo_tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width_screen, height_screen, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width_screen, height_screen);
glBindTexture (GL_TEXTURE_2D, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo_tex, 0);
int objectType;
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,&objectType);
ASSERT(objectType == GL_TEXTURE);
int objectName;
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,&objectName);
ASSERT(glIsTexture(objectName) == GL_TRUE);
int wid, hei, fmt;
glBindTexture(GL_TEXTURE_2D, objectName);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &wid);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &hei);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT,
&fmt);
glBindTexture(GL_TEXTURE_2D, 0);
std::string format = convertInternalFormatToString(fmt);
std::cout << "Color attachment 0: " << objectName << " " << wid << "x" << hei << ", " << format << std::endl;
ASSERT(checkFramebufferStatus());
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
// this is the init function that gets called.
void init_rendered_multisample_FBO() {
init_rendered_FBO();
// now I'm going to set up the additional component necessary to perform multisampling which is a new fbo
// that has a multisampled color buffer attached. I won't need a multisample depth buffer.
glGenFramebuffers(1,&multi_fbo);
glBindFramebuffer(GL_FRAMEBUFFER,multi_fbo);
glGenRenderbuffers(1,&renderbuffer_multi);
glBindRenderbuffer(GL_RENDERBUFFER,renderbuffer_multi);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA, width_screen,height_screen);
glBindRenderbuffer(GL_RENDERBUFFER,0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer_multi);
int objectType;
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,&objectType);
ASSERT(objectType == GL_RENDERBUFFER);
int objectName;
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,&objectName);
ASSERT(glIsRenderbuffer(objectName) == GL_TRUE);
glBindRenderbuffer(GL_RENDERBUFFER,objectName);
int wid,hei,fmt,sam;
glGetRenderbufferParameteriv(GL_RENDERBUFFER,GL_RENDERBUFFER_WIDTH,&wid);
glGetRenderbufferParameteriv(GL_RENDERBUFFER,GL_RENDERBUFFER_HEIGHT,&hei);
glGetRenderbufferParameteriv(GL_RENDERBUFFER,GL_RENDERBUFFER_INTERNAL_FORMAT,&fmt);
glGetRenderbufferParameteriv(GL_RENDERBUFFER,GL_RENDERBUFFER_SAMPLES,&sam);
glBindRenderbuffer(GL_RENDERBUFFER,0);
printf("Renderbuffer: %dx%d, fmt=%d, samples=%d\n",wid,hei,fmt,sam);
ASSERT(checkFramebufferStatus());
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
// this is called after rendering to multi_fbo
void resolve_multisample_FBO() {
glBindFramebuffer(GL_READ_FRAMEBUFFER, multi_fbo);
glReadBuffer(GL_COLOR_ATTACHMENT0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
GLenum drawbuf = GL_COLOR_ATTACHMENT0;
glDrawBuffers(1,&drawbuf);
glBlitFramebuffer(0,0,width_screen,height_screen,0,0,width_screen,height_screen,GL_COLOR_BUFFER_BIT,GL_NEAREST);
}
你能发现我遗漏的任何东西吗?我认为问题可能出在
glFramebufferRenderbuffer
调用上。我尝试将第一个arg切换为GL_READ_FRAMEBUFFER
,但未解决。我检查了
glGetError
,没有错误。如果我设置错误,肯定会失败,并给我INVALID_ENUM
或INVALID_OPERATION
来帮助我缩小问题的范围。我使用此代码的方式是,要启用多重采样,我要做的所有更改就是在绘制时绑定(bind)multi_fbo,然后调用resolve函数,该函数将进行绑定(bind)和blit。之后,我的fbo纹理(当我直接对其进行渲染时可以正常工作)现在应该包含多重采样的渲染。但这只是黑色。我也曾在初始化代码的另一部分中调用
glEnable(GL_MULTISAMPLE)
。现在,我将尝试将非多重采样纹理映射到另一个纹理,以确保能够正常工作。希望这可以帮助我缩小我搞砸的地方。
更新:原来,将常规FBO复制到另一个相同的FBO(两个纹理都附加到颜色附件0上)会产生相同的黑屏。 blit根本行不通。
同样奇怪的是,一旦我尝试过点血,然后绘制SOURCE fbo的纹理,它仍然是全黑的。就像尝试破口只是毁了一切。
有人知道或有任何FBO上位码吗?我找不到任何东西,但我知道人们已经得到了多采样FBO的工作。
这是您可以提供帮助的方法:如果您有在任何时候调用
glBlitFramebuffer
的代码,我希望看到其他有关设置该操作的调用。调用它后,除了黑色缓冲区和纹理外,我似乎一无所获。更新:即使使用多重采样,Blit到backbuffer也能正常工作!当然,因为我只绑定(bind)了帧缓冲区0,所以绝对不需要任何设置。因此,问题似乎出在我设置了FBO的过程中,该FBO的纹理附件被认为是盲目的。
最佳答案
好吧,事实证明我没有做任何错误,只是未能重置帧缓冲区绑定(bind)。
在void resolve_multisample_FBO()
的结尾,我只需要一个glBindFramebuffer(GL_FRAMEBUFFER, 0);
我向您保证,这是浪费3小时的可怕方式。但是多重采样看起来很棒,而且远远不能弥补。
关于opengl - FBO发条不起作用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9248223/