Атрибуты OpenGL Vertex не включены - PullRequest
1 голос
/ 16 января 2020

Я пытаюсь заставить некоторые базовые c шейдеры работать в OpenGL, и мне кажется, что я преодолел блокпост на первом барьере. Я пытаюсь включить некоторые атрибуты вершин, но получаю странные результаты. Я поднял вызов отрисовки в RenderDo c, и только атрибут вершины 0 включен. Вот мой код создания VAO и мой рендер l oop. Я, наверное, упускаю из виду нечто действительно очевидное. Спасибо!

std::vector<float> positions;
std::vector<float> normals;
std::vector<float> texCoords;

for (auto x : model->positions)
{
    positions.push_back(x.x);
    positions.push_back(x.y);
    positions.push_back(x.z);
}

for (auto x : model->normals)
{
    normals.push_back(x.x);
    normals.push_back(x.y);
    normals.push_back(x.z);
}

for (auto x : model->texCoords)
{
    texCoords.push_back(x.x);
    texCoords.push_back(x.y);
}

GLuint indicesVBO = 0;
GLuint texCoordsVBO = 0;
GLuint vertsVBO = 0;
GLuint normsVBO = 0;

glGenVertexArrays(1, &model->vao);
glBindVertexArray(model->vao);

glGenBuffers(1, &vertsVBO);
glBindBuffer(GL_ARRAY_BUFFER, vertsVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * positions.size(), positions.data(), GL_STATIC_DRAW);

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid*)0);
glEnableVertexAttribArray(0);

glGenBuffers(1, &normsVBO);
glBindBuffer(GL_ARRAY_BUFFER, normsVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * normals.size(), normals.data(), GL_STATIC_DRAW);

glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid*)0);
glEnableVertexAttribArray(1);

glGenBuffers(1, &texCoordsVBO);
glBindBuffer(GL_ARRAY_BUFFER, texCoordsVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * texCoords.size(), texCoords.data(), GL_STATIC_DRAW);

glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid*)0);
glEnableVertexAttribArray(2);

glGenBuffers(1, &indicesVBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesVBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, model->indices.size() * sizeof(uint32_t), model->indices.data(), GL_STATIC_DRAW);

glBindVertexArray(0);

Мой рендер L oop это:

//I'm aware this isn't usually needed but I'm just trying to make sure
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);


for (GamePiece * x : gamePieces)
{
    glUseProgram(x->program->programID);
    glBindVertexArray(x->model->vao);
    glBindTexture(GL_TEXTURE_2D, x->texture->texID);

    glDrawElements(GL_TRIANGLES, x->model->indices.size(), GL_UNSIGNED_INT,(void*)0);
}

И мой вершинный шейдер:

#version 330 core



layout(location = 0) in vec3 position;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec2 texCoord;

out vec2 outUV;
out vec3 outNormal;

void main() 
{
    outUV = texCoord;
    outNormal = normal;

    gl_Position = vec4(position, 1.0f);
}

RenderDoc Vertex Attributes not showing!

#version 330

in vec2 inUV;
in vec3 normal;

out vec4 outFragcolor;

uniform sampler2D colourTexture;

void main() 
{
  outFragcolor = texture2D(colourTexture, inUV);
}

1 Ответ

2 голосов
/ 16 января 2020

См. Спецификация профиля ядра OpenGL 4.5 - 7.3.1 Программные интерфейсы , стр. 96:

[...] Когда программа связана, GL формирует список активных ресурсов для каждого интерфейса. [...] Например, переменные могут считаться неактивными, если они объявлены, но не используются в исполняемом коде , [...] Набор активных ресурсов для любого интерфейса зависит от реализации, поскольку зависит на различные анализы и оптимизации, выполняемые компилятором и компоновщиком

Это означает, что если компилятор и компоновщик определят, что переменная атрибута «не используется», когда исполняемый код выполняется, то атрибут неактивен.
Неактивные атрибуты не являются активными программными ресурсами и поэтому не отображаются в RenderDo c.


Кроме того, выходные переменные этапа шейдера связаны с входными переменными следующего Этап шейдера по имени.

texCoord не является активным программным ресурсом, поскольку он назначен выходной переменной outUV. Фрагментный шейдер не имеет входной переменной outUV.

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

out vec2 outUV;
out vec3 outNormal;

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

in vec2 inUV;
in vec3 normal;

См. Связь разделения программ :

Либо использовать одинаковые имена для выходов вершинного шейдера и входов фрагментного шейдера, либо использовать расположение макетов для связывания переменных интерфейса:

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

layout(location = 0) out vec2 outUV;
layout(location = 1) out vec3 outNormal;

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

layout(location = 0) in vec2 inUV;
layout(location = 1) in vec3 normal;
...