Разъяснение по параметру индекса glVertexAttribPointer

#c #opengl #3d #glsl #vertex-attributes

#c #opengl #3D #glsl #атрибуты вершин

Вопрос:

У меня есть очень простая программа для отображения 3D-треугольника в OpenGL. значение шляпы, которое я ввел, отображается некорректно. Я поместил следующий массив в буфер вершин

 float triangle[] = {
//  x     y       z      r      g      b      a
    0.2f, -0.2f, -0.5f,  0.0f,  0.0f,  0.0f,  1.0f,
   -0.2f, -0.2f, -0.5f,  0.0f,  0.0f,  0.0f,  1.0f,
   -0.2f,  0.2f,  1.0f,  0.0f,  0.0f,  0.0f,  1.0f,
    0.0f, -0.2f,  0.0f,  0.0f,  0.0f,  0.0f,  1.0f
};
  

И я использую следующее, чтобы передать их в вершинный шейдер

 glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 7, 0);

glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 7, 0);
  

Но выходной треугольник имеет странную синюю область, даже если позиции правильные, что не имеет смысла, поскольку входные цвета должны быть черными. Я видел, что некоторые используют индекс как sizeof (float) * 3 и sizeof (float) * 4, но это делает треугольник зеленым и делает позиции неправильными. The docs.gl запись довольно расплывчата и не содержит никаких примеров. Вот мои шейдеры

Фрагмент шейдера

 #version 330 core
out vec4 color;

in vec4 outColor;

void main() {
    out vec4 outColor;
    uniform mat4 transform;

    void main() {
      gl_Position = transform * inPos;
      outColor = inColor;
    };
  

Что здесь не так?

Ответ №1:

Если привязан именованный объект буфера, то последний аргумент glVertexAttribPointer обрабатывается как смещение в байтах в хранилище данных буферов.
Смещение атрибута color составляет 3*sizeof(float) байты:

 glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 7, 0);

glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 7, 
    (void*)(sizeof(float) * 3)); // <--- byte offset
  

Атрибут состоит из 7 компонентов (x, y, z, r, g, b, a). Смещение координаты вершины равно 0, потому что это первые 3 компонента в кортеже. Смещение цвета равно 3*sizeof(float) , потому что это компоненты от 4 до 7.

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

1. Я продолжал думать, что последний параметр не имеет значения из-за типа указателя void, но, черт возьми, я ошибался. Спасибо!