2012-03-31 61 views
3

我有一個打包的頂點緩衝區,其中包含位置座標以及格式爲{X,Y,Z,R,G,B,A}的頂點的顏色值。使用glVertexAttribPointer和glDrawElements從打包的頂點緩衝區中繪製

當我通過取出a_Color屬性並硬編碼gl_FragColor的vec4值來更改片段着色器時,我能夠使用硬編碼顏色正確顯示矩形,但我無法將顏色vec4屬性傳遞到片段中着色器(矩形將不會在該場景中顯示)。

使用glVertexAttribPointer(...)和glDrawElements(...)從OpenGL ES 2.0中的打包頂點緩衝區中繪製的正確方法是什麼?

見下面我的代碼:

public class GameRenderer implements Renderer { 
    public static final int POS_SZ = 3; 
    public static final int COL_SZ = 4; 
    public static final int FLOAT_SZ = 4; 
    public static final int SHORT_SZ = 2; 

    private FloatBuffer gridVB; 
    private ShortBuffer gridIndices; 
    int programCode, paPositionHandle, paColorHandle, puMVPMatrixHandle; 

    private final String vertexShaderCode = 
     "uniform mat4 u_MVPMatrix; \n" + 
     "attribute vec4 a_Position; \n" + 
     "void main(){    \n" + 
     " gl_Position = u_MVPMatrix * a_Position; \n" + 
     "} \n"; 

    private String fragmentShaderCode = 
     "precision mediump float; \n" + 
     "attribute vec4 a_Color; \n" + 
     "void main(){    \n" + 
     " gl_FragColor = a_Color; \n" + 
     "}       \n"; 

    public void staticGrid() { 
     float vertexArray[] = { 
      -0.75f, 0.75f, 0.0f,  // position 
      0.0f, 0.0f, 1.0f, 1.0f,  // colour 
      0.75f, 0.75f, 0.0f, 
      0.0f, 0.0f, 1.0f, 1.0f, 
      0.75f, -0.75f, 0.0f, 
      0.0f, 0.0f, 1.0f, 1.0f, 
      -0.75f, -0.75f, 0.0f, 
      0.0f, 0.0f, 1.0f, 1.0f 
     }; 

     short indicesArray[] = { 
      0, 1, 2, 0, 2, 3 
     }; 

     ByteBuffer vbb = ByteBuffer.allocateDirect(vertexArray.length * FLOAT_SZ); 
     vbb.order(ByteOrder.nativeOrder()); 
     gridVB = vbb.asFloatBuffer(); 
     gridVB.put(vertexArray); 
     gridVB.position(0); 

     ByteBuffer ibb = ByteBuffer.allocateDirect(indicesArray.length * SHORT_SZ); 
     ibb.order(ByteOrder.nativeOrder()); 
     gridIndices = ibb.asShortBuffer(); 
     gridIndices.put(indicesArray); 
     gridIndices.position(0); 
    } 

    public void onSurfaceCreated(GL10 unused, EGLConfig arg1) { 
     GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f); 
     staticGrid(); 
     int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode); 
     int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode); 
     programCode = GLES20.glCreateProgram(); 
     GLES20.glAttachShader(programCode, vertexShader); 
     GLES20.glAttachShader(programCode, fragmentShader); 
     GLES20.glLinkProgram(programCode); 

     paPositionHandle = GLES20.glGetAttribLocation(programCode, "a_Position"); 
     paColorHandle = GLES20.glGetAttribLocation(programCode, "a_Color"); 
     puMVPMatrixHandle = GLES20.glGetUniformLocation(programCode, "u_MVPMatrix"); 
    } 

    public void onDrawFrame(GL10 unused) { 
     GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); 
     GLES20.glUseProgram(programCode); 

     int stride = (POS_SZ + COL_SZ) * FLOAT_SZ; 
     int indices_cnt = 6; 

     gridVB.position(0); 
     GLES20.glEnableVertexAttribArray(paPositionHandle); 
     GLES20.glVertexAttribPointer(paPositionHandle, POS_SZ, GLES20.GL_FLOAT, false, stride, gridVB); 

     gridVB.position(POS_SZ); 
     GLES20.glEnableVertexAttribArray(paColorHandle); 
     GLES20.glVertexAttribPointer(paColorHandle, COL_SZ, GLES20.GL_FLOAT, false, stride, gridVB); 

     // matrix manipulation ... 

     GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices_cnt, GLES20.GL_UNSIGNED_SHORT, gridIndices); 
    } 
} 

回答

6

片段着色器不使用的屬性。屬性是每個頂點的值,片段着色器不會知道任何事情。你想要做的是將顏色作爲attribute加到頂點着色器上,然後使用varying將顏色傳遞給片段着色器。

也請開始使用錯誤檢查你的着色器,它會告訴你,當你犯錯誤是這樣的:

http://www.khronos.org/opengles/sdk/docs/man/xhtml/glGetProgramiv.xml(檢查GL_LINK_STATUS

http://www.khronos.org/opengles/sdk/docs/man/xhtml/glGetShaderiv.xml(檢查GL_COMPILE_STATUS

http://www.khronos.org/opengles/sdk/docs/man/xhtml/glGetProgramInfoLog.xml

http://www.khronos.org/opengles/sdk/docs/man/xhtml/glGetShaderInfoLog.xml

相關問題