PDA

View Full Version : GLUT is great! but -- how to break the message loop?



herc
05-12-2002, 02:17 AM
hello folks, glut is a really great, really simple to use CROSS platform lib. and that cross platform aspect is what i use to implement a port of gaffers tinyptc (www.gaffer.org - a cross platform "low level graphics library for software rendering in 32 bit color") to opengl (using ortho mode and texture blitting) for even more platforms available to tinyptc. but the interface of tinyptc allows the user to write his own "message loop"
a prog looks like this:

if (!ptc_open("test",WIDTH,HEIGHT))
return 1;
while (1)
{
render_something_to(pixels);
ptc_update(pixels);
}


thats all one needs to do all the nice demo's or such and one is not bothered with event handling, callbacks and window-os-specific stuff. but - sadly glut needs to use callbacks and its mainloop.
but - WHY ?!?!?! - glut does not allow to set up a user mainloop - somehow like this:

while(1)
{
// my code
...
...
glutRun();
}

so glut still could process all events and so on.
you may watch the current implementation using glut and another implementation using windows api at
http://www.andre-krause.net/tinyptc/src

(look at gl_glut.c and gl_test.c and maybe at gl.c - the win32 implementation)
i really would like to use glut instead of os dependent windows stuff. so please someone help or can convince the author of glut ??
and besides fltk.org - a cross platform gui toolkit ALLOWS a user defined mainloop!!
so why not glut ?


[This message has been edited by herc (edited 05-12-2002).]

davepermen
05-12-2002, 02:29 AM
www.libsdl.org (http://www.libsdl.org)
sets up your gl-window, you can do your own loop, and you can even use the glutfuncs anyways http://www.opengl.org/discussion_boards/ubb/wink.gif

herc
05-12-2002, 02:37 AM
ok, i will give it a try - but i think you can understand me - glut is installed on most systems, an sdl-port would require the user to install the sdl lib....

and besides - with sdl i would no longer need opengl ;-) -- because sdl does all what tinyptc can and far more. tinyptc was developed to be much smaller, (a little easy'er) and lighter than sdl or openptc.

davepermen
05-12-2002, 02:43 AM
well.. glut is normally not installed on my pc, i always have to search a glut32.dll when i download a demo..

sdl is just an sdl.dll (for windowsworlds), and so its easy as well.

with sdl you don't need glut anymore, no, with sdl you don't need tinyptc anymore, no. its up to you.. i provided you only the solution to get rid of your problems.. http://www.opengl.org/discussion_boards/ubb/smile.gif

herc
05-12-2002, 02:52 AM
yes - you are right :-)
hmm glut is not installed by default ? hmm, think i forgot that i installed glut manually decades ago ;-) besides the tinyptc and sdl stuff -

i still cannot understand why glut does not allow a user defined message loop......

jmathies
05-12-2002, 08:02 AM
There is a hack, glutMainLoopUpdate which
allows for this. sjbaker wrote it.
www.sjbaker.org/steve/software/glut_hack.html (http://www.sjbaker.org/steve/software/glut_hack.html)

or search Google for glutmainloopupdate.

Regards,
Jim



[This message has been edited by jmathies (edited 05-12-2002).]

herc
05-12-2002, 12:37 PM
thanks !
is there hope, that this hack get's included in the official glut releases ?

jmathies
05-12-2002, 05:22 PM
Originally posted by herc:
thanks !
is there hope, that this hack get's included in the official glut releases ?

doubtful. glut is dead. the author hasn't
released a new version in years, and
the source is not open source. there
are a number of replacements, but none
of these have the breadth of support
glut does.. yet.

Take a look at:

Cpw: http://www.mathies.com/cpw/ (Win32)
GLFW: http://hem.passagen.se/opengl/glfw/ (X11, Win32)

Regards,
Jim

dorbie
05-12-2002, 08:44 PM
It's a shame what happened to GLUT. The author refused to incorporate needed improvements requested by developers, the splitting of the loop was the biggest issue and the most requested feature. People have been asking for this for 4 years now and have even offered the required code. Unfortunately they have been ignored. The original GLUT author also refused release it under a real open source license.

There is freeglut now, find it here:
http://freeglut.sourceforge.net/

I'm not sure how maintained this is, the latest download is fairly recent, looks like Steve Baker is the current keeper.


[This message has been edited by dorbie (edited 05-12-2002).]

marcus256
05-12-2002, 10:16 PM
With GLFW you use your own loop ("split" it however you like).

GLFW is constantly updated. It links statically with your app => no need for a separate installation, and you can include the GLFW source with your project if you want to distribute the source (it's compact enough for that: the source for the win32 + x11 versions together is just above 200 KB, or 60 KB compressed).


[This message has been edited by marcus256 (edited 05-13-2002).]

dorbie
05-12-2002, 10:45 PM
Splitting open the loop means you write your own loop and call an event function maybe two. A key operation of splitting open the event loop is the ability to incorporate the API in other asinine libraries which insist on their event loop. Hence you need a couple of functions you can call and no loop co you can place them in a handler function (should you need to).

marcus256
05-12-2002, 11:37 PM
In GLFW you have glfwPollEvents() and glfwSwapBuffers() (which calls glfwPollEvents). All input and window events go through callback functions and/or state polling functions (e.g. glfwGetKey() and glfwGetWindowSize()).

That is truely an "open loop". You typically do something like:



running = 1;
while( running )
{
render_OpenGL_stuff();
glfwSwapBuffers();
if( glfwGetKey( GLFW_KEY_ESC ) | |
!glfwGetWindowParam( GLFW_OPENED ) )
{
running = 0;
}
}

Future versions of GLFW will also have a glfwWaitEvents() function.



[This message has been edited by marcus256 (edited 05-13-2002).]

dorbie
05-13-2002, 12:37 AM
I agree this is desirable, but you are aware that you don't have to call glut main loop now right? That's what Steve's hack and was all about and one of the reasons for the freeglut implementation.

dorbie
05-13-2002, 12:48 AM
P.S.

If glfw added this function to the library, it wouldn't make your version less of an open loop:




void glfwMainLoop(void)
{
running = 1;
while( running )
{
*opengl_draw_callback();
glfwSwapBuffers();
if( glfwGetKey( GLFW_KEY_ESC )| | !glfwGetWindowParam( GLFW_OPENED ) )
{ running = 0; }

}
}





[This message has been edited by dorbie (edited 05-13-2002).]

herc
05-13-2002, 01:09 AM
oh i see. i was offline last night, so i could not reply. i wanted to use glut mainly because its multiplatform support. now that you point out its dev is dead, it's not so good idea to use it for the tinyptc project.
so i will have a look at glw und freeglut!
hopefully one of them evolves into a glut replacement and reaches such a broad range of platforms.

thanks to you guys anyway, greetz, herc.

p.s. hacking the glut source would not of any use, scince tinyptc is especially for users who want to code quick and not download libs, hack source and compile and get crazy with lib-deps and missing libs and so on.

dorbie
05-13-2002, 01:24 AM
Herc, you are correct, this is an almost universal viewpoint when using a library like GLUT, hence the extreme frustration with the original GLUT author ignoring the feature request.

It effectively eliminated GLUT as an option for many developers and at the time there wasn't an alternative.

[This message has been edited by dorbie (edited 05-13-2002).]

marcus256
05-13-2002, 02:32 AM
Dorbie,

Yes, I could add such a function, but I see no need for it right now (unless you want to make it easier to port GLUT programs to GLFW). I think most people like to have their own loop. Then you have the freedom to implement different methods for things like handling window iconification etc (e.g. pause timer and wait for window restoration).

I for one initially had some trouble understanding exactly what happened once the glutMainLoop() function was called. Personally, I think a custom loop makes a program source more readable (if it's done right).


Herc,

I doubt that GLFW will ever reach the popularity of GLUT (GLUT is almost accepted as part of OpenGL, similar to GLU). However, the goal is that GLFW should support as many platforms as possible. It's gotten quite far, since it supports Windows 95/98/ME/NT4/2000 (and I believe XP too), plus any Unix or Unix-like station with pthreads support and X11 (it's been tested on Irix, Linux, Digital UNIX and Solaris).

Currently GLFW is only available as a static link library, meaning that you do not need to install a shared library on your destination system. The disadvantage is of course that if you want to distribute simple tutorial-like demonstrations, the user needs to download and compile GLFW before he/she can use it, but for larger projects I see no problem with including GLFW as part of the project source.

In the future GLFW will also be available as a Windows DLL, meaning a wider range of users (Delphi, Visual Basic etc).



[This message has been edited by marcus256 (edited 05-13-2002).]

dorbie
05-13-2002, 03:15 AM
I'm not advocating it, I'm merely pointing out that freeglut is just as capable of an open loop. You still don't seem to understand thet freeglut has the exact same open loop capability.

Like you I think an open loop makes a lot of sense, to insist (as the original author does) that GLUT retain it's closed loop or that users should hack their own open loop in as needed is completely asinine.

Thankfully some people have reimplemented GLUT as freeglut to fix the problem.

marcus256
05-13-2002, 04:13 AM
Dorbie,

I have nothing against freeglut. I know it has open loop support. I just happen to prefer GLFW in general. Surprised? http://www.opengl.org/discussion_boards/ubb/wink.gif

dorbie
05-13-2002, 04:16 AM
No, I've never tried it and I don't use GLUT either although I have tried it. Surprised? :-) I preffer to grow my own, or use something with real meat on the bones.

FogAudio
05-13-2002, 12:01 PM
Anyone of you guys know if one can gain access to the device and rendering contexts when setting up a window in GLFW or CPW? I am trying to setup an application in which I generate a supersampled image in the background (At like 8x supersampling), then in a separate context I want to place a sample of the hidden buffer downsampled at the machines native resolution?



Originally posted by jmathies:
doubtful. glut is dead. the author hasn't
released a new version in years, and
the source is not open source. there
are a number of replacements, but none
of these have the breadth of support
glut does.. yet.

Take a look at:

Cpw: http://www.mathies.com/cpw/ (Win32)
GLFW: http://hem.passagen.se/opengl/glfw/ (X11, Win32)

Regards,
Jim

nickels
05-13-2002, 12:31 PM
Just use the Glutidle function. It is topologically equivalent to busting out of the loop.

Rationalle:
1) If you are using GLUT your program is a temporary hack anyway.

2) Therefore using glutidle function and not worrying about doing anything after glutMainLoop is fine.

3) Event driven programming is a completely different paradigm than sequential programming; it is not at all uncommon to have to give up control for good (c.f. XtAppMainLoop )

marcus256
05-13-2002, 11:46 PM
Originally posted by FogAudio:
Anyone of you guys know if one can gain access to the device and rendering contexts when setting up a window in GLFW or CPW?

In GLFW you can't. Well, you could, in an undocumented, unportable way: since you link statically to GLFW, you get acess to all the global variables used internally by GLFW. For instance, you can access the GLFW rendering context with the variable _glfwWin.RC, but that requires that you extract the definition of the _glfwWin struct from "internal.h" in the lib\win32 directory of the GLFW source distribution.

In other words, not a nice solution. Since the GLFW API is designed to be portable, things that are wgl/glX specific are kept hidden away from the user.

If you can think of a portable solution to this problem, I would happily include the functionality in GLFW in the future.

FogAudio
05-14-2002, 11:43 AM
Actually, I think that access to the device and rendering contexts isn't necessarily needed. Rather it would be very useful to simply have some methods that could make a certain instantiation current. That way one could flip between contexts very easily. Obviously then in creating each instance of a window (or buffer, or any context) a handle would have to be returned which is specific to that instance. That way when a glfwMakeCurrent(hVisible) like call is made you may provide the "handle" (or identifier-obviously it doesn't need to be device context handle itself). I'm sorry if I don't have all of the details down on how to do this since I am fairly new to this stuff. But hopefully I am not too off track.

But I think it would look something like this

myVisibleWindow = glfwOpenWindow(...);
myHiddenWindow = glfwOpenBuffer(...);
myVisibleWindow2 = glfwOpenWindow(...);
//etc...

glfwMakeCurrent(myHiddenWindow);
// do some rendering
glDoSomething(...);
glDoSomethingElse(...); ...
// maybe sample my hidden buffer

glfwMakeCurrent(myVisibleWindow);
// do some other stuff
etc.

This way device and rendering contexts are really never exposed to the user at all. Also if they are creating a simple application with a single window then they could ignore the handle from the OpenWindow() command since most likely you would want it to switch to that context when it is created. Therefore they wouldn't have to ever make it current since it would be by default.


Originally posted by marcus256:
In GLFW you can't. Well, you could, in an undocumented, unportable way: since you link statically to GLFW, you get acess to all the global variables used internally by GLFW. For instance, you can access the GLFW rendering context with the variable _glfwWin.RC, but that requires that you extract the definition of the _glfwWin struct from "internal.h" in the lib\win32 directory of the GLFW source distribution.

In other words, not a nice solution. Since the GLFW API is designed to be portable, things that are wgl/glX specific are kept hidden away from the user.

If you can think of a portable solution to this problem, I would happily include the functionality in GLFW in the future.

marcus256
05-14-2002, 11:25 PM
This is something I have planned for a long time now. It doesn't fit 100% with the current code layout of GLFW, but I'm trying to get GLFW in that direction. Multiple windows is always a problem, especially when we're dealing with fullscreen windows, multiple threads, event polling etc, so I have some work ahead before I can get there.

When you say "buffer", do you mean a pbuffer?

API-wise, the changes are not huge. As you said, if only one window is opened, one would not have to care about the handle (so basically it would be source code dompatible with the present API). All window management functions (glfwSetWindowTitle etc) should act on the window that was most recently selected with a suitible function (e.g. glfwSelectWindow). I'm just not sure what happens with event polling when an app has opened several windows (this should be portable - work under both X11 and Windows), which is one of the reasons that I have not done so much about it yet.



[This message has been edited by marcus256 (edited 05-15-2002).]

FogAudio
05-15-2002, 06:29 AM
Hmmm...Yeah I am not so sure about event polling. I think you could provide a different WinProc (or X11 equivalent) callback for each window or context. In fact, you may want to provide an optional argument when registering a callback for resize, key and mouse events. Or it could just use the current state (whatever context is current) when registering these callbacks. There again, current apps would still be correct if you had the context argument be optional. I am not sure as to the implications of having multiple windows (i.e. threads) trigger events back to your manager. I presume that you would have to provide conditionals to make sure each RenderScene() like function for any given context is atomic. I am not sure whether your own glfwCreateCond() can be used to do this synchronization but it does seem like a natural fit? How different this needs to be done in UNIX??? Again I plead ignorance.


Originally posted by marcus256:
This is something I have planned for a long time now. It doesn't fit 100% with the current code layout of GLFW, but I'm trying to get GLFW in that direction. Multiple windows is always a problem, especially when we're dealing with fullscreen windows, multiple threads, event polling etc, so I have some work ahead before I can get there.

When you say "buffer", do you mean a pbuffer?

API-wise, the changes are not huge. As you said, if only one window is opened, one would not have to care about the handle (so basically it would be source code dompatible with the present API). All window management functions (glfwSetWindowTitle etc) should act on the window that was most recently selected with a suitible function (e.g. glfwSelectWindow). I'm just not sure what happens with event polling when an app has opened several windows (this should be portable - work under both X11 and Windows), which is one of the reasons that I have not done so much about it yet.


[This message has been edited by marcus256 (edited 05-15-2002).]

marcus256
05-15-2002, 10:47 PM
I have some pretty good ideas about how to do it now (I did some thinking yesterday). I think the key is to make everything context sensitive (including the callback functions and the key/mouse/window state queries). I may also end up requiring that the programmer only deals with events, input and window management from the main thread (I heard that under MacOS X the event loop could only be called from the main thread - and GLFW should be portable).

The biggest problem as I see it is fullscreen windows. I may limit GLFW so that a fullscreen window can only be opened when no other widnows are opened, and no "normal" windows can be opened when a fullscreen window is opened. Another solution may be to always iconify fullscreen windows when another window is opened/activated/selected (which is basically already done in the present version of GLFW).

As for buffers, I think simply adding a third window "mode" option to glfwOpenWindow should be enough:

glfwOpenWindow( ..., GLFW_BUFFER );

FogAudio
05-16-2002, 08:37 AM
As far as fullscreen goes I think the near future will include dual displays or more for gamers and consumers. Especially in a couple years or so with the advent of Microsoft Windows Longwood (or whatever it is called). In that case I could see opening more than 1 full screen. But I haven't researched that much into how multipipe displays are configured yet (so this is just hypothetical). Princeton's Wall project has an awfully interesting site on building super-res displays via multipipes. I downloaded a ton of research papers on the subject about a month ago but thus far have only skimmed a couple.

I will keep an eye on the GLFW webpage over the coming months to see how this multicontext version turns out. In the meantime I may access those variables which you eluded to a few posts ago (your global device contexts) and see if I can scrap together what I need for now. Oh and specifying an optional argument (GLFW_BUFFER) in glfwOpenWindow() works for me!

Thanks for all the feedback, Marcus. It's really fun interacting with such a power programmer like yourself. It makes me really appreciate this newsgroup knowing that system architects are monitoring and active in it! http://www.opengl.org/discussion_boards/ubb/cool.gif

dorbie
05-16-2002, 08:52 AM
No, it's not the equivalent of busting the loop. It is in no way the equivalent of busting the loop.

jmathies
05-17-2002, 08:08 AM
Originally posted by FogAudio:
Actually, I think that access to the device and rendering contexts isn't necessarily needed. Rather it would be very useful to simply have some methods that could make a certain instantiation current. That way one could flip between contexts very easily. Obviously then in creating each instance of a window (or buffer, or any context) a handle would have to be returned which is specific to that instance. That way when a glfwMakeCurrent(hVisible) like call
<snip>


Hey Fog,

Cpw supports multiple contexts. The library
is multi-state in design, so there are no
global variables. Everything related to a
state is stored in a state structure, which
you can access.

For example:




Single State Example:

pCpw cpw;
cpwInitContext( &amp;cpw );
..

cpwFreeContext( &amp;cpw );
exit(0);

Multistate Example:
pCpw cpw1;
pCpw cpw2;

cpwInitContext( &amp;cpw1 );
cpwInitContext( &amp;cpw2 );

cpwDisplayCallback( cpw1, app1_displayCallback );
cpwDisplayCallback( cpw2, app2_displayCallback );

cpwCreateWindowEx( cpw1, "App1 Win1", 100, 100, 300, 300 );
cpwCreateWindowEx( cpw1, "App1 Win2", 120, 120, 300, 300 );
cpwCreateWindowEx( cpw2, "App2 Win1", 200, 200, 300, 300 );
cpwCreateWindowEx( cpw2, "App2 Win2", 220, 220, 300, 300 );

..
while ( running ) {
cpwMainLoopUpdate( cpw1, 1 );
cpwMainLoopUpdate( cpw2, 1 );
}
..

cpwFreeContext( &amp;cpw1 );
cpwFreeContext( &amp;cpw2 );
exit(0);


You can access the rendering contexts through
the cpw state structure if needed. FYI this
library is currently supported on Win32.

Regards,
Jim

nickels
05-17-2002, 08:13 AM
If you want to do all this stuff, if you want to break out of the loop, etc...

Why are you programming in GLUT? GLUT is a toolkit for rapid prototyping, not a thourough windowing mechanism.

Write in Win32....
I don't get it.

Now if the issue is portability, that is a different story but GLUT is still not the answer.

jmathies
05-17-2002, 08:48 AM
Originally posted by nickels:
If you want to do all this stuff, if you want to break out of the loop, etc...

Why are you programming in GLUT? GLUT is a toolkit for rapid prototyping, not a thourough windowing mechanism.


Yet people use GLUT as if it is a "thourough windowing" framework... hence all the traffic about it, and hence the newer solutions out there that do supply a solid solution for this kind of use.

Regards,
Jim


[This message has been edited by jmathies (edited 05-17-2002).]

herc
05-20-2002, 02:42 PM
I'm now using FLTK - the fast light toolkit - http://www.fltk.org
it has opengl support too, a glut emulation layer and avaiable on many platforms.
i just wrote last week a little tetris game using fltk. look here: http://www.andre-krause.net/tetris/coloris_ver_01_small.gif
http://www.andre-krause.net/tetris/index.html

[This message has been edited by herc (edited 05-20-2002).]