#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, но, черт возьми, я ошибался. Спасибо!