2011-12-31 108 views
7

我想在OpenGL2.0中的四邊形繪製紋理。到目前爲止,我已經得到了四邊形顯示和一切,但紋理不存在 - 四邊形都是黑色的。Android OpenGL2.0顯示黑色紋理

我的主要懷疑的是,我不是正確映射貼圖 - 我的紋理是2不國,也不是方 - 它們的寬度是在該領域mWidth及其mRowHeight高度。

四邊形繪製在一個垂直列表中,用一個平移矩陣完成。

我會非常感謝,如果任何人都可以過去這個事業,我絕望!

下面是相關的代碼:

初始化緩衝區:

void initBuffers() { 
     float r = (float) mRowHeight/(mHeight/2f); 
     ByteBuffer bb; 

     float[] bounds = { // X Y Z 
     /* 0 - TL */-1f, 1f, 0f, 
     /* 1 - BL */-1f, 1 - r, 0f, 
     /* 2 - BR */ 1f, 1 - r, 0f, 
     /* 3 - TR */ 1f, 1f, 0f }; 
     bb = ByteBuffer.allocateDirect(bounds.length * 4); 
     bb.order(ByteOrder.nativeOrder()); 
     mVertBuffer = bb.asFloatBuffer(); 
     mVertBuffer.put(bounds).position(0); 

     short[] indices = { 0, 1, 2, 0, 2, 3 }; 
     bb = ByteBuffer.allocateDirect(indices.length * 2); 
     bb.order(ByteOrder.nativeOrder()); 
     mIndBuffer = bb.asShortBuffer(); 
     mIndBuffer.put(indices).position(0); 

     float[] texture = { 
       /* 0 - BL */-1f, 1f, 
       /* 1 - TL */-1f, 1 - r, 
       /* 2 - BR */1f, 1 - r, 
       /* 3 - TR */1f, 1f }; 
     bb = ByteBuffer.allocateDirect(texture.length * 4); 
     bb.order(ByteOrder.nativeOrder()); 
     mTexBuffer = bb.asFloatBuffer(); 
     mTexBuffer.put(texture).position(0); 

    } 

繪製框架:

@Override 
    public void drawFrame() { 
     long startTime = System.currentTimeMillis(); 
     if (!mLayoutComplete) { 
      return; 
     } 
     final float halfw = mHeight/2f; 
     final int rowHeight = mRowHeight; 
     final float r = (float) rowHeight/halfw; 

     int i = mFirstRow; 

     final float initial = (float) ((i * rowHeight) - mScroll)/halfw; 

     Matrix.setIdentityM(mTMatrix, 0); 
     Matrix.translateM(mTMatrix, 0, 0, -initial, 0); 

     GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, 
       false, 0, mVertBuffer); 
     GLES20.glEnableVertexAttribArray(maPositionHandle); 

     final int l = mLastRow; 
     for (; i <= l; i++) { 

      ThumbRow thr = mCache.get(i); 
      if (thr != null) { 
       GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 
       if (thr.mDirty) { 
        thr.loadTexture(null, null); 
        thr.mDirty = false; 
       } else { 
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, thr.mRow + 1); 
       } 
       GLES20.glUniform1i(msTextureHandle, 0); 

       GLES20.glVertexAttribPointer(maTextureHandle, 2, 
         GLES20.GL_FLOAT, false, 0, mTexBuffer); 
       GLES20.glEnableVertexAttribArray(maTextureHandle); 

       GLES20.glUniformMatrix4fv(muTMatrixHandle, 1, false, 
         mTMatrix, 0); 
       GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, 
         GLES20.GL_UNSIGNED_SHORT, mIndBuffer); 
       Log.i(TAG, GLES20.glGetProgramInfoLog(mProgram)); 
      } 

      Matrix.translateM(mTMatrix, 0, 0, -r, 0); // Shift drawing 
                 // window to next 
                 // row. 
     } 

     GLES20.glDisableVertexAttribArray(maPositionHandle); 
     GLES20.glDisableVertexAttribArray(maTextureHandle); 

     Log.d(TAG, "onDrawFrame(): " 
       + (System.currentTimeMillis() - startTime)); 
    } 

載入紋理:

 public void loadTexture(GL10 gl, Context c) { 
      GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mRow + 1); 

      // Create Nearest Filtered Texture 
      GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, 
        GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); 
      GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, 
        GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); 

      // Different possible texture parameters, e.g. 
      // GLES20.GL_CLAMP_TO_EDGE 
      GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, 
        GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT); 
      GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, 
        GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT); 

      Bitmap bitmap = mBitmap; 
      if (bitmap == null) { 
       bitmap = mEmptyBitmap; 
      } 
      GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); 
     } 

頂點着色器:

uniform mat4 uTMatrix; 
uniform mat4 uMVPMatrix; 
attribute vec4 aPosition; 
attribute vec2 aTextureCoord; 
varying vec2 vTextureCoord; 

void main() { 
    gl_Position = uMVPMatrix * uTMatrix * aPosition; 
    vTextureCoord = aTextureCoord; 
} 

片段着色器:

precision mediump float; 
varying vec2 vTextureCoord; 
uniform sampler2D sTexture; 
void main() { 
    gl_FragColor = texture2D(sTexture, vTextureCoord); 
} 

任何幫助將非常感激。

+0

一旦調用''glBindTexture(..)''''mRow + 1'是什麼例如?如果它是一些內部變量,則應將其更改爲從''glGenTextures(..)''得到的紋理名稱。基本上,如果您僅使用一個紋理(並僅更新其內容),請始終使用該紋理名稱。 – harism 2011-12-31 15:52:24

+0

mRow是正在繪製的當前四邊形的索引 - 四邊形的紋理由它的mRow確定。編輯:從我的理解可以使用我自己的紋理名稱,只要他們是獨特的,我記得他們 – saarraz1 2011-12-31 15:54:41

+0

沒有。你必須使用glGenTextures(..)分配紋理名稱,你不能只是想出自己的。在你的情況下,你應該分配ROW_COUNT紋理名稱並使用glBindTexture(..,TEXTURE_NAMES [mRowIdx])。但是,如果ROW_COUNT非常高,最好將位圖重新加載到每個行的一個紋理中,以避免不必要的內存使用。 – harism 2011-12-31 16:11:14

回答

20

這是一個很常見的OpenGL ES 2.0紋理問題,這在過去給我造成了很多頭痛的問題。

在OpenGL ES 2.0中,在2個紋理無功率的情況下,換行模式只能是GL_CLAMP_TO_EDGE。

有限制,以及對可以使用其可僅GL_NEAREST或GL_LINEAR(換句話說沒有紋理映射)

在簡單的話,檢查你loadtexture功能,這2行代碼從改變濾波器:

GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, 
        GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT); 
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, 
        GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT); 

GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, 
        GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); 
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, 
        GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); 

我希望這個解決這個問題,讓我知道:)

Maurizio Benedetti

+0

OMG IT WORKS !!我不能夠感謝你!我幾乎放棄了使用OGL,然後你出現了。再次感謝。 – saarraz1 2012-01-06 12:28:16

+0

哇,很高興看到這一點。祝您有個美好的一天,祝您的項目順利。 – 2012-01-06 12:37:41

+0

Tx。也幫助了我。猜讀規格是必須:) – 2012-09-29 23:44:28