You are looking at historical revision 30953 of this page. It may differ significantly from its current revision.

## opengl-glew

Bindings to OpenGL with GLEW extension loading.

Chicken's other opengl bindings are based on the old fixed function pipeline OpenGL. These bindings generated by bind with the OpenGL core header file. Additionally, bindings to GLEW are provided for extension management.

The opengl-glew egg provides three modules, an eponymous module that provides the main OpenGl and GLEW functionality, `gl-math` which provides functions for working with matrices (similar to those that are found in GLU), and `gl-utils` which provides various high-level functions.

### Requirements

- make
- bind
- z3 (gl-utils)
- matchable (gl-utils and a compile-time requirement for gl-math)
- miscmacros (gl-utils)
- srfi-42 (gl-utils

### Documentation

All functions and constants from the OpenGL core header file are exported. Scheme style names are provided (underscores and camelCase replaced with hyphens), the `gl` prefix is removed from names, `is` functions are given question marks, and constants are bookended by `+`s (e.g. `tex-image2d`, `enabled?`, `+arb-viewport-array+`).

Functions whose C counterparts accept or return `GLboolean` accept or return a Scheme boolean value. *Do not* pass `+true+` or `+false+` to these functions.

#### GLEW functions

*[procedure]*

`(init)`

Required to initialize GLEW/OpenGL. An OpenGL context must be created before this is called.

*[procedure]*

`(supported? EXTENSION-NAME)`

Query whether the OpenGL extension, given as a string, is supported.

#### GL helper functions

The functions in this section are part of the opengl-glew module, rather than gl-utils because they either provide a direct interface to an OpenGL function in a more Scheme-like fashion, or they simplify fundamental operations that rarely must be performed differently.

*[procedure]*

`(make-shader TYPE SOURCE)`

Creates and compiles a shader object given the shader's type (e.g. `+vertex-shader+`, `+geometry-shader+`, `+fragment-shader`), and a string containing the GLSL source. Returns an integer representing the ID of the shader.

*[procedure]*

`(make-program SHADER-LIST [PROGRAM-ID])`

Creates and links a program object, given a list of shader objects (i.e. the integers returned by `make-shader`. Returns an integer representing the ID of the program.

Accepts an optional `PROGRAM-ID` argument. If given, `make-program` will use this ID rather than generating a new one.

*[procedure]*

`(gen-buffer)`

*[procedure]*

`(gen-framebuffer)`

*[procedure]*

`(gen-program-pipeline)`

*[procedure]*

`(gen-query)`

*[procedure]*

`(gen-renderbuffer)`

*[procedure]*

`(gen-sampler)`

*[procedure]*

`(gen-texture)`

*[procedure]*

`(gen-transform-feedback)`

*[procedure]*

`(gen-vertex-array)`

Analogous to their pluralized counterparts, but only generates and returns one (integer) object.

*[procedure]*

`(delete-buffer BUFFER)`

*[procedure]*

`(delete-framebuffer FRAMEBUFFER)`

*[procedure]*

`(delete-program-pipeline PROGRAM-PIPELINE)`

*[procedure]*

`(delete-query QUERY)`

*[procedure]*

`(delete-renderbuffer RENDERBUFFER)`

*[procedure]*

`(delete-sampler SAMPLER)`

*[procedure]*

`(delete-texture TEXTURE)`

*[procedure]*

`(delete-transform-feedback TRANSFORM-FEEDBACK)`

*[procedure]*

`(delete-vertex-array VERTEX-ARRAY)`

Analogous to their pluralized counterparts, but only accepts and deletes one (integer) object.

*[procedure]*

`(check-error)`

Performs `get-error` (`glGetError`) and prints the error type when an error is returned.

#### gl-math

gl-math provides a number of functions for working with 4x4 matrices (plus a handful of others). The functionality is similar to what can be found in the glm egg, but with some notable differences:

- Matrix functions only operate on 4x4 matrices
- Matrix functions can accept either f32vectors or pointers
- No container is used to represent matrices

Additionally, gl-math is one fifth the compiled size of glm, has a more straight-forward code-base, and complete documentation.

gl-math expects matrices to be f32vectors or pointers. f32vectors must be 16 elements long. The memory pointed to should likewise be an array of 16 floats. If a function accepts more than one matrix, all matrices must be of the same type.

gl-math operates on matrices in a column-major fashion in correspondence with OpenGL (e.g. translation components are at indices 12, 13, and 14).

*[procedure]*

`(print-mat4 MATRIX)`

Prints the given `MATRIX` to `(current-output-port)`.

*[procedure]*

`(m* A B #!optional RESULT)`

Multiply matrix `A` by matrix `B`. If the matrix `RESULT` is given, it will be modified to contain the results of the multiplication. If `RESULT` is not provided, `A` and `B` must be f32vectors and the returned value will be an f32vector.

*[procedure]*

`(mat4-identity #!optional RESULT)`

Return an identity matrix. If `RESULT` is not provided, the returned value will be an f32vector.

*[procedure]*

`(translate X Y Z MATRIX)`

Translate `MATRIX` by `X`, `Y`, and `Z`.

*[procedure]*

`(rotate-x ANGLE MATRIX)`

Rotate `MATRIX` around the x-axis by `ANGLE` radians.

*[procedure]*

`(rotate-y ANGLE MATRIX)`

Rotate `MATRIX` around the y-axis by `ANGLE` radians.

*[procedure]*

`(rotate-z ANGLE MATRIX)`

Rotate `MATRIX` around the z-axis by `ANGLE` radians.

*[procedure]*

`(rotate X Y Z ANGLE MATRIX)`

Rotate `MATRIX` around the vector given by `X`, `Y`, and `Z` by `ANGLE` radians.

*[procedure]*

`(scale-2d SCALE-X SCALE-Y MATRIX)`

Scale the x and y axis of `MATRIX` by `SCALE-X` and `SCALE-Y`.

*[procedure]*

`(scale-3d SCALE-X SCALE-Y SCALE-Z MATRIX)`

Scale the x, y, and z axis of `MATRIX` by `SCALE-X`, `SCALE-Y`, and `SCALE-Z`.

*[procedure]*

`(scale SCALE MATRIX)`

Scale the x, y, and z axis of `MATRIX` by `SCALE`.

*[procedure]*

`(flip-x MATRIX)`

Flip (mirror) `MATRIX` along the x-axis.

*[procedure]*

`(flip-y MATRIX)`

Flip (mirror) `MATRIX` along the y-axis.

*[procedure]*

`(flip-z MATRIX)`

Flip (mirror) `MATRIX` along the z-axis.

*[procedure]*

`(translate-scale X Y Z SCALE #!optional RESULT)`

Efficiently create a matrix translated by `X`, `Y`, and `Z` then scaled by `SCALE`. If the matrix `RESULT` is given, it will be modified to contain the result. If `RESULT` is not provided, the returned value will be an f32vector.

*[procedure]*

`(translate-rotate-scale-2d X Y Z ANGLE SCALE #!optional RESULT)`

Efficiently create a matrix translated by `X`, `Y`, and `Z`, rotated around the z-axis by `ANGLE` radians, then scaled by `SCALE`. If the matrix `RESULT` is given, it will be modified to contain the result. If `RESULT` is not provided, the returned value will be an f32vector.

*[procedure]*

`(translate-rotate-scale X Y Z RX RY RZ ANGLE SCALE #!optional RESULT)`

Efficiently create a matrix translated by `X`, `Y`, and `Z`, rotated `ANGLE` radians around the axis defined by `(RX, RY, RZ)`, then scaled by `SCALE`. If the matrix `RESULT` is given, it will be modified to contain the result. If `RESULT` is not provided, the returned value will be an f32vector.

*[procedure]*

`(transpose MATRIX #!optional RESULT)`

Transpose `MATRIX`. If the matrix `RESULT` is given, it will be modified to contain the result. If `RESULT` is not provided, the returned value will be an f32vector.

*[procedure]*

`(inverse MATRIX #!optional RESULT)`

Invert `MATRIX`. If the matrix `RESULT` is given, it will be modified to contain the result. If `RESULT` is not provided, the returned value will be an f32vector.

*[procedure]*

`(ortho WIDTH HEIGHT NEAR FAR #!optional RESULT)`

Create an orthographic projection matrix. If the matrix `RESULT` is given, it will be modified to contain the result. If `RESULT` is not provided, the returned value will be an f32vector.

*[procedure]*

`(perspective WIDTH HEIGHT NEAR FAR ANGLE #!optional RESULT)`

Create an perspective projection matrix. If the matrix `RESULT` is given, it will be modified to contain the result. If `RESULT` is not provided, the returned value will be an f32vector.

*[procedure]*

`(frustum LEFT RIGHT BOTTOM TOP NEAR FAR #!optional RESULT)`

Create a view-frustum matrix. If the matrix `RESULT` is given, it will be modified to contain the result. If `RESULT` is not provided, the returned value will be an f32vector.

*[procedure]*

`(look-at EYE-X EYE-Y EYE-Z X Y Z UP-X UP-Y UP-Z #!optional RESULT)`

Create a “look-at” style camera matrix. The camera is positioned at `(EYE-X, EYE-Y, EYE-Z)`, pointing towards `(X, Y, Z)`. `(UP-X, UP-Y, UP-Z)` defines the camera’s up vector. If the matrix `RESULT` is given, it will be modified to contain the result. If `RESULT` is not provided, the returned value will be an f32vector.

*[procedure]*

`(camera-inverse CAMERA #!optional RESULT)`

Invert `CAMERA` in an efficient fashion. This allows the camera to be constructed in an intuitive fashion by translating and rotating before inverting in order to position the scene properly. This function is far faster than the general `inverse` function, but the matrix `CAMERA` must only be a matrix representing a translation and a rotation (no scaling). If the matrix `RESULT` is given, it will be modified to contain the result. If `RESULT` is not provided, the returned value will be an f32vector.

*[procedure]*

`(cross-product AX AY AZ BX BY BZ)`

Return the result of the cross product between the vectors `(AX, AY, AZ)` and `(BX, BY, BZ)`. The resulting vector is returned as three values.

*[procedure]*

`(dot-product AX AY AZ BX BY BZ)`

Return the result of the dot product between the vectors `(AX, AY, AZ)` and `(BX, BY, BZ)`.

*[procedure]*

`(normalize X Y Z)`

Return the normalized vector `(X, Y, Z)`. The resulting vector is returned as three values.

*[procedure]*

`(degrees->radians ANGLE)`

Converts `ANGLE` from degrees to radians.

*[procedure]*

`(radians->degrees ANGLE)`

Converts `ANGLE` from radians to degrees.

#### gl-utils

gl-utils provides functions for creating VAOs, and loading PLY files.

*[procedure]*

`(make-vao VERTEX-DATA INDEX-DATA ATTRIBUTES #!optional USAGE)`

`make-vao` generalizes the typically repetitious code used to initialize vertex attribute objects. It deals with the case of having packed vertex data (`VERTEX-DATA`) and a vector of indices (`INDEX-DATA`) for those vertexes.

`ATTRIBUTES` is the list of data necessary for the vertex attributes, in the form of `((LOCATION TYPE N [normalize?: NORMALIZE?]) ...)`. `LOCATION` is the attribute location, `TYPE` is the type of data corresponding to the given attribute, given as a keyword. For possible types, see `type->gl-type`. `N` is the number of elements for the givien attribute. The keyword `normalize?:` accepts a boolean argument which instructs OpenGL to normalize the attribute or not. Defaults to `#f`.

The optional `USAGE` must be one of `+stream-data+`, `+stream-read+`, `stream-copy`, `+static-data+`, `+static-read+`, `static-copy`, `+dynamic-data+`, `+dynamic-read+`, `dynamic-copy`. Defaults to `+static-draw+`.

`make-vao` returns the ID of a vertex array object. This object should be deleted with `delete-vertex-array` when no longer used. Intermediate vertex buffers are generated and deleted, thus only the returned vertex array ID needs to be managed.

*[procedure]*

`(load-ply FILE BUFFER-SPEC)`

Loads a PLY file. `FILE` is a path that may be pointing to a gziped PLY file. `BUFFER-SPEC` is a list in the form `((NAME VARS) ...)` where `NAME` is the name of an element in the PLY file and `VARS` is either a list of property names or, in the case of a property list, a single name. Two values are returned: a list of blobs which correspond to the buffers named in `BUFFER-SPEC` and a list of the elements that are in the PLY file in the form of:

(element-name n-elements (property-name property-type))

Or, when an element is a property list:

(element-name n-elements (property-name (list: list-length-type element-type)))

The buffers returned are packed with the contents of the properties named in the `BUFFER-SPEC`. Thus, for a PLY file that has element `vertex` with properties `float x`, `float y`, `float z`, `float confidence`, `uchar r`, `uchar g`, and `uchar b`, as well as a nelement `face` with a property list `uchar ushort vertex_index`, the following `BUFFER-SPEC` could be used:

(load-ply "example.ply.gz" '((vertex: (x y z r g b)) (face: vertex_index)))

This buffer spec would result in a list of two blobs being returned: one with the packed elements corresponding to properties `x`, `y`, `z`, `r`, `g`, and `b` (with the corresponding property types), and the second containing the vertex indices.

*[procedure]*

`(load-ply-vao FILE #!key VERTEX FACE)`

Similar to `load-ply`, but returns a number of values:

- A vertex array ID as generated by
`make-vao`. - A blob representing the vertex data of the model
- A blob representing the index data of the model
- The number of vertices of the model
- The GL enum value of the type of primitive used for the model (e.g.
`+triangles+`) - The GL enum value of the element data type

`FILE` is a PLY file (which may be gziped). The PLY file must contain at least the elements `vertex` and `face` (other elements will be ignored). `VERTEX` is a list of `(attribute-location property-name ...)` elements, which specifies how the vertex buffers of the VAO will be arranged. All properties named by each element of `VERTEX` must be of the same type. `FACE` is the name of the face property list.

Again, for a PLY file that has element `vertex` with properties `float x`, `float y`, `float z`, `float confidence`, `uchar r`, `uchar g`, and `uchar b`, as well as a element `face` with a property list `uchar ushort vertex_index`, the following could be used:

(load-ply-vao "example.ply" vertex: `((,vertex-location x y z) (,color-location r g b)) face: vertex_index)

*[procedure]*

`(type->gl-type TYPE)`

Converts the keyword `TYPE` into a OpenGL type enum value. Accepted types (grouped by synonyms) are:

`char:``int8:``byte:``uchar:``uint8:``unsigned-byte:``short:``int16:``ushort:``uint16:``unsigned-short:``int:``int32:``integer:``integer32:``uint:``uint32:``unsigned-int:``unsigned-int32:``unsigned-integer:``unsigned-integer32:``float:``float32:``double:``float64:`

### Example

This example depends on the glfw3 egg for window and context creation.

(import chicken scheme) (use (prefix glfw3 glfw:) (prefix opengl-glew gl:) gl-math gl-utils) (define*vertex* #<<END #version 330 in vec2 vertex; in vec3 color; out vec3 c; uniform mat4 MVP; void main(){ gl_Position = MVP * vec4(vertex, 0.0, 1.0); c = color; } END ) (define*fragment* #<<END #version 330 in vec3 c; out vec4 fragColor; void main(){ fragColor = vec4(c, 1.0); } END ) (definevertex-data (f32vector -1 -1 1 0 0 1 -1 0 1 0 1 1 0 0 1 -1 1 1 0 1)) (defineindex-data (u16vector 0 1 2 0 2 3)) (definevao (make-parameter #f)) (defineprogram (make-parameter #f)) (defineprojection-matrix (perspective 640 480 0.1 100 70)) (defineview-matrix (look-at 1 0 3 0 0 0 0 1 0)) (definemodel-matrix (mat4-identity)) (define(render) (gl:use-program (program)) (gl:uniform-matrix4fv (gl:get-uniform-location (program) "MVP") 1 #f (m* projection-matrix (m* view-matrix model-matrix))) (gl:bind-vertex-array (vao)) (gl:draw-elements-base-vertex gl:+triangles+ 6 (type->gl-type ushort:) #f 0) (gl:check-error) (gl:bind-vertex-array 0)) (glfw:with-window (640 480 "Example" resizable: #f) (gl:init) (print (gl:supported? "GL_ARB_framebuffer_object")) (set! *vertex* (gl:make-shader gl:+vertex-shader+ *vertex*)) (set! *fragment* (gl:make-shader gl:+fragment-shader+ *fragment*)) (program (gl:make-program (list *vertex* *fragment*))) (vao (make-vao (f32vector->blob vertex-data) (u16vector->blob index-data) `((,(gl:get-attrib-location (program) "vertex") float: 2) (,(gl:get-attrib-location (program) "color") float: 3)))) (letloop() (glfw:swap-buffers (glfw:window)) (gl:clear (bitwise-ior gl:+color-buffer-bit+ gl:+depth-buffer-bit+)) (render) (glfw:poll-events) (unless (glfw:window-should-close (glfw:window)) (loop))))

### Version history

#### Version 0.4.4

2 June 2014

`load-ply-vao`now returns buffer data (which is important to keep around!)

**Version 0.4.3**

30 May 2014

- Add optional program argument to
`make-program` - gl-math short-circuits rotations of 0

**Version 0.4.2**

24 May 2014

- Fix segfaults caused by glewExperimental not being set (thanks, Terpri!)

**Version 0.4.1**

12 May 2014

- Remove rogue print statement

**Version 0.4.0**

11 May 2014

- Add gl-math module
- Add gl-utils module
- Add
`check-error`

#### Version 0.3.0

- Add single element
`gen`and`delete`functions

#### Version 0.2.0

- Add glcorearb.h - no longer downloaded at install time

#### Version 0.1.0

- Initial release

### Source repository

Source available on GitHub.

Bug reports and patches welcome! Bugs can be reported via GitHub or to alex.n.charlton at gmail.

### Author

Alex Charlton

### Licence

BSD