Передача цветовых координат в вершинный шейдер через указатель атрибута вершины - PullRequest
1 голос
/ 24 марта 2019

Я пытаюсь получить данные цвета vec3 в вершинный шейдер (как указатель attrib), а затем передаю их во фрагмент, чтобы все было готово.

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

Также я уверен, что шейдерсистема загрузки работает.Моя лучшая идея заключается в том, что информация не передается в «layout = 1» вершинного шейдера, но я, скорее всего, ошибаюсь.

VAO / Буфер / настройка шейдера

float vert[] = {
        //Vert Locs   Normal Coords
        -0.5f,-0.5f,  1.0f,1.0f,1.0f,  //0
         0.5f,-0.5f,  1.0f,1.0f,1.0f,  //1
         0.5f,0.5f,   1.0f,1.0f,1.0f,  //2
        -0.5f, 0.5f,  1.0f,1.0f,1.0f,  //3
    };


    unsigned int index[] = {
        0,1,2, //Order of drawing vertices
        2,3,0
    };

    unsigned int vao;
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    unsigned int buffer;
    glGenBuffers(1, &buffer);
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    glBufferData(GL_ARRAY_BUFFER, 5 * 4 * sizeof(float), vert, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 2, GL_FLOAT,GL_FALSE, 5 * sizeof(float), 0);
    glVertexAttribPointer(1, 3,  GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(2 * sizeof(float)));


    glEnableVertexAttribArray(0); // vao ^^

    unsigned int ibo;
    glGenBuffers(1, &ibo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(unsigned int), index, GL_STATIC_DRAW);

    Shader v("VertexN.shader", GL_VERTEX_SHADER);
    Shader f("FragmentN.shader", GL_FRAGMENT_SHADER);

    unsigned int shaders2[] = {v.id, f.id};
    unsigned int program2 = Shader::getProgram(shaders2);

    glUseProgram(0);
    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

Визуализация петли

glClearColor(0, 0, 0, 1);
        /* Render here */
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

        glUseProgram(program2);
        //tex.bind(slot);
        glBindVertexArray(vao);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);

        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); //Drawing mode, Type indecies , type of index buffer , pointer to index buffer

        glfwSwapBuffers(window);

        glfwPollEvents();

        glFlush();

        glBindVertexArray(0);
        glUseProgram(0);
        glActiveTexture(0);

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

#version 330 core

layout(location = 0)in vec2 pos;
layout(location = 1)in vec3 normals;

out vec3 normal;

void main() {

    normal = normals;

    gl_Position = vec4(pos, 0.0f, 1.0f);

};

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

#version 330 core

layout(location = 0)out vec4 colour;

in vec3 normal;

void main() {
    colour = vec4(normal, 1.0f);
};

1 Ответ

1 голос
/ 24 марта 2019

Понятия не имею, что это за комментарий к исходному коду:

glEnableVertexAttribArray(0); // vao ^^

должно означать. Однако у меня сложилось впечатление, что вы неправильно поняли, что делает эта функция.

GL управляет набором общих атрибутов вершин (спецификация гарантирует, что их как минимум 16, а может и больше), и для каждого такого атрибута данные могут поступать из массива. Помимо указания указателя атрибута и форматов данных, вы также должны активировать массив для каждого атрибута в отдельности. При выполнении вызова отрисовки для каждого индекса вершины i графический процессор извлекает i -значение в массиве атрибутов для каждого атрибута, для которого этот массив включен. Для атрибутов, где массив отключен, он будет использовать постоянное значение на протяжении всего вызова отрисовки. (Вы можете установить его через glVertexAttrib*() семейство функций перед выполнением вызова отрисовки).

Поскольку вы никогда не включаете массив для атрибута 1 (ваш normals ввод для шейдера), все вершины будут видеть текущее значение атрибута 1 - скорее всего, просто vec4(0), поскольку это начальное значение по умолчанию, и вы никогда не будете похоже, это изменило.

Решение, конечно, состоит в том, чтобы включить все массивы атрибутов, из которых вы хотите извлечь:

glEnableVertexAttribArray(1);

И пока вы это делаете: в цикле рендеринга у вас есть

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);

Это не обязательно. ВАО будет хранить эту информацию уже, нет необходимости повторно связывать ее для рисования.

...