PDA

View Full Version : GLSL and deprecated fixed functionality functions



Lefteris
01-25-2010, 03:29 AM
Hello all,

I am trying to make everything the "modern" 3.0 openGL way in my app and I have a question.

Say I want to access stuff like light properties and material properties in my shader. In GLSL there are the so-called build-int uniform variables/structs for this so I think that as far as the shader's part is concerned I am okay.

But how can I set the light and material properties from the main openGL application? I am asking since glLight and glMaterial are deprecated. Generally, even though I know what is deprecated I have not figured out exactly how to do all the deprecated functionalities in 3.0 code. Any help would be appreciated.

EDIT: I have a general idea about how it would be done but I am not sure if it is correct. I am thinking that they should be declared and passed to the shaders as any other uniform/attribute variables. Is this assumption correct?

For example setting the LightSource 0 position would be something like this?




glUniform3fv(getUniformLocation(shaderProgram, "glLightSource[0].position"),3, lightPosition);

BionicBytes
01-25-2010, 04:55 AM
you will need to declare uniforms in your shaders and your application will have to track and pass values into these uniforms.
Basically, what ever GL has done for you in the past you'll have to recreate your self - but you are free from the legacy way of doing it and you can implement it which ever way you see fit.

Lefteris
01-25-2010, 05:12 AM
Hmm yes I see. Thanks!
What about the already built-in uniforms/attribs/constants? There are many of them whose purpose is to provide in GLSL what the fixed functionality did for us in the past.

I read in the orange book that they exist. But do I need to declare them at the top of my shaders? Or can I jsut use them in the shader and pass values to them with glUniform like I would any other uniform variable, be it user defined or built in?

EDIT: Actually reading glGetUniformLocation specification it says that it returns -1 if the variable is prefixed with gl_ ... so that means that there must be another way to give values to the already built-in uniform variables

Ilian Dinev
01-25-2010, 05:31 AM
1) if using only regular uniforms (glUniformXXX) :
For uniforms that won't change more than 1-2 times per frame, you can do this:


foreach(GLProgram p in AllPrograms){
glUseProgram(p->glProgramHandle);
UploadLightUniforms();
UploadOtherGlobalUniforms();
}

For others, on program-bind upload the light-uniforms. As an optimization, you can implement state-versioning. Have each program wrapped in a struct, that contains a version-index of its state. On bind, compare versions and upload only if different.

Ilian Dinev
01-25-2010, 05:33 AM
About the gl_ prefix, simply avoid it. I.e change to gg_ .

Lefteris
01-25-2010, 05:43 AM
I see, thanks for the advice. So the built-in uniforms are just for being set from the deprecated fixed functionality functions? No other way e?

So I need to make my own variables in the shaders. Hmm using different programs eh? I need to read a bit more of the orange book to get a better feel for shader programs and how they should be used to change fixed functionality functions such as glPushMatrix() glPopMatrix() e.t.c.

Again thanks for your advice Ilian

Iulian B
01-25-2010, 08:25 AM
The built in uniforms themselves are deprecated in the later versions of glsl, so just don't use them . If you don't have them in your shader, when you compile/link it, the compiler won't add them as referenced so they simply won't exist in your shader, won't have any value, won't transfer and track any data and won't consume from your variable limit.

About the naming convention, as Ilian suggested, don't touch anything gl_ related. Just treat any variable starting with gl_ as RESERVED(even though deprecated) by OGL. Anyhow, I'm sure that you will have some naming convention at one point in your life which will dictate the name of those vars (and I hope it won't be "gg_" :) ).

Lefteris
01-25-2010, 11:50 AM
Thanks.

I guess the same goes for the built-in attributes. Except for gl_Vertex , this one seems to be a little special. Since when I submitted the vertices of my VBO with Either that or index 0 of vertex attrib array gotta be special:



glEnableVertexAttribArray(0);
glVertexAttribPointer(..);


Only for the vertices it worked which were at index 0. I had wrongly assumed that this is all that's needed. But for the other attributes (normals) for example my shaders worked correctly when I bound the attribs with glBindAttribLocation. What's so special about gl_Vertex? Or about index 0? It is the only attribute that worked without being bound anywhere.

Ilian Dinev
01-25-2010, 12:15 PM
The end of this page: http://www.opengl.org/sdk/docs/tutorials/ClockworkCoders/attributes.php

gl_Vertex is also deprecated, btw :) .

Only gl_Position, gl_ClipDistance, gl_FragCoord stay. There are also gl_InstanceID, etc that have been added.

Iulian B
01-25-2010, 12:40 PM
gl_vertex, like other input attribs, is just something reserved, so if you don't use it, it won't be transmited. I'm preety sure it's the same for gl_InstanceID, meaning that if you don't use it, I think that the compiler is free to optimise it away and not bind it at all (but you don't care about that, either way). So basically you have no fixed input, whatever you input in a vertex shader (either perVertex attributes or uniforms) is flexible and totally up to you.

On the other hand, gl_Position is used to rasterise the projected triangles, to transform them into pixels (sorry, fragments), and since it's used by some fixed functionality between vertex shader and fragment shader, it's needed. gl_ClipDistance, i am not that sure about it, so I'm gonna skip it (maybe Ilian may shed some light into it), and gl_FragCoord, you could do without, but basically it's just the fragment's "position", so it's what results from that fixed functionality between vertex shader and fragment shader. Everything else is for you to decide. That's the beauty (and, of course, the scary part) of shaders...

Lefteris
01-25-2010, 01:45 PM
The end of this page: http://www.opengl.org/sdk/docs/tutorials/ClockworkCoders/attributes.php

gl_Vertex is also deprecated, btw :) .

Only gl_Position, gl_ClipDistance, gl_FragCoord stay. There are also gl_InstanceID, etc that have been added.


That was it. Ilian now I understand. The pc on which I am developing is equipped with a nvidia GPU. So vertex attribute index 0 is automatically associated with gl_Vertex. And that's why gl_Normal was not automatically associated with index 1, it would have worked if I had used index 2.

Anyway the way I understand it now is that I should just lose all built-in variables and use my own attributes/uniform e.t.c..

That's both a blessing and a curse in my opinion as Iulian said. But I have to admit I like the control that is given to the developer using GLSL. I just have to get used to it. Thanks for clarifying things for me.

Iulian B
01-26-2010, 03:46 PM
the builtin variables, especialy if you're not using any part of the fixed pipeline, are just crutches that help the ones used with the old style GL use the new style GL.

So the difference between gl_Vertex and myVertexPosition is that the first one, if used inside the vertex shader, is automatically declared by the shader and preferentially bound to a specific vertex attrib index (1, in this case), while the second one you have to define explicitly and find out where did the linker bound it (if you don't specify, before linking a program, where you would like to link it).

So just think clear and outside of the fixed functionality. That thing doesn't exist anymore (ok, it exists, but shhhhh). The only thing set in stone is that, in the vertex shader, you have to output gl_Position (because it's used to generate fragments ) and in the fragment shader you have to output at least one color... it's as simple as that (riiiiight :p )