Я занимаюсь разработкой приложения, использующего Qt 4.7, с целью создания простого трехмерного средства просмотра OpenGL.Я хочу использовать шейдеры GLSL 3.30.Я использую Linux Ubutu 11.10, мой CG - это NVIDIA с графическим процессором NVS 3100M, версия драйвера NVIDIA - 280.13, а версия OpenGL - 3.3.0
У меня есть работающий базовый шейдер, который не вычисляет никакого освещения.Это нужно сделать дальше, но я застрял с проблемой.
Вот мой неработающий модифицированный вершинный шейдер.
#version 330
in vec3 inPosition;
in vec4 inColor;
in vec3 inNormal;
uniform mat4 inModelMatrix;
uniform mat4 inViewMatrix;
uniform mat4 inProjectionMatrix;
out vec4 exColor;
uniform Light {
vec4 position;
vec4 ambient;
vec4 diffuse;
vec4 specular;
} lights[4];
void main(void)
{
gl_Position = inProjectionMatrix * inViewMatrix * inModelMatrix * vec4(inPosition, 1.0);
exColor = lights[0].ambient;
}
Ссылка на язык затенения OpenGL для GLSL 3.30 гласит:
uniform Transform { // API uses “Transform[2]” to refer to instance 2
mat4 ModelViewMatrix;
mat4 ModelViewProjectionMatrix;
float Deformation;
} transforms[4];
...
... = transforms[2].ModelViewMatrix; // shader access of instance 2
// API uses “Transform.ModelViewMatrix” to query an offset or other query
Так что, если я не ошибаюсь, код верен.Тем не менее, он даже не компилируется.Выдается следующая ошибка:
QGLShader::link: "Vertex info
-----------
Internal error: assembly compile error for vertex shader at offset 1805:
-- error message --
line 38, column 15: error: expected '='
line 82, column 36: error: expected ';'
-- internal assembly text --
!!NVvp4.1
OPTION NV_parameter_buffer_object2;
# cgc version 3.1.0001, build date Jul 27 2011
# command line args:
#vendor NVIDIA Corporation
#version 3.1.0.1
#profile gp4_1vp
#program main
#semantic Light.lights
#semantic inModelMatrix
#semantic inViewMatrix
#semantic inProjectionMatrix
#var float4 gl_Position : $vout.POSITION : HPOS : -1 : 1
#var float4 lights[0].position : BUFFER[0] : buffer[0][0] : -1 : 0
#var float4 lights[0].ambient : BUFFER[0] : buffer[0][16] : -1 : 1
#var float4 lights[0].diffuse : BUFFER[0] : buffer[0][32] : -1 : 0
#var float4 lights[0].specular : BUFFER[0] : buffer[0][48] : -1 : 0
#var float4 lights[1].position : BUFFER[1] : buffer[1][0] : -1 : 0
#var float4 lights[1].ambient : BUFFER[1] : buffer[1][16] : -1 : 0
#var float4 lights[1].diffuse : BUFFER[1] : buffer[1][32] : -1 : 0
#var float4 lights[1].specular : BUFFER[1] : buffer[1][48] : -1 : 0
#var float4 lights[2].position : BUFFER[2] : buffer[2][0] : -1 : 0
#var float4 lights[2].ambient : BUFFER[2] : buffer[2][16] : -1 : 0
#var float4 lights[2].diffuse : BUFFER[2] : buffer[2][32] : -1 : 0
#var float4 lights[2].specular : BUFFER[2] : buffer[2][48] : -1 : 0
#var float4 lights[3].position : BUFFER[3] : buffer[3][0] : -1 : 0
#var float4 lights[3].ambient : BUFFER[3] : buffer[3][16] : -1 : 0
#var float4 lights[3].diffuse : BUFFER[3] : buffer[3][32] : -1 : 0
#var float4 lights[3].specular : BUFFER[3] : buffer[3][48] : -1 : 0
#var float3 inPosition : $vin.ATTR0 : ATTR0 : -1 : 1
#var float4 inColor : : : -1 : 0
#var float3 inNormal : : : -1 : 0
#var float4x4 inModelMatrix : : c[0], 4 : -1 : 1
#var float4x4 inViewMatrix : : c[4], 4 : -1 : 1
#var float4x4 inProjectionMatrix : : c[8], 4 : -1 : 1
#var float4 exColor : $vout.ATTR0 : ATTR0 : -1 : 1
PARAM c[12] = { program.local[0..11] };
CBUFFER buf0[][] = { program.buffer[0..3] };
ATTRIB vertex_attrib[] = { vertex.attrib[0..0] };
OUTPUT result_attrib[] = { result.attrib[0..0] };
TEMP R0, R1, R2, R3, R4, R5, R6, R7, R8;
MOV.F R3, c[9];
MOV.F R2, c[8];
MUL.F R0, R3, c[5].y;
MOV.F R1, c[10];
MAD.F R0, R2, c[5].x, R0;
MAD.F R5, R1, c[5].z, R0;
MOV.F R0, c[11];
MAD.F R6, R0, c[5].w, R5;
MUL.F R4, R3, c[4].y;
MAD.F R5, R2, c[4].x, R4;
MAD.F R5, R1, c[4].z, R5;
MAD.F R5, R0, c[4].w, R5;
MUL.F R4, R6, c[1].y;
MAD.F R8, R5, c[1].x, R4;
MUL.F R4, R3, c[6].y;
M UL.F R7, R6, c[0].y;
MAD.F R4, R2, c[6].x, R4;
MUL.F R3, R3, c[7].y;
MAD.F R2, R2, c[7].x, R3;
MAD.F R3, R1, c[6].z, R4;
MAD.F R1, R1, c[7].z, R2;
MAD.F R2, R0, c[6].w, R3;
MUL.F R4, R6, c[2].y;
MAD.F R0, R0, c[7].w, R1;
MAD.F R3, R2, c[1].z, R8;
MAD.F R1, R0, c[1].w, R3;
MAD.F R7, R5, c[0].x, R7;
MAD.F R3, R2, c[0].z, R7;
MAD.F R3, R0, c[0].w, R3;
MUL.F R1, vertex.attrib[0].y, R1;
MAD.F R1, vertex.attrib[0].x, R3, R1;
MUL.F R3, R6, c[3].y;
MAD.F R3, R5, c[3].x, R3;
MAD.F R3, R2, c[3].z, R3;
MAD.F R4, R5, c[2].x, R4;
MAD.F R3, R0, c[3].w, R3;
MAD.F R2, R2, c[2].z, R4;
MAD.F R0, R0, c[2].w, R2;
MAD.F R0, vertex.attrib[0].z, R0, R1;
ADD.F result.position, R0, R3;
LDC.F32X4 result.attrib[0], buf0[0][16];
END
# 41 instructions, 9 R-regs
"
Если я удаляю вызов lights [0] .ambient, шейдер компилируется, но когда я пытаюсь получить единое местоположение, он не работает:
int lightsLocation = shaderProgram.uniformLocation("Light[0]");
PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)(context()->getProcAddress("glGetUniformLocation"));
qDebug() << lightsLocation << glGetUniformLocation(shaderProgram.programId(), "Light[0]"); // -1 -1
Я также пробовал это с "Light", "lights", "lights [0]", "lights [0] .ambient" как единое имя без успеха.
ПослеПри поиске я нашел этот пост: Установка значений массива struct от JS до GLSL и, таким образом, пытался использовать структуры, как показано, но это тоже не работает.
Последующий вопрос
Событие, если я смогу заставить это работать благодаря некоторому ответу, я не знаю, какой метод QGLShaderProgram мне следует использовать для загрузки данных.
tl; dr
1) Почему следующий код не компилируется?out vec4 exColor;
uniform Light {
vec4 ambient;
} lights[4];
void main(void) {
exColor = lights[0].ambient;
}
2) Какое унифицированное имя следует использовать в качестве параметра QGLShaderProgam ::iformLocation () для получения местоположения uniform Light { ... } lights[4];
или struct Light { ... }; uniform Light lights[4];
?
3) Как только местоположение будет найдено, какую функцию QGLShaderProgram следует использовать для загрузки данных в графический процессор?
Большое спасибо!