2015-01-05 75 views
0

我想在我的android應用程序上使用壓縮紋理。加載紋理時出現問題,紋理似乎在對象的右側「截斷」。閱讀ATI壓縮紋理的問題

對於壓縮紋理,我使用ATI的「TheCompressonator」。 測試我使用的Nexus 5.

我懷疑問題是與我的「計算」的紋理大小,但無法找到任何refenreces /規範這種壓縮格式。

有誰知道如何正確閱讀這種文件格式?

這裏是承上啓下截圖:

Nexus 5, blowfish right side is cut off

這裏是應該已經看過(不介意的黑色物體的紋理,對於圖像缺失) Samsung tab 2, this is how blowfish should look

這裏我的代碼片段。

final int[] textureObjectIds = new int[1]; 

glGenTextures(1, textureObjectIds, 0); 

if(textureObjectIds[0] == 0){ 
    logTextureHelper(Log.WARN, "Could not generate a new OpenGL texture object"); 
    return 0; 
} 

final InputStream bitmap = context.getResources().openRawResource(resourceId); 
byte[] buffer; 
ByteBuffer bf; 

try { 
    buffer = new byte[bitmap.available()]; 
    bitmap.read(buffer); 

    int offset = 0; // 64 bit = header, 15 bit = metadata 
    bf = ByteBuffer.wrap(buffer, offset, buffer.length-offset); 
    bf.order(ByteOrder.LITTLE_ENDIAN); 

    int height = bf.getInt(16); 
    int width = bf.getInt(12); 


    int size = ((height + 3)/4) * ((width + 3)/4) * 16; 
    Log.d("TextureHelper","Buffer size: "+width+" "+height+" "+size); 

    glBindTexture(GL_TEXTURE_2D, textureObjectIds[0]); 

    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); 
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); 
    glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); 
    glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); 


    GLES20.glCompressedTexImage2D(GL_TEXTURE_2D, 0,ATC_RGBA_EXPLICIT_ALPHA_AMD, width, height, 0, size, bf); 
    Log.d("TextureHelper","Buffer size: "+bf.capacity()+" : "+buffer.length+" error:"+GLES20.glGetError()); 

    glBindTexture(GL_TEXTURE_2D, 0); //unbind texture 

} catch (IOException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 

return textureObjectIds[0]; 

編輯:解

buffer = new byte[bitmap.available()]; 
      bitmap.read(buffer); 

      int offset = 128; // 64 bit = header, 15 bit = metadata 
      bf = ByteBuffer.wrap(buffer, offset, buffer.length-offset); 
      bf.order(ByteOrder.LITTLE_ENDIAN); 

      int height = bf.getInt(16); 
      int width = bf.getInt(12); 


      int size = ((height + 3)/4) * ((width + 3)/4) * 16; 
      Log.d("TextureHelper","Buffer size: "+width+" "+height+" "+size); 


      bf.compact();///////SOLUTION! 
      bf.position(0); 


      glBindTexture(GL_TEXTURE_2D, textureObjectIds[0]); 

      GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); 
      GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); 
      glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); 
      glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); 


      GLES20.glCompressedTexImage2D(GL_TEXTURE_2D, 0,ATC_RGBA_EXPLICIT_ALPHA_AMD, width, height, 0, size, bf); 
      Log.d("TextureHelper","Buffer size: "+bf.capacity()+" : "+buffer.length+" error:"+GLES20.glGetError()); 

      glBindTexture(GL_TEXTURE_2D, 0); //unbind texture 

注意:您需要在0位置有數據,如果你只是偏移位置(128),它會拋出空指針異常。

回答

1

您的大小計算看起來正確,但是您將頭部上傳爲圖像數據。 之後,您從頭文件中提取寬度和高度,將字節緩衝區偏移適當的數量以跳過標題並開始指向圖像數據。

有幾種方法可以做到這一點,但類似的東西可能會作爲一個例子(這可以優化,以消除第二個字節緩衝區)。另外,我不確定你使用的是什麼紋理格式,但我們假設你的標題長度爲124字節。

// assumption that buffer[] is the fully loaded contents of the file 
byte[] buffer = ... // load entire file from input stream 

// read the header 
ByteBuffer bfHeader = ByteBuffer.wrap(buffer); 
bfHeader.order(ByteOrder.LITTLE_ENDIAN); 

int height = bfHeader.getInt(16); 
int width = bfHeader.getInt(12); 

// offset to image data 
int headerSize = 124; // (replace with correct header size) 
ByteBuffer bfData = ByteBuffer.wrap(buffer, headerSize, buffer.length-headerSize); 
bfData.order(ByteOrder.LITTLE_ENDIAN); 

// load image data 
int size = ((height + 3)/4) * ((width + 3)/4) * 16; 
glBindTexture(GL_TEXTURE_2D, textureObjectIds[0]); 
GLES20.glCompressedTexImage2D(GL_TEXTURE_2D, 0,ATC_RGBA_EXPLICIT_ALPHA_AMD, width, height, 0, size, bfData);