2014-02-13 48 views
1

我有一個OpenGL紋理,上面有UV貼圖。我已經閱讀了關於使用alpha通道來存儲其他值,這可以節省從某處加載額外映射的需求。例如,您可以在alpha中存儲高光信息(發光度)或發射貼圖,因爲您只需要一個浮點並且不使用alpha。如何在開放式gl紋理的alpha中編碼發射或鏡面反射信息

所以我試了一下。編寫着色器不是問題。我已經完成了所有這一部分。問題是讓所有4個通道進入紋理,就像我想要的那樣。

我有PSD中的所有地圖,我把基本地圖放在rgb和放射圖中。但是當你保存爲png時,alpha不會保存(如果將它添加爲新頻道),或者通過將透明度預乘到rgb(如果將地圖應用爲掩碼)來破壞rgb。

顯然PNG文件支持透明,但本身不支持alpha通道。所以似乎沒有辦法控制所有4個通道。

但我讀過關於這樣做。那麼我可以從PSD中將它保存到我可以在iPhone中使用圖像加載器加載的格式是什麼?

NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:type]; 
NSData *texData = [[NSData alloc] initWithContentsOfFile:path]; 
UIImage *image = [[UIImage alloc] initWithData:texData]; 

此方法是否接受其他文件格式?像TIFF那樣可以讓我控制所有4個頻道?

我可以使用紋理工具來製作一個PVR ..但是從文檔看,它似乎也採用PNG作爲輸入。

編輯:

首先要明確這是在iPhone上。

這可能是psd的錯。就像我說的,在我可以找到的我的psd版本(cc 14.2 mac)中有兩種方法來設置文檔。一種是手動添加一個新頻道並將地圖粘貼在那裏。它顯示爲紅色疊加層。第二個是添加一個蒙版,選項點擊它並將alpha粘貼在那裏。在這種情況下,它將alpa顯示爲透明度,棋盤在alpha零區。當我保存爲PNG的alpha選項灰色。

當我將png加載回psd時,它似乎是預乘。我無法回到我在Photoshop中的完整RGB數據。

是否有一個不同的工具,我可以用它來合併兩個地圖成一個PNG,將存儲它的PNG-32?

TIFF不起作用,因爲它不存儲alpha。也許我在想TGA。

我也注意到這在我的裝載機...

GLuint width = CGImageGetWidth(image.CGImage); 
    GLuint height = CGImageGetHeight(image.CGImage); 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
    void *imageData = malloc(height * width * 4); 
    CGContextRef thisContext = CGBitmapContextCreate(imageData, width, height, 8, 4 * width, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); 

    if (flipImage) 
    { 
     CGContextTranslateCTM (thisContext, 0, height); 
     CGContextScaleCTM (thisContext, 1.0, -1.0); 
    } 

    CGColorSpaceRelease(colorSpace); 
    CGContextClearRect(thisContext, CGRectMake(0, 0, width, height)); 
    CGContextDrawImage(thisContext, CGRectMake(0, 0, width, height), image.CGImage); 

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData); 

    glBindTexture(GL_TEXTURE_2D, textureInfo[texIndex].texture); 

當我創建上下文選項kCGImageAlphaPremultipliedLast

也許我需要嘗試glkit loader,但看起來我的png是預乘。

+0

PNG應該支持alpha通道,並且在很多情況下我一直在使用它。也許你有關於如何從UIImage(CGImage)中檢索原始數據的問題?甚至你如何從PSD導出你的PNG。 –

+0

我同意 - PNG可以存儲32位RGBA,並且'UIImage'可以加載它,所以這聽起來像是一個Photoshop問題。既然你問了,但是:是的,'UIImage'也支持TIFF。另外,如果您使用['GLKTextureLoader'](https://developer.apple.com/library/ios/documentation/GLkit/Reference/GLKTextureLoader_ClassRef),加載到OpenGL紋理中,您可以剪掉一些中間商並編寫更少的代碼/Reference/Reference.html)類。這支持所有這些格式,並且也支持alpha。 – rickster

+0

(實際上,有可能你正在讀取你的圖像,並將其加載到你的紋理錯誤,所以'GLKTextureLoader'可能也會幫助保持你的代碼的一部分不太容易出錯。) – rickster

回答

0

可以使用alpha通道創建PNG,但是如果沒有預乘功能,您將無法使用內置iOS API讀取該PNG圖像。核心問題是CoreGraphics僅出於性能原因支持預乘alpha。您還必須小心禁用Xcode對附加到項目文件的PNG的優化,因爲它在編譯時進行了預乘。你可以做的是在關閉Xcode PNG處理之後,在你自己的libpng副本中編譯和鏈接,然後直接用C級別的libpng讀取文件。但是,老實說這是浪費時間。只需保存一個圖像的RGB值,另一個圖像的灰度值爲alpha值,即0-255灰度值。你可以讓這些灰度值意味着你想要的任何東西,而且你不必擔心前景會讓事情變得糟糕。你的opengl代碼只需要從多個紋理讀取,而不是一個大問題。