Почему 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
.