Hacker News new | ask | show | jobs
by skocznymroczny 2108 days ago
I like OpenGL, but I really hate the global state. If only there was some concept of state objects that record state, something like:

glBeginState(&stateObj); glEnable(GL_BLEND); glDepthTest(GL_LEQUAL); glEndState(&stateObj);

and then later on you'd do glBindState(&stateObj) to apply it.

I have high hopes for WebGPU though and I am going to migrate my renderer to it soon.

4 comments

That sounds much worse. That's still global state, just encapsulated global state. Any time you say glBindWhatever(), you're assigning global state. And the state obj should be an opaque handle so you don't end up with stale pointers. Should be glEnable(state, GL_BLEND); glDepthTest(state, GL_LEQUAL);.
I recently wrote a tiny game[1] and rendering with WebGPU was reasonably easy as it was mostly clear why/where things were going wrong and there was little state to manage, while WebGL was enough of a hassle that I didn't even manage to get instancing working.

[1]https://specificprotagonist.itch.io/cary

Something like `glBindState()` would encapsulate the global state, but it wouldn't eliminate it. A better approach would be to pass in the state to the draw command like WebGPU/Metal/Vulkan do, which would also allow the driver to amortize the cost of state validation.
Webgl doesn't have this problem since it runs those functions on a context object. But yeah i wish there was a way to do that with opengl.
The problems of global state persist in WebGL, because (1) if you need to save and restore state inside a single context, WebGL provides no help; (2) the driver is unable to amortize validation as the state is not tied to the individual render pass/pipeline descriptors.
Interesting. When you say "save and restore state", do you mean actually serializing it and loading it later? In what situation would you want to do this? Not doubting that there is one but i haven't heard of this before.
Typically you use this feature to associate state with an object in your render graph. For example, all of the render state used to render the sky, including shader program, vertex buffers, textures, blend state, etc. can be attached to the sky node in your scene graph. Then you can (basically) have a generic "draw an object in your scene graph" function that just performs the appropriate drawcall with the right state. The performance advantage of this is that the driver can do all the validation once, when you construct the sky object, instead of every frame.