PDA

View Full Version : OpenGL Context to CGContext & Printing



ericgorr
01-30-2006, 07:55 PM
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?

OneSadCookie
01-30-2006, 09:06 PM
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.

ericgorr
01-31-2006, 04:56 AM
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.

ericgorr
01-31-2006, 08:02 AM
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.

ericgorr
01-31-2006, 09:48 AM
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 );
}