2010-10-13 312 views
5

我使用GLUtils.texImage2D, 成功地生成了我的紋理,但是當我使用生成的紋理時,我得到的問題是我的alpha:它們比想要的要暗。紋理中的GLUtils.texImage2D和Alpha問題

檢查了幾件事後,我終於得出了問題來自GLUtils.texImage2D(GL10.GL_TEXTURE_2D,level,bmp,0)的結論;我創建了第二個函數,它使用gl.glTexImage2D(GL10.GL_TEXTURE_2D,級別,GL10.GL_RGBA,寬度,高度,0,GL10.GL_RGBA,GL10.GL_UNSIGNED_BYTE,像素2);我創建了第二個函數。

但創建像素2是一個字節緩衝區,其中我必須在將位圖ARGB中的值更改爲紋理RGBA時重新複製字節的代價高昂。

有沒有人注意到?如果是的話你怎麼解決這個...

傑森


謝謝你的回答, 我已經使用

gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA); 

和我得到這個問題

我的問題是,由GLUtils生成的alpha不是紋理,它的顏色較暗。

區別就像在陽光下和陰影中看顏色(如果這使得任何感覺)。

我已經嘗試過gl.gltextimage2d但創建緩衝時間過長,除非有位圖轉換爲一個字節緩衝區,我不知道的工具...

回答

3

alpha通道是大量程序員可憐的虐待繼子女是我可以說...但上傳的作品相當有效的,如果你這樣做:

  • 估計你的最大的紋理(如1024×1024),並創建一個尺寸(1024 * 1024)的int數組,你在一些靜態變量存儲或其他地方,你可以訪問它,這樣你就不需要重新創建該數組(分配時間是寶貴這裏)

  • 然後做到這一點:

    bitmap.getPixels(pixels, 0, width, 0, 0, width, height); 
    gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGBA, width, height, 
        0, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, IntBuffer.wrap(pixels)); 
    

我很抱歉沒有發現了一個不同的解決方案......原來的問題是,GLUtils.texImage2D函數的實現者以某種方式錯誤地處理了Alpha通道,導致圖像顯示的大於黑色邊框時(雙線性濾鏡計算四個像素之間的顏色並且當具有透明alpha的像素的rgb值已經被破壞(像設置爲黑色)時,結果是,在形成的透明邊界上發生某種「顏色滲色」。十分難看。也許這樣做是爲了提高壓縮比,因爲PSD中alpha透明區域的RGB值包含很多垃圾,當消除時,壓縮算法會產生很大的改進空間)

編輯:可惜的是,這種方法只是正確地處理灰色圖像,因爲紅色和藍色通道在從位圖中提取像素時被交換。至少在MY設備上。我不知道如何正確,這是其他設備,但對我來說,這確實在這裏的伎倆:

for (int i=0;i<pixels.length;i+=1) { 
    int argb = pixels[i]; 
    pixels[i] = argb&0xff00ff00 | ((argb&0xff)<<16) | ((argb>>16)&0xff); 
} 
0

有一個問題在GLUtils中預乘alpha。我能提出的唯一解決方法是使用:

gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA) 

如果你需要其他的混合功能,你將不得不使用gl.glTexImage2D

5

GLUtils.texImage2D生成預乘alpha-texture。在這個生成的紋理中,所有像素都乘以alpha值,因此您不需要再次乘以alpha值。 讓我們試試吧

gl.glBlendFunc(GL10.GL_ONE,GL10.GL_ONE_MINUS_SRC_ALPHA);

1

的Android Bitmap存儲從PNG裝有預乘顏色的圖像。 GLUtils.texImage2D也使用由alpha預乘的顏色,所以你不能以這種方式獲得原始顏色。

爲了加載PNG圖像,而無需RGB渠道被預乘我使用第三方PNGDecoder和負載質地glTexImage2D。您可以通過PNGDecoder庫從這裏解碼PNG:http://twl.l33tlabs.org/#downloads

3

找到解決辦法here。正如其他人用預乘alpha所述的那樣。

在surfaceView構造

setEGLConfigChooser(8, 8, 8, 8, 0, 0); 
    getHolder().setFormat(PixelFormat.RGBA_8888); 

在View.Renderer onSurfaceCreated

gl.glEnable(GL10.GL_BLEND); 
    gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);