Sign in to follow this  

GLSL shader management

This topic is 2550 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi everyone.

I'm begining to work with shaders using GLSL. I understand most of the basic rendering techniques like multitexturing, bump-mapping, light-mapping and shadow mapping (i have done some little tests using those).

Putting all those things together is a bit more complicated.

I read a post on these forums about managing shaders. It seems to be an expensive "state" change (because of the need to re-compile everything). In order to decrease the penalty of those changes, people were talking about über-shader and dynamic linking vs static linking.

My question is about dynamic linking. Tell me if i'm right or wrong, i just want to make sure i understand.

1. For what i get, you can send multiple shaders (vertex shaders and fragment shaders) to the video card but you can have only one program at a time (makes sense). So dynamic linking consists of choosing the right combination of shaders for what you are rendering then linking them into a program at run time and selecting this program. Then you delete the program and link a new one for the next thing you have to render, etc. Am i correct ?


2. My hardware supports the shader binary extension (recent driver is no longer beta on NVidia hardware :D). Does that mean you can precompile only your shaders and still have to link them dynamicly or can you generate the binary of the program and just push the whole thing (pre-compiled) to the hardware ? Anyone have tried the shader binary ?

Thank you very much for you replies.

Share this post


Link to post
Share on other sites
It is not a terribly expensive operation to change shaders (glUseProgram).
Compiling and linking a shader can take 100 ms. I have a few hundred so it took a few minutes to compile all at startup.

Avoid linking a shader while the user is playing.

I am now using binary shader. It is about fucking time they offered us this.

Share this post


Link to post
Share on other sites
Quote:
Original post by V-man
It is not a terribly expensive operation to change shaders (glUseProgram).
Compiling and linking a shader can take 100 ms. I have a few hundred so it took a few minutes to compile all at startup.

Avoid linking a shader while the user is playing.

I am now using binary shader. It is about fucking time they offered us this.



I totally agree, shader binary looks like heaven. Unfortunatly, as far as i know, it's not yet widespread on hardware (latest video cards only). I think, since shader is the way to go, it is a logical evolution. It did take some time thouhg.

So, if you can't compile and link shadres at runtime (100 ms is just more time then you have in one frame), can you send more then one to the video card and just switch ?

If not, i guess you don't have much choice then to go with a huge shader with alot of branching in it ... which is a pain to work with and debug.

If i understand you correctly, you compile and link all your programs at startup even when not using shader binary ?


[Edited by - Laval B on December 25, 2010 9:25:27 AM]

Share this post


Link to post
Share on other sites
sure, you can have as much shaders as u wish.

At startup compile and link every shader u will use and at runtime just switch them with the useProgramm(?) command

Share this post


Link to post
Share on other sites
Quote:
Original post by Danny02
sure, you can have as much shaders as u wish.

At startup compile and link every shader u will use and at runtime just switch them with the useProgramm(?) command


Oh thank you very much, that clears that out. I would have made some tests, but i'm stuck in an airport for another hour right now with a lousy lap top.

So i just have to use glUseProgram to switch (and of course set the parameters).

Just one quick and last question : the vertex attributes set with glVertexAttribPointers (or something like that) for meshes, are those set on a per vbo basis or do i need to set those every time i change mesh ?

Thank you very much and merry christmas to you all.

Share this post


Link to post
Share on other sites
how vertex attributes work are a little bit complicated, but I give it a try :-)

first a short summary how a draw call looks like

-bind shader

-enable all attribtues (glEnableVertexAttribArray)

-bind a buffer (glBindBuffer)

-set all attribute pointers for this buffer (glVertexAttribPointer)
optinonal:
bind another buffer, and set pointers of attributes which are stored in this buffer

-bind index buffer if one is used

-draw mesh

-disable attributes (glDisableVertexAttribArray)

at the moment where the attribute pointer is set a opengl state is set which binds the attribute to the current bound buffer, so as long the specific attribut isn't disabled the specified attribute(id) is querryed from the buffer which was bound to the attribute.

so to come back to your question^^. If u want t orender a differnent mesh, yes u have to set the attribute pointers again so that they are boudn to the new buffers


ps: If you are rendering a bunch of different models with perhaps also a lot of different buffers ther is a very neat extension(available on almost all opengl 2 video cards and core with opengl3).
It's called VertexArrayObject(VAO), the cool thing about it is that is let you save all these attribute/buffer state in a object to un/load all the different attribut states on your will.

usage:
creaet with glGenVertexArrays(int count, out int* ids, int offset)
bind with glBindVertexArray(int id)
disable with binding id 0

To use VAO u would creat one for each mesh u want to render. Create the VAO bind it, bind all attributes with there buffers of the mesh and after that just disable the VAO and do it with every mesh.

So now when it comes to rendering the msehes the only thing u need to do before calling the draw command is to bind the vao of the mesh(2 calls instead of maybe 10?)

Share this post


Link to post
Share on other sites
Quote:
Original post by Danny02
how vertex attributes work are a little bit complicated, but I give it a try :-)

first a short summary how a draw call looks like

-bind shader

-enable all attribtues (glEnableVertexAttribArray)

-bind a buffer (glBindBuffer)

-set all attribute pointers for this buffer (glVertexAttribPointer)
optinonal:
bind another buffer, and set pointers of attributes which are stored in this buffer

-bind index buffer if one is used

-draw mesh

-disable attributes (glDisableVertexAttribArray)

at the moment where the attribute pointer is set a opengl state is set which binds the attribute to the current bound buffer, so as long the specific attribut isn't disabled the specified attribute(id) is querryed from the buffer which was bound to the attribute.

so to come back to your question^^. If u want t orender a differnent mesh, yes u have to set the attribute pointers again so that they are boudn to the new buffers


ps: If you are rendering a bunch of different models with perhaps also a lot of different buffers ther is a very neat extension(available on almost all opengl 2 video cards and core with opengl3).
It's called VertexArrayObject(VAO), the cool thing about it is that is let you save all these attribute/buffer state in a object to un/load all the different attribut states on your will.

usage:
creaet with glGenVertexArrays(int count, out int* ids, int offset)
bind with glBindVertexArray(int id)
disable with binding id 0

To use VAO u would creat one for each mesh u want to render. Create the VAO bind it, bind all attributes with there buffers of the mesh and after that just disable the VAO and do it with every mesh.

So now when it comes to rendering the msehes the only thing u need to do before calling the draw command is to bind the vao of the mesh(2 calls instead of maybe 10?)



That's a very awesome responce and it is very clear, just what i needed. I will take a look at that VAO extension, it's very interesting and will simplify the states management alot.

Tanks again, let me go bump your raiting :P

Share this post


Link to post
Share on other sites

This topic is 2550 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this