2012-08-25 73 views
11

我遇到了Android模擬器上的紋理損壞問題(它在大多數Android設備上運行良好)。Android opengl紋理損壞

Android 4.1 reference rendering

上面的圖片是運行Android 4.1果凍豆仿真器產生的參考渲染,一切看起來都理所應當。

Android 1.6

第二畫面爲在仿真器捕獲的運行Android 1.6。需要注意的一些禁用的工具欄按鈕的腐敗(它們呈現的色彩1F,1F,1F,0.5F)

Android 1.6

第三畫面在同一個仿真器捕獲。不同之處在於現在得分顯示在右上角。 Score是一個位圖字體,它的紋理是一個alpha蒙版。在比分之後呈現的所有東西都鬆動了它的質感。請注意,以前的屏幕截圖還包含以相同方式呈現的位圖字體(但使用不同的紋理)。

在其中一個三星設備上出現類似的問題(我不記得該型號)。渲染地面紋理時,渲染後的所有內容都會丟失紋理。當我或者a)沒有綁定紋理時,問題並沒有表現出來b)綁定了紋理,但沒有使用三角形c)重新創建了png資產。

OpenGL設置:

gl.glDisable(GL10.GL_LIGHTING); 
gl.glDisable(GL10.GL_CULL_FACE); 
gl.glDisable(GL10.GL_DEPTH_TEST); 
gl.glDisable(GL10.GL_DITHER); 
gl.glDepthMask(false); 
gl.glEnable(GL10.GL_TEXTURE_2D); 
gl.glBlendFunc(GL10.GL_ONE,GL10.GL_ONE_MINUS_SRC_ALPHA); 
gl.glShadeModel(GL10.GL_FLAT); 
gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_MODULATE); 

如何紋理加載:

public void doGLLoading(Engine renderer) { 
     GL10 gl=renderer.getGl(); 
     int[] ids=new int[1]; 
     gl.glGenTextures(1, ids,0); 
     id=ids[0]; 
     gl.glBindTexture(GL10.GL_TEXTURE_2D, id); 
     Log.d("SpriteDraw", String.format("Texture %s has format %s",getPath(),bitmap.getConfig().toString())); 
     buildMipmap(gl, bitmap); 
     gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER, minFilter); 
     gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER, magFilter); 
     gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_WRAP_S, textureWrapS); 
     gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_WRAP_T, textureWrapT); 
    } 
private void buildMipmap(GL10 gl, Bitmap bitmap) { 
    int level = 0; 
    int height = bitmap.getHeight(); 
    int width = bitmap.getWidth(); 

    while (height >= 1 || width >= 1) { 
     // First of all, generate the texture from our bitmap and set it to 
     // the according level 
        //TextureUtils.texImage2D(gl, GL10.GL_TEXTURE_2D, level, -1, bitmap, -1, 0); 
     GLUtils.texImage2D(GL10.GL_TEXTURE_2D, level, bitmap, 0); 
     if (height == 1 || width == 1) { 
      break; 
     } 
     // Increase the mipmap level 
     level++; 
     height /= 2; 
     width /= 2; 
     Bitmap bitmap2 = Bitmap.createScaledBitmap(bitmap, width, height, 
       true); 

     // Clean up 
     bitmap.recycle(); 
     bitmap = bitmap2; 
    } 
} 

注:字體使用gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);GL10.glDrawArrays渲染。腐敗不僅會影響1.6模擬器,還會影響android的2.x系列,儘管它不如突出(alpha掩碼仍然渲染不正確)。所有資產都正確加載爲兩個位圖的權力。

+0

紋理尺寸是兩個冪嗎?你用superPng還是Png?正常的png文件不能正確保留alpha作爲掩碼。但superPng可以保留它。一個用於photoshop的插件可以導出爲superPng – Behnam

+0

是的,它們都是Power of Two(在帖子末尾提到)。位圖存儲爲灰度位圖,由android加載爲ARGB_8888,並通過我的代碼轉換爲alpha蒙版。 – rkapl

回答

2
  1. 我建議使用32位紋理,不灰度,而不是「alphamasks」(那是什麼?)
  2. 檢查紋理的大小,它不應該超過最大尺寸(glGetInteger(GL_MAX_TEXTURE_SIZE)。也使舒爾你紋理的權力是2.是的,你提到他們之前,但如果他們在可伸縮資產(drawable_x_dpi文件夾),他們將被縮放android。爲了避免縮放,把它們放在「原始」文件夾。
  3. 只爲請嘗試禁用所有過濾功能,包括mipmap - 將GL_TEXTURE_WRAP_S和GL_TEXTURE_WRAP_T設置爲GL_NEAREST
+0

Alpha蒙版是一種只有alpha通道的紋理。他們應該工作好。所有的紋理都真正加載爲兩個位圖的強大功能(它們使用'InputStream'加載,而不是資源ID,因此它們不會縮放)。至於過濾,我想你的意思是'GL_TEXTURE_MIN_FILTER'。將其設置爲「GL_NEAREST」不能解決問題。 – rkapl

+0

是的,我的意思是GL_TEXTURE_MIN_FILTER。 接下來你可以嘗試的是用紋理工作正常的紋理文件。所以你會知道問題是在加載紋理還是在你使用它們的方式。 – Dave