- View manipulation
- The Table
- User Messages
- OpenGL State for Rendering Procedures
- Version History
3viewer is a simple 3D viewer application for OpenGL graphics.
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.
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.
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.
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 is a list of text shown on the right side of the viewing window.
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.
message[procedure] (message text)
Shows a message centered on the screen.
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.
Disables all existing effects.
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 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|
The default keymap, which defines some basic viewer operations:
- terminate process
- toggle table
- rotate upwards
- rotate downwards
- rotate left
- rotate right
- zoom in
- zoom out
- 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.
Sets or returns the currently active keymap.
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.
Returns a list of the IDs of all existing objects.
Returns the number of existing 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.
Marks all objects as "dirty".
Should hold a thunk that sets the current world-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
;;; 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)
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.
- fixed missing dependencies (thanks to Mario)
- initial release