该代码应该使用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;
}
它首先清除具有指定颜色的帧缓冲区对象,然后将其缓冲到默认的帧缓冲区。代码有问题吗?我似乎找不到确切的问题所在。
答案 0 :(得分:3)
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错误,该错误在以下任何一种情况下发生:
- 读取缓冲区包含定点或浮点值,并且任何绘制缓冲区都不包含定点或浮点值。
- 读取缓冲区包含无符号整数值和任何绘制缓冲区 不包含无符号整数值。
- 读取缓冲区包含有符号整数值,任何绘制缓冲区都可以 不包含有符号整数值。