通常情况下,我们使用openGL将渲染好的图片绘制到屏幕上,但有时候我们不想显示处理结果,这时候就需要使用离屏渲染了。
正常情况下,我们将屏幕,也就是一个CAEAGLLayer对象作为渲染目标,离屏渲染就是重定位渲染目标,将内存开辟的一块空间作为渲染目标,然后再从内存中获取图片。
在离屏渲染过程中需要使用到FBO,不熟悉的朋友可以先查阅FBO相关资料 http://blog.csdn.net/dreamcs/article/details/7691690
下面让我们来一起看看如何进行离屏渲染:
glGenRenderbuffers(1, &_colorBufferRender); glBindRenderbuffer(GL_RENDERBUFFER, _colorBufferRender); // [_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:_EALayer]; glGenFramebuffers(1, &_frameBuffer); glBindFramebuffer(GL_FRAMEBUFFER, _frameBuffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB8_OES, _drawableWidth, _drawableHeight); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _colorBufferRender);
其实过程很简单,为renderBuffer分配内存,然后将renderBuffer挂载到frameBuffer上,这样就将渲染目标从原来的CAEALyaer定向到了为renderBuffer分配的内存。
好像也有将纹理作为渲染目标的,可惜没研究明白,有会的朋友可以留言教我一下。
其余的过程并没有什么区别,在渲染结束后,从内存中获取图片就可以了。
NSInteger dataLength = self.drawableWidth * self.drawableHeight * 4; GLubyte *buffer = (GLubyte *)malloc(dataLength * sizeof(GLubyte)); glReadPixels(0, 0, self.drawableWidth, self.drawableHeight, GL_RGBA, GL_UNSIGNED_BYTE, buffer); CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer, dataLength, NULL); int bitsPerComponent = 8; int bitsPerPixel = 32; int bytesPerRow = 4 * self.drawableWidth; CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB(); CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault; CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault; CGImageRef imageRef = CGImageCreate(self.drawableWidth, self.drawableHeight, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, true, renderingIntent); UIImage *myImage = [UIImage imageWithCGImage:imageRef];