* Introduction:: The what, why, and how of Figl.
* GL:: A Scheme interface to OpenGL.
-* Low-Level GL:: Primitive interface to OpenGL.
-
* GLU:: The GL Utility library.
-* Low-Level GLU:: Primitive interface to ``glu'' functionality.
-
* GLX:: Using OpenGL with the X Window System.
-* Low-Level GLX:: Primitive interface to ``glX'' functionality.
+* GLUT:: The GL Utility Toolkit.
+
+* FAQ:: Figl answers questions.
* Function Index::
@end menu
@chapter Introduction
Figl is the Foreign Interface to GL: an OpenGL binding for Guile.
-It's a ``foreign'' interface because it uses the dynamic foreign
-function interface provided by Guile 2.0, providing access to OpenGL
-without any C code at all. In fact, much of the binding (and its
-documentation) is automatically generated from upstream API
+
+OpenGL is a family of APIs and layers. The following chapters discuss
+the parts of OpenGL and how they are bound by Figl.
+
+But before that, some notes on the Figl binding as a whole.
+
+@menu
+* About Figl:: The structure of the binding.
+@end menu
+
+
+@node About Figl
+@section About Figl
+
+Figl is a @dfn{foreign} interface to OpenGL because it uses the
+dynamic @dfn{foreign function interface} provided by Guile 2.0,
+providing access to OpenGL without any C code at all. In fact, much
+of Figl (and this manual) is automatically generated from upstream API
specifications and documentation.
-In this section, we give a brief introduction to OpenGL and some
-details about the binding as a whole. The following chapters cover
-the specifics of the interfaces provided by Figl.
+We have tried to do a very complete job at wrapping OpenGL, and
+additionally have tried to provide a nice Scheme interface as well.
+Our strategy has been to separate the binding into low-level and
+high-level pieces.
+
+The low-level bindings correspond exactly with the GL specification,
+and are well-documented. However, these interfaces are not so nice to
+use from Scheme; output arguments have to be allocated by the caller,
+and there is only the most basic level of type checking, and no sanity
+checking at all. For example, you can pass a bytevector of image data
+to the low-level @code{glTexImage2D} procedure, but no check is made
+that the dimensions you specify actually correspond to the size of the
+bytevector. This function could end up reading past the end of the
+bytevector. Worse things can happen with procedures that write to
+arrays, like @code{glGetTexImage}.
+
+The high-level bindings are currently a work in progress, and are
+being manually written. They intend to be a complete interface to the
+GL, without the need to use the low-level bindings. However, the
+low-level bindings will always be available for you to use if needed,
+and have the advantage that their behavior is better documented and
+specified by OpenGL itself.
+
+Low-level bindings are accessed by loading the @code{(figl
+@var{module} low-level)}, for example via:
+
+@example
+(use-modules (figl gl low-level))
+@end example
+
+The high-level modules are named like @code{(figl @var{module})}, for
+example @code{(figl gl)}.
+
+
+@node GL
+@chapter GL
+
@menu
-* About OpenGL:: A brief introduction to OpenGL.
-* GL Contexts:: Finding a square of pixels to paint.
-* GL Extensions:: Beyond OpenGL.
-* FAQ:: Figl answers questions.
+* About OpenGL:: Know the past to understand the present.
+* GL Contexts:: Finding a square of pixels.
+* Rendering:: How to paint.
+* Low-Level GL:: Primitive interface to OpenGL.
+* GL Extensions:: Beyond core OpenGL.
@end menu
+
@node About OpenGL
@section About OpenGL
OpenGL is a standard API for drawing three-dimensional graphics. From
-its origin in Silicon Graphics's workstations in the mid-1990s, today
+its origin in Silicon Graphics's workstations the early 1990s, today
it has become ubiquitous, with implementations on mobile phones,
televisions, tablets, desktops, and even web browsers.
units.
@item OpenGL 2.x
-By the early 2000s, graphics hardware evolved to that was much more
-general-purpose. The so-called @dfn{fixed-function rendering
-pipeline} of the earlier years was replaced with a @dfn{programmable
-rendering pipeline}, in which effects that would have required special
-hardware were instead performed by custom programs running on the
-graphics card's processors. OpenGL added support for allocating
-@dfn{buffer objects} on the graphics card, and for @dfn{shader
-programs}, which did the actual rendering. In time, this
-buffer-focused API came to be the preferred form of talking to the GL.
+By the early 2000s, graphics hardware had become much more
+general-purpose and needed a more general-purpose API. The so-called
+@dfn{fixed-function rendering pipeline} of the earlier years was
+replaced with a @dfn{programmable rendering pipeline}, in which
+effects that would have required special hardware were instead
+performed by custom programs running on the graphics card. OpenGL
+added support for allocating @dfn{buffer objects} on the graphics
+card, and for @dfn{shader programs}, which did the actual rendering.
+In time, this buffer-focused API came to be the preferred form of
+talking to the GL.
@item OpenGL ES
OpenGL ES was a ``cut-down'' version of OpenGL 2.x, designed to be
removed some of the legacy functionality from OpenGL, while adding
interfaces to use fixed-point math, for devices without floating-point
units. OpenGL ES 2.x went farther still, removing the fixed-function
-pipeline entirely.
+pipeline entirely. OpenGL ES 2.x is common on current smart phone
+platforms.
@item OpenGL 3.x and above
The OpenGL 3.x series followed the lead of OpenGL ES, first
context given a window (or a drawable), @dfn{GLX}. @xref{GLX}, for
more information on its binding in Guile.
-TODO: Write about GLUT, EGL, the current context, and threads.
-
-
-@node GL Extensions
-@section GL Extensions
+Bseides creating contexts from native windows or drawables, each
+backend also supports functions to make a context @dfn{current}. The
+OpenGL API is stateful; you can think of each call as taking an
+implicit @dfn{current context} parameter, which holds the current
+state of the GL and is operated on by the function in question.
+Contexts are thread-specific, and one context should not be active on
+more than one thread at a time.
-TODO: Write about extensions, and how to get access to them.
+All calls to OpenGL functions must be made while a context is active;
+otherwise the result is undefined. Hopefully while you are getting
+used to this rule, your driver is nice enough not to crash on you if
+you call a function outside a GL context, but it's not even required
+to do that. Backend-specific functions may or may not require a
+context to be current; for example, Windows requires a context to be
+current, wheras GLX does not.
+There have been a few attempts at abstracting away the need for
+calling API specific to a given windowing system, notably GLUT and
+EGL. GLUT is the older of the two, and though it is practically
+unchanged since the mid-1990s, it is still widely used on desktops.
+@xref{GLUT}, for more on GLUT.
-@node FAQ
-@section FAQ
+EGL is technically part of OpenGL ES, and was designed with the modern
+OpenGL API and mobile hardware in mind, though it also works on the
+desktop. Figl does not yet have an EGL binding.
-TODO: Write about things readers will want to know (instead of
-commenting them in the source :)
-
-@node GL
-@chapter GL
+@node Rendering
+@section Rendering
To draw with OpenGL, you obtain a drawing context (@pxref{GL
Contexts}) and send @dfn{the GL} some geometry. (You can think of the
doesn't keep around a scene graph of objects. Instead, at every frame
you as the OpenGL user have to tell the GL what is in the world, and
how to paint it. It's a fairly low-level interface, but a powerful
-one. @uref{http://www.opengl.org/wiki/Rendering_Pipeline_Overview}
+one. See
+@uref{http://www.opengl.org/wiki/Rendering_Pipeline_Overview}, for
+more details.
In the old days of OpenGL 1.0, it was common to call a function to
paint each individual vertex. You'll still see this style in some old
tutorials. This quickly gets expensive if you have a lot of vertexes,
though. This style, known as @dfn{Legacy OpenGL}, was deprecated and
-even removed from some versions of OpenGL.
+even removed from some versions of OpenGL. See
@uref{http://www.opengl.org/wiki/Legacy_OpenGL}, for more on the older
APIs.
Instead, the newer thing to do is to send the geometry to the GL in a
-big array, and...
+big array buffer, and have the GL draw geometry from the buffer. The
+newer functions like @code{glGenBuffers} allocate buffers, returning
+an integer that @dfn{names} a buffer managed by the GL. You as a user
+can update the contents of the buffer, but when drawing you reference
+the buffer by name. This has the advantage of reducing the chatter
+and data transfer between you and the GL, though it can be less
+convenient to use.
+
+So which API should you use? Use what you feel like using, if you
+have a choice. Legacy OpenGL isn't going away any time soon on the
+desktop. Sometimes you don't have a choice, though; for example, when
+targeting a device that only supports OpenGL ES 2.x, legacy OpenGL is
+unavailable.
+
+But if you want some advice, we suggest that you use the newer APIs.
+Not only will your code be future-proof and more efficient on the GL
+level, reducing the number of API calls improves performance, and it
+can reduce the amount of heap allocation in your program. All
+floating-point numbers are currently allocated on the heap in Guile,
+and doing less floating-point math in tight loops can only be a good
+thing.
@node Low-Level GL
-@chapter Low-Level GL
+@section Low-Level GL
@include low-level-gl.texi
+@node GL Extensions
+@section GL Extensions
+
+@quotation
+The future is already here -- it's just not very evenly distributed.
+
+-- William Gibson
+@end quotation
+
+Before interfaces end up in core OpenGL, the are usually present as
+vendor-specific or candidate extensions. Indeed, the making of an
+OpenGL standard these days seems to be a matter of simply collecting a
+set of mature extensions and making them coherent.
+
+Figl doesn't currently provide specific interfaces for extensions.
+Perhaps it should, but that's a lot of work that we haven't had time
+to do. Contributions are welcome.
+
+In the meantime, if you know enough about GL to know that you need an
+extension, you can define one yourself -- after all, Figl is all a
+bunch of Scheme code anyway.
+
+For example, let's say you decide that you need to render to a
+framebuffer object. You go to @uref{http://www.opengl.org/registry/}
+and pick out an extension, say
+@uref{http://www.opengl.org/registry/specs/ARB/framebuffer_object.txt}.
+
+This extension defines a procedure, @code{GLboolean
+glIsRenderBuffer(GLuint)}. So you define it:
+
+@example
+(use-modules (figl gl runtime) (figl gl types))
+(define-gl-procedure (glIsRenderBuffer (buf GLuint) -> GLboolean)
+ "Render buffer predicate. Other docs here.")
+@end example
+
+And that's that. It's a low-level binding, but what did you expect?
+
+Note that you'll still need to check for the availability of this
+extension at runtime with @code{(glGetString GL_EXTENSIONS)}.
+
+
@node GLU
@chapter GLU
+@menu
+* Low-Level GLU:: Primitive interface to ``glu'' functionality.
+@end menu
@node Low-Level GLU
-@chapter Low-Level GLU
+@section Low-Level GLU
@include low-level-glu.texi
@node GLX
@chapter GLX
+@menu
+* Low-Level GLX:: Primitive interface to ``glX'' functionality.
+@end menu
+
@node Low-Level GLX
-@chapter Low-Level GLX
+@section Low-Level GLX
@include low-level-glx.texi
+@node GLUT
+@chapter GLUT
+
+TODO: Write GLUT documentation.
+
+
+@node FAQ
+@chapter FAQ
+
+TODO: Write about things readers will want to know (instead of
+commenting them in the source :)
+
+
@node Function Index
@unnumbered Function Index
@printindex fn