OpenGL4 Shader (#version 410) непредвиденное поведение

У меня есть проблема, выясняющая, что происходит в моих простейших шейдерах. Вот мой вершинный шейдер:

#version 410 core

in vec3 position;
in vec2 textureCoords;
out vec2 color;

void main(void)
{

    gl_Position = vec4(position.x, position.y, position.z, 1.0);
    color = vec2(1.0,0.5);
}

И фрагмент шейдера:

#version 410 core

in vec2 color;
out vec4 out_color;

void main(void)
{
    out_color = vec4(0.0, 1.0, 0.0, 1.0);
}

Обратите внимание, что переменная цвета, передаваемая из VS в FS, на самом деле ничего не делает. Эти шейдеры дают мне ожидаемый результат, который представляет собой следующее изображение:

Визуализация от оригинальных шейдеров выше

Теперь, если я просто передаю textureCoords из VS в FS, используя переменную цвета без каких-либо изменений в FS, это смещает мое изображение вправо. Таким образом, модифицированная VS (и ЕДИНСТВЕННАЯ модификация для шейдеров):

#version 410 core

in vec3 position;
in vec2 textureCoords;
out vec2 color;

void main(void)
{
    gl_Position = vec4(position.x, position.y, position.z, 1.0);
    color = textureCoords;
}

Это дает неожиданный следующий рендер (треугольник смещается в верхний правый угол):

После модификации в VS

Я не понимаю, почему это происходит, так как я даже не использую цветовую переменную в FS.

Почему это происходит? Я просто пытаюсь передать vec2 в FS! Что я здесь не вижу?

Вот некоторая дополнительная информация: Информация о GL: Поддерживаемая версия GL: 4.1 NVIDIA-10.16.34 355.10.05.35f05 Поддерживаемый язык затенения: 4.10

Полный код здесь: полный код Точка входа - tests.cpp

Вот мои текущие массивы вершин:

GLfloat PossibleVertices[] = {
    // Left bottom triangle
     0.0f,  0.5f, 0.0f, // v0
    -0.5f,  -0.5f, 0.0f, // v1
     0.5f,  -0.5f, 0.0f
};

GLuint Indices[] = {
    0, 1, 2
};

GLfloat TextureCoords[] = 
{
    0.5f, 1.0f, // v0
    0.0f, 0.0f, // v1
    1.0f, 0.0f
};

// Load data to VAO
LoadToVAO(PossibleVertices, 9, Indices, 3, TextureCoords, 6);

... 

LoadToVAO
(
    GLfloat Positions[], GLuint PosArrySize,
    GLuint Indices[], GLuint IndArrySize,
    GLfloat TexCoords[], GLuint TCArrySize
)
{
    GLuint VaoID = CreateVAO();
    BindIndicesBufferVBO(Indices, IndArrySize); // Buffer Index - optimization
    StoreDataInAttrList(0, 3, Positions, PosArrySize);
    StoreDataInAttrList(1, 2, TexCoords, TCArrySize);
    UnbindVAO();
    CGCore::RawModel* ret = new CGCore::RawModel(VaoID, IndArrySize);
    return ret;
}

Вот функция, которая вызывается для фактического хранения данных в VAO. Вызывается для обоих массивов Vertex:

void CGCore::Loader::StoreDataInAttrList(GLuint AttrNumber, GLuint AttrSize, GLfloat Data[], GLuint DataSize)
{
    GLuint VboID; 
    glGenBuffers(1,&VboID);
    VBOContainer.push_back(VboID);
    glBindBuffer(GL_ARRAY_BUFFER, VboID);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*DataSize, Data, GL_STATIC_DRAW);
    glVertexAttribPointer(AttrNumber, AttrSize, GL_FLOAT, GL_FALSE, 0, (void*) 0); // write to VAO
    glBindBuffer(GL_ARRAY_BUFFER, 0); // unbind current VBO
}

Вот код привязки attr:

void BindAttributes()
{
    BindAttribute(0, "position");
    BindAttribute(1, "textureCoords"); 
}

// and also ... 

void BindAttribute(int Attrib, const GLchar* VarName)
{
    glBindAttribLocation(ProgramID, Attrib, VarName);
}

И наконец код рендеринга:

void CGCore::Renderer::Render(CGCore::TexturedModel* TexturedModelObj)
{
    CGCore::RawModel* Model = TexturedModelObj->GetModel();
    glBindVertexArray(Model->GetVaoID());
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glActiveTexture(GL_TEXTURE0);
    glDrawElements( GL_TRIANGLES, Model->GetVertexCount(), GL_UNSIGNED_INT, (void*) 0);
    glBindTexture(GL_TEXTURE_2D, TexturedModelObj->GetTexture()->GetTextureID());
    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
    glBindVertexArray(0);
}

Простите за длинный пост. Thanx!

1 ответ

После экспериментов, просмотра тонны документации OpenGL и так далее, я наконец решил свою проблему. Вопреки некоторым комментариям, проблема была в вершинном шейдере. Т.е. объявление в переменных. Следующее изменение в VS дает мне ожидаемый результат:

#version 410 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 textureCoords;

out vec2 TexCoord;

void main()
{
    gl_Position = vec4(position, 1.0f);
    TexCoord = textureCoords;
}

Поэтому я явно указываю расположение параметров in в VOA при объявлении параметров in. Я думаю, это связано с версией вершинного шейдера (v4.10), но я не уверен. В любом случае укажите местоположения attr, объявив переменные типа in this, как этот макет (location = X) в типе var_name

Другие вопросы по тегам