Opengl 无法使用多重采样渲染到纹理
我运行了页面中的帧缓冲区示例——(在osx 10.8的xcode 4.6中使用glfw3和glew),效果很好,然后我想添加多重采样(为了避免立方体边缘和地板上的锯齿状边缘,Opengl 无法使用多重采样渲染到纹理,opengl,graphics,textures,framebuffer,Opengl,Graphics,Textures,Framebuffer,我运行了页面中的帧缓冲区示例——(在osx 10.8的xcode 4.6中使用glfw3和glew),效果很好,然后我想添加多重采样(为了避免立方体边缘和地板上的锯齿状边缘,glfwWindowHint(GLFW_SAMPLES,4)在直接渲染到后缓冲区时就足够了),找到了一些指向opengl.org的答案,尝试使用glTexImage2DMultisample,但未显示任何内容(黑屏)。帧缓冲区设置和渲染循环为: // Create frame buffer GLuint frameBuffe
glfwWindowHint(GLFW_SAMPLES,4)
在直接渲染到后缓冲区时就足够了),找到了一些指向opengl.org的答案,尝试使用glTexImage2DMultisample
,但未显示任何内容(黑屏)。帧缓冲区设置和渲染循环为:
// Create frame buffer
GLuint frameBuffer;
glGenFramebuffers(1, &frameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
// Create texture to hold color buffer
GLuint texColorBuffer;
glGenTextures(1, &texColorBuffer);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texColorBuffer);
//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGB, width, height, GL_FALSE);
/*
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
*/
//glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texColorBuffer, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, texColorBuffer, 0);
// Create Renderbuffer Object to hold depth and stencil buffers
GLuint rboDepthStencil;
glGenRenderbuffers(1, &rboDepthStencil);
glBindRenderbuffer(GL_RENDERBUFFER, rboDepthStencil);
//glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
glRenderbufferStorageMultisample (GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rboDepthStencil);
// ...
while (!window->shouldClose()) {
static int rot = 0;
// Bind our framebuffer and draw 3D scene (spinning cube)
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
auto err_res = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(err_res != GL_FRAMEBUFFER_COMPLETE) {
ERR("Incomplete frameBuffer:%X!", err_res);
goto end;
}
glBindVertexArray(vaoCube);
glEnable(GL_DEPTH_TEST);
glUseProgram(sceneShaderProgram);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texKitten);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texPuppy);
// Clear the screen to white
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUniformMatrix4fv(uniModel, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(uniView, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(uniProj, 1, GL_FALSE, glm::value_ptr(proj));
// Draw cube
glEnable(GL_MULTISAMPLE);
glDrawArrays(GL_TRIANGLES, 0, 36);
glEnable(GL_STENCIL_TEST);
// Draw floor
glStencilFunc(GL_ALWAYS, 1, 0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glStencilMask(0xFF);
glDepthMask(GL_FALSE);
glClear(GL_STENCIL_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 36, 6);
// Draw cube reflection
glStencilFunc(GL_EQUAL, 1, 0xFF);
glStencilMask(0x00);
glDepthMask(GL_TRUE);
model = glm::scale(glm::translate(model, glm::vec3(0, 0, -1)), glm::vec3(1, 1, -1));
glUniformMatrix4fv(uniModel, 1, GL_FALSE, glm::value_ptr(model));
glUniform3f(uniColor, 0.3f, 0.3f, 0.3f);
glDrawArrays(GL_TRIANGLES, 0, 36);
glUniform3f(uniColor, 1.0f, 1.0f, 1.0f);
glDisable(GL_STENCIL_TEST);
/*
// Bind default framebuffer and draw contents of our framebuffer
glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
glBindVertexArray(vaoQuad);
glDisable(GL_DEPTH_TEST);
glUseProgram(screenShaderProgram);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texColorBuffer);
glDrawArrays(GL_TRIANGLES, 0, 6);
*/
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); // Make sure no FBO is set as the draw framebuffer
glBindFramebuffer(GL_READ_FRAMEBUFFER, frameBuffer); // Make sure your multisampled FBO is the read framebuffer
glDrawBuffer(GL_BACK); // Set the back buffer as the draw buffer
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
// Swap buffers
glfwSwapBuffers(window->getHandle());
glfwPollEvents();
}
- glVersion:3.2 NVIDIA-8.10.44 304.10.65f03
- glRenderer:NVIDIA GeForce 9400M OpenGL引擎
编辑:现在绑定
GL\u纹理\u 2D\u多样本
并获取GL\u帧缓冲区\u不完整\u多样本
错误 如果您检查帧缓冲区对象的完整性,您现在可能已经发现了这一点。。。深度/模具缓冲区也需要进行多采样
如果一个附件的采样数与任何其他附件的采样数不同,则core和EXT FBO扩展都认为帧缓冲区不完整。在您的示例中,您有一个带有4个样本的颜色缓冲区附件和一个带有1个样本的深度/模具附件
名称
-检查帧缓冲区的完整性状态
描述
glCheckFramebufferStatus
查询当前绑定到目标的帧缓冲区对象的完整性状态target
必须是GL\u DRAW\u FRAMEBUFFER
,GL\u READ\u FRAMEBUFFER
或GL\u FRAMEBUFFER
GL\u帧缓冲区
相当于GL\u-DRAW\u帧缓冲区
如果绑定到目标的帧缓冲区已完成,则返回值为GL\u FRAMEBUFFER\u COMPLETE
。否则,返回值确定如下:
[……]
如果GL\u RENDERBUFFER\u SAMPLES
GL\u RENDERBUFFER\u SAMPLES
的值对于所有附加的renderbuffers不相同,则返回;如果所有附加纹理的GL\u纹理\u样本的值不相同;或者,如果附加的图像是渲染缓冲区和纹理的混合,则GL\u RENDERBUFFER\u SAMPLES
的值与GL\u TEXTURE\u SAMPLES
的值不匹配
要解决此问题,您需要分配一个包含4个示例的多采样深度/模具附件:
顺便说一句,因为您的实现是=3.0,所以任何东西都不需要EXT后缀。EXT扩展定义的所有常量都与ARB/core FBO相同,但一些EXT函数(如glCheckFramebufferStatusEXT
)具有更严格的行为(例如,要求每个附件具有相同的图像尺寸)。我显然错过了它,但我已经在检查了(正确吗?)并且没有得到任何错误!。。不管怎样,我编辑了代码(和问题),但没有任何改变??老实说,我不知道为什么您首先要使用多采样纹理。多采样纹理增加了额外的硬件要求(您的硬件足以支持它们,但您仍然不需要它们)。我将使用多采样渲染缓冲区作为颜色缓冲区,除非您确实希望在着色器中使用多采样颜色缓冲区。无论何种情况,您都应该将texColorBuffer
绑定到GL\u TEXTURE\u 2D\u MULTISAMPLE
。同样,您可能会尝试更正glTexParameteri(GL\u TEXTURE\u 2D,GL\u TEXTURE\u MIN\u FILTER,GL\u LINEAR)代码>要在您使用时应用于GL\u纹理\u 2D\u多采样
。。。但是不要。在多采样纹理上无法进行纹理过滤。事实上,没有采样器参数适用于多采样纹理,这就是为什么GL\u TEXTURE\u 2D\u MULTISAMPLE
不是该函数的有效目标。当您从多采样纹理提取时,必须在着色器中使用texelFetch(…)
,该着色器绕过所有采样器状态。更改了它,现在获得GL\u FRAMEBUFFER\u Complete\u MULTISAMPLE错误?是的,现在您遇到了GL\u FRAMEBUFFER\u Complete\u MULTISAMPLE
的另一个原因:“GL\u FRAMEBUFFER\u complete\u MULTISAMPLE
如果所有附加纹理的GL\u TEXTURE\u FIXED\u SAMPLE\u LOCATIONS
的值不相同,也会返回;或者,如果附加的图像是渲染缓冲区和纹理的混合体,则GL_TEXTURE\u FIXED\u SAMPLE\u LOCATIONS
的值对于所有附加的纹理都不是GL_TRUE
。在调用glTexImage2DMultisample(…)
时,需要使用GL_TRUE
而不是GL_FALSE
)
glRenderbufferStorageMultisample (GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, width, height);