- Administrivia
-
The Computer Graphics Workshop will be taught Mondays, Wednesdays, and
Fridays during IAP, except for the holiday of 1/20. That week the class
will meet on Tuesday.
We will occasionally have laboratory sessions to help clarify the material
and to assist with problem sets. These sessions will meet in the SGI
cluster in 4-035. Dates and times of the labs will be announced in
class.
- Purpose of the course
- The early weeks of the course will be devoted primarily to learning
how to write programs using Open Inventor. Early on, we will have frequent
problem sets which will assist you in becoming familiar with the
capabilities of the toolkit. Because we believe that you learn best by
actually implementing something, we strongly recommend that you form groups
for, and participate in, the creation of a final project.
- The final project
- This year the final project will be to implement a simple game using
Open Inventor. The feasibility of this project has been demonstrated;
however, it will almost definitely not be possible to implement Doom or
Quake. We have a suggested list of games which should be implementable
within the IAP timeframe:
- True 3-D Tetris
- Space Invaders
- Missile Command
- Simple networked 3D maze game
We suggest you begin thinking about which game you would like to help write
and who you would like to work with. We hope to present all the material
necessary for the construction of this game within the first two weeks, so
that you have plenty of time to work your project.
- The development environment
- The development environment we will use on Athena is a version of
Scheme (SCM) which has an Open Inventor binding. This allows you to write
Scheme programs which use the Open Inventor 3D graphics toolkit.
Note that currently Open Inventor is only available on Athena
SGIs. Therefore, you will have to find an Indy in order to be able to work
with Inventor.
To get started, add the following line to the end of your
~/.environment file:
-
add iap-cgw # Current location of IvySCM
Add the following lines to the end of your ~/.cshrc.mine file:
-
if ($hosttype == sgi) then
limit coredumpsize 0 # Don't let anything dump core
setenv SCHEME_INIT_PATH /afs/athena.mit.edu/course/other/iap-cgw/lib/scm/
setenv SCHEME_LIBRARY_PATH /afs/athena.mit.edu/course/other/iap-cgw/lib/slib/
setenv LD_LIBRARY_PATH /afs/athena.mit.edu/course/other/iap-cgw/lib
endif
Note: you will need to log out and log back in for the above changes
to take effect.
Although you can run the class's Scheme interpreter, ivyscm,
directly from an Athena prompt, we strongly recommend you run it from
within emacs. To set up ivyscm within emacs, add the following lines to the
end of your ~/.emacs file (or create one if you don't have one):
- (setq load-path
(cons "/afs/athena.mit.edu/course/other/iap-cgw/elisp"
load-path))
; Use scheme-mode for files with .scm suffix
(setq auto-mode-alist
(append '(("\\.scm$" . scheme-mode)
)
auto-mode-alist))
; Autoload run-scheme from file cmuscheme.el
(setq scheme-mode-hook
'((lambda () (autoload 'run-scheme "cmuscheme"
"Run an inferior Scheme" t))))
(autoload 'run-scheme "cmuscheme"
"Run an inferior Scheme process."
t)
(setq scheme-program-name "ivyscm")
Now typing M-x run-scheme
from within emacs will bring up a
buffer in which ivyscm is running. After several seconds, the Scheme system
will print a banner message, and then bring up a prompt:
- > (display "Hello, world\n")
- Hello, world
- >
While you can work by typing directly into the interpreter's buffer, it is
much more convenient to work in a separate buffer. If you save your current
buffer with the suffix .scm, you can evaluate the current Scheme
expression (the one which the cursor is on) by typing C-c
C-e
. You can load in an entire Scheme file into the interpreter by
typing C-c C-l
and specifying the file name. You can get help
by typing M-x describe-mode
inside the Scheme window or a
scheme-mode buffer. The most useful commands are as follows:
Inside the *scheme* buffer:
- key binding
--- -------
C-c C-l scheme-load-file
C-c C-c comint-interrupt-subjob
(C-c C-c
interrupts what the Scheme interpreter is doing. If
it was in the middle of reading input or performing a computation, it will
print "ERROR: user interrupt" and go back to the idle state. However, if
you interrupt the interpreter while it is idle, the interpreter will quit,
the emacs interface will display "Process scheme interrupt", and you will
have to type M-x run-scheme
again to restart Scheme.)
Inside a scheme-mode buffer (i.e, filename ending in .scm):
- key binding
--- -------
C-c C-l scheme-load-file
C-c C-r scheme-send-region
C-c C-e scheme-send-definition
C-c C-z switch-to-scheme
Warning: Do not try to use the
scheme-compile-definition
or scheme-compile-file
commands to evaluate Scheme expressions or load Scheme files. All of the
commands you need are listed above. Experimentation is not recommended.
Example code, as well as documentation, resides in /mit/iap-cgw (after you
type "add iap-cgw"); see especially /mit/iap-cgw/src. Most of the examples
from the Inventor Mentor have been converted to Scheme and are located in
the Mentor subdirectory. Several convenience functions for this course are
given in /mit/iap-cgw/lib/scm/CGWInit.scm; we will describe (and likely add
to) them as the course proceeds.
To exit Scheme, you can exit emacs or kill the Scheme buffer. If you're
running ivyscm on the command line, type (exit)
.
- Paradigms of Open Inventor
- Open Inventor is a high-level toolkit, unlike many existing 2D and
3D graphics libraries. The data structures and flow of control in programs
will seem very abstract at first, but as you gain experience with the
toolkit you will understand more about how and why things happen.
Open Inventor is an object-oriented 3D graphics toolkit. Each
"object" on the screen is represented as an "object" in memory (in the
6.001 sense of the word -- remember the "object-oriented" adventure
game?). Each object is stored in the scene database, SoDB,
which stores such information as the name of each part in the current
scene.
The fundamental data structure in Open Inventor is called the scene
graph. A scene graph is a directed acyclic graph; you can think of
it, for the most part, as a tree. Most of the operations in Open
Inventor involve applying actions to these scene
graphs. Actions traverse this tree from left to right, and from the
top down.
For example, when an application renders a scene, it does so by applying a
render action to the scene graph. When a program wants to find a
certain node in the scene graph, it does so by applying a search
action to the scene graph.
The scene graph paradigm has been shown to be a successful one, and has
been adopted in many current and forthcoming 3D graphics standards.
Familiarity with Open Inventor will allow you to more easily learn similar
toolkits and prepare you for the next generation of 3D programming
environments.
- Creation of a simple scene graph
- As a first example, we will create a viewer (a window for
viewing Open Inventor scenes) and add some objects to the scene. The
first problem set will involve creating a simple scene graph like this
one and modifying some of its parameters.
The scene graph we will create will look like this:
SoSeparator
|
-------------------------------------------------------------------
| | | | | | |
SoMaterial SoCone SoTransform SoSphere SoMaterial SoTransform SoCube
First, let's start up the Scheme interpreter, and create and show our
window:
- (define my-viewer (new-SoXtExaminerViewer))
- (-> my-viewer 'show)
Now let's create the root node of our scene graph.
- (define root (new-SoSeparator))
- (-> root 'ref)
Note that we increment the reference count of the root
node. We will discuss the reasons for this as we proceed through the
course; for now, just remember to always ref your root node.
Now let's add a material node, which allows us to change the
material properties of objects which follow it in the scene graph:
- (define my-mat (new-SoMaterial))
- (-> root 'addChild my-mat)
And a shape node (in our example, a cone):
- (define my-cone (new-SoCone))
- (-> root 'addChild my-cone)
Nothing has yet appeared in our window. In order to view our scene, we must
tell the viewer which scene graph to render.
- (-> my-viewer 'setSceneGraph root)
Voila! A cone appears. Note that you can translate (middle mouse button),
spin (left mouse button), and scale (left and middle mouse buttons) the
cone. This is standard functionality that Open Inventor provides for
viewing scenes.
Now let's try changing the color of our cone to be red.
- (-> (-> my-mat 'diffuseColor) 'setValue 0.9 0.0 0.0)
The values in the above expression indicate red, green, and blue values,
from left to right, and they range from values of 0.0 to 1.0. They are
additive, so that high values for red and green make yellow.
We will next add a transform node to the scene graph, in
preparation for placing a sphere next to the cone.
- (define my-transform (new-SoTransform))
- (-> root 'addChild my-transform)
We will now add a sphere to our scene graph.
- (define my-sphere (new-SoSphere))
- (-> root 'addChild my-sphere)
Hmm. The sphere appears in the same place as our cone. Since we want to
have the sphere next to the cone, we must change its translation:
- (-> (-> my-transform 'translation) 'setValue 2.0 0.0 0.0)
Note that the sphere is the same color as the cone. It inherits the
material properties defined by the material node we added
before it.
Finally, let's add a blue cube to our scene. This second material node will
override the presence of the first one for all objects which follow it in
the scene graph.
- (define my-mat-2 (new-SoMaterial))
- (-> root 'addChild my-mat-2)
- (-> (-> my-mat-2 'diffuseColor) 'setValue 0.0 0.0 0.9)
- (define my-transform-2 (new-SoTransform))
- (-> root 'addChild my-transform-2)
- (define my-cube (new-SoCube))
- (-> root 'addChild my-cube)
Note that the cube appears this time in the place where the sphere
is, not where the cone is. Therefore we want to move the cube relative to
the center of the sphere:
- (-> (-> my-transform-2 'translation) 'setValue 2.1 0.0 0.0)
The default orientation of the coordinate axes in Inventor (before any
interaction with the viewer is done) is positive x to the right, positive y
up, and positive z out of the screen. This is a right-handed
coordinate system.
Using just these basic tools, you should now be able to approach the first problem set , which is to design a simple scene
composed of these objects.
- Next lecture
- Next time we will introduce more of the tools for manipulating
scene graphs, explain the workings of nodes and fields,
and show how to understand the manual pages from the perspective of
Scheme programming.