I've been working on generating bindings from the .spec files on opengl.org, and it seems to be to the point where it could be turned into a patch...
Before that though, I wanted to get some feedback about changing the naming for the bindings:
First suggestion is moving the function bindings to a separate package, and giving them lisp style names, so people like me who want to use them directly have supported access to them.
Second is changing the GLenums from cffi:defcenums to defconstants. Advantages I can think of from doing that: *Easier for users to add enums from a new extension without modifying library code (unless cffi allows adding to an enum after it is defined, not sure about that)
*Easier to add offsets to them, for example a loop to disable all lights could use (+ index gl:+light0+) instead of having to convert from enum and back, or store a list of the light enums or whatever.
*being able to add offsets also solves the problem of some values (light in particular) potentially having more valid values than are enums. (The .spec files name 8 lights, but leaves room for 4096, I'm pretty sure there has been hardware supporting at least 32.)
*compatibility with other bindings (glx and cl-sdl both use +foo+ style for enums if I remember correctly)
*possibly speed. If cffi can remap values at compile time it probably isn't too bad, but it probably wouldn't be too hard to find code with a lot of enums specified at runtime.
(Alternately, is it possible to tell cffi to allow using either the constants or the keywords?)
Also, a small patch: someone in #lisp was having problems with OpenMCL objecting to compute-applicable-methods being called with extra arguments in glut/interface.lisp, which was fixed by the following patch to define-glut-event:
diff -rN old-pct/glut/interface.lisp new-pct/glut/interface.lisp 130c130 < :func ',event-func :arg-count ,(length args)) ---
:func ',event-func :arg-count ,(length arg-names))
On 12.11.2006, at 09:44, Bart Botta wrote:
First suggestion is moving the function bindings to a separate package, and giving them lisp style names, so people like me who want to use them directly have supported access to them.
This is fine by me.
Second is changing the GLenums from cffi:defcenums to defconstants. Advantages I can think of from doing that:
This is not. The whole point of cl-opengl was having hand-written bindings that feel Lispy and not like a direct mapping to C. I do NOT want to write code like (gl:clear-color (logior gl:+color-buffer-bit+ gl:+depth- buffer-bit+)) or having to think about how to construct a foreign array to pass to glLightfv.
If somebody wants to use bindings like this, Glouton[1] or kt-opengl [2] seem like a better fit. They follow a different, more direct approach for people who prefer that model. Writing bindings isn't exactly rocket science, so having more than one way to do things is a good thing as far as I'm concerned.
*Easier for users to add enums from a new extension without modifying library code (unless cffi allows adding to an enum after it is defined, not sure about that)
This sounds like an easy addition to CFFI.
*Easier to add offsets to them, for example a loop to disable all lights could use (+ index gl:+light0+) instead of having to convert from enum and back, or store a list of the light enums or whatever. *being able to add offsets also solves the problem of some values (light in particular) potentially having more valid values than are enums. (The .spec files name 8 lights, but leaves room for 4096, I'm pretty sure there has been hardware supporting at least 32.)
The right way (IMHO) would be to have functionality in CFFI to add offsets to enums if desired, but there aren't that many places in OpenGL where this would even apply.
Off the top of my head, I can name GL_LIGHTi, GL_AUXi, GL_TEXTUREi, GL_CLIPPLANEi and GL_COLOR_ATTACHMENTi_EXT and I don't know a single graphics card whose limits exceed those defined in the spec/ headers, since a few of these are obsolete anyway thanks to programmable hardware.
You can see limits for most Macintosh graphics cards at http://homepage.mac.com/arekkusu/bugs/GLInfo.html
I /do/ agree that functions like GL:LIGHT should be able to take both a symbolic and a numeric identifer though, for the reasons you mentioned. But this can be done without ditching CFFI enums.
*compatibility with other bindings (glx and cl-sdl both use +foo+ style for enums if I remember correctly)
I neither care about GLX nor CL-SDL. If neither CLX, nor any other non-C library use +foo+, why should we? Personally, I think it looks way too ugly.
*possibly speed. If cffi can remap values at compile time it probably isn't too bad, but it probably wouldn't be too hard to find code with a lot of enums specified at runtime.
It does remap values where possible. Here's an example from OpenMCL:
? (defun foo () (gl:clear :color-buffer-bit :depth-buffer-bit)) FOO ? (disassemble 'foo) (TWNEI NARGS 0) (MFLR LOC-PC) (BLA .SPSAVECONTEXTVSP) (STWU SP -80 SP) (STW RZERO 8 SP) (LWZ ARG_Y '#<EXTERNAL-ENTRY-POINT "_glClear" (#x92E83368) /System/ Library/Frameworks/OpenGL.framework/OpenGL #x8476C8E> FN) (LWZ ARG_Z 2 ARG_Y) (TWEQI ARG_Z NIL) (VPUSH ARG_Z) (LI IMM0 16640) (STW IMM0 24 SP) (LWZ ARG_Z 0 VSP) (LA VSP 4 VSP) (BLA .SPPOWEROPEN-FFCALL) (LI ARG_Z NIL) (BA .SPPOPJ)
Note the LI IMM0 16640. GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT => 0x4100 => 16640.
But even then, the performance impact of doing so at runtime is neglible.
Also, a small patch: someone in #lisp was having problems with OpenMCL objecting to compute-applicable-methods being called with extra arguments in glut/interface.lisp, which was fixed by the following patch to define-glut-event:
diff -rN old-pct/glut/interface.lisp new-pct/glut/interface.lisp 130c130 < :func ',event-func :arg-count ,(length args))
:func ',event-func :arg-count ,(length
arg-names))
Applied, thank you.
[1] http://common-lisp.net/project/glouton/ [2] Somewhere in http://common-lisp.net/project/cello/
On 11/12/06, Oliver Markovic entrox@entrox.org wrote:
On 12.11.2006, at 09:44, Bart Botta wrote:
Second is changing the GLenums from cffi:defcenums to defconstants. Advantages I can think of from doing that:
This is not. The whole point of cl-opengl was having hand-written bindings that feel Lispy and not like a direct mapping to C. I do NOT want to write code like (gl:clear-color (logior gl:+color-buffer-bit+ gl:+depth- buffer-bit+)) or having to think about how to construct a foreign array to pass to glLightfv.
I'm not arguing that the behavior of the hand written API should change*, just the shape of the parameters. gl:clear still handles combining the arguments, it just uses logior instead of make-bitfield.
*(well, actually, I might argue that the API should change, but if I did, the argument would be that cl-opengl is too low level, not that it should be closer to the C API :)
If somebody wants to use bindings like this, Glouton[1] or kt-opengl [2] seem like a better fit.
Or my bindings if I release them, I was just hoping to have that behavior as a subset of cl-opengl to avoid pointless forks :)
Off the top of my head, I can name GL_LIGHTi, GL_AUXi, GL_TEXTUREi, GL_CLIPPLANEi and GL_COLOR_ATTACHMENTi_EXT and I don't know a single graphics card whose limits exceed those defined in the spec/ headers, since a few of these are obsolete anyway thanks to programmable hardware.
I was thinking more of workstation level cards, 3dlabs realizm, etc. http://www.delphi3d.net/hardware/viewreport.php?report=1503
Easy enough to just add more enums to cover the extra if you stay with cffi enums, so it isn't too much of a problem.
*compatibility with other bindings (glx and cl-sdl both use +foo+ style for enums if I remember correctly)
I neither care about GLX nor CL-SDL. If neither CLX, nor any other non-C library use +foo+, why should we? Personally, I think it looks way too ugly.
Sorry, I meant CLX, not GLX : http://common-lisp.net/~crhodes/clx/gl.lisp and CL-SDL is a set of lisp bindings for SDL and OpenGL.
The 2 libraries you linked both used GL_FOO style constants/defparameters though, so not sure how much it matters.
But even then, the performance impact of doing so at runtime is neglible.
Might be, I'll have to see if I can think of any concrete tests and try it...
trick stupid gmane web poster here...
I'm somehow concerned about the constants issue myself,so i think this is the right place to post my thoughts.
Oliver Markovic <entrox <at> entrox.org> writes:
Second is changing the GLenums from cffi:defcenums to defconstants. Advantages I can think of from doing that:
This is not. The whole point of cl-opengl was having hand-written bindings that feel Lispy and not like a direct mapping to C. I do NOT want to write code like (gl:clear-color (logior gl:+color-buffer-bit+ gl:+depth- buffer-bit+)) or having to think about how to construct a foreign array to pass to glLightfv.
opengl is state based and therefore not lispy at all, it's all about side effects. Wrapping it to a lispy interface is for a higher level interface like a whole gfx engine, not for a simple opengl bindings package. you can still have (clear +color-buffer-bit+ +depth-buffer-bit+) which has much less overhead.
If somebody wants to use bindings like this, Glouton[1] or kt-opengl [2] seem like a better fit. They follow a different, more direct approach for people who prefer that model. Writing bindings isn't exactly rocket science, so having more than one way to do things is a good thing as far as I'm concerned.
where is the cl-opengl approach indirect? replacing constants by keywords doesn't change the way the binding work,it's only cosmetic for the end user.
[snip, agreed as solveable with keywords]
I neither care about GLX nor CL-SDL. If neither CLX, nor any other non-C library use +foo+, why should we? Personally, I think it looks way too ugly.
*possibly speed. If cffi can remap values at compile time it probably isn't too bad, but it probably wouldn't be too hard to find code with a lot of enums specified at runtime.
It does remap values where possible. Here's an example from OpenMCL:
? (defun foo () (gl:clear :color-buffer-bit :depth-buffer-bit)) FOO ? (disassemble 'foo) (TWNEI NARGS 0) (MFLR LOC-PC) (BLA .SPSAVECONTEXTVSP) (STWU SP -80 SP) (STW RZERO 8 SP) (LWZ ARG_Y '#<EXTERNAL-ENTRY-POINT "_glClear" (#x92E83368) /System/ Library/Frameworks/OpenGL.framework/OpenGL #x8476C8E> FN) (LWZ ARG_Z 2 ARG_Y) (TWEQI ARG_Z NIL) (VPUSH ARG_Z) (LI IMM0 16640) (STW IMM0 24 SP) (LWZ ARG_Z 0 VSP) (LA VSP 4 VSP) (BLA .SPPOWEROPEN-FFCALL) (LI ARG_Z NIL) (BA .SPPOPJ)
Note the LI IMM0 16640. GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT => 0x4100 => 16640.
But even then, the performance impact of doing so at runtime is neglible.
no it is not. here (sbcl/amd64) a (defun clear (&rest args) ...) is ~15-20 instructions long, no extra function call. the standard keyword based version is ~120 instructions long and calls a generic function. this _IS_ a lot of overhead for such fundamental functions as opengl operations. I think the more the applications become the less are the possibilities for the compiler to optimize at compile time. think of extra effect files or external data in general where constants are simply unknown at compile time and keyword->constant dispatch has to be done at runtime. Sure, it doesn't matter for any glut demo, and also for any small game or application, but complex applications (think of a lisp version of Oblivion) it will become significant. I really don't see why we should slow down opengl applications for a small bit of "beauty". It [beauty] will be there when higher level apis are written based upon cl-opengl. My last thought: what are your points for using keywords? you seem to be really keen on not dropping them; from changing cffi to accept runtime overhead. why?
mfg thomas
PS: don't get me wrong, i really like to see that there is a opengl wrapper in active development. sorry if i hit the wrong note.
On 10/03/07, thomas weidner 3.14159@gmx.net wrote:
here (sbcl/amd64) a (defun clear (&rest args) ...) is ~15-20 instructions long, no extra function call. the standard keyword based version is ~120 instructions long and calls a generic function. this _IS_ a lot of overhead for such fundamental functions as opengl operations.
You should mention that this only happens if the arguments aren't constant. GL:CLEAR has a compiler macro that removes all that overhead.
If this turns out to be a problem we can also have the enum type accept integers as well and add some operators to get the value of the keywords at compile-time. Then you can play with LOGIOR all you want. :-)
My last thought: what are your points for using keywords? you seem to be really keen on not dropping them; from changing cffi to accept runtime overhead. why?
I'd be in favor of, in addition to the big enum, having restricted enums like we used to so that we get errors (at compile-time usually) when we pass the wrong keyword.
The spec even gives us that info in enum.spec and gl.spec. Not a big priority though.
cl-opengl-devel@common-lisp.net