EAGLViewの画面キャプチャ

作っているゲームの画面キャプチャをアプリ内でする必要があり、いろいろ調べて実装してテストしたのですが、なかなか上手くいかず困っていましたが、なんとか行きました、という内容です。

@interface EAGLView : UIView
{
@private
    EAGLContext *context;
    
    // The pixel dimensions of the CAEAGLLayer.
    GLint framebufferWidth;
    GLint framebufferHeight;
    
    // The OpenGL ES names for the framebuffer and renderbuffer used to render to this view.
    GLuint defaultFramebuffer, colorRenderbuffer;
}

@property (nonatomic, retain) EAGLContext *context;

- (void)setFramebuffer;
- (BOOL)presentFramebuffer;
- (UIImage *) capture;

@end


- (UIImage *) capture
{
	int pixelCount = 4 * framebufferWidth * framebufferHeight;
	GLubyte* data = malloc(pixelCount * sizeof(GLubyte));
	glReadPixels(0, 0, framebufferWidth, framebufferHeight, GL_RGBA, GL_UNSIGNED_BYTE, data);
	
	CGColorSpaceRef space =  CGColorSpaceCreateDeviceRGB();
	CGContextRef ctx = CGBitmapContextCreate(data, framebufferWidth, framebufferHeight, 8, framebufferWidth * 4, space, kCGImageAlphaPremultipliedLast);
	CGImageRef img = CGBitmapContextCreateImage(ctx);
	UIGraphicsBeginImageContext(CGSizeMake(framebufferWidth, framebufferHeight)); 
	CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, framebufferWidth, framebufferHeight), img);
	CGContextScaleCTM(UIGraphicsGetCurrentContext(), 1.0f, -1.0f);

	UIImage *capturedImage = UIGraphicsGetImageFromCurrentImageContext();
	CGContextRelease(ctx);
	CGColorSpaceRelease(space);
	CGImageRelease(img);
	UIGraphicsEndImageContext();
	free(data);
	return capturedImage;
}


で、重要なのが、ViewControllerでの呼び出し方の方。

- (void)drawFrame
{
// 略
	if (_captureFlag)
	{
    [(EAGLView *)self.view capture];
		_captureFlag = NO;
	}

	[(EAGLView *)self.view presentFramebuffer];
}

と、[(EAGLView *)self.view presentFramebuffer]; の前で呼び出さないと、上手くキャプチャ出来ないのでした。