Jump to content
  • Advertisement
Sign in to follow this  
NickGravelyn

Taking SDL/OpenGL Screenshot

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to get a screenshot system into my game, but I can't quite figure out part of the example code. Where did the 'foo' variable come from? Is it of type SDL_Surface? Thanks for any help.

Share this post


Link to post
Share on other sites
Advertisement
The 'foo' is supposed to be named 'image'. They also seemed to have missed calling SDL_FreeSurface() on 'temp' so make sure you do that. Good Luck.

Share this post


Link to post
Share on other sites
That's what I was thinking. I'm still getting weird results in the outputted file. Probably some error in the memcpy() functions. Here's my full code:

char screenshotName[64];
sprintf(screenshotName, "screenshot%d.bmp", screenshotCounter);
Uint32 rmask, gmask, bmask, amask;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
rmask = 0xff000000;
gmask = 0x00ff0000;
bmask = 0x0000ff00;
amask = 0x000000ff;
#else
rmask = 0x000000ff;
gmask = 0x0000ff00;
bmask = 0x00ff0000;
amask = 0xff000000;
#endif
SDL_Surface *temp = SDL_CreateRGBSurface(SDL_SWSURFACE, screenWidth, screenHeight, 32, rmask, gmask, bmask, amask);
SDL_Surface *image = SDL_CreateRGBSurface(SDL_SWSURFACE, screenWidth, screenHeight, 32, rmask, gmask, bmask, amask);
glReadBuffer(GL_FRONT);
glReadPixels(0, 0, screenWidth, screenHeight, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels);
int i;
for(i = 0; i < screenHeight; i++)
memcpy((char *)temp->pixels + 3 * screenWidth * i, (char *)image->pixels + 3 * screenWidth * (screenHeight - i), 3 * screenWidth);
memcpy(image->pixels, temp->pixels, screenWidth * screenHeight * 3);
SDL_SaveBMP(image, screenshotName);
SDL_FreeSurface(image);
SDL_FreeSurface(temp);





And here's what the screenshot looks like:
[link]

Any ideas?


(Edited because the image was nearly 4MB - much too big for many users -- Kylotan)

[Edited by - Kylotan on April 7, 2006 1:12:01 PM]

Share this post


Link to post
Share on other sites
Ok. After some experimenting, I found that my surface depth was too high. Then I just had to fix the masks and I was all set. Here's the final code that does work:



takeScreenshot = false;
char screenshotName[64];
sprintf(screenshotName, "screenshot%d.bmp", screenshotCounter);
Uint32 rmask, gmask, bmask, amask;
amask = 0x000000;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
rmask = 0xff0000;
gmask = 0x00ff00;
bmask = 0x0000ff;
#else
rmask = 0x0000ff;
gmask = 0x00ff00;
bmask = 0xff0000;
#endif
SDL_Surface *temp = SDL_CreateRGBSurface(SDL_SWSURFACE, screenWidth, screenHeight, 24, rmask, gmask, bmask, amask);
SDL_Surface *image = SDL_CreateRGBSurface(SDL_SWSURFACE, screenWidth, screenHeight, 24, rmask, gmask, bmask, amask);
glReadBuffer(GL_FRONT);
glReadPixels(0, 0, screenWidth, screenHeight, GL_RGB, GL_UNSIGNED_BYTE, image->pixels);
int i;
for(i = 0; i < screenHeight; i++)
memcpy((char *)temp->pixels + 3 * screenWidth * i, (char *)image->pixels + 3 * screenWidth * (screenHeight - i), 3 * screenWidth);
memcpy(image->pixels, temp->pixels, screenWidth * screenHeight * 3);
SDL_SaveBMP(temp, screenshotName);
SDL_FreeSurface(image);
SDL_FreeSurface(temp);




And for kicks, here's an funny image I got during my testing phase (before fixing the alpha channel mask (in my first fix, I just didn't define amask as anything, that's when I got this cool picture)):
[Link]


(Edited because the image was nearly 4MB - much too big for many users -- Kylotan)

Share this post


Link to post
Share on other sites
Just to wrap things up.

If the colors are wrong you may need to use GL_BGRA_EXT or GL_BGR_EXT in glReadPixels().

I don't think the depth was too high, you just forgot to change the ByterPerPixel values in the flip/copy step(change 3 to 4).

for(i = 0; i < screenHeight; i++)
memcpy((char *)temp->pixels + 4 * screenWidth * i, (char *)image->pixels + 4 * screenWidth * (screenHeight - i), 4 * screenWidth);
memcpy(image->pixels, temp->pixels, screenWidth * screenHeight * 4);




Jpeg/Png are your friends:)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!