Почему glGetUniformLocation терпит неудачу?

Я нашел Гвен несколько дней назад и подумал, что это выглядит как идеальный инструментарий GUI для моего проекта. Но, о, дорогой, посмотрите на весь код OpenGL 2 в рендерере. Поэтому я решил написать рендеринга OpenGL 3, чтобы я мог его использовать, но я больше знаком с CG, чем с GLSL, и я сам застрял в написании образца. Я думаю, что если я могу просто установить эти равномерные переменные, это должно быть сделано в основном.

Шейдеры компилируются и соединяются без проблем. Я сузил его до glGetUniformLocation, возвращающего -1 для орфографической матрицы и сэмплера текстур, но я не знаю, почему именно он это делает. Типичная проблема заключается в том, что если вы на самом деле не используете их, они оптимизируются, но я использовал их оба.

Если у кого-нибудь есть идеи, я все уши. Будет более чем счастлив опубликовать/связать всю вещь, как только она будет работать должным образом. Это мой первый удар в GLSL, так что я мог легко сделать что-то немое. Я только что закончил настройку CG для другого проекта, поэтому я не совсем понятен.

Код Shader Init, вызванный после настройки контекста OpenGL:

void InitializeShaders(void)
{
    g_ShaderProgram = glCreateProgram();
    g_VertexShader = glCreateShader(GL_VERTEX_SHADER);
    g_FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);

    glShaderSource(g_VertexShader, 1, (const GLchar **)&VertexShaderData, 0);
    glShaderSource(g_FragmentShader, 1, (const GLchar **)&FragmentShaderData, 0);

    glCompileShader(g_VertexShader);
    CheckShaderCompile(g_VertexShader);

    glCompileShader(g_FragmentShader);
    CheckShaderCompile(g_FragmentShader);

    glAttachShader(g_ShaderProgram, g_VertexShader);
    glAttachShader(g_ShaderProgram, g_FragmentShader);

    glBindAttribLocation(g_ShaderProgram, 0, "position");
    glBindAttribLocation(g_ShaderProgram, 1, "color");
    glBindAttribLocation(g_ShaderProgram, 2, "texCoord");

    glBindFragDataLocation(g_ShaderProgram, 0, "color");

    glLinkProgram(g_ShaderProgram);
    CheckShaderLink();

    g_OrthoTransformLocation = glGetUniformLocation(g_ShaderProgram, "orthoTransform");
    g_TextureLocation = glGetUniformLocation(g_ShaderProgram, "textureSampler");
}

Шейдеры хранятся в виде строки в файле заголовка, но я удалил все символы новой строки и обратную косую черту, чтобы их было не так больно смотреть.

Vertex shader:

#version 330

in vec4 position;
out vec4 outPosition;
uniform mat4x4 orthoTransform;
void main(void)
{
    outPosition = position * orthoTransform;
}

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

#version 330

in vec2 texCoord;
in vec4 color;
out vec4 outColor;
uniform sampler2D textureSampler;
void main(void)
{
    //outColor = texture(textureSampler, texCoord) * color;
    outColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);
}

Ответ 1

Проблема очень проста: ваш вершинный шейдер ничего не делает, поэтому OpenGL оптимизирует его.

Для рендеринга треугольника OpenGL требуется позиция пространства клипа для каждой из треугольников. Это задача вершинного шейдера. Поскольку OpenGL не может определить, какой вывод вершинного шейдера вы намерены быть позицией клипа, OpenGL требует, чтобы вы записывали в gl_Position в качестве вывода. Законно избегать этого, поэтому ваши шейдерные компиляции и ссылки. Но, как вы нашли, рендеринг завершается неудачно.

Ответ 2

Прежде всего, glBindFragDatalocation должен привязать outColor, а не color в этом случае. Во-вторых, то, что вы даете шейдерной программе, это vertex атрибуты, а не атрибуты фрагментов. out вершинного шейдера должен соответствовать in шейдера фрагмента.

Причина, по которой местоположение textureSampler равно -1, заключается в том, что вы закомментировали код. Причина, по которой местоположение orthoTransform равно -1, состоит в том, что он фактически никогда не используется и не оптимизируется. out outPosition никогда не используется шейдером фрагментов, что в свою очередь заставляет его оптимизировать orthoTransform.

Я думаю, что вы ищете gl_Position.