RealtimeDisplayMode: DrawOpenGl, IsFrameBufferAvailable and SignalRedraw

I am seeing that on occasion DrawOpenGl gets called continually, even after the final frame is done.

More often, once the image has converged, I see the viewport being rendered in pure white, with an orange HUD bar.

Perhaps we are doing something wrong after the recent change to the API. Should we expect IsFramebufferAvailable to be called before each call to DrawOpenGl? After rendering, do we still need to call SignalRedraw to trigger this?


You should be calling SignalRedraw() only when you have a new/updated render result. If you call this in your DrawOpenGl() function you’ll cause the underlying pipeline to issue a new redraw of the viewport, which will result into a check to IsFramebufferAvailable(), and if that gives true, then issue the DrawOpenGl() call.

Does that clarify enough?


Thanks, that is what we have. Then my DrawOpenGl problem remains. Sometimes I just get called repeatedly by Rhino, without intermediate calls to IsFrameBufferAvailable, or calls to Render, just repeatedly drawing the OpenGl, and returning false. What might we be doing wrong to cause this? It basically freezes the interface.

Hmm, question: what does the return value of DrawOpenGl mean?

Essentially whether you are of the opinion you drew anything or not. I.e. if something in your code determines you cannot draw (or failed to do so) you return false.

Okay, that is what we are doing, we didn’t render a frame internally, so when the DrawOpenGl call comes, we do nothing and return false, repeatedly.

Could it have something to do with changing the max iterations in the HUD? When I change this from 500 to 10, say, then there is a redraw glitch on the HUD, and the rendered image only refreshes behind the iterations text in the HUD.

Hmm, I don’t see that happening with Raytraced. @andy, any idea what could be causing the redraw issues @CarstenW is having?

Any news on this? I am a bit stuck on my OpenGL checkin.

@CarstenW, any chance you can reproduce this through setting up the simplest RhinoCommon plug-in that does what your plug-in does and shows the behavior you are reporting? I have had no problem with the drawing through OpenGL, and I’m not really understanding how you get into that situation. The explanation is hard to follow without any code to look at.


I found the problem on our side, but there may be something you want to change on your side too.

We were under some circumstances returning true for IsFrameBufferAvailable, but then false from DrawOpenGl, due to insufficient synchronisation between two threads for the boolean in question. This caused Rhino to call IsFrameBufferAvailable once, get the true, and then call DrawOpenGl forever without ever calling IsFrameBufferAvailable again. Possibly, it should just give up after the first time and wait for the next SignalRedraw instead, and in any case, I think it ought to call IsFrameBufferAvailable each time just in case, which would have also solved our problem for us.

The synchronisation problem on our side is rather involved, and I may end up always returning true from DrawOpenGl for now, and simply drawing the most recent frame again, if it should be entered twice. As long as IsFrameAvailable starts returning false soon, which it will in our case, then there should be no problem with that, I think.

We have also seen surprisingly long sequences of IsFrameBufferAvailable calls to us, with no action, we return false each time, at least tens, maybe hundreds of them. Waiting for SignalRedraw again seems like a better solution, after the first false.

Finally, for some reason, we often see an orange HUD bar, and occasionally a white frame at the end of the sequence, after convergence. Any idea why this happens?


Note also:

The HUD bar is with our current code always orange, and the max samples field is missing.

Whenever we pause in the HUD, we get a white frame.

[Edit: we do not always get the white frame, just sometimes.]

Another observation:

If I start Iray in one VP, then start wildly resizing the VP and then right- and left-clicking in the neighbour VP, then I can provoke it into starting another instance of Iray, although I didn’t ask for it.

Right-clicking in Rhino viewport means repeat last command. In your case most likely the switching of viewport mode to Iray. Switch one viewport to Iray, then right-click in another.

Does that clarify?

Ah, that is unexpected! I guess right-clicking-and-dragging is separate, because we do this all the time to navigate.

Is there some way we can stop that from happening, or should we simply allow it and switch rendering off in the first VP? We cannot currently support two simultaneous renders in VPs.

I think you can either stop the current render, or just bail early from the StartRenderer returning false for the new vp

Thanks, will try that.

Note that the question with the orange HUD and missing iterations counter still stands, i.e. what causes the orange HUD to appear?

Orange is used when a redraw happens while IsFramebufferAvailable returns false. After a viewport manipulation you should return false until the very first render result is complete, after that return true.

For the maximum pass count to show override HudShowMaxPasses and return true.

We do return true from HudShowMaxPasses, and the iterations normally show, just not when orange.

I will take a look at our return values when navigating, thanks. Do you mean that we call SignalRedraw() but then return false from IsFrameBufferAvailable()?

For the moment we now return true always for both IsFrameBufferAvailable and DrawOpenGl, everything seems to work better that way, and we simply draw the last image we rendered. With this change, the orange HUD is gone, the iterations are back, and performance is fine. When I get a chance, I will revisit this and try to figure out what is going wrong.