2010-07-08 129 views
3

我將紋理加載到具有各種Alpha值的RGBA格式的內存中。在OpenGL中繪製紋理,同時忽略Alpha通道

的圖像加載爲這樣:

GLuint texture = 0; 
glGenTextures(1, &texture); 
glBindTexture(GL_TEXTURE_2D, texture); 
self.texNum = texture; 

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR); 

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, self.imageWidth, self.imageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, [self.imageData bytes]); 

我想知道,這樣的圖像中的alpha通道被視爲全1和紋理繪製像一個RGB圖像,我可以怎樣得出這個紋理。

考慮基本圖像:

http://www.ldeo.columbia.edu/~jcoplan/alpha/base.png

此圖像是級數從0到255的α,並且具有在整個255,0,0

的RGB值。然而,如果我與繪製它混合禁用我得到那個看起來像一個形象: www.ldeo.columbia.edu/~jcoplan/alpha/no_alpha.png

當我真正想要的是,像這樣的圖像: www.ldeo.columbia.edu/~jcoplan/alpha/correct.png

我真的很感謝一些指針,讓它完全忽略alpha通道。請注意,我不能只是將圖像作爲RGB加載,因爲我確實需要其他位置的Alpha通道。

編輯:我試圖用GL_COMBINE解決我的問題如此:

glColorf(1,1,1,1); 
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); 

glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE); 
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE); 
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); 

glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); 
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PRIMARY_COLOR); 
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); 
[self drawTexture]; 

但仍沒有運氣,它吸引黑變紅仍。

+0

這兩個解決方案建議看起來是正確的。查看調試器內存視圖中[self.imageData bytes]返回的指針。你期望的價值是什麼?你得到的結果表明他們不會是... – 2010-07-08 17:34:56

+1

你使用預乘alpha嗎?如果是這樣,那麼淡入黑色就是紋理的RGB值。你的glBlendFunc是什麼? – Alan 2010-07-08 17:38:47

+0

@Alan&brone 看完它們的字節後,這是正確的,圖像正在通過XCode優化預倍增,並且字節內部並非我所期望的。 所以答案是我沒有正確加載圖像。 謝謝! – jcoplan 2010-07-08 18:04:19

回答

3

我已經加載到內存中的紋理是RGBA格式的各種alpha值

glDisable( GL_BLEND)

但是,如果我繪製它與禁用混合I GE牛逼,看起來像一個形象:www.ldeo.columbia.edu/~jcoplan/alpha/no_alpha.png

這是因爲在你的源圖像中的所有透明像素爲黑色。這是你的紋理/圖像的一個問題,或者可能與加載函數有關,但它不是OpenGL問題。

你也許可以嘗試使用glTexEnv(GL_COMBINE ...)(即混合紋理顏色與基於Alpha通道的基礎顏色),但由於我沒有這樣做過,我不完全確定,並且不能給你確切的操作數。這是可能的Direct3D9(使用D3DTOP_MODULATEALPHA_ADDCOLOR),所以很可能有辦法在opengl中做到這一點。

+0

我不完全明白你的意思是我所有的透明像素是黑色的。 我試過一個GL_COMBINE,但沒有運氣,它仍然畫黑到紅色...... – jcoplan 2010-07-08 17:25:47

+0

@jcoplan:透明只是另一個通道。如果像素具有R255,G0,B0,A255,則它是不透明的紅色。如果它有R255,G0,B0,A0,它是完全透明的紅色。如果它有R0,G0,B0,A0,那麼它是完全透明的黑色。在紋理顏色中,漸變是從transaprent BLACK(R0,G0,B0,A0)到非透明RED(R255G0B0A255)線性插值的漸變。這就是爲什麼你看到黑色部分。如果你想要另一個結果,你需要另一張圖片。不過,我建議使用兩個不同的圖像。當漸變出現在A和RGB中時,在白色背景下可能看起來不太好。 – SigTerm 2010-07-08 17:51:19

+0

你是正確的,我沒有正確加載圖像。我正在遭受驚人的alpha前乘法。 – jcoplan 2010-07-08 18:04:58

1

你不應該禁用勾兌但適當的參數使用glBlendFunc

glBlendFunc(GL_ONE, GL_ZERO); 
+0

我想嘗試,但圖像仍然是這樣看起來像這樣: www.ldeo.columbia.edu/~jcoplan/alpha/no_alpha.png – jcoplan 2010-07-08 16:39:54

0

或者你可以告訴OpenGL使用

glPixelStorei(GL_UNPACK_ALIGNMENT, 4) 

你叫glTexImage2D設置爲GL_RGB格式之前只上傳圖片的RGB通道。它會導致它跳過每個像素的第四個字節,即alpha通道。

+0

GL_UNPACK_ALIGNMENT影響*行*的對齊,而不是單個像素。見http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml – 2013-07-16 16:27:30

0

我有一個類似的問題,並發現這是因爲iOS圖像加載正在對RBG值進行預乘(如其他一些答案和評論中所述)。我很想知道是否有一種禁用前乘法的方法,但同時我使用從this threadthis thread派生的代碼進行「不預乘」。

// un pre-multiply 
    uint8_t *imageBytes = (uint8_t *)imageData ; 
    int byteCount = width*height*4 ; 
    for (int i=0; i < byteCount; i+= 4) { 
     uint8_t a = imageBytes[i+3] ; 
     if (a!=255 && a!=0){ 
      float alphaFactor = 255.0/a ; 
      imageBytes[i] *= alphaFactor ; 
      imageBytes[i+1] *= alphaFactor ; 
      imageBytes[i+2] *= alphaFactor ; 
     } 
    }