GLSL / C ++: поведение по умолчанию из пользовательского шейдера - PullRequest
1 голос
/ 12 ноября 2011

У меня есть некоторые шейдеры GLSL, которые правильно компилируются и успешно подключаются к программе, которая правильно связывается.Я подтвердил, что другие шейдеры правильно работают в моей программе.Странно то, что результат, который я вижу, выглядит так же, как и у шейдеров по умолчанию (цвет, без освещения).

Я вставлю исходный код как вершинного, так и фрагментного шейдеров, так кака также все выдержки из моего исходного кода C ++, которые относятся к шейдерам.Я объясню в комментариях любые функции или классы, которые являются уникальными для моей программы.

Мой вершинный шейдер (содержится в "dirlight.vs")

uniform int lightcount;
uniform vec4 lightdirs[];
uniform vec4 lightdifs[];
uniform vec4 lightambs[];
uniform vec4 lightposs[];

void main()
{
    vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
    vec4 diffuse = vec4(0.0, 0.0, 0.0, 0.0);
    for(int i = 0; i < lightcount; i++)
    {
        //Adding the diffuse term multiplied by gl_Color for each light.
        //There should be no color (0,0,0,0) if the lights are null
        diffuse += lightdifs[i] * max(dot(normal, normalize(lightdirs[i])), 0.0) * gl_Color;
    }

    gl_FrontColor = diffuse;
    gl_Position = ftransform();
}

Мой фрагментный шейдер (содержится в "dirlight.fs ")

void main()
{
    gl_FragColor = gl_Color;
}

Выдержка из инициализации в C ++ main ...

//class program manages shaders
Program shaders = Program();
//attach a vertex shader, compiled from source in dirlight.vs
shaders.addShaderFile(GL_VERTEX_SHADER, "dirlight.vs");
//attach a fragment shader compiled from source in dirlight.fs
shaders.addShaderFile(GL_FRAGMENT_SHADER, "dirlight.fs");
//link program
shaders.link();
//use program
shaders.use();

//Program::getUniformLoc(const char* name) grabs the location
//of the uniform specified
GLint sTime = shaders.getUniformLoc("time");
GLint lightcount = shaders.getUniformLoc("lightcount");
GLint lightdir = shaders.getUniformLoc("lightdirs");
GLint lightdif = shaders.getUniformLoc("lightdifs");
GLint lightamb = shaders.getUniformLoc("lightambs");

glUniform1i(lightcount, 2);
GLfloat lightdirs[] = {-1.f, 1.f, 1.f, 1.f,
                       1.f, 1.f, -1.f, 1.f};
glUniform4fv(lightdir, 2, lightdirs);
GLfloat lightdifs[] = {1.f, 1.f, 1.f, 1.f,
                       1.f, 1.f, 1.f, 1.f};
glUniform4fv(lightdif, 2, lightdifs);
glUniform4f(lightamb, 0.4f, 0.4f, 0.4f, 1.f);

Выдержка из основного цикла в C ++ main ...

glUniform1f(sTime, newTime);
//This should cause the light directions to rotate around the origin
GLfloat lightdirs[] = {sinf(newTime * 2.f), 1.f, cosf(newTime * 2.0f), 1.f,
                       cosf(newTime * 2.f), 1.f, sinf(newTime * 2.0f), 1.f};
glUniform4fv(lightdir, 2, lightdirs);

1 Ответ

2 голосов
/ 12 ноября 2011
uniform vec4 lightdirs[];

Это не законно GLSL.Я не могу объяснить, почему ваш компилятор позволяет компилировать (я предполагаю, что это компилятор NVIDIA, верно? Это, конечно, предполагает, что вы проверяете статус компиляции / ссылки), но единообразные массивы должны иметь длинуопределено явно в шейдере.Если вы хотите иметь массивы переменной длины, вы должны выбрать максимальную длину и запечь ее в шейдер.Шейдер может считывать меньшее количество значений (длина основана на форме, которую вы передаете), но это все.

...