Использование glVertexAttribPointer и glDrawElements для рисования из упакованного буфера вершин

У меня есть упакованный буфер вершин, содержащий координаты позиции, а также значения цвета для вершины в формате {X, Y, Z, R, G, B, A}.

Я могу правильно отображать прямоугольник с жестко кодированным цветом, когда я изменяю шейдер фрагмента, вынимая атрибут a_Color и строгая кодировка значения vec4 для gl_FragColor, но я не могу передать атрибут color 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); } } 

Фрагментные шейдеры не используют атрибуты. Атрибуты – это значения для вершин, о которых фрагментарный шейдер ничего не знал. То, что вы хотите сделать, – это взять цвет как 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