RE: [fltk.general] Fltk and glew

133 views
Skip to first unread message

MacArthur, Ian (Selex ES, UK)

unread,
Apr 28, 2015, 4:47:38 AM4/28/15
to fltkg...@googlegroups.com
> I'm using (trying to use..!) fltk in combination with glew, and for most
> of the basic tasks so far it's working well. However, as soon as I start
> using functions like glGenBuffers(), the program crashes.


Yup - as you note below, you have to init glew. But...


> From reading various Google search links, it appears it is something to
> do with glew not being initialised.

Yup. Almost certainly. GL's such a pain sometimes... (usually.)

> So I've tried putting glewInit()
> (and setting the experimental flag) in various locations around the
> window class, but all are returning an error, with the error string
> reading "Missing GL version". Is it possible to initialise glew and work
> with the library in tandem with FLTK? If so, does anyone know how to
> initialise the glew library for use with an fltk window?
> My window is currently derived from Fl_Gl_Window, cheers.

OK; here's what works for me...

Firstly, when I hit this the first time, I was trying to call glewInit() but it would not work.

The key is that glewInit() needs a valid GL context to exist for it to work with, it seems, but in fltk such a context is not instantiated until the first attempt to actually draw() a Fl_Gl_Window.

So, what I do is put a pile of glew init trash into a helper function, then call that from the window's draw() method *one time only* they very first time that window is ever drawn. (And if you have multiple GL windows you might need to get a bit fancy there, though I think that calling glewInit() multiple times might be relatively benign...)

Some code fragments (very incomplete...):-


void eye_view::draw()
{
GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };

// First time? Or at least first time after a resize or etc... init the viewport, context...
if (!valid())
{
init_gl();
} // end of "first time" check

:
:
etc...


which calls:-

void eye_view::init_gl()
{
valid(1);

if(do_construct)
{
do_construct = 0;

// init GLEW
GLenum err = glewInit();
if (GLEW_OK != err)
{
/* Problem: glewInit failed, something is seriously wrong. */
fprintf(stdout, "GLEW Error: %s\n", glewGetErrorString(err));
}
fprintf(stdout, "GLEW Status: Using GLEW %s\n", glewGetString(GLEW_VERSION));

// construct object
Create_Object();
printf("Objects set up\n");
fflush(stdout);
}

// Initialize GL
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);

glShadeModel(GL_SMOOTH);
:
:

//Set up the left and right FBO
glGenFramebuffers(2, framebuffer); // make 2 framebuffers
glGenFramebuffers(2, renderbuffer); // make 2 renderbuffers

:
:
etc...

The key flag here is "do_construct" which is set non-zero by the widget constructor, then cleared down after glewInit() et al have been executed once.

I'm reasonably hopeful the same merry dance can work for you.

Hope that helps,
--
Ian




Selex ES Ltd
Registered Office: Sigma House, Christopher Martin Road, Basildon, Essex SS14 3EL
A company registered in England & Wales. Company no. 02426132
********************************************************************
This email and any attachments are confidential to the intended
recipient and may also be privileged. If you are not the intended
recipient please delete it from your system and notify the sender.
You should not copy it or use it for any purpose nor disclose or
distribute its contents to any other person.
********************************************************************

eyeball_en...@hotmail.com

unread,
Apr 28, 2015, 6:06:20 AM4/28/15
to fltkg...@googlegroups.com, ian.ma...@selex-es.com
Hi there Ian,

The key flag here is "do_construct" which is set non-zero by the widget constructor, then cleared down after glewInit() et al have been executed once.

I'm reasonably hopeful the same merry dance can work for you.
 
interesting - I had a few errors with this. It trips up the first 2-3 times draw() is called. But the early failed attempts might be me trying to use draw() somewhere before the window is open. I'll need to have a little hunt around just to see. But it does go through eventually, and glGenBuffers() etc appear to be working as expected.
 
Hope that helps,

Certainly did! Thanks again

MacArthur, Ian (Selex ES, UK)

unread,
Apr 28, 2015, 6:19:50 AM4/28/15
to fltkg...@googlegroups.com
> interesting - I had a few errors with this. It trips up the first 2-3
> times draw() is called. But the early failed attempts might be me trying
> to use draw() somewhere before the window is open.

Um... You probably know this, but the way you worded that last comment made me wonder...

You really shouldn't ever be calling draw() yourself anywhere, you should let the fltk core do that (as it'll do it once the window context exists, and so on...)
You should only ever call redraw() and let fltk figure out when best to actually execute the draw() method.

[Strictly speaking, for a GL context, if you call make_current() for the window, then it is *probably* OK to call draw() yourself, but I'd caution against it as it is tricky to get right. And is never right for a non-GL window!]



> I'll need to have a
> little hunt around just to see. But it does go through eventually, and
> glGenBuffers() etc appear to be working as expected.


eyeball_en...@hotmail.com

unread,
Apr 28, 2015, 9:43:44 AM4/28/15
to fltkg...@googlegroups.com, ian.ma...@selex-es.com
Ah, I do remember this being mentioned somewhere.

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. I've just changed that over to redraw(), but it's now crash-prone. 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. I'm using the Fl_Gl_Window as an offscreen "drawer", does this do anything to boost the case for draw()?

Is it possible to force a redraw without the core deciding on whether it needs to redraw or not?

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. Should I dig into the redraw() crash a little more? Or Is it 'safe' to keep using draw() directly in an environment like this?

MacArthur, Ian (Selex ES, UK)

unread,
Apr 28, 2015, 10:26:44 AM4/28/15
to fltkg...@googlegroups.com
> 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
Reply all
Reply to author
Forward
0 new messages