Screenshots in openGL/SDL fullscreen

Nibbie
Posts: 1
Joined: 2010.11
Post: #1
Hi,
I'm hard (Rasp) at work on my uDG entry and I would like to show off a bit. Does anyone have any info on how I can make a screen shot, or even simply make a function like getRGB_Pixel_From_Render_Buffer(int x,int y, &r,&g,&b); or something. Anyone?
Thanks.
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #2
man glReadPixels
Quote this message in a reply
Nibbie
Posts: 1
Joined: 2010.11
Post: #3
So I would use it like this?:
unsigned int pixel[4];
glReadPixels(x,y,1,1,GL_RGBA,GL_UNSIGNED_INT_8_8_8_8,& pixel);
Quote this message in a reply
Apprentice
Posts: 14
Joined: 2004.07
Post: #4
Here's the code I use, which is from Hardwarie, which handles the hardware side of drawing for SpriteWorld. I've just copy/pasted the entire function so you can get an idea. You'll need to strip out some of the Hardwarie specific stuff to get it to compile.

If you have any questions, let me know.

And SpriteWorld 3.0.1 should be out any day now, btw Wacko

Code:
OSErr HardwarieCopyContextToGWorld (
    HardwarieContextPtr    hardwareContextP,
    GWorldPtr    *gworldBufferP,
    RectPtr        copyRectP)
{
    OSErr            err = noErr;
    char               *dataBuffer;
    long            dataRowBytes;
    Rect             newRect;
    PixMapHandle    pix;
    GLRect             glRect;
    GLenum             glerr;

    *gworldBufferP = NULL;

    HARDWARE_ASSERT( hardwareContextP != NULL );
    HARDWARE_ASSERT( copyRectP != NULL );
    
    if (hardwareContextP == NULL || hardwareContextP->context == NULL)
        return -1;    // error code ?

    if (!hardwareContextP->contextActive)
        return -1;    // error code ?

    glFinish();

    if (copyRectP == NULL)
    {
        newRect.left = newRect.top = 0;
        newRect.right = hardwareContextP->width;
        newRect.bottom = hardwareContextP->height;
    }
    else
    {
        newRect = *copyRectP;
    }

    glRect.x         = newRect.left;
    glRect.y         = hardwareContextP->height - newRect.bottom;

    glRect.width     = newRect.right - newRect.left;
    glRect.height     = newRect.bottom - newRect.top;
    glRect.center.x    = glRect.width / 2;
    glRect.center.y    = glRect.height / 2;

    // Alloc enough memory for this data
    dataRowBytes = glRect.width * 4;
    dataBuffer = (char *) NewPtr(glRect.height * dataRowBytes);
    if (dataBuffer == NULL)
        return memFullErr;

    // Read the back buffer
    // (glReadBuffer() is set to GL_BACK by default in a double buffered context)
    glReadBuffer(GL_BACK);

    glReadPixels (glRect.x, glRect.y, glRect.width, glRect.height,
        GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, dataBuffer);

    glerr = glGetError();
    if(glerr == GL_NO_ERROR)
    {
        err = NewGWorld(gworldBufferP, 32, &newRect, (CTabHandle) NULL, (GDHandle) NULL, 0L);
        if (err == noErr)
        {
            unsigned long *src,*dst;
            long srcStride,dstStride;
            int x,y;
            
            pix = GetGWorldPixMap(*gworldBufferP);
            LockPixels(pix);
            
            src = (unsigned long *) dataBuffer;
            srcStride = dataRowBytes;

            dst = (unsigned long *) GetPixBaseAddr(pix);
            dstStride = GetPixRowBytes(pix);
            
            // flip vertical
            dst = (unsigned long *) (((unsigned char *) dst) + (glRect.height - 1) * dstStride);
            dstStride = -dstStride;
            
            srcStride -= glRect.width * sizeof(unsigned long);
            dstStride -= glRect.width * sizeof(unsigned long);
            
            for (y = 0; y < glRect.height; y++)
            {
                for (x = 0; x <  glRect.width; x++)
                {
                    // convert RGBA32 to RGB32
                    *dst++ = (*src++ >> 8);
                }
                
                src = (unsigned long *) (((unsigned char *) src) + srcStride);
                dst = (unsigned long *) (((unsigned char *) dst) + dstStride);
            }
            
            PortChanged((GrafPtr) *gworldBufferP);
            UnlockPixels(pix);
        }
    }
    else
        err = glerr;
    
    DisposePtr((Ptr) dataBuffer);

    return err;
}
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #5
In general, if you're reading back a lot of data, it's best to do it in one big chunk, not individual pixels one at a time scattered around. glReadPixels has a very significant performance hit per call.
Quote this message in a reply
Nibbie
Posts: 1
Joined: 2010.11
Post: #6
this is for screenshots so I really don't care about how long it takes. 1 second for a screenshot is fine, and I doubt it would take that.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #7
Joseph Duchesne Wrote:1 second for a screenshot is fine, and I doubt it would take that.

I don't...
Quote this message in a reply
Mars_999
Unregistered
 
Post: #8
OneSadCookie Wrote:I don't...

sickem Tiger LOL
Quote this message in a reply
FluxRider
Unregistered
 
Post: #9
You might consider looking at SDL_SaveBMP.
Simply pass your final SDL_Surface.
Quote this message in a reply
Moderator
Posts: 771
Joined: 2003.04
Post: #10
FluxRider Wrote:You might consider looking at SDL_SaveBMP.
Simply pass your final SDL_Surface.

Just remember to look at the saved BMP, it will probably be inverted (top <-> bottom)
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  SDL/OpenGL fullscreen text rendering StealthyCoin 2 6,583 Mar 26, 2009 09:47 AM
Last Post: StealthyCoin
  opengl bitmap font question: switching to fullscreen moon_magic 2 3,103 Jul 8, 2006 03:39 PM
Last Post: OneSadCookie
  Fullscreen windowed OpenGL mode maaaaark 8 5,181 Mar 11, 2005 12:34 PM
Last Post: maaaaark
  Cocoa OpenGL - Switching to/from fullscreen Indie Mac 5 3,988 Jan 28, 2005 12:40 AM
Last Post: OneSadCookie
  Fullscreen SDL/OpenGL &amp; CMD-TAB problem NicholasFrancis 5 4,560 Dec 2, 2004 01:00 PM
Last Post: NicholasFrancis