0
$\begingroup$

I am working on a software with lots of different shaders, which require different states in OpenGL. My problem is the following: The different models with different shaders are not rendered in the same order, so there is a switch form shader1 to shader23 to shader2 and so on. In the next frame this order can change (depending on the scenario). When I am adding a new kind of object (with new shader and so on) and I think it is working, I need to check every order of object-rendering to see, if bugs appear. With bugs I mean OpenGL states which are set to a specific value and later not changed back. How do you handle this?

I have the idea, to create a OpenGL state class where you can define each parameter. When running an render method, the current state will be compared with the OpenGL state and each setting which is different should be set to the state will is required for this rendering.

This seems to me more than a few lines of code... The most hardest part is to figure out which states are saved in which OpenGL table (with table I mean VAO, FBO, Texture, ...). Where can I find a table very good described where each OpenGL state will be saved?

I mean: when binding Shader1 and setting uniform "test" to value "123" and then binding Shader2, the uniform there also named "test" will not have the value "123"... so the uniform values are somehow stored on shader level?? Same with attributepointer and VAO...

On the other hand: PointSize is not stored on shader level... so each time I am rendering Points, I need to check which size they have and change it to the required size.

Can someone give me some URL to a table of OpenGL states?

Does someone has a better idea to handle this problem? BTW: I am not the only one who is working on this software... so saying "every time when changing a state, change it back at the end of the method" will not work.

$\endgroup$
4
  • $\begingroup$ You should avoid allowing arbitrary objects to have such arbitrary control over their rendering state. That is, the rendering state should be pulled out of the objects. $\endgroup$ Aug 28 '21 at 17:52
  • $\begingroup$ Let's say you have on one hand GPU procedural generated geometry and on the other hand obj mesh rendering... You need different shades with different states to render these... And with more different possibilities you need different settings / blendings. How would you manage this? Also when calculating in fragment shader you need different viewport sizes and so on. $\endgroup$
    – Thomas
    Aug 28 '21 at 21:29
  • $\begingroup$ "How would you manage this?" To what end? What are you making? That will ultimately inform how you manage anything. Are you making an "anything renderer" where user code gets to decide what state gets used for what? Are you making an engine that has rigid control over the means of rendering, with external users only being able to provide settings and the like? Is it somewhere in the middle, and if so, where? $\endgroup$ Aug 28 '21 at 21:45
  • $\begingroup$ I am not making an engine... It is a normal program with a scene. We are adding new content from time to time. We also use the GPU to calculate stuff like light intensity. The point is, that we have a lot of different stuff, and each needs diffend Opengl settings and blendings. From time to time we find bugs like: wrong blending function, from viewport size... We would like to keep it simple to implement new features, and therefore all states need to be managed in a simple way $\endgroup$
    – Thomas
    Aug 29 '21 at 8:55
0
$\begingroup$

This is more of a software design problem and might suit better software engineering se.

If I understood right, you have a problem like this:

scene1 with parameter P=1           object1
scene2 with parameter P=3           object2
scene3 with parameter K=1           object3
scene4 with parameter P=1           object4
                  \                    /
                   \                  /
                    \                /
                       drawing call

You can do one of the following. You can either embed states into objects or objects into scene states.

The first case is basically:

scene1 with parameter P=1 --------> object1
                       |
                       +----------> object4
scene2 with parameter P=3 --------> object2
scene3 with parameter K=1 --------> object3
                                       /
                                      /
                                     /
                       drawing call

The second solution (objects into shaders):

                                     object1
                                        |
                     +------------------+
                     |                  |
                     v                  |
scene1 with parameter P=1           object4
scene2 with parameter P=3 <-------- object2
scene3 with parameter K=1 <-------- object3
                  \                     
                   \                   
                    \                 
                       drawing call

Then during the draw call, you simply enumerate the objects in the order you wish them to be drawn with correct parameters. If the order changes dynamically along with parameters for each draw call; you either traverse the objects first to set correct parameters then draw. In the dynamic case embeding objects into your scene state class might result in better performance if you have a lot of objects, since you can order objects inside your scene states according to the drawing order (the problem is simply about ordering your sublists according to the containing list [[1,2,3],[4,5],[6,7,8,9]]).

Update 01 - 16/09/2021

The global state of OpenGL can be accessed using glGet function of state management functions. You can write a wrapper class over those functions as you had stated in the comments. If you need to access primitives and related information dynamically to determine state, you should be able to do so with query functions such as glBeginQuery

$\endgroup$
3
  • $\begingroup$ I am more talking about global states like: pointsize, linewidth, enableBlend, blend function, enable culling, enable stencil, Scissor, viewportsize and a lot more. I thought about a helper class which is the only class who is allowed to change these states. and each function which is going to draw something caries an object of this class where the wanted state values are saved in. Then the class checks out the difference of states and change these to the correct value. $\endgroup$
    – Thomas
    Sep 16 '21 at 6:11
  • $\begingroup$ But I think there must be a better solution to this problem, because this class will hold a lot of information and each drawing function needs to perfectly declare the wanted state... Does a buffer exist, where these states are stored to? so that I can directly bind the buffer to enable only the necessary states? Like the VAO, FBO, uniform buffer... $\endgroup$
    – Thomas
    Sep 16 '21 at 6:15
  • $\begingroup$ @Thomas I made an update as per your comments. Basically you can use glGet to access values. The state variables are not stored in a buffer. At least the documentation does not mention such a buffer. It seems logical as well since they require different types for each parameter $\endgroup$
    – Kaan E.
    Sep 16 '21 at 8:24

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.