I have a working screenshot code that I got from here (stackoverflow). Problem is I can’t do it asynchronously. My screen is all black.
Is this possible? If yes, how will I do it?
Here’s the code I’m using
CGSize winSize = [CCDirector sharedDirector].winSize;
int screenScale = [UIScreen mainScreen].scale;
int width = winSize.width * screenScale;
int height = winSize.height * screenScale;
NSInteger myDataLength = width * height * 4;
// allocate array and read pixels into it.
GLubyte *buffer = (GLubyte *) malloc(myDataLength);
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
// gl renders "upside down" so swap top to bottom into new array.
// there's gotta be a better way, but this works.
GLubyte *buffer2 = (GLubyte *) malloc(myDataLength);
for(int y = 0; y < height; y++)
{
for(int x = 0; x < width * 4; x++)
{
buffer2[(height-(1*screenScale) - y) * width * 4 + x] = buffer[y * 4 * width + x];
}
}
// make data provider with data.
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer2, myDataLength, NULL);
// prep the ingredients
int bitsPerComponent = 8;
int bitsPerPixel = 32;
int bytesPerRow = 4 * width;
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
// make the cgimage
CGImageRef imageRef = CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);
// then make the uiimage from that
UIImage *myImage = [UIImage imageWithCGImage:imageRef];
The following is a suggestion you could try to do to do SOME stuff on the separate thread, but you still have to get the OpenGL pixels from the main thread.
My suggestion would be to save the pixels to the buffer on the main thread, and then schedule the background task to create the UIImage with that buffer.
Instead of saving the buffer array as a class variable, you could actually send the buffer as NSData on the performSelectorInBackground call, and then add the parameter on finishScreenshot.
As I said, I’m not sure of the viability of this, but this should work. Try to do this and check if it really is worth the effort performance wise.