2014-02-27 54 views
0

我有一個使用OpenGL成功繪製的OpenGL上下文。在OpenGL上下文中繪製一個IOSurface

我需要在此上下文中繪製一個IOSurface的特定矩形。

在10.8上做到這一點的最佳方法是什麼?

: 我知道如何使用CoreImage做到這一點的10.9(由createing從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); 
+0

斜失真?你不是偶然使用RGB圖像嗎?這讓我想起了很多與數據對齊的問題...通常像素必須在32位邊界上對齊,24位圖像格式是司機試圖最大程度地隱藏起來的一堆煙霧和鏡子。如果在讀取/上傳像素數據時沒有獲得正確的像素包/解包狀態,幕後的魔法就不再是魔法了。這也適用於某些圖像文件格式,例如DIB('.bmp') - 每條掃描線都對齊到32位(DWORD)邊界。 –

+0

具有很多意義,但我使用'BGRA'來創建IOSurface,並且我找不到對齊/像素格式錯誤,或者爲什麼它在10.8上無法正常工作。這就是爲什麼我試圖使用較低級別的API。 我的NSOpenGLPixelFormat attributs包括{NSOpenGLPFAColorSize,32,...},它在10.9上可以找到。我使用CIImage將JPG渲染到IOSurface,在OpenCL中將其處理到另一個表面,這是我當前使用Core Image呈現的表面。 –

+0

你可以顯示你用來在GL中繪製圖像的代碼嗎?我不確定是否使用Core Image爲表面提供OpenGL紋理句柄,或者如果您嘗試使用諸如'glTexImage2D(...)之類的東西上傳圖像數據...)'添加了與之相關的像素傳輸狀態/格式轉換。 –

回答

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