2012-01-02 37 views
0

我正在爲Android(here)編寫一個開源遊戲引擎,並且在渲染帶紋理的三角形時遇到了一些問題。 OpenGL不會報告任何錯誤,但不會呈現。我可以渲染頂點顏色的三角形,所以我知道我的VBO和着色器加載函數可以工作。我有一種感覺,我只是缺少一些細節。下面是相關的代碼:在Android OpenGL ES 2.0中渲染紋理原語 - 我在做什麼錯?

// loaded is a boolean field 
if(!loaded){ 
    int[] tex = { 0 }; 
    GLES20.glGenTextures(1, tex, 0); 
    int handle = tex[0]; 

    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, handle); 
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, 
      GLES20.GL_CLAMP_TO_EDGE); 
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, 
      GLES20.GL_CLAMP_TO_EDGE); 
    if (useMipmaps) { 
     GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, 
       GLES20.GL_TEXTURE_MIN_FILTER, 
       GLES20.GL_LINEAR_MIPMAP_NEAREST); 
    } else { 
     GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, 
       GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); 
    } 
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, 
      GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); 

    // bmp is an android.graphics.Bitmap object 
    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bmp, 0); 
    if (useMipmaps) 
     GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_2D); 
    loaded = true; 
} 

GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + glTexture); 
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, handle); 
GLES20.glUniform1i(GLES20.glGetUniformLocation(programHandle, 
       "s_baseMap"), glTexture); 

GLES20.glDrawElements(GLES20.GL_TRIANGLES, 
        indexCount, GLES20.GL_UNSIGNED_SHORT, 0); 

頂點着色器:

precision mediump float; 

uniform mat4 u_viewProj; 
uniform vec3 u_lightColor; 

attribute mat4 a_model; 
attribute vec4 a_pos; 
attribute vec2 a_mtl; // Stores UV coords 

varying vec2 v_tc; 

void main() { 
    gl_Position = (u_viewProj * a_model) * a_pos; 
    v_tc = a_mtl; 
} 

而片段着色器:

precision mediump float; 

varying vec2 v_tc; 

uniform sampler2D s_baseMap; 

void main() { 
    vec4 black = vec4(0.0, 0.0, 0.0, 1.0); 
    gl_FragColor = black + texture2D(s_baseMap, v_tc); 
} 
+0

你有沒有使用過'glEnable(GLES20.GL_TEXTURE_2D);'? – 2012-01-03 12:36:02

+0

'glEnable(GLES20.GL_TEXTURE_2D);'根據[規範](http://www.khronos.org/opengles/sdk/docs/man/xhtml/glEnable.xml)導致INVALID_ENUM錯誤。我很確定這在GLES 2.0中是沒有必要的。 – drmercer 2012-01-03 17:22:58

+0

檢查「glGenTextures」實際產生的值。如果它在10萬年內給你一些隨機數,那麼你可能不想使用它,並有自己的系統來生成唯一的紋理ID。當我將我的應用程序從opengl-ES 1.1轉換爲openGL-es 2.0時,出現了這個問題 – 2012-01-03 19:24:28

回答

0

我解決它。問題不在紋理或碎片着色器中。這是模型矩陣屬性加載到頂點着色器的方式。我的矩陣加載代碼是這樣的:

GLES20.glDisableVertexAttribArray(a_model); 
GLES20.glVertexAttrib4fv(a_model, matrix, matrixOffset * 16); 
GLES20.glVertexAttrib4fv(a_model, matrix, (matrixOffset * 16) + 4); 
GLES20.glVertexAttrib4fv(a_model, matrix, (matrixOffset * 16) + 8); 
GLES20.glVertexAttrib4fv(a_model, matrix, (matrixOffset * 16) + 12); 

是啊,這是的,我在my second edit去掉了「不必要的」代碼的一部分。 * facepalm *

原來,a_model是模型矩陣的第一行的第一行的位置。因爲我只是將數據加載到第一行,所以矩陣的最後三行是空的,所以頂點位置被搞亂了,三角形變得退化了。我解決了這個問題,加入1至a_model爲每個連續行,像這樣:

GLES20.glDisableVertexAttribArray(a_model); 
GLES20.glDisableVertexAttribArray(a_model + 1); 
GLES20.glDisableVertexAttribArray(a_model + 2); 
GLES20.glDisableVertexAttribArray(a_model + 3); 
GLES20.glVertexAttrib4fv(a_model, matrix, matrixIndex * 16); 
GLES20.glVertexAttrib4fv(a_model + 1, matrix, (matrixIndex * 16) + 4); 
GLES20.glVertexAttrib4fv(a_model + 2, matrix, (matrixIndex * 16) + 8); 
GLES20.glVertexAttrib4fv(a_model + 3, matrix, (matrixIndex * 16) + 12); 

現在,它完美的作品!