当我使用 glBlitFramebuffer 实现 MSAA 时收到 INVALID OPERATION
Posted
技术标签:
【中文标题】当我使用 glBlitFramebuffer 实现 MSAA 时收到 INVALID OPERATION【英文标题】:I receive INVALID OPERATION when I use glBlitFramebuffer to implement MSAA 【发布时间】:2017-09-12 07:56:41 【问题描述】:也许我有一些愚蠢的问题。如果有人可以回复他们,我将不胜感激。 所有问题都是基于android环境和OpenGL ES。
如何验证我是否打开了 MSAA?如果我画一些点大小为 50 的GL_POINTS
,就会有一些小方块。如果我启用了 4x MSAA,小方块可以变成圆点吗?
我尽了最大的努力来启用带有 FBO 和 BlitFBO 的 MSAA。但它什么也没画,glBlitFramebuffer()
调用后出现错误 INVALID_OPERATION。
这是我上面提到的完整项目:https://github.com/Enoch-Liu/GL
以下是关键代码:
void Renderer::MultisampleAntiAliasing()
glGenRenderbuffers(1, &m_MSColor);
glBindRenderbuffer(GL_RENDERBUFFER, m_MSColor);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, m_width, m_height);
checkGLError("GenMSColorBuffer");
glGenFramebuffers(1, &m_MSFBO);
glBindFramebuffer(GL_FRAMEBUFFER, m_MSFBO);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_MSColor);
checkGLError("FboRbo,COLORATTACHMENT");
glGenRenderbuffers(1, &m_MSDepth);
glBindRenderbuffer(GL_RENDERBUFFER, m_MSDepth);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH_COMPONENT16, m_width, m_height);
checkGLError("GenDepthBuffer");
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_MSDepth);
checkGLError("DepthBuffer,Renderbuffer");
GLenum drawBufs[] = GL_COLOR_ATTACHMENT0;
glDrawBuffers(1, drawBufs);
checkGLError("DrawBuffer");
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
LOG_ERROR("failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
void Renderer::drawFrame()
//LOG_INFO("drawFrame %d x %d", width, height);
static float r=0.9f;
static float g=0.2f;
static float b=0.2f;
LOG_INFO("xxx %d, %d", m_width,m_height);
if (OPENMSAA)
glBindFramebuffer(GL_FRAMEBUFFER, m_MSFBO);
glBindRenderbuffer(GL_RENDERBUFFER, m_MSColor);
checkGLError("BindTwoBuffers");
glViewport(0,0,m_width,m_height);
glScissor(0,0,m_width,m_height);
glClearColor(r, g, b, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
const GLfloat landscapeOrientationMatrix[16] =
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f ;
const GLfloat color[4] =
1.0f, 0.0f, 0.0f, 1.0f
;
glUseProgram( m_program );
glUniformMatrix4fv(m_uMvp, 1, GL_FALSE, landscapeOrientationMatrix);
glUniform4fv(m_uColor, 1, color);
m_p = glGetAttribLocation(m_program, "vPosition");
m_p1 = glGetAttribLocation(m_program, "vPosition1");
glEnableVertexAttribArray( m_p );
glVertexAttribPointer( m_p , 3, GL_FLOAT, false, 3 * sizeof( float ), squareCoords);
glDrawArrays(GL_POINTS, 0, 4);
glDisableVertexAttribArray( m_p );
glFlush();
checkGLError("Before Blit");
if (OPENMSAA)
glBindFramebuffer(GL_READ_FRAMEBUFFER, m_MSFBO);
checkGLError("BindReadBuffer");
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
checkGLError("BindFramebuffer");
glBlitFramebuffer(0, 0, m_width, m_height, 0, 0, m_width, m_height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
checkGLError("BlitFramebufferColor");
glBlitFramebuffer(0, 0, m_width, m_height, 0, 0, m_width, m_height, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
checkGLError("BlitFramebufferDepth");
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
帧缓冲区已完成。
【问题讨论】:
MSAA 不会影响点是呈现为圆形还是正方形。它可以在亚像素的基础上平滑边缘。 非常感谢,BDL。 【参考方案1】:深度缓冲区的内部格式必须匹配:https://www.opengl.org/discussion_boards/showthread.php/173275-Alternative-to-glBlitFramebuffer%28%29
查看您的 github 项目,您根本没有配置深度缓冲区。来自您的项目:
const EGLint attribs[] =
// EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
EGL_BLUE_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_RED_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_SAMPLE_BUFFERS, 1,
EGL_SAMPLES, 4,
EGL_NONE
;
【讨论】:
是的!你说的对 !但是,在我的代码中,实现 FBO-Blit MSAA 的属性应该更少。 EGL_SAMPLE_BUFFERS 和 EGL_SAMPLES 也应该被删除。正确代码如下: const EGLint attribs[] = EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_BLUE_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_RED_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_NONE ;以上是关于当我使用 glBlitFramebuffer 实现 MSAA 时收到 INVALID OPERATION的主要内容,如果未能解决你的问题,请参考以下文章
Intel和Nvidia之间的OpenGL fbo blitting不一致
为啥当我使用hibernate时这个类应该实现java.io.Serializable?