Как работают несколько буферов для атрибутов в шейдерах openGL (ES) и API C ++

У меня есть образец пресловутого куба, и я писал код, чтобы проверить все это и узнать больше о шейдерах. Мой вопрос о том, как нескольким буферам назначается доступ в шейдере и как написать код шейдера для ссылки на них. Кажется, что образцы основаны на неких неявных ссылочных значениях по умолчанию, которые скрывают то, что действительно происходит, и то, как кто-то манипулирует им в образцах.

Моя настройка буфера выглядит следующим образом (данные опущены)

        glGenBuffers(1, &vertexPosObject);
glBindBuffer(GL_ARRAY_BUFFER, vertexPosObject);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,
sizeof(Vec3f), (void*)0);

/* load index buffer with array of indices */
glGenBuffers(1, &indexBufferObject);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

/* load color buffer with array of colors */
glGenBuffers(1, &colorBufferObject);
glBindBuffer(GL_ARRAY_BUFFER, colorBufferObject);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertColors), vertColors, GL_STATIC_DRAW);

glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE,
sizeof(Vec4f), 0);

С этим я получаю рисунок куба и могу вращать его. с.

        Matrix4d modelView;
double rot = rc.timing().frameTime()*.3;
rot = fmod(rot, ARTD_M_PI * 2);
modelView.setRotation(Vec3d(0, 1, 1), rot);
artdGlUniformMatrix4(modelViewId, modelView); // convenience call

тогда я могу нарисовать это ниже

        glUseProgram(cubeShader);

glBindBuffer(GL_ARRAY_BUFFER, vertexPosObject);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, colorBufferObject);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);

const int vertexCount = 36;
const int type = GL_UNSIGNED_INT; // unsigned short ??
const int firstIndex = 0;

// vertexCount is the number of verts in your vertex array object
// firstIndex is the first index to use in an array of offsets (element index) into the vertex data.

glDrawElements(GL_TRIANGLES, vertexCount, type, (void *)firstIndex);

glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);

Я предполагал, что массиву вершин назначается «слот» с

        glEnableVertexAttribArray(0);

И этот слот «0» implicily что шейдер принимает в качестве входных вершин. (???)

Итак, я решил попробовать назначить массив цветов для слота «1», дескриптор массива индекса передается непосредственно в glDrawElements () и извлекает вершины для ввода в шейдер, используя массив индекса, обращающийся к буферу, назначенному слоту «0».

В целом, я полагаю, что может потребоваться несколько буферов для всех видов нормалей, цветов и т. Д., И необходимо получить доступ к значениям этих буферов, обращаясь к ним с помощью индексов. Так что общий случай ответа был бы желателен.

Мой вопрос: как получить доступ к буферу цветовых массивов в шейдере, а также получить доступ к другим буферам в качестве индексируемых массивов в вершинном шейдере ???

Как связать буферы с различными идентификаторами, доступными для шейдеров, и как получить к ним доступ из этих идентификаторов в коде шейдера. Понимание этих отношений является ключевым.

В настоящее время эта пара шейдеров работает для рисования куба с вычисленными цветами.

    "uniform mat4 Projection;\n""uniform mat4 Model;\n"
"attribute vec4 vPosition;\n""varying vec3 color;\n""void main(){\n""mat4 MVP = Model * Projection;\n""gl_Position = vPosition * MVP;\n""color = gl_Position.xyz + vec3(0.5);\n""}\n"

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

   "precision mediump float;\n""varying vec3 color;\n""void main()\n""{\n""gl_FragColor = vec4 ( color, 1.0 );\n""}\n"

Простите C ++ строки 🙂

Спасибо !!

2

Решение

Если вы хотите использовать атрибут цвета, вам нужно добавить новый атрибут в шейдер:

Вершинный шейдер

attribute vec4 vPosition;
attribute vec4 vColor;

varying vec4 color;

uniform mat4 Projection;
uniform mat4 Model;

void main()
{
mat4 MVP    = Model * Projection;
gl_Position = vPosition * MVP;
color       = vColor;
}

После того, как шейдерная программа связана glLinkProgram, Атрибут ind3ex можно получить glGetAttribLocation:

GLuint cubeShader = ....;

glLinkProgram(cubeShader);

GLint pos_attr_i   = glGetAttribLocation(cubeShader, "vPosition");
GLint color_attr_i = glGetAttribLocation(cubeShader, "vColor");

Это индексы атрибутов, которые должны использоваться в glVertexAttribPointer соответственно glEnableVertexAttribArray:

glBindBuffer(GL_ARRAY_BUFFER, vertexPosObject);
glVertexAttribPointer(pos_attr_i, 3, GL_FLOAT, GL_FALSE, sizeof(Vec3f), (void*)0);

glBindBuffer(GL_ARRAY_BUFFER, colorBufferObject);
glVertexAttribPointer(color_attr_i, 4, GL_FLOAT, GL_FALSE, sizeof(Vec4f), 0);

glEnableVertexAttribArray(pos_attr_i);
glEnableVertexAttribArray(color_attr_i);
4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]