In my program I use color picking + immediate mode gui, which is a really nice combination from a implementation standpoint. From a performance standpoint it is a wholly different matter.
For every element (button etc.) I draw the element, bind the picking fbo, draw the mask and then reset the target to the framebuffer.
This is enormously expensive (hundreds of elements).
Is it possible to selectively buffer openGL functions such that I only need to bind the fbo once?
The imgui is highly dynamic.
Should this be on the beginner thread? All comments are welcome.
I’m not sure what you mean by “selectively buffer openGL functions”. What would be the purpose of the buffer?
For FBO, if the texture size and perhaps format as well, if they are the same, you can use 1 FBO. This means you would have to attach the texture every time you want to render to a texture but it improves performance.
Other than that, reduce state changes as much as possible.
Peter, do you mean that for each widget, you draw once on the visible framebuffer, then once on the color picking framebuffer ?
Then you should, as said V-man, reduce state change.
A good way is to draw each widget on the color picking framebuffer, then switch to the visible fb, then draw again each widget.
Does it help ?
Thanks for the responses!
This is exacly what I’m asking for, a way to buffer all widget openGL calls that are intended for the fbo such that I need to switch to the fbo only once and send all buffered calls there.
With imgui there isn’t a list of widgets available: there are no objects.
Replace the term ‘widget’ by ‘element’ in my previous post if you prefer.
You use imgui because it is simpler to use, then complain it is not full-featured ?
How your current code looks like ? Maybe that would help people help you …
Maybe I’ve expressed myself inappropriate, but I never intended to come over complaining. I’m just looking for optimization.
Code wise it’s as you’d expect:
somewhere in the main loop:
void button(int id, GLfloat w, GLfloat h)
draw button code;
bind picking fbo;
set color to id;
draw button mask code;
Except from the binding hit, I’m not really missing any features.
Perhaps you could try binding both the color and picking textures to the same FBO, and use a fragment shader to direct the color to gl_FragData and the pick id to gl_FragData. This would allow you to draw all your widgets in one pass. Something like (fragment shader):
uniform int id;
// compute col
gl_FragData = col;
gl_FragData = vec4(id);
Attach your color texture to GL_COLOR_ATTACHMENT0, and the pick texture to GL_COLOR_ATTACHMENT1. You’ll need to use glDrawBuffers() select those buffers to draw to.
Interesting solution, thanks!
I’ll probably also draw to fbo soon enough anyway.
Need a little change in the shader though:)
gl_FragData = vec4(id);
gl_FragData = vec4(0);
I’d reckon this still gives quite a boost in comparison to binding whole the time…
The mask is actually within the texture, not the model.