1. 3viewer
    1. Introduction
    2. Usage
    3. Requirements
    4. Documentation
      1. General
        1. start-viewer
      2. View manipulation
        1. current-radius
        2. rotate-view
        3. current-refresh-delay
        4. resize-window
      3. The Table
        1. current-table
      4. User Messages
        1. message
      5. Effects
        1. add-effect
        2. remove-effect
        3. remove-all-effects
        4. animation
      6. Keymaps
        1. make-keymap
        2. default-keymap
        3. join-keymaps
        4. keymap-ref
        5. keymap-set!
        6. current-keymap
      7. Objects
        1. add-object
        2. remove-object
        3. object-property
        4. object-highlighted?
        5. all-objects
        6. number-of-objects
        7. remove-all-objects
        8. update-object
        9. update-all-objects
      8. Transformations
        1. current-world-transformation
        2. current-view-transformation
      9. OpenGL State for Rendering Procedures
    5. Examples
    6. Author
    7. License
    8. Version History

3viewer

Introduction

3viewer is a simple 3D viewer application for OpenGL graphics.

Usage

(require-extension 3viewer)

Requirements

opengl

glut

defstruct

matchable

Documentation

General

start-viewer
[procedure] (start-viewer #!key w h title init)

Starts the viewer by opening a window with the given size and title. If given, then init keyword parameter should hold a thunk that will be executed after the viewer has been initialized. start-viewer never returns.

View manipulation

The view is centered around 0/0/0, and the camera position is initially set up at 0/0/<radius>. The radius and the rotation of the camera relative to the current view-transformation can be manipulated using current-radius and rotate-view. You can rotate with the mouse by holding the middle button and moving the pointer, and zoom by holding the right button and moving the pointer up or down. Clicking the left button over an object will select it.

current-radius
[parameter] current-radius

Gets or sets the radius of the camera-position, centered around the 0/0/0 coordinate.

rotate-view
[procedure] (rotate-view xd yd)

Rotates the camera by xd/yd degres around the X and Y axis, respectively.

current-refresh-delay
[parameter] current-refresh-delay

The time the current thread will sleep when the display is "idle". Defaults to 0.01 seconds.

resize-window
[procedure] (resize-window W H)

Resizes the display window to the given size.

The Table

The table is a list of text shown on the right side of the viewing window.

current-table
[parameter] current-table

Holds a list of table entries, where each table entry is either #f (which means an empty line) or a pair containing a title and a value to be shown in the respective line of the table. Setting this parameter to #f disables the table.

User Messages

message
[procedure] (message text)

Shows a message centered on the screen.

Effects

Effects are code that is executed before every redraw operation and if the system is idle.

add-effect
[procedure] (add-effect thunk #!optional name)

thunk will be executed repeatedly and should return a boolean indicating true if the effect should remain active or false if the effect should be removed. name gives the effect a name for later retrieval. If name is given and an effect is already registered under this name, then the previously existing effect is removed.

remove-effect
[procedure] (remove-effect name)

Removes the effect with the given name.

remove-all-effects
[procedure] (remove-all-effects)

Disables all existing effects.

animation
[parameter] animation

The default animation of the view. By default no animation is active. Suitable values are #f (off) or 'spin (spin view around Y axis).

Keymaps

Keymaps map keyboard input to actions.

make-keymap
[procedure] (make-keymap [KEY1 PROC1 ... [DEFAULTHANDLER]])

Creates and returns a keymap and fills it with the given key/keyhandler items. A key should be a character, a symbol indicating a special key or a list of the form ([alt] [control] [shift] CHAR)]]. A key-handler is a procedure that takes the key as its sole argument.

If DEFAULTHANDLER is given, it should be a procedure of one argument (the key value) that is invoked for all key-presses for which no item exists in the keymap. If the default-handler returns false, then any joined keymap (see below) will be tried.

Special keys are mapped to symbols like this:

F1 - F12 f1 - f12
left left
up up
right right
down down
Page up page-up
Page down page-down
Home home
End end
Insert insert
default-keymap
[constant] default-keymap

The default keymap, which defines some basic viewer operations:

#\esc
terminate process
#\t
toggle table
up
rotate upwards
down
rotate downwards
left
rotate left
right
rotate right
page-up
zoom in
page-down
zoom out
#\space
toggle animation
join-keymaps
[procedure] (join-keymaps KEYMAP1 ...)

Combines several keymaps and returns a new keymap that passes unhandled input to the next keymap in the list.

keymap-ref
[procedure] (keymap-ref KEYMAP KEY)

Returns the key-handler procedure for KEY in KEYMAP or #f if no entry exists for the given key.

keymap-set!
[procedure] (keymap-set! KEYMAP KEY HANDLER)

Assigns a new or existing key-handler to a given key.

current-keymap
[parameter] current-keymap

Sets or returns the currently active keymap.

Objects

Objects represent visual entities in the display and manage redisplaying and selection. Objects are addressed by their ID, an exact integer.

add-object
[procedure] (add-object RENDER #!key name select animate)

Creates a new object and returns its ID. name is an optional name for ther object. RENDER is a procedure taking an object ID and performs the necessary graphical operations to render the object into the OpenGL buffer. select is a procedure taking an object ID and is invoked when the user clicks on the rendered object in the viewer window. animate is a procedure taking an object ID and defines an animation to be executed on each "tick" (redraw or when the system is idle). If the animation procedure returns true, then the object will be re-rendered.

remove-object
[procedure] (remove-object id)

Removes the object with the given ID.

object-property
[procedure] (object-property ID PROPERTY)

Returns the named property of the given object. You can use

 (set! (object-property ID PROPERTY) VALUE)

to assign a value to a n object-property.

object-highlighted?
[procedure] (object-highlighted? ID)

Returns true, if the object with the given ID is currently under the mouse pointer.

all-objects
[procedure] (all-objects)

Returns a list of the IDs of all existing objects.

number-of-objects
[procedure] (number-of-objects)

Returns the number of existing objects.

remove-all-objects
[procedure] (remove-all-objects)

Removes all existing objects.

update-object
[procedure] (update-object id)

Marks the object with the given ID as "dirty" and as requiring re-rendering.

update-all-objects
[procedure] (update-all-objects)

Marks all objects as "dirty".

Transformations

current-world-transformation
[parameter] current-world-transformation

Should hold a thunk that sets the current world-transformation.

current-view-transformation
[parameter] current-view-transformation

A 16-element f64vector that specifies the view-transformation as a 4x4 matrix in column major order.

OpenGL State for Rendering Procedures

The initial OpenGL state is roughly as follows:

(glut:InitDisplayMode (bitwise-ior glut:DOUBLE glut:RGBA glut:DEPTH))

(glut:DisplayFunc <internal redrawing >)
(glut:VisibilityFunc <visible)
(gl:Enable gl:DEPTH_TEST)
(gl:Enable gl:CULL_FACE)
(gl:Enable gl:LINE_SMOOTH)
(gl:Enable gl:BLEND)
(gl:BlendFunc gl:SRC_ALPHA gl:ONE_MINUS_SRC_ALPHA)
(gl:LineWidth 1.0)

A select buffer is created internally.

GLUT callbacks are defined as with

 glut:DisplayFunc
 glut:VisibilityFunc
 glut:KeyboardFunc
 glut:SpecialFunc
 glut:MouseFunc
 glut:MotionFunc
 glut:PassiveMotionFunc
 glut:ReshapeFunc

Examples

;;; shows a spinning red cube

(use gl glut 3viewer)

(define a 0)

(define (spin id)
  (set! a (modulo (+ a 0.25) 360)))

(define (colorize id col)
  (gl:Materialfv 
   gl:FRONT_AND_BACK gl:AMBIENT_AND_DIFFUSE
   (if (object-highlighted? id)
       '#f32(1 1 0 1)
       col)))

(define (draw-cube id)
  (colorize id '#f32(1 0 0 1))
  (gl:Rotatef a 1 0 0)
  (gl:Rotatef a 0 1 0)
  (gl:Rotatef (- a) 0 0 1)
  (glut:SolidCube 1))

(add-object draw-cube animate: spin select: (lambda _ (print "oink!")))
(start-viewer)

Author

felix winkelmann

License

Copyright (c) 2010, Felix L. Winkelmann
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
3. The name of the authors may not be used to endorse or promote products
   derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 

Version History

0.2
fixed missing dependencies (thanks to Mario)
0.1
initial release