Reputation: 47
This code is supposed to clear the background with yellow color using framebuffer object and render buffers but what I get is black background.
#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;
}
It first clears the framebuffer object with the specified color then blits the framebuffer object to the default framebuffer. Is there something wrong in the code? I can't seem to find where exactly the problem is.
Upvotes: 2
Views: 1980
Reputation: 210880
The glBlitFramebuffer
operation fails, because the read buffer contains unsigned integer values and the default framebuffer doesn't. This gains a GL_INVALID_OPERATION
error.
The format of the read buffer is GL_RGBA32UI
glRenderbufferStorage( GL_RENDERBUFFER, GL_RGBA32UI, 500, 500);
while the format of the draw buffer (default framebuffer) is an unsigned normalized integer format (probably GL_RGBA8
).
If you change the internal format to GL_RGBA16
or GL_RGBA32F
your code will proper work.
Note, formats like RGBA8
and RGBA16
are normalized floating point formats and can store floating point values in range [0.0, 1.0].
But formats like RGBA16UI
and RGBA32UI
are unsigned integral formats and can store integer values in the corresponding range.
The specification says that unsigned integer values can only be copied to unsigned integer values. So the source format has to be *UI
and the target format has to be *UI
, too.
See OpenGL 4.6 API Compatibility Profile Specification - 18.3.2 Blitting Pixel Rectangles page 662:
void BlitFramebuffer( int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, bitfield mask, enum filter );
[...]
Errors
[...]
An INVALID_OPERATION error is generated if format conversions are not supported, which occurs under any of the following conditions:
- The read buffer contains fixed-point or floating-point values and any draw buffer contains neither fixed-point nor floating-point values.
- The read buffer contains unsigned integer values and any draw buffer does not contain unsigned integer values.
- The read buffer contains signed integer values and any draw buffer does not contain signed integer values.
Upvotes: 4