Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper way to manage shaders in OpenGL

I'm writing code in C++ to deal with the usual 3D stuff - models, materials, lights, etc. However, I'm finding that for anything to work, it needs to know about the shader. EG, to set uniform variables for a material, you need to know their handles from the shader; to load a mesh into memory, you need to know handles to different in locations.

I've ended up having models, materials, etc. each have a handle to the shader so they can do things like glUniform1f(shader->getKdLocation(),kd), but this kind of hot potato seems like bad design to me. I've seen tutorials where uniforms and ins and outs are hardcoded in the shader (eg layout = 0) and then just bound with glUniform1f(0,kd),. However, this means the rest of my code will only function with my specially laid out shaders and therefore seems like a suboptimal solution. Also, I don't think you can do this for subroutines, which makes this an inconsistent option.

It seems like a choice between everything getting a shader reference and in some cases being unable to even properly instantiate without one (eg meshes) OR hardcoding numbers in more places and having to deal with the problems that follow with hardcoding.

I should be able to have these models, lights, etc. live/operate independently and only "work" when I set a shader for the scene, but I can't seem to find a solid way to do this. My bottom line question is what is the best practice for handling shaders? I'm okay if it doesn't solve all my problems, I just want to know what a good design decision(s) is and why.

like image 647
GraphicsMuncher Avatar asked Jul 31 '13 13:07

GraphicsMuncher


People also ask

How do shaders work on OpenGL?

A Shader is a user-defined program designed to run on some stage of a graphics processor. Shaders provide the code for certain programmable stages of the rendering pipeline. They can also be used in a slightly more limited form for general, on-GPU computation.

Can you use multiple shaders OpenGL?

Multiple shader objects of the same type may not be attached to a single program object. However, a single shader object may be attached to more than one program object. However, even in OpenGL, using multiple shaders of the same type does not work they way you outline it in your question.

How do I link shaders in OpenGL?

After creating a program, the shader objects you wish to link to it must be attached to the program. This is done via this function: void glAttachShader(GLuint program​, GLuint shader​); This can be called multiple times with different shader​ objects.

Are shaders executed on the GPU?

To recap, shaders are programs that manipulate rendering output and are run on the GPU. Alternatives to shaders would be other methods of modifying rendering (output). The closests alternatives are the fixed-function pipeline and rendering manipulating software.


1 Answers

The problem is your engine architecture,or it's lack.In many game engines game objects are divided into several categories like Mesh object which takes care of geometry (vertex buffers etc),Material objects(responsible for the appearance of the mesh object).In such a design the material is usually an entity which contains info for the uniforms that being passed into shaders during rendering.Such a design allows a good amount of flexibility as you can reuse,reassign different materials between different renderable objects.So for the starter you can set specific shader program to specific material type so each time a mesh is drawn, its materials interacts with the shader program passing in all needed uniforms.

I would suggest you to take a look at open source OpenGL engine to get an idea how it works.

like image 187
Michael IV Avatar answered Sep 17 '22 22:09

Michael IV