My Screenshot Problem with SDL and OpenGL in C

This topic is 1990 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Hi,
I wanted to write screen saver function for my mother OpenGL Suface yesterday.
First, i thinked this is very easy!
I wrote SDL_SaveBMP(screen,"deneme.bmp");
The End..
That can be comic for you but unluckily it did not be.
The program showed an error message me and it was grotesque for me.
Then, I found a function from a web site but does not work correctly.When it saved a bmp file, it only showed a color on all surface.The color was color of glClearColor function.
The Screenshot Code:
 int Screenshot(char *filename, SDL_Surface *screen) { SDL_Surface *temp; unsigned char *pixels; int i; if (!(screen->flags & SDL_OPENGL)) { SDL_SaveBMP(temp, filename); return 0; } temp = SDL_CreateRGBSurface(SDL_SWSURFACE, screen->w, screen->h, 24, #if SDL_BYTEORDER == SDL_LIL_ENDIAN 0x000000FF, 0x0000FF00, 0x00FF0000, 0 #else 0x00FF0000, 0x0000FF00, 0x000000FF, 0 #endif ); if (temp == NULL) return -1; pixels = malloc(3 * screen->w * screen->h); if (pixels == NULL) { SDL_FreeSurface(temp); return -1; } glReadBuffer(GL_FRONT_AND_BACK); glReadPixels(0, 0,screen->w, screen->h,GL_RGB , GL_UNSIGNED_BYTE, pixels); for (i=0; i<ekran->h; i++) memcpy(((char *) temp->pixels) + temp->pitch * i, pixels + 3*screen->w * (ekran->h-i-1), screen->w*3); free(pixels); SDL_SaveBMP(temp, filename); SDL_FreeSurface(temp); return 0; } 
Not : For first error the reason is not different between screen,"filename" and "filename",screen.SDL_SaveBMP and Screenshot are different fuctions.
Thanks. Edited by Graphic_Programmer

Share on other sites
Isn't there nobody?

Share on other sites
For starters, get rid of the "ekran" variable and use screen or temp in its place.

Check what is the value of gluErrorString(glGetError()) after the call to glReadBuffer. Overall, the code seems legit, but I'm not an OpenGL expert by any means.

Do you draw something in OpenGL? When do you call this Screenshot function?

Edit:
GL_FRONT_AND_BACK seems to be illegal value for glReadBuffer. Try with GL_FRONT_LEFT instead. Quoting the documentation:
mode
Specifies a color buffer.
Accepted values are
GL_FRONT_LEFT,
GL_FRONT_RIGHT,
GL_BACK_LEFT,
GL_BACK_RIGHT,
GL_FRONT,
GL_BACK,
GL_LEFT,
GL_RIGHT, and
GL_AUXi,
where i is between 0 and the value of GL_AUX_BUFFERS minus 1.
...

Nonstereo double-buffered configurations have only a front left and a back left buffer[/quote] Edited by dilyan_rusev

Share on other sites

For starters, get rid of the "ekran" variable and use screen or temp in its place.

Check what is the value of gluErrorString(glGetError()) after the call to glReadBuffer. Overall, the code seems legit, but I'm not an OpenGL expert by any means.

Do you draw something in OpenGL? When do you call this Screenshot function?

Edit:
GL_FRONT_AND_BACK seems to be illegal value for glReadBuffer. Try with GL_FRONT_LEFT instead. Quoting the documentation:
mode
Specifies a color buffer.
Accepted values are
GL_FRONT_LEFT,
GL_FRONT_RIGHT,
GL_BACK_LEFT,
GL_BACK_RIGHT,
GL_FRONT,
GL_BACK,
GL_LEFT,
GL_RIGHT, and
GL_AUXi,
where i is between 0 and the value of GL_AUX_BUFFERS minus 1.
...

Nonstereo double-buffered configurations have only a front left and a back left buffer

[/quote]
Thank you very much for your help! Me too not a expert of OpenGL but sure, you know it better than me becuse i am new in OpenGL and my English isn't very good to understand everything.
Oh, i am an idiot First, I might say thats:
Already, I called Screenshot function with screen surface and drew something to screen.The problem weren't them.
When i tried GL_FRONT_LEFT, i made it just and i have a question: why doesn't it be when i tried GL_FRONT_RIGHT instead?
What is different between LEFT and RIGHT? Does it mean front face and back face. I will try all of them. Edited by Graphic_Programmer

Share on other sites
To be honest, I do not know what is the difference between left and right. It must be some feature of OpenGL that I have never used. If you set-up OpenGL with SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ) before SDL_SetVideoMode, then you have two buffers: front and back.

Simply put, you draw continuously to the back buffer, and once everything is done, you show it to the user (with SDL_GL_SwapBuffers).

glReadBuffer is an OpenGL function. Its documentation says that double-buffered applications have only two buffers (obviously), and gives you the names. I guess they arbitrarily chose left, and not right. What matters is that what is currently displayed to your user should be in the front buffer, and therefore this is the buffer you load into the OpenGL's state machine. Again, according to the glReadBuffer documentation, the "mode" parameter for the front buffer should be GL_FRONT_LEFT. And that is why I said that you should perhaps use it that way.

As for the rest, I honestly do not understand what you ask (or if you are asking something).

I asked about how you call the Screenshot function, because it depends on the OpenGL state. If it is called before anything is displayed (i.e. before SDL_GL_SwapBuffers), then it will be empty (the value of glClearColor). It should also be called after OpenGL has been properly initialised and before SDL is shut down.