OpenGL ES 2d渲染成图像

我需要在iOS上编写OpenGL ES二维渲染器。 它应该绘制一些原始的线条和多边形到2D图像(这将是vector地图的渲染)。 在这个任务中,哪种方式最适合从OpenGL环境中获取图像? 我的意思是,我应该把这些图元渲染成纹理,然后从中获取图像,或者是什么? 另外,如果有人给我看所需要的例子或教程(2d GL渲染成图像),这将是非常好的。 提前致谢!

如果您需要渲染OpenGL ES 2-D场景,然后提取该场景的图像以在OpenGL ES之外使用,则有两个主要选项。

首先是渲染场景,然后使用glReadPixels()获取场景的RGBA数据,并将其放置在字节数组中,如下所示:

 GLubyte *rawImagePixels = (GLubyte *)malloc(totalBytesForImage); glReadPixels(0, 0, (int)currentFBOSize.width, (int)currentFBOSize.height, GL_RGBA, GL_UNSIGNED_BYTE, rawImagePixels); // Do something with the image free(rawImagePixels); 

第二种更快的方法是将场景渲染到纹理支持的帧缓冲区对象(FBO),其中纹理由iOS 5.0的纹理caching提供。 我在这个答案中描述了这种方法,尽pipe我没有在那里显示原始数据访问的代码。

您可以执行以下操作来设置纹理caching并绑定FBO纹理:

  CVReturn err = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, (__bridge void *)[[GPUImageOpenGLESContext sharedImageProcessingOpenGLESContext] context], NULL, &rawDataTextureCache); if (err) { NSAssert(NO, @"Error at CVOpenGLESTextureCacheCreate %d"); } // Code originally sourced from http://allmybrain.com/2011/12/08/rendering-to-a-texture-with-ios-5-texture-cache-api/ CFDictionaryRef empty; // empty value for attr value. CFMutableDictionaryRef attrs; empty = CFDictionaryCreate(kCFAllocatorDefault, // our empty IOSurface properties dictionary NULL, NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); attrs = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionarySetValue(attrs, kCVPixelBufferIOSurfacePropertiesKey, empty); //CVPixelBufferPoolCreatePixelBuffer (NULL, [assetWriterPixelBufferInput pixelBufferPool], &renderTarget); CVPixelBufferCreate(kCFAllocatorDefault, (int)imageSize.width, (int)imageSize.height, kCVPixelFormatType_32BGRA, attrs, &renderTarget); CVOpenGLESTextureRef renderTexture; CVOpenGLESTextureCacheCreateTextureFromImage (kCFAllocatorDefault, rawDataTextureCache, renderTarget, NULL, // texture attributes GL_TEXTURE_2D, GL_RGBA, // opengl format (int)imageSize.width, (int)imageSize.height, GL_BGRA, // native iOS format GL_UNSIGNED_BYTE, 0, &renderTexture); CFRelease(attrs); CFRelease(empty); glBindTexture(CVOpenGLESTextureGetTarget(renderTexture), CVOpenGLESTextureGetName(renderTexture)); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, CVOpenGLESTextureGetName(renderTexture), 0); 

然后你可以直接从背景纹理的字节(BGRA格式,而不是glReadPixels()的RGBA)使用类似的东西读取:

  CVPixelBufferLockBaseAddress(renderTarget, 0); _rawBytesForImage = (GLubyte *)CVPixelBufferGetBaseAddress(renderTarget); // Do something with the bytes CVPixelBufferUnlockBaseAddress(renderTarget, 0); 

但是,如果您只是想在OpenGL ES中重新使用图像,则只需将场景渲染到纹理支持的FBO,然后在第二级渲染中使用该纹理。

我将展示一个渲染到纹理的例子,然后在我的开源GPUImage框架内的CubeExample示例应用程序中对它进行一些处理,如果你想看到这个实际效果。

Interesting Posts