# -*- org -*-

Guile-OpenGL
Copyright (C) 2014 Free Software Foundation, Inc.

Guile-OpenGL is free software: you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or (at
your option) any later version.

Guile-OpenGL is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this program.  If not, see
<http://www.gnu.org/licenses/>.

* Completeness

** Complete the high-level GL binding.

*** Bind newer versions.

Would be nice to bind newer versions as well, while keeping the
compatibility profile.

The newer versions are backwards compatible with only rare exceptions
where some function's behaviour (but not prototype) is subtley
redefined.  To support newer versions in a simple way we can export
all bindings and the user effectively chooses which version they use
by their choice of procedures.

Exporting particular profiles is a nice addition to this.

** Complete the high-level GLU binding.

** Complete the high-level GLX binding.

** Complete the high-level GLUT binding.

*** Do not keep alive callback pointers indefinitely.

Perhaps by moving the gc-protect mechanism to the high-level bindings,
and track which callbacks are active on each window and globally.

Users of the low-level bindings can still use the foo-callback-*
helpers, but must assume control of pointer lifetime.  Such an
approach permits great flexibility for alternative high-level
interfaces to reuse the low-level bindings.

** Write an EGL binding.

There is a wip-egl branch with upstream documentation.

** Packed structures.

To facilitate passing data to buffer objects.  Rather than dealing
with bytevectors, offsets, and strides directly, we can use a
packed-struct. and field pair to compute the arguments for
vertex-pointer and friends (size, type, stride, and pointer).

Existing work:

- make-structure-descriptor (r7rs-large):
  http://trac.sacrideo.us/wg/wiki/StructuresCowan

  : (define-structure my-vertex-type
  :   (position 'f32 3 position-ref position-set!)
  :   (normal 'f32 3 normal-ref normal-set!)
  :   (color 'u8 4 color-ref color-set!)
  :   (non-gl-data 'f32 2))
  : (define foo (list->structure my-vertex-type ...))
  : ;; (set-vertex-pointer FIELD BV)
  : (set-vertex-pointer position foo)
  : (set-color-pointer color foo)
  : ;; position, normal, etc. are identifiers bound to the required
  : ;; field specs. by the define-structure expression.

- define-gl-array-format (cl-opengl):

  Specifically maps each component to an OpenGL array type (one of
  vertex, color, normal, ...).  This permits automatically binding an
  entire structure to the relevent array pointers.

  Additional per-component options include:
  - named access to sub-components (e.g. vertex x, y, z);
  - whether values are normalized on assignment.

* Interface

** Implement rest of spec parsing module.

To parse functions (gl.spec, etc.), enums, and typemaps.

** Do not export meta-enumerations (version-2-1, etc.).

These are listed in the “Extensions” definition (enum.spec) and are
defined only to indicate the version or extension that introduces
various symbolic constants.  In theory, all useful constants that
appear in version-2-1, for example, also appear in at least one other
enumeration which is an actual data type as referred to by gl.spec.

They can still be used to provide versioned interfaces and profiles,
there is just no need to export them as enumerations at run time.

Need to make sure all required symbolic constants will still be
accessible before removing these.

** Make using enumerations implicit.

Instead of:

: (gl-begin (begin-mode triangles) ...)
: (gl-matrix-mode) => 123

more like this:

: (gl-begin #:triangles ...)
: (gl-matrix-mode) => #:modelview

and lists of symbols for bitfields.

Enumeration type checking (i.e. does gl-begin accept #:foo?) can be
done two ways.

*** Type checking by Guile.

Before this can be done we must parse gl.spec to know which enums to
apply for each procedure argument.  _Probably_ foreign-types can no
longer be syntax either.

Requires also some manual overriding and mapping as there is some
inconsistency between gl.spec, gl.tm, and enum.spec.  For example,
gl.spec occasionally refers to an enumeration type that is not listed
in enum.spec, or is listed under another name.

*** Type checking by GL.

Most GL procedures already check the range of enum and bitfield
arguments, and flag an invalid-enum error as appropriate.  We can rely
on this and create a single, super-enumeration to convert to and from
symbols.

This may incur a notable performance hit due to the large number of
symbolic constants.

* Naming

** Mangle low-level binding names.

Probably we should do this only if this low-level bindings are good
enough.  In practice this means that output arguments should be natively
supported, and they low-level bindings should check errors as
appropriate.

** TODO Document the naming convention.

Specifically we should document when a name changes significantly,
like when to use a "set-" prefix and the abbreviation expansions
("accum" -> "accumulation-buffer", "coord" -> "coordinates").

Getting this done early will permit implementing the policy more
accurately.

** Maybe drop the "gl-" prefix for high-level bindings.

The names for most gl, glu, etc.  procedures are unique enough to not
conflict with each other, and most Scheme names generally.  Removing
the prefix will make names where an additional prefix is used (such as
"set-") much more natural.

Users with specific namespace concerns can use selective and renaming
imports.

* Documentation

** Figure out how to incorporate low-level bindings into the
   documentation.

Often-times the high-level bindings just duplicate information from the
low-level bindings, but poorly.  To do this, we'd have to make a map of
how to organize the low-level bindings, probably according to their
section in the specification.

** Mangle enumeration names to link to the enumerator documentation.

** Give an @anchor{} to each API element so that we can link back and
   forth.

* Examples

** examples/README explaining the layout.

** OpenGL standards.

Language bindings typically provide ports of the standard examples, to
demonstrate usage patterns and their own unique style.

http://www.sgi.com/products/software/opengl/examples/index.html

Implement at least a few of these, their licencing is permissive
enough and they have been widely ported to Free Software language
bindings already.

** More interesting demos.

* Meta

** Mailing list?

** Web page for documentation?
