Skip to content

ChickenProp/cloggle

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

50 Commits
 
 
 
 

Repository files navigation

OVERVIEW

cloggle provides a Clojure interface to OpenGL through JOGL. Currently it is
very thin, and only the GL interface is implemented; there is no support for
GLAutoDrawable or the like.

A GL object can be interfaced with using the with-gl macro, which initialises a
context for all calls to opengl functions which occur within its body. This is a
dynamic context, so it will be in effect for functions called from within the
body of with-context. The current context object can be accessed through the
variable *opengl-context*.

Within a context, OpenGL functions and fields are exposed through Lispified
names. Any GL_FIELD_NAME is accessible as gl-field-name (downcased with dashes),
and any glFunctionName is accessible through calling (function-name ...).
(Note: function names are stripped of the gl- prefix.)

cloggle also provides some convenience functions which wrap gl functions with
type suffixes (e.g. vertex2i, color3d, rotatef, etc). Any such function
can be accessed using the simpler name (e.g. vertex, color, rotate).

Functions operate only on the current context object; there is no way to pass
a different one. But you can make a new call to with-context, or just use the
java interop to the JOGL API directly.

cloggle also provides the with-primitive macro, which wraps its body between
calls to glBegin and glEnd.

Illustrative example (not working code):
    (use 'net.philh.cloggle)
    (def gl-obj (get-gl-object-somehow))
    (with-gl gl-obj
      (matrix-mode gl-projection)
      (ortho 0 300 0 300 1 128)
      (matrix-mode gl-modelview)
      (translate 0 0 -10)

      (clear gl-depth-buffer-bit)
      (clear gl-color-buffer-bit)
      (with-primitive gl-triangles
        (vertex 30 0 0)
        (vertex 0 30 0)
        (vertex 0 0 0)))

TYPECASTING

int, float, ratio and double types are handled intelligently: functions which
expect one can take any of the others. (ratio is native to clojure, so no
functions expect that, but it can still be passed.) short and byte are not
handled; there seems little point, and clojure doesn't supply short-array or
byte-array functions. You can still call those functions if you like, but you
must specifically pass shorts or bytes to them.

Likewise, functions which expect an array of ints, floats or doubles can accept
an array of any type, or any Seqable clojure type. (Provided in both cases that
all the elements can be cast appropriately; Maps, for instance, don't work.)

These calls will all have the same effect:

    (vertex2i  5 10)
    (vertex2iv (int-array [5 10] 0))
    (vertex2i  5.5 10.7)
    (vertex2iv (float-array [5.5 10.7] 0))
    (vertex2iv [5 10] 0)
    (vertex2iv '(5.5 10.7) 0)

As will calls to the vertex convenience function (provided the parameters are
integral):

    (vertex 5 10)
    (vertex [5 10])
    (vertex '(5 10))

Note that JOGL functions expecting an array typically also take an offset
argument for the first element to use, so another equivalent call would be
(vertex2iv [3 5 10] 1).

EXPORTS

The following symbols are provided, in addition to the standard gl* functions
(and convenience functions) and GL_* variables:

(with-gl context body...)
Macro. Bindings *opengl-context* to context within body. Also wraps body in
io! (so don't try to use it inside a transaction).

(with-primitive mode body...)
Macro. Wraps body in calls to (glBegin mode) and (glEnd).

(with-pushed-matrix body...)
Macro. Wraps body in calls to (glPushMatrix) and (glPopMatrix).

(texture-from-file file)
Function. Loads an image from file and returns a 2d RGBA texture representing
it.

The flush function is exported as gl-flush to avoid a namespace conflict with
the core library. Similarly, no convenience function is provided for glMap*.

BUGS

The typecasting of convenience methods is fragile: it relies on the order in
which Java exposes the JOGL methods. It works for me, but might not for anyone
else, and might stop working at any time.

This does not apply when arguments to methods do not need to be typecast, or
only need typecasting from int or float to float or double: (vertex 0 1),
(vertex 3.1 4.1) and (vertex -1 2.1) should all work in any case, but (vertex 0
(/ 1 2)) might call glVertex2i instead of glVertex2d. If this is the case,
simple.clj will not display correctly. But it might also call glVertex2f, which
won't be noticeable; or functions other than vertex might display this problem,
which won't be caught by simple.clj.

FUTURE PLANS

* Fix bugs.
* Add support for related interfaces, like GLAutoDrawable, GLEventListener and
  GLU.
* Should vertex only accept up to 3 arguments? I don't know if there's any
  reason to ever call vertex4*, and it might screw things up if someone had
  a longer sequence than they expected.

COPYRIGHT

Copyright 2009 Philip Hazelden. All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted.

This software comes with NO WARRANTY, to the extent permitted by law.

About

OpenGL library for Clojure based on JOGL

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published