在OpenGL上下文中绘制IOSurface

在OpenGL上下文中绘制IOSurface,opengl,gpu,osx-mountain-lion,osx-mavericks,core-image,Opengl,Gpu,Osx Mountain Lion,Osx Mavericks,Core Image,我有一个OpenGL上下文,我使用OpenGL成功地在其上绘制 我需要在此上下文中绘制一个IOSurface的特定矩形 在10.8上,最好的方法是什么 注: 我知道如何使用CoreImage在10.9上实现这一点(通过从IOSurface创建CIImage,并使用[CIContext drawImage:inRect:fromRect]进行渲染)。 但是,在10.8上,这对我来说不太合适(图像的每个原始图像都以不同的偏移量显示,并且图像沿对角线方向扭曲) 编辑:以下是适用于10.9但不适用于10

我有一个OpenGL上下文,我使用OpenGL成功地在其上绘制

我需要在此上下文中绘制一个IOSurface的特定矩形

在10.8上,最好的方法是什么

注: 我知道如何使用CoreImage在10.9上实现这一点(通过从IOSurface创建CIImage,并使用
[CIContext drawImage:inRect:fromRect]
进行渲染)。 但是,在10.8上,这对我来说不太合适(图像的每个原始图像都以不同的偏移量显示,并且图像沿对角线方向扭曲)

编辑:以下是适用于10.9但不适用于10.8的代码:

CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);

CIImage* ciImage = [[CIImage alloc] initWithIOSurface:surface plane:0 format:kCVPixelFormatType_32BGRA options:@{kCIImageColorSpace : (__bridge id)colorSpace}];
NSRect flippedFromRect = fromRect;
// Flip rect before passing to CoreImage:
{
  flippedFromRect.origin.y = IOSurfaceGetHeight(surface) - fromRect.origin.y - fromRect.size.height;
}
[ciContext drawImage:ciImage inRect:inRect fromRect:flippedFromRect];


CGColorSpaceRelease(colorSpace);

以下是使用OpenGL纹理包装iSurface并将纹理绘制到屏幕上的解决方案。这假设API与
[CIContext render:toIOSurface:bounds:colorSpace:][/code>类似,但它是一个垂直翻转的OpenGL坐标系

  // Draw surface on OpenGL context
  {
    // Enable the rectangle texture extenstion
    glEnable(GL_TEXTURE_RECTANGLE_EXT);
    
    // 1. Create a texture from the IOSurface
    GLuint name;
    {
      CGLContextObj cgl_ctx = ...

      glGenTextures(1, &name);
      GLsizei surface_w = (GLsizei)IOSurfaceGetWidth(surface);
      GLsizei surface_h = (GLsizei)IOSurfaceGetHeight(surface);
      
      glBindTexture(GL_TEXTURE_RECTANGLE_EXT, name);
      
      CGLError cglError =
      CGLTexImageIOSurface2D(cgl_ctx, GL_TEXTURE_RECTANGLE_EXT, GL_RGBA, surface_w, surface_h, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, surface, 0);
      
      glBindTexture(GL_TEXTURE_RECTANGLE_EXT, 0);          
    }
    
    // 2. Draw the texture to the current OpenGL context
    {
      glBindTexture(GL_TEXTURE_RECTANGLE_EXT, name);
      glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
      glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
      glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
      
      glBegin(GL_QUADS);
      
      glColor4f(0.f, 0.f, 1.0f, 1.0f);
      glTexCoord2f(   (float)NSMinX(fromRect),    (float)(NSMinY(fromRect)));
      glVertex2f(     (float)NSMinX(inRect),      (float)(NSMinY(inRect)));
      
      glTexCoord2f(   (float)NSMaxX(fromRect),    (float)NSMinY(fromRect));
      glVertex2f(     (float)NSMaxX(inRect),      (float)NSMinY(inRect));

      glTexCoord2f(   (float)NSMaxX(fromRect),    (float)NSMaxY(fromRect));
      glVertex2f(     (float)NSMaxX(inRect),      (float)NSMaxY(inRect));
      
      glTexCoord2f(   (float)NSMinX(fromRect),    (float)NSMaxY(fromRect));
      glVertex2f(     (float)NSMinX(inRect),      (float)NSMaxY(inRect));
      
      glEnd();
      
      glBindTexture(GL_TEXTURE_RECTANGLE_EXT, 0);
    }
    glDeleteTextures(1, &name);
  }
如果需要绘制显示器的颜色配置文件,可以显式调用ColorSync并将其传递给源配置文件和目标配置文件。它将返回给您一个执行颜色校正的“配方”。该配方实际上具有线性化、颜色转换(3x3转换矩阵)和伽马

FragmentInfo = ColorSyncTransformCopyProperty (transform, kColorSyncTransformFullConversionData, NULL);
如果愿意,可以将所有这些操作合并到三维查找表中。许多OSX框架和应用程序的颜色管理实际上就是这样

参考资料:


  • 对角扭曲?你不是偶然使用RGB图像的吧?这让我想起了很多与数据对齐有关的问题。。。通常,像素必须在32位边界上对齐,24位图像格式是一堆烟雾和镜像,驱动程序会尽力隐藏它们。如果在读取/上传像素数据时,像素打包/解包状态不正确,那么这种幕后魔术就不再是魔术了。这也适用于某些图像文件格式,例如DIB(
    .bmp
    )-每条扫描线都与32位(
    DWORD
    )边界对齐。这很有意义,但我使用“BGRA”创建iSurface,我找不到对齐/像素格式有什么问题,或者为什么它在10.8上不起作用。这就是为什么我尝试使用较低级别的API。我的NSOpenGLPixelFormat属性包括{NSOpenGLPFAColorSize,32,…},它可以在10.9上找到。我使用CIImage将JPG渲染到IOSurface,然后在OpenCL中将其处理到另一个曲面,这就是我当前使用Core Image渲染的曲面。您可以显示用于在GL中绘制图像的代码吗?我不确定您是否正在使用Core Image为曲面提供OpenGL纹理句柄,或者您是否正在尝试使用像
    glTexImage2D(…)
    这样的东西上载图像数据,该东西添加了与之相关的像素传输状态/格式转换。是的,我将其添加到了结果中。我正在使用核心图像包装IOSurface,并在当前OpenGL上下文中绘制它。我不使用CGLTexImageIOSurface2D,但这可能是另一个不使用核心映像的解决方案。