1
votes

I thought i had it working but I still can't figure out how to change a value in my vertex shader. What i do in opengl is the following, for each render:

//i bind my shader
shader.bind();

// Then trying to set the value in my vertex shader like so:
GLuint test = glGetUniformLocation(shader.id(), "Test");
glUniform1f(test, 6.0f);

// Do some other stuff like rendering an object
// ...

// then unbind shader
shader.unbind();

This is the value i want to change in my vertex shader:

uniform float Test = 0.66; // Doesn't work
//const float Test = 0.66; // Works

But my shader doesn't work when i try that, it renders my object black.

If i comment the glGetUniform(Location) part out and if use the float as a const instead of a uniform then my shader works fine. But i want to be able to change the value in my shader in each render. I though i had to use a uniform for that...?

Is there something i'm missing..??


EDIT:

Appearently i'm getting the following GLSL error:

non constant expression in initialization

So it must be constant in order to work... Does that mean there is no way to have this as a dynamic value..?

This is my Vertex Shader:

const float FresnelPower = 1.0;
uniform float Eta;         // <---- MUST BE CONSTANT...

const float F  = ((1.0-Eta) * (1.0-Eta)) / ((1.0+Eta) * (1.0+Eta));

varying vec3  Reflect;
varying vec3  Refract;
varying float Ratio;

void main()
{
    vec4 ecPosition  = gl_ModelViewMatrix * gl_Vertex;
    vec3 ecPosition3 = ecPosition.xyz / ecPosition.w;

    vec3 i = normalize(ecPosition3);
    vec3 n = normalize(gl_NormalMatrix * gl_Normal);

    Ratio   = F + (1.0 - F) * pow((1.0 - dot(-i, n)), FresnelPower);

    Refract = refract(i, n, Eta);
    Refract = vec3(gl_TextureMatrix[0] * vec4(Refract, 1.0));

    Reflect = reflect(i, n);
    Reflect = vec3(gl_TextureMatrix[0] * vec4(Reflect, 1.0));

    gl_Position = ftransform();
}
2

2 Answers

1
votes
uniform float Eta;         // <---- MUST BE CONSTANT...

When GLSL says "constant", what it means is a compile time constant. The value of Eta is certainly uniform within a particular draw call. But it is not constant, because it can change between draw calls. The compiler does not know what this value will be at compile time.

A const variable is a compile time constant. It therefore must be initialized with an expression consisting only of compile time constants. uniforms are not compile time constants, so you cannot initialize a const variable with them.

1
votes

You must declare your uniform in the vertex shader like this:

uniform float Test;

Also, you have to call glUseProgram() with your program object handle before calling glUniform1f(), so make sure that's what your shader.bind() does. It's enough if you call glGetUniformLocation() once and cache the result. Also, check the errors of your OpenGL calls with glGetError() to ensure everything else is working correctly.

Replying to your edit, I think this line is your problem:

const float F  = ((1.0-Eta) * (1.0-Eta)) / ((1.0+Eta) * (1.0+Eta));

const means compile time constant, as in, the value cannot be changed by a uniform. F can't be a constant because a uniform variable is not a (compile time) constant. Move the line that declares F to the body of main and remove the const qualifier. Then your shader should work.