Hey Embers,
I could use some experience/thoughts/opinions on using Cinder’s update()
and draw()
calls in a multi-window application. I’m a little fuzzy on certain details even in a simple context. Therefore, I thought I’d describe some scenarios from simple to complex, and state how I think things are generally supposed to work along with some questions.
One useful fact as I understand it upfront:
Cinder calls update()
once per frame, and calls draw()
once per frame, per window.
Scenario 1: Single Window
-
update()
- All CPU related code should ideally be run here. -
draw()
- All GPU related code should ideally be run here.
Question 1: It is my understanding that Cinder handles some graphics context matters around the draw()
call, so even rendering graphics that will not immediately be shown on-screen (i.e. rendering something into a FrameBufferObject
), should occur in draw()
, is this true?
Scenario 2: Multi-window, no shared graphics
Pretty much the same approach as above, as there is no shared graphics between the two windows.
I’ve noticed that the Cinder sample entitled BasicAppMultiWindow
makes use of setUserData()
and getUserData()
, to tie data context to a given window. In my case I instead bind separate draw()
, resize()
, close()
functions to the two windows, and each drawWindowX()
call simply access its own data. E.g. Window 1 connects to drawWindow1()
, where as window 2 connects to drawWindow2()
.
Question2 : Are there any side-effects or problems with this approach? I.e. not using setUserData()
and getUserData()
, and instead just storing the individual window data in the application object.
Scenario 3: Multi-window, shared graphics
This is my current use case. Window 1 has a unique scene to render which includes a scaled down render of Window 2’s scene. Since textures can be easily shared across graphics contexts, my approach is as follows:
Window 2’s scene is rendered in the update()
call, into a FrameBufferObject
. In drawWindow1()
window 1’s scene is rendered, which uses the color texture of the FrameBufferObject
. In drawWindow2()
basically only the color texture from the FrameBufferObject
is, again, rendered in its full resolution.
Question 3: Is this a bad approach? Should Window 2’s scene ideally be rendered in drawWindow1()
? If so, how do I ensure that drawWindow1()
is always called before drawWindow2()
for every frame?
Question 4: What if a scene needs to be rendered every n
-th frame into a texture, where n
is higher than 1 but still drawn on-screen every frame (via the texture). Should the rendering still ideally occur in draw()
or should it occur in update()
, and merely be drawn in draw()
?
I hope my questions make sense, and maybe the answer is ultimately “Do whatever you want.”, but I feel like there are probably some best practices to observe when it comes to these things.
Any thoughts are welcome.
Thanks in advance,
Gazoo