iphone - OpenGL ES 2d 渲染成图像

标签 iphone ios image opengl-es rendering

我需要在 iOS 上编写 OpenGL ES 二维渲染器。它应该将一些图元(例如线和多边形)绘制成二维图像(它将渲染矢量图)。在该任务中,哪种方式最适合从 OpenGL 上下文获取图像?我的意思是,我应该将这些图元渲染成纹理,然后从中获取图像,还是什么?此外,如果有人提供看起来像我需要的东西(2d GL 渲染成图像)的示例或教程,那将会很棒。提前致谢!

最佳答案

如果您需要渲染 OpenGL ES 二维场景,然后提取该场景的图像以在 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 的纹理缓存提供。我在 this answer 中描述了这种方法,虽然我没有在那里显示原始数据访问的代码。

您执行以下操作来设置纹理缓存并绑定(bind) 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,然后在第二级渲染中使用该纹理。

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

关于iphone - OpenGL ES 2d 渲染成图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10455329/

相关文章:

javascript - iPhone 上的动态下拉菜单

ios - 防止 UISwitch 改变 UI 状态

python - 图像文件的 Django 内容类型

css - 具有多个图像的多个类

iphone - 如何制作带边框的半圆形(顶角圆角) TextView ?

iphone - 应首先验证什么 - hostReachability 还是 netReachability?

c++ - OpenCV - 混淆不同功能的位深度要求

iphone - 关于数据驱动的 iPhone 应用程序的建议和技巧

ios - 这是从标签获取文本并与 iOS 中的字符串连接的标准方法吗?