1. FreeGlut Example Not Working
- Posted by Icy_Viking Feb 03, 2021
- 1120 views
Hello all,
I have finished writing my FreeGlut wrapper, however the example I am working on does nothing. No command prompt is showing nor is the window showing. Am I missing something, or some snag in the code somewhere?
--Wrapper public constant xglutInit = define_c_proc(glut,"+glutInit",{C_POINTER,C_POINTER}) public procedure glutInit(atom parg,sequence args) atom str = allocate_string(args,1) c_proc(xglutInit,{parg,str}) end procedure public constant xglutMainLoop = define_c_proc(glut,"+glutMainLoop",{}) public procedure glutMainLoop() c_proc(xglutMainLoop,{}) end procedure public constant xglutCreateWindow = define_c_func(glut,"+glutCreateWindow",{C_POINTER},C_INT) public function glutCreateWindow(sequence title) atom str = allocate_string(title,1) return c_func(xglutCreateWindow,{str}) end function
--Example without warning include EuFreeGlut.ew include flags.e glutInit(0,"") glutInitDisplayMode(GLUT_DEPTH) glutInitWindowPosition(100,100) glutInitWindowSize(640,480) atom x = glutCreateWindow("My Window") glutMainLoop()
2. Re: FreeGlut Example Not Working
- Posted by petelomax Feb 03, 2021
- 1114 views
I know nothing, but
In fact, you must register a display callback via glutDisplayFunc() before you enter glutMainLoop().
3. Re: FreeGlut Example Not Working
- Posted by ghaberek (admin) Feb 03, 2021
- 1076 views
I know nothing, but
In fact, you must register a display callback via glutDisplayFunc() before you enter glutMainLoop().
Well you must know something because I think you're right. I reconstructed the demo and this is what I get when I run it:
freeglut (C:\Euphoria\bin\eui.exe): ERROR: No display callback registered for window 1
Edit: Assigning an empty callback via glutDisplayFunc() makes the window open correctly. Make sure you are testing these things with eui and not euiw so you don't miss out on any console-printed error messages.
-Greg
4. Re: FreeGlut Example Not Working
- Posted by ghaberek (admin) Feb 03, 2021
- 1083 views
--Wrapper public constant xglutInit = define_c_proc(glut,"+glutInit",{C_POINTER,C_POINTER}) public procedure glutInit(atom parg,sequence args) atom str = allocate_string(args,1) c_proc(xglutInit,{parg,str}) end procedure
--Example glutInit(0,"")
A note on wrapping this function: glutInit() expects a pointer to argc because it wants to mangle the value of argv and return back the new values in your pointers.
So you can't just pass it the raw value of argc, you have to allocate memory for an int value and then poke it and pass the pointer.
Now, since you're passing zero, the function reads this as a NULL pointer, so maybe it's okay?
But if you were to try and pass an actual value this way it would probably kick back an error or, more likely, just crash right out.
Here is how I wrapped glutInit():
public procedure glutInit( sequence argv=command_line() ) -- glutInit expects C-style argv, so drop the first -- argument if it's the same as the second, which -- happens if we are running bound or translated. if length( argv ) >= 2 and equal( argv[1], argv[2] ) then argv = argv[2..$] end if atom pargc = allocate_data( sizeof(C_INT) ) atom pargv = allocate_string_pointer_array( argv ) poke4( pargc, length(argv) ) c_proc( xglutInit, {pargc,pargv} ) -- If you want to maintain the original functionality -- of glutInit mangling the argv array, you should peek -- back the strings here and return them to the user. free_pointer_array( pargv ) free( pargc ) end procedure
-Greg
5. Re: FreeGlut Example Not Working
- Posted by Icy_Viking Feb 05, 2021
- 1041 views
Thanks for the tips. I tried a more simple idea, but it still isn't working.
without warning include EuFreeGlut.ew include std/math.e include flags.e glutInit(0,"") glutInitDisplayMode(or_all({GLUT_DEPTH,GLUT_DOUBLE,GLUT_RGBA})) glutInitWindowPosition(100,100) glutInitWindowSize(640,480) atom x = glutCreateWindow("My Window") procedure Render() glutSwapBuffers() end procedure atom y = routine_id("Render") call_proc(y,{}) glutDisplayFunc(y) --window still doesn't show glutMainLoop()
6. Re: FreeGlut Example Not Working
- Posted by ghaberek (admin) Feb 05, 2021
- 1043 views
Thanks for the tips. I tried a more simple idea, but it still isn't working.
atom y = routine_id("Render") call_proc(y,{}) glutDisplayFunc(y)
That needs to be call_back() not call_proc(). They have very similar names but very different purposes. And you need to pass the result of call_back() (not the result of routine_id()) to glutDisplayFunc.
integer Render_id = routine_id( "Render" ) atom Render_cb = call_back( Render_id ) glutDisplayFunc( Render_cb )
A few notes about the Euphoria internals:
- routine_id() returns an integer that counts from one, which is the index to an internal routine list that then contains another index to somewhere in the internal symbol table.
- call_func() and call_proc() take that index value from routine_id() and simply make normal internal routine call to the value at that index in the routine list, the same way you would if you called the routine directly by name.
- call_back() takes an index value from routine_id() and sets up a small C function in memory and returns an atom that contains the new memory address. You then take that memory address value and give it to some external system so that the system can make a call back into your Euphoria application from the outside.
-Greg
7. Re: FreeGlut Example Not Working
- Posted by Icy_Viking Feb 05, 2021
- 1033 views
Thanks for the tips. I tried a more simple idea, but it still isn't working.
atom y = routine_id("Render") call_proc(y,{}) glutDisplayFunc(y)
That needs to be call_back() not call_proc(). They have very similar names but very different purposes. And you need to pass the result of call_back() (not the result of routine_id()) to glutDisplayFunc.
integer Render_id = routine_id( "Render" ) atom Render_cb = call_back( Render_id ) glutDisplayFunc( Render_cb )
A few notes about the Euphoria internals:
- routine_id() returns an integer that counts from one, which is the index to an internal routine list that then contains another index to somewhere in the internal symbol table.
- call_func() and call_proc() take that index value from routine_id() and simply make normal internal routine call to the value at that index in the routine list, the same way you would if you called the routine directly by name.
- call_back() takes an index value from routine_id() and sets up a small C function in memory and returns an atom that contains the new memory address. You then take that memory address value and give it to some external system so that the system can make a call back into your Euphoria application from the outside.
-Greg
Thanks Greg. So I tried making some more changes and I still can't get the window to appear.
--Wrapper code public constant xglutInit = define_c_proc(glut,"+glutInit",{C_POINTER,C_POINTER}) public procedure glutInit(sequence args = command_line()) if length(args) >= 2 and equal(args[1],args[2]) then args = args[2..$] end if atom pargc = allocate_data(sizeof(C_INT)) atom pargv = allocate_string_pointer_array(args) c_proc(xglutInit,{pargc,pargv}) free_pointer_array(pargv) free(pargc) end procedure
--Example without warning include EuFreeGlut.ew include std/machine.e include std/math.e include std/dll.e include flags.e glutInit("") glutInitDisplayMode(or_all({GLUT_DEPTH,GLUT_DOUBLE,GLUT_RGBA})) glutInitWindowPosition(100,100) glutInitWindowSize(640,480) atom x = glutCreateWindow("My Window") procedure Render() glutSwapBuffers() end procedure integer id = routine_id("Render") atom id_cb = call_back(id) glutDisplayFunc(id_cb) glutMainLoop()
8. Re: FreeGlut Example Not Working
- Posted by ghaberek (admin) Feb 06, 2021
- 1024 views
Thanks Greg. So I tried making some more changes and I still can't get the window to appear.
procedure Render() glutSwapBuffers() end procedure integer id = routine_id("Render") atom id_cb = call_back(id) glutDisplayFunc(id_cb)
Call backs must be functions, not procedures:
You can set up as many call-back functions as you like, but they must all be Euphoria functions (or types) with 0 to 9 arguments. If your routine has nothing to return (it should really be a procedure), just return 0 (say), and the calling C routine can ignore the result.
When I run your code I get this output, which clearly describes the problem. Like I said, make sure you're testing with eui.exe on the command line, so you see errors like this.
C:\Euphoria\include\std\dll.e:552 in function call_back() call-back routine must be a function or type ... called from C:\Users\Greg\Projects\ghaberek\freeglut\demo.ex:16 --> See ex.err
Also, I realized that the FreeGLUT library on Windows is using __declspec() calling convention, so you need to add a '+' to your call_back(). It works as-is because the render function accepts and returns no parameters, but as soon as you add parameters, it will crash because they are passed differently depending on the calling convention. (And really this is only a problem if you're using 32-bit because 64-bit uses the same calling convention regardless of platform.)
include std/dll.e -- for NULL and call_back() include std/math.e -- for or_all() include GL/freeglut.e function Render() glutSwapBuffers() return NULL end function constant Render_id = routine_id( "Render" ) constant Render_cb = call_back( '+' & Render_id ) procedure main() glutInit( "" ) glutInitDisplayMode( or_all({GLUT_DEPTH,GLUT_DOUBLE,GLUT_RGBA}) ) glutInitWindowPosition( 100, 100 ) glutInitWindowSize( 640, 480 ) atom x = glutCreateWindow( "My Window" ) glutDisplayFunc( Render_cb ) glutMainLoop() end procedure main()
-Greg