Я создал две шейдерные программы shaderProgram0 и shaderProgram1. Я добавил все связанные шейдеры и переменные с 0 или 1, чтобы показать их связь с shaderProgram0 или shaderProgram1. Обе программы шейдеров работают так, как они были разработаны. shaderProgram0 использовать SimpleVertexShader0.vert в качестве вершинного шейдера:Как вершинный шейдер получает доступ к данным буфера вершин, связанным с другим атрибутом shaderprogram?
#version 330
in vec3 vertexPosition0;
void main()
{
gl_Position = vec4(vertexPosition0, 1);
}
Выход shaderProgram0 таков:
shaderProgram1 использовать SimpleVertexShader1.vert в качестве вершинного шейдера:
#version 330
in vec3 vertexPosition1;
void main()
{
gl_Position = vec4(vertexPosition1, 1);
}
Выходной сигнал shaderProgram1 таков:
Теперь эта забавная часть; при использовании shaderProgram1 я случайно прокомментировал привязку массива атрибутов вершин vao1 и оставил привязку vao0 uncommented, результатом которой стал вывод, такой как следующий рисунок, который на самом деле является результатом, который (я думаю) может быть сгенерирован только shaderProgram0 !:
код упрощается и записывается с помощью Qt Creator в Windows:
void OpenGLWidget::initializeGL()
{
initializeOpenGLFunctions();
glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
shaderProgram0.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/SimpleVertexShader0.vert");
shaderProgram0.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/SimpleFragmentShader0.frag");
shaderProgram0.link();
shaderProgram1.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/SimpleVertexShader1.vert");
shaderProgram1.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/SimpleFragmentShader1.frag");
shaderProgram1.link();
}
void OpenGLWidget::resizeGL(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
}
void OpenGLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLfloat vertexBufferData0[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
};
GLuint vbo0;
glGenBuffers(1, &vbo0);
glBindBuffer(GL_ARRAY_BUFFER, vbo0);
glBufferData(GL_ARRAY_BUFFER,
sizeof(vertexBufferData0),
vertexBufferData0,
GL_STATIC_DRAW);
GLuint vao0;
glGenVertexArrays(1, &vao0);
glBindVertexArray(vao0);
glBindBuffer(GL_ARRAY_BUFFER, vbo0);
glVertexAttribPointer(glGetAttribLocation(shaderProgram0.programId(),"vertexPosition0"), 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
GLfloat vertexBufferData1[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
};
GLuint vbo1;
glGenBuffers(1, &vbo1);
glBindBuffer(GL_ARRAY_BUFFER, vbo1);
glBufferData(GL_ARRAY_BUFFER,
sizeof(vertexBufferData1),
vertexBufferData1,
GL_STATIC_DRAW);
GLuint vao1;
glGenVertexArrays(1, &vao1);
glBindVertexArray(vao1);
glBindBuffer(GL_ARRAY_BUFFER, vbo1);
glVertexAttribPointer(glGetAttribLocation(shaderProgram1.programId(),"vertexPosition1"), 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
// Now Rendering-----------------------------------------------------
glBindVertexArray(vao0);
glEnableVertexAttribArray(glGetAttribLocation(shaderProgram0.programId(),"vertexPosition0"));
// glBindVertexArray(vao1);
// glEnableVertexAttribArray(glGetAttribLocation(shaderProgram1.programId(),"vertexPosition1"));
shaderProgram1.bind();
glDrawArrays(GL_TRIANGLES, 0, 3);
}
Разве не странно, что вершинные шейдеры из shaderProgram1 доступа к данным буфера, который связан с shaderProgram0 атрибут? Я думал, что он не должен генерировать какой-либо вывод, поскольку действительный массив атрибутов вершин не включен! Пожалуйста, объясните этот сценарий, если кто-то знает, как это работает. Если вы не понимаете, что я прошу, пожалуйста, внимательно ознакомьтесь с кодом, и вы поймете, что я буду объяснять дальше.
EDIT:
// Now Rendering-----------------------------------------------------
glBindVertexArray(vao0);
glEnableVertexAttribArray(glGetAttribLocation(shaderProgram0.programId(),"vertexPosition0"));
shaderProgram0.bind();
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(vao1);
glEnableVertexAttribArray(glGetAttribLocation(shaderProgram1.programId(),"vertexPosition1"));
shaderProgram1.bind();
glDrawArrays(GL_TRIANGLES, 0, 3);
Вывод редактируемого кода:
Тут вопрос возникает, если обе программы используют один и тот же место для единственного атрибута, то они должны либо генерировать один или другой треугольник, не оба они должны переписываться !? Медведь со мной пожалуйста, я только начал изучать его.
В настоящее время связанная программа полностью не зависит от конфигурации входов трубопровода, который хранится в VAO. Если связанное в настоящее время VAO извлекает данные из определенных буферов в определенные атрибуты. Вы можете продолжать изменять программу и все еще подавать конвейер с одних и тех же входных данных, которые выглядят так, как вы (случайно?). – peppe
Также обратите внимание, что включение атрибута вершины является настройкой VAO, а не программы. Точка, в которой VAO и программа «встречаются», это когда вы устанавливаете местоположения этих атрибутов, что вы не делаете явно в своем коде, - в вашей системе, случайно, обе программы используют одно и то же местоположение для только атрибут, поэтому они будут работать с одним и тем же VAO. – peppe
@peppe Я отредактировал мой вопрос, не могли бы вы его просмотреть? Ваш ответ имеет смысл, но я хочу очистить свои сомнения. –