2016-09-29 9 views
0

Я создал две шейдерные программы shaderProgram0 и shaderProgram1. Я добавил все связанные шейдеры и переменные с 0 или 1, чтобы показать их связь с shaderProgram0 или shaderProgram1. Обе программы шейдеров работают так, как они были разработаны. shaderProgram0 использовать SimpleVertexShader0.vert в качестве вершинного шейдера:Как вершинный шейдер получает доступ к данным буфера вершин, связанным с другим атрибутом shaderprogram?

#version 330 
in vec3 vertexPosition0; 
void main() 
{ 
    gl_Position = vec4(vertexPosition0, 1); 
} 

Выход shaderProgram0 таков:

enter image description here

shaderProgram1 использовать SimpleVertexShader1.vert в качестве вершинного шейдера:

#version 330 
in vec3 vertexPosition1; 
void main() 
{ 
    gl_Position = vec4(vertexPosition1, 1); 
} 

Выходной сигнал shaderProgram1 таков:

enter image description here

Теперь эта забавная часть; при использовании shaderProgram1 я случайно прокомментировал привязку массива атрибутов вершин vao1 и оставил привязку vao0 uncommented, результатом которой стал вывод, такой как следующий рисунок, который на самом деле является результатом, который (я думаю) может быть сгенерирован только shaderProgram0 !:

enter image description here

код упрощается и записывается с помощью 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); 

Вывод редактируемого кода:

enter image description here

Тут вопрос возникает, если обе программы используют один и тот же место для единственного атрибута, то они должны либо генерировать один или другой треугольник, не оба они должны переписываться !? Медведь со мной пожалуйста, я только начал изучать его.

+1

В настоящее время связанная программа полностью не зависит от конфигурации входов трубопровода, который хранится в VAO. Если связанное в настоящее время VAO извлекает данные из определенных буферов в определенные атрибуты. Вы можете продолжать изменять программу и все еще подавать конвейер с одних и тех же входных данных, которые выглядят так, как вы (случайно?). – peppe

+2

Также обратите внимание, что включение атрибута вершины является настройкой VAO, а не программы. Точка, в которой VAO и программа «встречаются», это когда вы устанавливаете местоположения этих атрибутов, что вы не делаете явно в своем коде, - в вашей системе, случайно, обе программы используют одно и то же местоположение для только атрибут, поэтому они будут работать с одним и тем же VAO. – peppe

+0

@peppe Я отредактировал мой вопрос, не могли бы вы его просмотреть? Ваш ответ имеет смысл, но я хочу очистить свои сомнения. –

ответ

2

Не странно ли, что вершинный шейдер shaderProgram1 получает доступ к данным буфера, связанным с атрибутом shaderProgram0?

No.

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

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

+0

@ShujaatAliKhan: ... как насчет вашего редактирования в частности? В этом поведении нет ничего удивительного или неожиданного, основанного на том, как все работает раньше. –

+0

Что я не понимаю, так это то, что каждая программа шейдера имеет разные идентификаторы id и glDrawArrays для активированного VAO, поэтому, когда я включил атрибут shaderProgram0 следующим образом: glEnableVertexAttribArray (glGetAttribLocation (shaderProgram0.programId(), "vertexPosition0")) ; , то как shaderProgram1 получает доступ к фрагменту данных, который инициализируется для shaderProgram0? Я знаю, что хочу спросить, но я не могу перевести свои мысли на слова из-за моей меньшей подверженности условным терминам, связанным с opengl: '( –

+1

@ShujaatAliKhan: Поскольку, как я уже сказал, местоположения атрибутов вершин являются * не * специфичными для программы. скорее, они не являются программными * уникальными *. Отдельные программы могут и часто используют одни и те же местоположения атрибутов. –

 Смежные вопросы

  • Нет связанных вопросов^_^