2
\$\begingroup\$

First, some details:

In a fragment shader, I'm trying to make an image do a sort of "flipping mirroring" animation (lines 44-57):

#version 450 core
in vec3 Color
in vec2 Texcoord;
out vec4 outColor;
uniform sampler2D tex;
uniform float factor;
void main() {
 if (Texcoord.y < factor) {
    outColor = texture(tex, Texcoord) * vec4(Color, 1.0);
  } else {
    outColor = texture(tex, vec2(Texcoord.x, 1.0 - Texcoord.y));
  }
}

When factor is 1, the image should be right-side up and has some color on it. When factor is 0, the image should be upside down and has no color added to it. When factor is 0.5, the top half should be right-side up and the bottom half should be upside down.

Currently, that is only the case if I replace factor with the number.

When I set the uniform factor with glUniform1f(), I'm getting very strange results. To illistrate, I added some debug code to lines 188-197 that sets the uniform with one number, retrieves the number from the uniform, and outputs both values to try and see what's going on.

Here's the code:

GLfloat factorToSet = 1.0f;
GLfloat setFactor = 0.0f;
GLint uniFactor = glGetUniformLocation(shader_program, "factor");

while (factorToSet > -0.1f) {
  glUniform1f(uniFactor, factorToSet);
  glGetUniformfv(shader_program, uniFactor, &setFactor);
  printf("Factor of %.1f becomes %f\n", factorToSet, setFactor);
  factorToSet -= 0.1;
}

And here are the results:

Factor of 1.0 becomes 0.000000
Factor of 0.9 becomes -2.000000
Factor of 0.8 becomes -0.000000
Factor of 0.7 becomes 2.000000
Factor of 0.6 becomes 0.000000
Factor of 0.5 becomes -0.000000
Factor of 0.4 becomes 2.000000
Factor of 0.3 becomes -36893488147419103232.000000
Factor of 0.2 becomes 0.000000
Factor of 0.1 becomes 36893488147419103232.000000
Factor of -0.0 becomes -0.000000

So with what little I understand about OpenGL and the way scalar types are stored in binary, I'm thinking that this issue is caused my GLfloat getting converted into something else on the way to the shader's uniform float. But I'm grasping at straws.

What could be causing this strange conversion between the number I send to the uniform float and the value that the uniform float becomes? What could I do to fix it if it's possible to fix?

Thanks in advanced for any help and leads, I really appreciate it :)


An additional note after receiving a working answer

George Hanna provided a link to a post where someone had a similar issue. I read over the comments and someone said to use -DGL_GLEXT_PROTOTYPES as a CFLAG. So I rolled back my local code to use glUniform1f() again, added -DGL_GLEXT_PROTOTYPES to the Makefile, and everything worked! Even crazier, all the compiler warnings I had for implicit declarations of OpenGL functions were gone!

So in addition to the answer below, if you have this issue, try adding -DGL_GLEXT_PROTOTYPES to your CFLAGS.

(You can also get this affect by adding #define GL_GLEXT_PROTOTYPES before any OpenGL #includes)

\$\endgroup\$
  • \$\begingroup\$ Are you checking that there isnt any errors in your program using for example: GLenum err; while((err = glGetError()) != GL_NO_ERROR) { //Process/log the error. } \$\endgroup\$ – George Hanna Aug 29 '17 at 7:39
  • \$\begingroup\$ Hi @GeorgeHanna, I had this code chuck full of error checking with every OpenGL call and there were no errors. I cleaned it out to make the code easier to follow on Github. \$\endgroup\$ – Faison Zutavern Aug 29 '17 at 17:36
1
+50
\$\begingroup\$

You can try solving the issue by using glUniform1fv(uniFactor, 1, &factorToSet); instead of glUniform1f as this has worked for others.

Similar problem and possible fix

\$\endgroup\$
  • \$\begingroup\$ This solved the issue. I'm not sure why OpenGL is having a better time getting a reference to a value rather than a copy of the value, but I'll roll with it :) Thanks! (FYI, I can't award the bounty for another 2 hours, so hang tight for that) \$\endgroup\$ – Faison Zutavern Aug 29 '17 at 18:17
  • 1
    \$\begingroup\$ Hi @GeorgeHanna, I read further in the comments of that link you provided and someone mentioned adding -DGL_GLEXT_PROTOTYPES to the CFLAGS for gcc. So I rolled back my code to use gluniform1f(uniFactor, factorToSet) and added -DGL_GLEXT_PROTOTYPES to the Makefile and it worked! I used to have a bunch of warnings for implicit declarations of OpenGL functions too, but those are gone when the flag is added. I'll add that as a note on the original question just in case anyone else has this issue in the future. \$\endgroup\$ – Faison Zutavern Aug 29 '17 at 18:37
  • \$\begingroup\$ Great that it worked out. It seems to be some kind of compiler issue. \$\endgroup\$ – George Hanna Aug 29 '17 at 19:20
1
\$\begingroup\$

You need to either use

glProgramUniform1f(shader_program, uniFactor, factorToSet);

if you have either at least GL 4.1 or the ARB_separate_shader_objects extension or use

glUseProgram(shader_program); // CALL THIS FIRST

glUniform1f(uniFactor, factorToSet);

to select which shader you want to "work on" before you can change the uniforms.

Uniform values are conceptually stored "inside" the shader program (actual implementation may vary but act as-if the same), each individual programs have their own uniforms so you must select the shader program first or use glProgramUniform1f to set uniforms on a specific program without selecting it first.

For completeness: If you want to share uniform values between shader programs you can use Uniform Buffer Objects.

\$\endgroup\$
  • \$\begingroup\$ Hi there. It's not 100% clear from my code snippets above, but if you look at the code on github, I am calling glUseProgram() on line 161. My question isn't "How do I set a uniform float?" My question is "Why are the values I send to a uniform float radically off?" If you look at the code snippet with a while loop (From lines 188-197), I'm sending a float to a uniform float, then I immediately retrieve it. Look at the results that start with "Factor of 1.0 becomes 0.000000" to see my issue. \$\endgroup\$ – Faison Zutavern Aug 29 '17 at 3:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.