newbie, inout function

I just started reading the orange book and wrote a simple program to incorporate a vertex and fragment shader, etc.

I want to use the vertex shader to perform a Z axis rotation on an object; to do that, I figured I could use a global float “ZRotation”, and set it to the z-rotation of the object before the draw calls. So the vertex shader looks like this:


void rotate2D (inout float x, inout float y, float rads);

uniform float ZRotation;

void main() {
	vec4 new_v = gl_Vertex;
	rotate2D (new_v[0], new_v[1], ZRotation);
	gl_Position = gl_ModelViewProjectionMatrix*new_v;
}


void rotate2D (inout float x, inout float y, float rads) {
	float x1 = x, y1 = y;
	x = x1*cos(rads) - y1*sin(rads);
	y = x1*sin(rads) + y1*cos(rads);
}

My impression of an “inout” variable is that this should modify new_v[0] and new_v[1], but nothing happens (it does compile and is used, if I tweak, eg, new_v[0] += 10.0f, the object is moved right).

Which brings up another elementary question: is there any way to run these in a debugger, or produce some kind of output to check values to see if I what I think is going on is going on? I am positive the problem is that “ZRotation” is always 0, but it would be much easier if I could track that value to be sure.

:smiley: I missed the “glUniform()” function. Unfortunately, using it does not seem to make any difference:


	var = glGetUniformLocation(Shaders[2],"ZRotation");
        glUniform1f(var,0.5f);

glGetUniformLocation returns a non-error value, and there are no errors subsequently from glGetError, but ZRotation in the vertex shader is still obviously 0.

Use of glGetUniform() confirms this. The variable is declared in the shader globally:


uniform float ZRotation;

How am I supposed to modify this?

void rotate2D (inout float x, inout float y, float rads) {
	float x1 = x, y1 = y;
	x = x1*cos(rads) - y1*sin(rads);
	y = x1*sin(rads) + y1*cos(rads);
}

This is not good GLSL code. Better code would be something like this:

void rotate2D (inout vec4 vertex, float rads)
{
  mat2 tmat = mat2(cos(rads), -sin(rads),
                   sin(rads), cos(rads));

  vertex.xy = vertex.xy * tmat;
}

As to the substance of your problem, I can’t say. glUniform is the function you use to set uniform values. Those values become part of the program object state.

you do realise that the shader has to be bound before the glUniform1f call?
So glGetUniformLocation works without the shader bound (because it takes the shader handle as a parameter), but glUniform needs to have the shader bound (doesn’t take a shader handle as a parameter).

What do you mean by “bound”? The openGL page (http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml) claims:

glUniform operates on the program object
that was made part of current state by calling
glUseProgram.

Which there is only one program object in the code, and it was presumably “made part of the current state” since it was called with glUseProgram. As I said in the first post, the shader clearly is operating, just I cannot submit variables to it.

Beyond that, I haven’t seen or found any other references to “binding” shaders at all.

Wow, looks to me now like this is a driver bug. Found a report of the exact same issue from 2 years ago which showed different output using different drivers:

http://www.gamedev.net/community/forums/topic.asp?topic_id=470542

Since the only value I’d tried so far was 0.5, I tried 0.85 and there is some visual change – but not appropriate to the value. Also, the value reported back by glGetUniform is always 0.

This is extremely pathetic – I was hoping all this stuff would be stable everywhere by now.

I will file a bug report with ATI (9.12 x86_64 for linux), but if anyone has any ideas about who else I should complain to, lemme know.

What do you mean by “bound”?

Just because it doesn’t have the word “bind” in the function name doesn’t mean that glUseProgram doesn’t bind the program to the context.

This is extremely pathetic – I was hoping all this stuff would be stable everywhere by now.

Um, if uniforms could not be used, then every program using GLSL on ATI hardware would be broken. I know mine isn’t, so I’m pretty sure it’s something in your code.

As a temporary solution, try “new_v.x, new_v.y” instead of “new_v[0], new_v[1]” .

I’m inclined to agree, but then again I don’t know of any software using GLSL on my system, and it could have been some peculiar specific card glitch with the driver, which by the time you get to the number of people using a specific chipset with GLSL on linux I dunno – the numbers might not be so great.

I took Alphonse’s advice about how to use the matrix math powers of GLSL already. Very nice, so I am pretty happy that what the problem turned out to be was just this:


#define GL_GLEXT_PROTOTYPES 1

Tee hee. Guess I’ll save that bug report for next time something doesn’t work right away again. :smiley: This is the second time I’ve done that, so if I do it again I have to start giving myself electric shocks.

I’m left with two questions:

  1. I notice most example code never bothers to include this #define either, so I am guessing on most implementations it is somehow not necessary?
    2) what do you normally use to debug shaders?

>> 2) what do you normally use to debug shaders?
I render into a FBO with 4 rendertargets, each is RGBA32f. I modify the GLSL code to write the values of the variables in interest into the different targets. Then, reading the focused pixel of the 4 textures and printing the values. A quick hack would be to just make “glFragColor=vec4(ZRotation,0,0,0);” and see the RGB values onscreen. (sometimes biasing and scaling is necessary, to fit in the [0;1] range).

>> 1)
GL_GLEXT_PROTOTYPES should stay undefined under Win32 (where the opengl32.dll simply doesn’t export those extension-funcs). Under Linux with updated .so and .a and .h files, you have immediate access to those funcs, thus there GL_GLEXT_PROTOTYPES should be defined.

you should be thanking me, not patronising me. You’re the idiot complaining on a public forum about a uniform not changing when you weren’t even calling the function to change the bloody thing. If you’re claiming to be a newbie, at least act with the humility of a newbie. From now on you won’t even be getting the steam off my shi t.
Someone else can explain to you what steam is.

I didn’t “patronize” you at all, idiot. I was just asking for a clarification.*

That is the hands down most PARANOID response I have ever seen on a programming forum, & my combined posts (mostly giving advice, not asking for it) are 6000+ in the past several years.

From now on you won’t even be getting the steam off my shi t.
Someone else can explain to you what steam is.

Please! Thank you! AFAICT you will be no help anyway.

I don’t presume any expertise on anyone’s behalf regardless of how special they think their tish is, BTW. You could be any moron.

  • Is it so hard to use the actual term, “glUseProgram()” rather than some vague term that could refer to anything for someone doing this the first time?
  • Is it so hard to use the actual term, “glUseProgram()” rather than some vague term that could refer to anything for someone doing this the first time?

Actually, yes.

OpenGL had a very consistent object paradigm, right up until GL 2.0 and GLSL objects. For some reason, they decided to abandon this consistency that they had used for something half-way between an actual opaque type and the standard object syntax. Because it isn’t really an opaque type, you don’t get the benefits of having it be an opaque type, but you do get all of the downsides. And it introduces inconsistency in what was a very consistent (if kinda silly) object paradigm.

glUseProgram binds the program to the context. This is functionally identical to what happens when you bind any other OpenGL object in every way. The program object takes over state just like a regular GL object does. And you have to bind the program in order to change its state. There is no reason for it to be called “UseProgram” rather than “BindProgram”. Thus, there is no reason for us as users to make a distinction between “using” a program and “binding” it.

we have a phrase for people like you round our way - and that phrase is “bell end”. Happy new year Mr.End.

yeah me too tough guy – it begins with a and ends with hole. go stick it.

you smell.
one thing I couldn’t understand about this thread was how you linked to a forum post complaining of a bug in nvidia drivers, yet subsequently tell us that you’re going to file a bug report with ATI. Are you running on ATI hardware or NVidia’s?
And before you start your usual vinegar, it would be worth you noting that the distinction between ATI and NVidia is most definitely important. They produce different hardware, and subsequently different drivers, old chap.