这段代码应该使用framebuffer对象和渲染缓冲区清除黄色背景,但我得到的是黑色背景。
#include <SDL2/SDL.h>
#include <GL/glew.h>
int main( int argc, char** argv)
{
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL, 1);
SDL_Window* gWindow= SDL_CreateWindow( "Title",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
500, 500, SDL_WINDOW_OPENGL);
SDL_GLContext gContext= SDL_GL_CreateContext( gWindow);
glewExperimental= GL_TRUE;
glewInit();
GLuint fbo;
glGenFramebuffers( 1, &fbo);
glBindFramebuffer( GL_FRAMEBUFFER, fbo);
GLuint color_rbr;
glGenRenderbuffers(1, &color_rbr);
glBindRenderbuffer( GL_RENDERBUFFER, color_rbr);
glRenderbufferStorage( GL_RENDERBUFFER, GL_RGBA32UI, 500, 500);
glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color_rbr);
GLuint depth_rbr;
glGenRenderbuffers( 1, &depth_rbr);
glBindRenderbuffer( GL_RENDERBUFFER, depth_rbr);
glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 500, 500);
glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_rbr);
if( glCheckFramebufferStatus( GL_DRAW_FRAMEBUFFER)!= GL_FRAMEBUFFER_COMPLETE)
return 1;
if( glCheckFramebufferStatus( GL_READ_FRAMEBUFFER)!= GL_FRAMEBUFFER_COMPLETE)
return 2;
glViewport( 0, 0, 500, 500);
glClearColor( 1, 1, 0, 0);
SDL_GL_SetSwapInterval( 1);
int quit= 0;
SDL_Event event;
glReadBuffer( GL_COLOR_ATTACHMENT0);
while( !quit)
{
while( SDL_PollEvent( &event))
if( event.type== SDL_QUIT)
quit= 1;
glBindFramebuffer( GL_DRAW_FRAMEBUFFER, fbo);
glDrawBuffer( GL_COLOR_ATTACHMENT0);
glClear( GL_COLOR_BUFFER_BIT);
glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0);
glDrawBuffer( GL_BACK);
glBlitFramebuffer(
0, 0, 500, 500,
0, 0, 500, 500,
GL_COLOR_BUFFER_BIT, GL_NEAREST);
SDL_GL_SwapWindow( gWindow);
}
SDL_DestroyWindow( gWindow);
return 0;
}
它首先使用指定的颜色清除framebuffer对象,然后将framebuffer对象blit到默认的帧缓冲区。代码中有什么问题吗?我似乎无法找到问题的确切位置。
glBlitFramebuffer
操作失败,因为读缓冲区包含无符号整数值而默认帧缓冲区不包含。这会获得GL_INVALID_OPERATION
错误。
读缓冲区的格式是GL_RGBA32UI
glRenderbufferStorage( GL_RENDERBUFFER, GL_RGBA32UI, 500, 500);
而绘制缓冲区(默认帧缓冲区)的格式是无符号规范化整数格式(可能是GL_RGBA8
)。
如果您将内部格式更改为GL_RGBA16
或GL_RGBA32F
,您的代码将正常工作。
请注意,RGBA8
和RGBA16
等格式是规范化浮点格式,可以存储范围[0.0,1.0]中的浮点值。
但是像RGBA16UI
和RGBA32UI
这样的格式是无符号整数格式,可以在相应的范围内存储整数值。
规范说无符号整数值只能复制到无符号整数值。所以源格式必须是*UI
,目标格式也必须是*UI
。
参见OpenGL 4.6 API Compatibility Profile Specification - 18.3.2 Blitting Pixel Rectangles第662页:
void BlitFramebuffer( int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, bitfield mask, enum filter );
[...]
错误
[...]
如果不支持格式转换,则会生成INVALID_OPERATION错误,该错误在以下任何条件下发生:
- 读缓冲区包含定点或浮点值,任何绘制缓冲区都不包含定点或浮点值。
- 读缓冲区包含无符号整数值,任何绘制缓冲区都不包含无符号整数值。
- 读缓冲区包含有符号整数值,任何绘制缓冲区都不包含有符号整数值。