Android glVertexAttribPointer Шаг / смещение

#java #android #opengl-es #shader

#java #Android #opengl-es #шейдер

Вопрос:

У меня есть упакованный буфер вершин, содержащий координаты положения, а также значения цвета для вершины в формате {x, y, z, r, g, b}.

Я могу передать правильные значения xyz в вершинный шейдер. Неожиданно отображаемый квадрат становится белым.

Как правильно использовать glVertexAttribPointer(…) для рендеринга из упакованного вершинного буфера?

Код:

 public float vertices[] = {
        1, 1, 1, 255, 255, 255,
        -1, 1, 1, 255, 87, 255,
        -1, -1, 1, 87, 67, 255,
        1, -1, 1, 0, 0, 0
};
public FloatBuffer verticesBuffer;

public int indices[] = {
        0, 1, 3,
        1, 2, 3
};
public IntBuffer indicesBuffer;

ByteBuffer bb = ByteBuffer.allocateDirect(vertices.length * 4);
bb.order(ByteOrder.nativeOrder());
verticesBuffer = bb.asFloatBuffer();
verticesBuffer.put(vertices);
verticesBuffer.position(0);

bb = ByteBuffer.allocateDirect(indices.length * 4);
bb.order(ByteOrder.nativeOrder());
indicesBuffer = bb.asIntBuffer();
indicesBuffer.put(indices);
indicesBuffer.position(0);
  

 @Override
public void onDrawFrame(GL10 notUsed) {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glUseProgram(programId);

    verticesBuffer.position(0);
    glEnableVertexAttribArray(vertexPositionHandle);
    glVertexAttribPointer(vertexPositionHandle, 3, GL_FLOAT, false, (POS_SZ   COL_SZ) * FLOAT_SZ, verticesBuffer);

    verticesBuffer.position(POS_SZ);
    glEnableVertexAttribArray(vertexColorHandle);
    glVertexAttribPointer(vertexColorHandle, 3, GL_FLOAT, false, (POS_SZ   COL_SZ) * FLOAT_SZ, verticesBuffer);

    glUniformMatrix4fv(projectionMatrixHandle, 1, false, projectionMatrix, 0);
    glUniformMatrix4fv(viewMatrixHandle, 1, false, viewMatrix, 0);
    glUniformMatrix4fv(modelMatrixHandle, 1, false, modelMatrix, 0);

    glDrawElements(GL_TRIANGLES, indices.length, GL_UNSIGNED_INT, indicesBuffer);

    glDisableVertexAttribArray(vertexPositionHandle);
    glDisableVertexAttribArray(vertexColorHandle);
}
  

Шейдеры:

 public static String VertexShader =
    "attribute vec3 a_Position;"  
    "attribute vec3 a_Color;"  
    ""  
    "uniform mat4 u_ProjectionMatrix;"  
    "uniform mat4 u_ViewMatrix;"  
    "uniform mat4 u_ModelMatrix;"  
    ""  
    "varying vec3 v_Color;"  
    ""  
    "void main()"  
    "{"  
        "gl_Position = u_ProjectionMatrix * u_ViewMatrix * u_ModelMatrix * vec4(a_Position, 1);"  
        "v_Color = a_Color;"  
    "}";
public static String FragmentShader =
    "precision mediump float;"  
    ""  
    "varying vec3 v_Color;"  
    ""  
    "void main()"  
    "{"  
        "gl_FragColor = vec4(1, v_Color);"  
    "}";
  

Комментарии:

1. Это возникало раньше, но я не уверен, как лучше всего найти один из дубликатов. Поскольку вы указываете цвета как значения с плавающей запятой, их необходимо нормализовать, что означает, что они находятся в диапазоне от 0.0 до 1.0.

Ответ №1:

Спасибо Рето Коради, у меня было две проблемы…

Цвет вершины передается как значения от 0-1. Массив вершин должен был быть:

 public float vertices[] = {
        1.0f,   1.0f,   1.0f,   1.0f,   0.0f,   0.0f,
        -1.0f,  1.0f,   1.0f,   0.0f,   1.0f,   0.0f,
        -1.0f,  -1.0f,  1.0f,   0.0f,   0.0f,   1.0f,
        1.0f,   -1.0f,  1.0f,   0.0f,   0.0f,   0.0f,
};
  

Также у меня была небольшая проблема в шейдере фрагментов:

 "gl_FragColor = vec4(1, v_Color);"  
  

Это (r, g, b, a), так что это должно быть:

 "gl_FragColor = vec4(v_Color, 1);"