> I just went back and had a look at the function I was using as my 'draw'
> caller, and you are right in that I have mistakenly used draw() and not
> redraw(). The function that I use to call the draw method in the Fl
> window looks like this (very simple):
> void My_Fl_Window::DrawFrame(void){
> this->make_current(); // I added this line after reading your post
> this->draw();
> }
> The idea being that I can call DrawFrame() from somewhere else to get
> the window to draw and then collect the pixel data associated with it.
For a GL window, with the make_current() added as above, this probably should work OK; this is in essence the case that make_current() for a GL context is meant to support (that you can draw into a GL surface outside the normal fltk rendering sequence, if you choose to do so.)
That said, I have pretty much never used this approach.
The caveats are that it may be sensitive to how a given GPU or GL driver works (which is outside fltk's control) and it is not likely to be thread safe, so you need to be sure you call DrawFrame() from the thread that owns the GL context.
> I've just changed that over to redraw(), but it's now crash-prone.
Hmm, that's interesting. Any info on the nature of the crash?
> It's
> not responding to variable changes like viewport camera angle changes,
> or window resizing, which are triggered and set from outside the Fl
> window itself.
Presumably the draw() method needs to apply these values to the context when it starts each draw update?
If you issue a redraw(), then the actual draw() will happen "sometime later" (and you don't know when) so in that case you can't collect the pixel data associated with the draw from the point at which the redraw() was called. (Is that possibly what causes the sporadic crashes?)
You are best to have the draw() method gather the pixel data immediately after it finishes updating the scene (i.e. whilst the context is certain still to be valid) and have it stick that data *somewhere* to be consumed by your other operations...
Trying to read the pixel data back asynchronously to the update process is likely to be fraught with difficulties and somewhat "fragile"...
> I'm using the Fl_Gl_Window as an offscreen "drawer", does
> this do anything to boost the case for draw()?
I think I'd use some sort of FBO for that rather than an actual window, but I don't see any real problem with what you are doing.
If "make_current(); draw()" is working for you, then it is a reasonable way to proceed for a GL context.
> Is it possible to force a redraw without the core deciding on whether it
> needs to redraw or not?
No, not really.
> For what it's worth, thus far, I haven't been getting any crashes using
> draw() directly apart from things like the glGenBuffers issue, which
> seemed to be a glew thing.
I think you need to find a way to let fltk create the window, map it to the display and draw() it one time, before you start calling draw() directly yourself. I suspect the issue is that you are trying to call draw() on a window that doesn't fully exist yet...
Add a flag that gets cleared down in the draw() method, and have your DrawFrame() method check that first.
That way, DrawFrame() can skip calling draw() at all until after you are sure fltk has created the window and called draw() at least one time. (And hence the context must now exist, so calling "make_current(); draw()" should then be valid.)
> Should I dig into the redraw() crash a little
> more? Or Is it 'safe' to keep using draw() directly in an environment
> like this?
I think this use of draw() is probably safe.
It might still be informative to understand why the redraw() case crashes...
--
Ian