У меня есть образец пресловутого куба, и я писал код, чтобы проверить все это и узнать больше о шейдерах. Мой вопрос о том, как нескольким буферам назначается доступ в шейдере и как написать код шейдера для ссылки на них. Кажется, что образцы основаны на неких неявных ссылочных значениях по умолчанию, которые скрывают то, что действительно происходит, и то, как кто-то манипулирует им в образцах.
Моя настройка буфера выглядит следующим образом (данные опущены)
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 ++ строки 🙂
Спасибо !!
Если вы хотите использовать атрибут цвета, вам нужно добавить новый атрибут в шейдер:
Вершинный шейдер
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);
Других решений пока нет …