所以,我使用多重渲染目标帧缓冲,其中第一个颜色附件是颜色纹理(RGBA8),而第二个颜色附件(颜色附件1)是索引纹理(R32UI)。
gl::BindTexture(gl::TEXTURE_2D_MULTISAMPLE, m_Textures[eTEXTURE_COLORBUFFER]);
gl::TexParameteri(gl::TEXTURE_2D_MULTISAMPLE, gl::TEXTURE_BASE_LEVEL, 0);
gl::TexParameteri(gl::TEXTURE_2D_MULTISAMPLE, gl::TEXTURE_MAX_LEVEL, 0);
gl::TexImage2DMultisample(gl::TEXTURE_2D_MULTISAMPLE, m_Multisample,gl::RGBA8,width,height,gl::FALSE_);
gl::BindTexture(gl::TEXTURE_2D_MULTISAMPLE, m_Textures[eTEXTURE_CLASSBUFFER]);
gl::TexParameteri(gl::TEXTURE_2D_MULTISAMPLE, gl::TEXTURE_BASE_LEVEL, 0);
gl::TexParameteri(gl::TEXTURE_2D_MULTISAMPLE, gl::TEXTURE_MAX_LEVEL, 0);
gl::TexImage2DMultisample(gl::TEXTURE_2D_MULTISAMPLE, m_Multisample,gl::R32UI,width,height,gl::FALSE_);
两个纹理都是多重采样的,我想在渲染完成后在CPU上下载它们。虽然,当我将多重采样FBO单独放入单样本FBO时,返回的索引纹理数据由全零组成,而颜色纹理正确分辨。
// Resolve multisampling
if ( m_Multisample > 0 )
{
gl::BindFramebuffer(gl::READ_FRAMEBUFFER, m_Framebuffers[eFBO_RENDERBUFFER]);
gl::BindFramebuffer(gl::DRAW_FRAMEBUFFER, m_Framebuffers[eFBO_RESOLVEBUFFER]);
gl::BlitFramebuffer(0, 0, m_FrameDims, m_FrameDims, 0, 0, m_FrameDims, m_FrameDims,
gl::COLOR_BUFFER_BIT, gl::NEAREST);
gl::enum_t blit_error = gl::NO_ERROR_;
blit_error = gl::GetError();
if ( blit_error != gl::NO_ERROR_ )
{
throw framebuffer_error(string::format<128>(
"BlitFramebuffer failed with error: %d",blit_error));
}
gl::BindFramebuffer(gl::READ_FRAMEBUFFER, m_Framebuffers[eFBO_RESOLVEBUFFER]);
}
我使用NEARST标志,因为实际上整数纹理看起来不适用于LINEAR插值。
我在此处列出了用于下载图像的代码。
uint32_t* tex_data = new uint32_t[query.m_FrameDims*query.m_FrameDims];
memset(tex_data,0,sizeof(uint32_t)*query.m_FrameDims*query.m_FrameDims);
gl::BindTexture(gl::TEXTURE_2D,query.m_DestColorTexture);
{
// Copy color texture
gl::ReadBuffer(gl::COLOR_ATTACHMENT0);
gl::ReadPixels(0,0,query.m_FrameDims,query.m_FrameDims,
gl::RGBA,gl::UNSIGNED_BYTE,tex_data);
gl::TexSubImage2D(gl::TEXTURE_2D,0,0,0,query.m_FrameDims,query.m_FrameDims,
gl::RGBA,gl::UNSIGNED_BYTE,tex_data);
}
gl::BindTexture(gl::TEXTURE_2D,query.m_DestClassTexture);
{
// Copy class texture
gl::ReadBuffer(gl::COLOR_ATTACHMENT1);
gl::ReadPixels(0,0,query.m_FrameDims,query.m_FrameDims,
gl::RED_INTEGER,gl::UNSIGNED_INT,tex_data);
gl::TexSubImage2D(gl::TEXTURE_2D,0,0,0,query.m_FrameDims,query.m_FrameDims,
gl::RED_INTEGER,gl::UNSIGNED_INT,tex_data);
}
delete[] tex_data;
如果我禁用多重采样FBO,因此避免调用gl :: BlitFramebuffer()函数,一切正常。
我没有看到任何文档说整数纹理可以被多重采样,但即使如此,我也不确定它们是否有意义。
我可能会误以为哪些线索?
答案 0 :(得分:1)
当您执行帧缓冲区blit时,您只能从单个颜色缓冲区 读取 ;你可以 写 到很多绘制缓冲区(技术上一次最多GL_MAX_DRAW_BUFFERS
)。这里的问题是你想要从两个不同的颜色缓冲区读取,并且你试图在一个blit中进行。
当传输颜色缓冲区时,将从读取帧缓冲区的读取缓冲区中获取值,并将其写入 绘制缓冲区中的每一个绘制帧缓冲区。
你的代码向我表明你忘了为第二个颜色附件实际做了第二个blit,这就是为什么它变空了。
为了纠正这个问题,我希望看到类似的内容:
// Resolve multisampling
if ( m_Multisample > 0 )
{
//
// Do the first resolve (COLOR_ATTACHMENT0)
//
gl::BindFramebuffer(gl::READ_FRAMEBUFFER,m_Framebuffers[eFBO_RENDERBUFFER]);
gl::ReadBuffer (gl::COLOR_ATTACHMENT0); // Read: Attachment 0 (MSAA)
gl::BindFramebuffer(gl::DRAW_FRAMEBUFFER,m_Framebuffers[eFBO_RESOLVEBUFFER]);
gl::DrawBuffer (gl::COLOR_ATTACHMENT0); // Write: Attachment 0 (Resolve)
gl::BlitFramebuffer(0, 0, m_FrameDims, m_FrameDims, 0, 0, m_FrameDims,
m_FrameDims, gl::COLOR_BUFFER_BIT, gl::NEAREST);
gl::enum_t blit_error = gl::NO_ERROR_;
blit_error = gl::GetError();
if ( blit_error != gl::NO_ERROR_ )
{
throw framebuffer_error(string::format<128>(
"BlitFramebuffer failed with error: %d",blit_error));
}
//
// Do the second resolve (COLOR_ATTACHMENT1)
//
gl::BindFramebuffer(gl::READ_FRAMEBUFFER,m_Framebuffers[eFBO_RENDERBUFFER]);
gl::ReadBuffer (gl::COLOR_ATTACHMENT1); // Read: Attachment 1 (MSAA)
gl::BindFramebuffer(gl::DRAW_FRAMEBUFFER,m_Framebuffers[eFBO_RESOLVEBUFFER]);
gl::DrawBuffer (gl::COLOR_ATTACHMENT1); // Write: Attachment 1 (Resolve)
gl::BlitFramebuffer(0, 0, m_FrameDims, m_FrameDims, 0, 0, m_FrameDims,
m_FrameDims, gl::COLOR_BUFFER_BIT, gl::NEAREST);
gl::enum_t blit_error = gl::NO_ERROR_;
blit_error = gl::GetError();
if ( blit_error != gl::NO_ERROR_ )
{
throw framebuffer_error(string::format<128>(
"BlitFramebuffer failed with error: %d",blit_error));
}
gl::BindFramebuffer(gl::READ_FRAMEBUFFER,m_Framebuffers[eFBO_RESOLVEBUFFER]);
}
这假设您想要从/到blit的纹理/渲染缓冲区具有相同的附着点。如果没有,您可以相应地调整gl::ReadBuffer (...)
和gl::DrawBuffer (...)
。