1. FreeGlut Example Not Working

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() 
new topic     » topic index » view message » categorize

2. Re: FreeGlut Example Not Working

I know nothing, but

http://openglut.sourceforge.net/group__window.html#ga9 said...

In fact, you must register a display callback via glutDisplayFunc() before you enter glutMainLoop().

new topic     » goto parent     » topic index » view message » categorize

3. Re: FreeGlut Example Not Working

petelomax said...

I know nothing, but

http://openglut.sourceforge.net/group__window.html#ga9 said...

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

new topic     » goto parent     » topic index » view message » categorize

4. Re: FreeGlut Example Not Working

Icy_Viking said...
--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

new topic     » goto parent     » topic index » view message » categorize

5. Re: FreeGlut Example Not Working

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() 
new topic     » goto parent     » topic index » view message » categorize

6. Re: FreeGlut Example Not Working

Icy_Viking said...

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

new topic     » goto parent     » topic index » view message » categorize

7. Re: FreeGlut Example Not Working

ghaberek said...
Icy_Viking said...

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() 
new topic     » goto parent     » topic index » view message » categorize

8. Re: FreeGlut Example Not Working

Icy_Viking said...

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:

docs said...

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

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu