Почему glGetUniformLocation подводит меня?
Я нашел Гвен несколько дней назад и подумал, что это выглядит как идеальный набор инструментов GUI для моего проекта. Но, боже мой, посмотрите на весь этот код OpenGL 2 в рендерере. Поэтому я подумал, что напишу рендерер OpenGL 3, чтобы действительно использовать его, но я гораздо лучше знаком с CG, чем GLSL, и я застрял, записывая образец. Я думаю, что если я могу просто получить набор этих однородных переменных, это должно быть в основном сделано.
Шейдеры компилируются и связываются без проблем. Я сузил его вплоть до glGetUniformLocation, возвращающего -1 для ортогональной матрицы и текстурного сэмплера, но я не знаю, почему именно это происходит. Типичная проблема, кажется, заключается в том, что если вы на самом деле не используете их, они оптимизируются, но я использовал их оба.
Если у кого-то есть какие-то идеи, я весь внимание. Будет более чем счастлив опубликовать / связать полную вещь, как только она будет работать должным образом. Это мой первый удар по GLSL, так что я легко могу сделать что-то глупое. Я только что закончил установку CG для другого проекта, так что я не полностью невежествен.Код инициализации шейдера вызывается после настройки контекста 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");
}
Шейдеры хранятся в виде строки в заголовочном файле, но я убрал все новые строки и обратные косые черты, чтобы на них не было так больно смотреть.
Вершинный шейдер:
#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);
}
2 ответа:
Проблема действительно проста: ваш вершинный шейдер ничего не делает, поэтому OpenGL оптимизирует его.
Чтобы отобразить треугольник, OpenGL требуется позиция пространства клипов для каждой из вершин треугольника. Обеспечить это-задача вершинного шейдера. Поскольку OpenGL не может определить, какие выходные данные вершинного шейдера вы собираетесь использовать в качестве позиции пространства клипов, OpenGL требует, чтобы вы записали в
gl_Position
в качестве выходных данных. Это законно, чтобы избежать этого,поэтому ваш шейдер компилирует и связывает. Но как же вы нашли, рендеринг не удается.
Прежде всего,
glBindFragDatalocation
должен связыватьoutColor
, а неcolor
в этом случае. Во-вторых, вы даете программе шейдера атрибутывершин , а не атрибуты фрагментов.out
s вершинного шейдера должны совпадать сin
S фрагментного шейдера.Причина, по которой расположение
Я думаю, что то, что вы ищете, этоtextureSampler
равно -1, заключается в том, что вы закомментировали код. Причина, по которой расположениеorthoTransform
равно -1, заключается в том, что оно фактически никогда не используется и не оптимизируется. Тот самыйout
outPosition
никогда не используется фрагмент шейдера, который в свою очередь заставляет егоorthoTransform
единообразно оптимизироваться.gl_Position
.