将IOSurface绘制到OpenGL上下文

时间:2014-02-27 18:43:09

标签: 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.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);

1 个答案:

答案 0 :(得分:1)

通过使用OpenGL纹理包裹IOSurface并将纹理绘制到屏幕上,可以获得解决方案。这假定与[CIContext render:toIOSurface:bounds:colorSpace:]类似的API,但是垂直翻转的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);

如果您愿意,可以将所有这些操作组合到3D查找表中。这实际上是在许多OS X框架和应用程序的颜色管理中发生的事情。

参考文献:

  1. Apple TextureUpload sample code

  2. Draw IOSurfaces to another IOSurface

  3. OpenGL Options for Advanced Color Management