Hello,
I am currently developing 'something interesting' using SBCL and OpenGL via Apple X11.
I have built SBCL and OpenGLUT from source as I am lucky enough to have an Intel 20" iMac and I wanted to make sure I was getting maximum speed i.e. no Rosetta in the way. My 'project' is coming along but it bugs me that I have to keep stopping and starting the application in order to make changes to the software because once the 'glutMainLoop' gets control the SLIME session doesn't respond anymore.
I had to slightly modify the cl-opengl package as it has two symbol naming problems concerning the roman fonts but that is the only change I have had to make along with the library.lisp package which needed to be coaxed into loading my OpenGLUT build on an Intel Darwin platform. Apart from that it works very well, the MESADEMOS:GEARS averages about 4900 frames per second much to my disbelief!!!
I know that SBCL does not currently support threading on the intel iMac which maybe would solve all my problems in one fell swoop.
Software:
SLIME CVS latest as of 13-July-2006 SBCL 0.9.13 OpenGLUT 0.6.3
I have spent a few hours reading the SWANK code trying to see where I can make changes but I am just to new to it, I have used SLIME but never before had a need to modify it and right now it looks a bit intimidating to try and figure out how to do what I would like to do which is basically find a way to make the OpenGL timer function and the display function both to 'keep the SWANK backend alive' by somehow calling whatever is needed to ensure that the SLIME session remains active at the same time as my OpenGL application is running. For me this would be incredibly productive as it means (if I have understood LISP so far [used Smalltalk for about 6 years]) that I can fiddle with my application while it is running and see any changes that affect the display be effected the next time the display is rendered.
Is this at all possible???
I would think that a new SWANK back end could be created.
I have also toyed with the idea of hacking the SBCL source code directly to contain the OpenGL libraries and somehow making the changes at that point but id I thought SWANK / SLIME was big, SBCL is enormous by comparison and I'd rather be coding my application that fiddling with the tools.
Many thanks
Sean Charles www.objitsu.com
* Sean Charles [2006-07-13 09:44+0200] writes:
I have spent a few hours reading the SWANK code trying to see where I can make changes but I am just to new to it, I have used SLIME but never before had a need to modify it and right now it looks a bit intimidating to try and figure out how to do what I would like to do which is basically find a way to make the OpenGL timer function and the display function both to 'keep the SWANK backend alive' by somehow calling whatever is needed to ensure that the SLIME session remains active at the same time as my OpenGL application is running.
Since use are on a Mac, you probably use the :fd-handler communication style. Perhaps you can arrange things so that a OpenGL timer calls SB-SYS:SERVE-ALL-EVENTS. This will then (hopefully) invoke SWANK's fd-handlers if there is some input from Emacs.
Helmut.
On 13/07/06, Helmut Eller heller@common-lisp.net wrote:
- Sean Charles [2006-07-13 09:44+0200] writes:
I have spent a few hours reading the SWANK code trying to see where I can make changes but I am just to new to it, I have used SLIME but never before had a need to modify it and right now it looks a bit intimidating to try and figure out how to do what I would like to do which is basically find a way to make the OpenGL timer function and the display function both to 'keep the SWANK backend alive' by somehow calling whatever is needed to ensure that the SLIME session remains active at the same time as my OpenGL application is running.
Since use are on a Mac, you probably use the :fd-handler communication style. Perhaps you can arrange things so that a OpenGL timer calls SB-SYS:SERVE-ALL-EVENTS. This will then (hopefully) invoke SWANK's fd-handlers if there is some input from Emacs.
Helmut. _______________________________________________ slime-devel site list slime-devel@common-lisp.net http://common-lisp.net/mailman/listinfo/slime-devel
Do you have your heart set on using GLUT? A while ago I wrote some CFFI bindings for GLFW, (http://glfw.sourceforge.net/) which I ought to have around somewhere if you'd like them. From memory, GLFW doesn't require that you give up the main loop, at the expense of slightly more manual input handling. Of course, I'm assuming that "GLUT stealing the main loop" is actually the issue. I'm on an intel mac as well.
Cheers Brad
On Thu, Jul 13, 2006 at 08:44:14AM +0100, Sean Charles wrote:
Hello,
I am currently developing 'something interesting' using SBCL and OpenGL via Apple X11.
I have built SBCL and OpenGLUT from source as I am lucky enough to have an Intel 20" iMac and I wanted to make sure I was getting maximum speed i.e. no Rosetta in the way. My 'project' is coming along but it bugs me that I have to keep stopping and starting the application in order to make changes to the software because once the 'glutMainLoop' gets control the SLIME session doesn't respond anymore.
I had to slightly modify the cl-opengl package as it has two symbol naming problems concerning the roman fonts but that is the only change I have had to make along with the library.lisp package which needed to be coaxed into loading my OpenGLUT build on an Intel Darwin platform. Apart from that it works very well, the MESADEMOS:GEARS averages about 4900 frames per second much to my disbelief!!!
I know that SBCL does not currently support threading on the intel iMac which maybe would solve all my problems in one fell swoop.
Software:
SLIME CVS latest as of 13-July-2006 SBCL 0.9.13 OpenGLUT 0.6.3
I have spent a few hours reading the SWANK code trying to see where I can make changes but I am just to new to it, I have used SLIME but never before had a need to modify it and right now it looks a bit intimidating to try and figure out how to do what I would like to do which is basically find a way to make the OpenGL timer function and the display function both to 'keep the SWANK backend alive' by somehow calling whatever is needed to ensure that the SLIME session remains active at the same time as my OpenGL application is running. For me this would be incredibly productive as it means (if I have understood LISP so far [used Smalltalk for about 6 years]) that I can fiddle with my application while it is running and see any changes that affect the display be effected the next time the display is rendered.
Is this at all possible???
I would think that a new SWANK back end could be created.
I have also toyed with the idea of hacking the SBCL source code directly to contain the OpenGL libraries and somehow making the changes at that point but id I thought SWANK / SLIME was big, SBCL is enormous by comparison and I'd rather be coding my application that fiddling with the tools.
Have you considered using glutMainLoopEvent() instead? It may require some restructuring of your program (remove glutIdleFunc mainly).
Still, from when glutMainLoopEvent is called until it returns, slime will still be unresponsive. However, if you stick SB-SYS:SERVE-ALL-EVENTS in all of your callback functions, then maybe it will be good enough.
I'm not an expert on slime, but I do know GLUT pretty well and how to beat it into playing nicely with other stuff.
Still, from when glutMainLoopEvent is called until it returns, slime will still be unresponsive. However, if you stick SB-SYS:SERVE-ALL-EVENTS in all of your callback functions, then maybe it will be good enough.
A ZEN MOMENT
I now have a working OpenGL setup *and* a still function REPL/SLIME session to SBCL. Thanks to Helmut's suggestion about calling SB- SYS:SERVE-ALL-EVENTS. However, I made a fascinating blunder which has caused me some time to realise and on reflection is very very funny. I have included the mail I was *going* to send at the end as it just goes to show how you can be fooled (by yourself) into barking up the wrong tree. I am still laughing at my own stupidity as I type this.
It all comes back to Helmuts comment: "Maybe SERVE-ALL-EVENTS loops forever if no timeout is given. Try to call it with something small like 100ms."
So I did try it with 100, however, coming from a real-time embedded systems background I assumed that the parameter to SERVE-ALL-EVENTS would be in 'mS' and passed in 100. Not until much later did I realise! HA HA HA, LOL, and all that.
So, if you want to read and 'see' one mans trip into persona debugging hell, read below and enjoy a good laugh on me!
Thanks everybody for your comments. As I speak I have a running gears window and a running SLIME session and it all seems to work.
I know that *my* application may have to do something clever about changing the display code because I think I am treading on thin-ice here. I imagine having to build me new display handler then have an internal means to flag that I want to ditch 'a' and use 'b' the next time I render a frame... after all, I could be trying to change something via SLIME/REPL at the same time that OpenGL is trying to render it.
--- here's what I was *going* to send ---
Helmut suggested I do this and I have now tried it with a timeout of '100' and the result is the same: the REPLY stays alive but the OpenGL application now seems to either have died or broken. If I click the 'close window' button it doesn't close.
Pressing keys no longer produces any output to the SLIME/REPL session which is how I am assuming my application is broken.
My print statements are using the form
(format *terminal-io* "..." args...)
I guess it is possible that the connection between the OpenGL application back to the SLIME session has somehow gotten dazed and confused and in fact my progroam might still be working! I shall try writing the test output to a file as well.
FLASH OF INSPIRATION! --> I am going to hack the MESADEMOS:GEARS to see if it still runs when I call the SB-SERVE-ALL-EVENTS function... that way I will know for sure if what I want to do is possible. [...later...] Oh dear. I added a call to (sb-sys:serve-all-events) just after the swap-buffers call and the gears appear to have stopped in their tracks...but no!! What's this.... I resized the window and continued typing this message and about 45 seconds later the window updated and froze again... it might be alive somewhere. I made the window bigger again and this time it took about 90 seconds to update. it seems that the glut loop is still alive but it being held inside the SERVE-ALL- EVENTS code perhaps???
I have spent several minutes resizing the window gradually down to about 30 pixels square and the refresh rate seems to be in multiples of approx. 45 seconds:
45 90 45 85 80
It 'feels' like there is some kind of internal timeout maxed at 45 seconds and occasionally the resize event may miss the 'window of opportunity' and that's why I have to wait 2 'cycles' for the update to occur. Maybe it's 50 seconds??? Here's the output from the SLIME session:
CL-USER> (mesademos:GEARS) 3 frames in 100.0 seconds = 0.030 FPS 1 frames in 100.0 seconds = 0.010 FPS 1 frames in 99.3 seconds = 0.010 FPS 1 frames in 100.0 seconds = 0.010 FPS 1 frames in 100.0 seconds = 0.010 FPS 1 frames in 100.0 seconds = 0.010 FPS 1 frames in 100.0 seconds = 0.010 FPS 1 frames in 100.0 seconds = 0.010 FPS 1 frames in 100.0 seconds = 0.010 FPS
Pressing the Esc key finally terminates the application after a suitable period of waiting!
If I remove the call to SB-SYS:SERVE-ALL-EVENTS then all goes back to normal. I added a TRACE to the calls
-- My modus operandi for this is that I have used LUSH and it's pretty cool and all that but at the end of the day is is not LISP proper. I thought it would be great to be able to have an OpenGL application alive and running and still be able to fiddle with the guts of it, kind of like changing the tyre on your car without stopping, and just as hairy I expect!
I'm not an expert on slime, but I do know GLUT pretty well and how to beat it into playing nicely with other stuff.
I'll be in touch then! You'll be sorry you said that!! LOL... I have some experience of OpenGL but I am by no means a Guru.
OK, in a drug fuelled moment of madness (diet-coke and a Snickers, too much sugar I guess) I decided I want to write an OpenGL interface to SLIME and I have been fiddling with it on and off for a few months now, don't ask, it's not going 'that' well. :-)
I am using cl-opengl and Apple X11 X-server and it's working as expected, I had to make a small change to the library.lisp file to load the OpenGLUT library that I built:
(define-foreign-library glut ;;-- (sjc-03-jul-06) -- added this line to ensure my locally built ;;-- OpenGLUT library is loaded as the "glut" library! ((:and :darwin :x86) "/usr/local/lib/libopenglut.dylib") ;((:and :darwin :x86) (:framework "GLUT")) ;(:darwin (:or "libglut.dylib" "libglut.3.dylib" #-(and) (:framework "GLUT"))) (:windows "freeglut.dll") ; XXX: is this right? (:unix (:or "libglut.so" "libglut.so.3")))
I had to do it this way because at the time I just couldn't get the GLUT.framework to load after many hours of head scratching. Anyhow, I have just been trying to get the Cocoa GLUT framework to load again (I hate being beaten by dumb machines) and I am stuck!
In an attempt to get around the blasted message:
<NSInternalInconsistencyException> Error (1002) creating CGSWindow
which appears every time it tried to load the framework, I ended up with the following code:
;; For GLUT.framework to operate we also need to load the Cocoa.framework ;; and the OpenGL frameworks ?!?!?! ;; (define-foreign-library cocoa ((:and :darwin :x86) (:framework "Cocoa")))
(define-foreign-library opengl ((:and :darwin :x86) (:framework "OpenGL")))
(define-foreign-library glut ;((:and :darwin :x86) "/usr/local/lib/libopenglut.dylib") ((:and :darwin :x86) (:framework "GLUT")) ;(:darwin (:or "libglut.dylib" "libglut.3.dylib" #-(and) (:framework "GLUT"))) (:windows "freeglut.dll") ; XXX: is this right? (:unix (:or "libglut.so" "libglut.so.3")))
(use-foreign-library cocoa) (use-foreign-library opengl) (use-foreign-library glut)
(cffi:defcfun ("NSApplicationLoad" nsapplicationload) :int) (nsapplicationload)
...which kind of worked in that the NSInternalInconsistencyException has now gone away but when I try to run the MESADEMOS:GEARS program, the system hangs and when I hit CTRL-C I get:
* (mesademos:gears) ^C debugger invoked on a SIMPLE-CONDITION in thread #<THREAD "initial thread" {122A9301}>: interrupted at #X90009857
Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name): 0: [CONTINUE] Return from SB-UNIX:SIGINT. 1: [ABORT ] Exit debugger, returning to top level.
(SB-UNIX::SIGINT-HANDLER #<unavailable argument> #<unavailable argument> #.(SB-SYS:INT-SAP #X02206D5C)) 0]
...my only thoughts are that NSApplicationLoad is an Objective-C function and that there may be a problem using (defcfun ...) to call it.... does anybody have any idea why I am not getting my OpenGL windows ?
Thanks, Sean Charles.
At Thu, 14 Dec 2006 17:00:04 +0000, Sean Charles wrote:
OK, in a drug fuelled moment of madness (diet-coke and a Snickers, too much sugar I guess) I decided I want to write an OpenGL interface to SLIME and I have been fiddling with it on and off for a few months now, don't ask, it's not going 'that' well. :-)
Interesting... I am sorry i'm not responding to you question, poking you with my curiosity instead.
If it is not a secret-matter-until-released, may i ask you what kind of an interface it is? Do you think you were able to avoid sacrificing the emacs integration in that interface? How did you manage to achieve this, if so?
It's a dizzying thing to think about, so please, forgive me my curiosity, if you may :-)
regards, Samium Gromoff