OpenGL Context to CGContext & Printing

How can I copy an OpenGL Context to a CGContext?

The reason I need to do this is so I can print what OpenGL has rendered.

Based on some searching, I came up with this general procedure:

  1. use glReadPixels to obtain what has currently been rendered
  2. use CGDataProviderCreateWithData
  3. use CGImageCreate and pass in the CGDataProvider
  4. use CGContextDrawImage

However, I am having some trouble figuring out all the details on how to call
the various functions.

First, I am using the following attributes, passed to aglChoosePixelFormat:

{ AGL_RGBA, AGL_DOUBLEBUFFER, AGL_DEPTH_SIZE, 16, AGL_NONE }

Second, I am using:

aglSetInteger( mGLContext, AGL_BUFFER_RECT, mBufferRect );
aglEnable( mGLContext, AGL_BUFFER_RECT);

to specify the specific part of the window OpenGL should render to.

I tried to find some sample code, but was unable.
What I’ve got so far is:

aglSetCurrentContext( mGLContext );
glReadPixels( 0, 0, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, image
);
dataProvider = CGDataProviderCreateWithData( NULL, image, imageSize, NULL );
CGImageCreate( width, height, 8, 8 * 4, rowBytes, …

It is this CGImageCreate function that is causing me the most trouble, assuming
I’ve got everything else correct.

Should glReadPixels be based on what is in mBufferRect?

Has anyone else tried this? Any pointers or sample code available?

You could create a CGBitmapContext from the data you get from ReadPixels, and turn that into an image (there’s a function to do that). Seems like it might be easier.

Originally posted by OneSadCookie:
You could create a CGBitmapContext from the data you get from ReadPixels, and turn that into an image (there’s a function to do that). Seems like it might be easier.
It is still unclear to me what the

CGColorSpaceRef colorspace,
CGBitmapInfo bitmapInfo

parameters should be for the CGBitmapContextCreate function.

Originally posted by OneSadCookie:
You could create a CGBitmapContext from the data you get from ReadPixels, and turn that into an image (there’s a function to do that). Seems like it might be easier.
Unfortunately, CGBitmapContextCreateImage is 10.4 only. I need to build under 10.3.9.

Ok, I’ve got the following code, which almost works, however, the image it upside down and the colors are all wrong…it is rendered on screen as a grayscale image, but appears within Print Preview in pastel.

Any ideas on how to fix this?

Thank You.

 
 long              width           = mBufferRect[2];
 long              height          = mBufferRect[3];
 Rect              src_rect        = { 0, 0, height, width };
 long              rowBytes        = width * 4;
 long              imageSize       = rowBytes * height;
 char              *image          = NewPtr( imageSize );
 CGRect            imageRect       = CGRectMake( 0, 0, width, height );
 CGDataProviderRef dataProvider;
 CGColorSpaceRef   colorSpace;
 CGImageRef        imageRef;

 aglSetCurrentContext( mGLContext );
 glReadPixels( 0,
               0,
               width,
               height,
               GL_BGRA,
               GL_UNSIGNED_INT_8_8_8_8_REV,
               image );

 dataProvider = CGDataProviderCreateWithData(  NULL, image, imageSize, NULL );

 if ( dataProvider )
 {
   colorSpace = CGColorSpaceCreateDeviceRGB();

   if ( colorSpace )
   {
     imageRef = CGImageCreate( width,
                               height,
                               8,
                               8*4,
                               width*4,
                               colorSpace,
                               kCGImageAlphaLast,
                               dataProvider,
                               NULL,
                               false,
                               kCGRenderingIntentDefault );

     if ( imageRef )
     {
       CGContextDrawImage( cgRef, imageRect, imageRef );
       CGImageRelease( imageRef );
     }
     CGColorSpaceRelease( colorSpace );
   }
   CGDataProviderRelease( dataProvider );
 }  

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.