Dolphin
Tween and skinning are two kinds of 3D animation techniques. Tween or key frame interpolation
technique blends vertex positions or normals with a time parameter. The linear tween generates
a new vertice from two vertices v0 and v1 with the formula v0*(1-t) + v1*t (t in [0, 1]).
Hermite spline interpolation is a more complex tween technique. The dolphins under the sea
used the key frame interpolation.
The Dolphin swimming example is implemented with MCL and vertex shader assembly language.
It extended the single dolphin example in the Microsoft DirectX SDK 8.1. The dolphin performs
lerp and moves around circular path under the seafloor. The lerp animation
is completed by interpolation between three dolphin models. The seafloor is implemented as
caustic texture. Two dolphins are rendered by two shaders in sequence.
Dolphin Couple
This example demostrated
- multi-object with two dolphins and seafloor
- multi-shader that each object has a vertex shader
- multi-layer executes shaders in sequence
- caustic for seafloor environment
- keyframe interpolation on dolphin lerp
- matrix transform specifies the motion around of dolphins
To run this example, you need to download the MS DirectX 8.1 SDK.
Now let's study the source code.
package require mcl
This command loaded the mcl package.
proc GetWeight {fBlendWeight} {
float fWeight1
float fWeight2
float fWeight3
if {fBlendWeight > 0.0} {
set fWeight1 $fBlendWeight
set fWeight2 [expr 1.0-fBlendWeight]
set fWeight3 0.0
} else {
set fWeight1 0.0
set fWeight2 [expr 1.0+fBlendWeight]
set fWeight3 [expr -fBlendWeight]
}
return [list $fWeight1 $fWeight2 $fWeight3 0.0]
}
It gets blend weight components for the linear interpolation. Suppose a = fabs(fBlendWeight), if fBlendWeight > 0 then the blend vector is (a, 1-a, 0, 0), otherwise it is (0, 1-a, a, 0).
proc MoveDolphin {n} {
global app asmShader
global mat curCausticTexture
MoveDolphin is a procedure to let dolphins move. The argument n represents the dolphin identification.
global command specifies the global variables that may have been defined or used in other procedures.
app is the application object. asmShader is the shader object. mat is an array of global variable. Finally, curCausticTexture is the current caustic texture.
set fTime [$app getTime]
switch -exact $n {
0 {
float fKickFreq [expr 3*fTime]
float fPhase [expr (fTime+3.0)/3.0]
float fBlendWeight [expr sin(fKickFreq)]
}
1 {
float fKickFreq [expr 2*fTime]
float fPhase [expr fTime/3.0]
float fBlendWeight [expr sin(fKickFreq)]
}
}
[$app getTime] retrives the current time to fTime. The fKickFreq represents the lerp frequency of a dolphin. Since the dolphin 0 has the value 3 multiply the fTime that is bigger than the fKickFreq of
dolphin 1 with the value 2, the first dolphin kick faster than second one. The fPhase value sets the
initial cycle position. The dolphin lerp with a sin cyclic function.
MatrixScaling $mat(Dolphin) 0.01 0.01 0.01
MatrixRotationZ $mat(Rotate1) [expr -cos(fKickFreq)/6.0]
MatrixMultiply $mat(Dolphin) $mat(Dolphin) $mat(Rotate1)
MatrixRotationY $mat(Rotate2) $fPhase
MatrixMultiply $mat(Dolphin) $mat(Dolphin) $mat(Rotate2)
MatrixTranslation $mat(Trans) [expr -5.0*sin(fPhase)] \\
[expr sin(fKickFreq)/2.0] \\
[expr 10.0-10.0*cos(fPhase)]
MatrixMultiply $mat(Dolphin) $mat(Dolphin) $mat(Trans)
The matrix completes following transforms:
M(Dolphin) = Scale(a, b, c)*RotationZ(-cos(freq)/6.0)*RotationY(fPhase)*Translation(x, y, z)
It scales a little bit then rotation around Z and Y and move ahead.
set curCausticTexture [expr int([$app getTime]*32)%32]
# Set the vertex shader constants.
float4 vZero [list 0.0 0.0 0.0 0.0]
float4 vOne [list 1.0 0.5 0.2 0.05]
float4 vWeight [GetWeight $fBlendWeight]
float4 fLight [list 0.0 1.0 0.0 0.0]
float4 fDiffuse [list 1.0 1.0 1.0 1.0]
float4 fAmbient [list 0.25 0.25 0.25 0.25]
float4 fFog [list 0.5 50.0 [expr 1.0/(50.0-1.0)] 0.0]
float4 fCaustics [list 0.05 0.05 \\
[expr sin(fTime)/8.0] [expr cos(fTime)/10.0]]
This code sets the values of vertex shader constants. curCausticTexture is the current Caustic number. Its value is from 0 to 31. vZero and vOne is the constant vector. vWeight is the weight value for interpolation. The fLight, fDiffuse, fAmbient, and fFog are vectors for light, diffuse, ambient, and fog. fCaustics is the caustic vector.
# set matrix
MatrixMultiply $mat(Camera) $mat(Dolphin) $mat(View)
MatrixMultiply $mat(Temp) $mat(Camera) $mat(Proj)
MatrixTranspose $mat(CameraTranspose) $mat(Camera)
MatrixTranspose $mat(Transpose) $mat(Temp)
MatrixTranspose $mat(ViewTranspose) $mat(View)
MatrixTranspose $mat(ProjTranspose) $mat(Proj)
M(CameraTranspose) = Transpose( M(Dolphin)*M(View) )
M(Transpose) = Transpose( M(Dolphin)*M(View)*mat(Proj) )
M(ViewTranspose) = Transpose( M(View) )
M(ProjTranspose) = Transpose( M(Proj) )
# set vertex shader constants
$asmShader($n) vconst 0 $vZero 1
$asmShader($n) vconst 1 $vOne 1
$asmShader($n) vconst 2 $vWeight 1
$asmShader($n) vconst 4 $mat(Transpose) 4
$asmShader($n) vconst 8 $mat(CameraTranspose) 4
$asmShader($n) vconst 12 $mat(ViewTranspose) 4
$asmShader($n) vconst 20 $fLight 1
$asmShader($n) vconst 21 $fDiffuse 1
$asmShader($n) vconst 22 $fAmbient 1
$asmShader($n) vconst 23 $fFog 1
$asmShader($n) vconst 24 $fCaustics 1
$asmShader($n) vconst 28 $mat(ProjTranspose) 4
}
This code sets the constants of for each asmShader(n) vertex shader.
proc InitStartup {} {}
This is a required callback function although there is nothing to do inside.
proc FrameMove {} {
global app mat vfillmode
if {[$app keyState F]} {
if {[string compare $vfillmode wireframe] == 0} {
set vfillmode solid
} else {
set vfillmode wireframe
}
$app setRenderState fillmode $vfillmode
}
}
FrameMove sets the paramters for each frame.
[$app keyState F] checks if the key 'F' is pressed,
if it is true the fillmode state will be changed.
If current fillmode is solid then the new fillmode will
be wireframe. By pressing the F key you can see the wireframe
and back from it.
proc Render {} {
global app asmShader vtShader
global vbDolphin vbSeafloor
global mhDolphin mhSeafloor
global ibDolphin ibSeafloor
global texDolphin texSeafloor texCaustic
global curCausticTexture
global vertice ft water_color
global nNum mat
# clear flags color z stencil with water color ARGB
$app clear {target zbuffer} $water_color 1.0 0
$app beginScene
Render is a callback funciton to render polygons.
Here the global command declares the global variables used inside the Render.
[$app clear flags color z stencil] clear the clip plane with target and zbuffer flags. The flags could be a list with elements from . color is a 32-bit value. The water_color has the value 0x00004080 with ARGB (00, 00, 40, 80). z and stencil are float values for zbuffer and stencil respectively.
[$app beginScene] starts the scene.
for {set h 0} {h < 2} {incr h} {
# render seafloor and dolphin 0
MoveDolphin $h
This loop starts render 3 dolphin model to simulat the leap of the dolphins.
# Render seafloor
$texSeafloor set 0
$vtShader(Seafloor) active
$vbSeafloor stream 0 [$vertice size]
$ibSeafloor indices 0
$app drawIndexedPrimitive trianglelist \\
0 $nNum(SeafloorVertices) 0 $nNum(SeafloorFaces)
It sets the seafloor texture and active the shader with the stream 0. After setting the indices of index buffer of seafloor with 0, it draws indexed primitive trianglelist.
# Render dolphin 0
$texDolphin($h) set 0
$vtShader(Dolphin,$h) active
for {set i 0} {i < 3} {incr i} {
$vbDolphin($h,$i) stream $i [$vertice size]
}
$ibDolphin($h) indices 0
$app drawIndexedPrimitive trianglelist \\
0 $nNum(DolphinVertices) 0 $nNum(DolphinFaces)
like seafloor, this code paragraph renders dolphin. Notes that there are 3 streams for each dolphin models.
# set render state
$app setRenderState alphablendenable true
$app setRenderState srcblend srccolor
$app setRenderState destblend one
It sets the render state with alpha belnd enable, srcblend to be srccolor, and destblend to be one.
$texCaustic($curCausticTexture) set 0
float4 ambientDark {0.0 0.0 0.0 0.0}
$asmShader(0) vconst 22 $ambientDark 1
$app setRenderState fogcolor 0x00000000
it sets the ambient dark to shader constant.
$vtShader(Seafloor2) active
$vbSeafloor stream 0 [$vertice size]
$ibSeafloor indices 0
$app drawIndexedPrimitive trianglelist \\
0 $nNum(SeafloorVertices) 0 $nNum(SeafloorFaces)
# render dolphin 0 again
$vtShader(Dolphin2,$h) active
for {set i 0} {i < 3} {incr i} {
$vbDolphin($h,$i) stream $i [$vertice size]
}
$ibDolphin($h) indices 0
$app drawIndexedPrimitive trianglelist \\
0 $nNum(DolphinVertices) 0 $nNum(DolphinFaces)
it render seafloor2 and dolphin2 again.
$app setRenderState alphablendenable false
$app setRenderState fogcolor $water_color
}
restore to disable the alphablendenable and set fog color as water color.
if {[$app showHelp]} {
set cmdTitle "Keyboard Controls:"
set cmdOp "Play\nStep\nHelp\nPlay\nFullscreen\nExit"
set cmdKey "Enter\nSpace\nF1\nF2\nF5\nEsc"
$ft(1) draw 2 40 0xFFFFFFFF $cmdTitle
$ft(1) draw 20 60 0xFFFFFFFF $cmdOp
$ft(1) draw 210 60 0xFF00FFFF $cmdKey
$ft(0) draw 2 0 0xff00ff00 [$app getFrameStats]
$ft(0) draw 2 20 0xff00ff00 [$app getDeviceStats]
}
This code shows the help text on the window. ft(0) and ft(1) are two font objects defined in the MCLMain. [$ft(0) draw row col text-color text-string] draws text-string in the row and the col with text-color. [$app getFrameStats] returns a string with the frame rate and windows' width, height, and color depth. [$app getDeviceStats] returns a information string of the video card.
$app endScene
}
[$app endScene] terminates a scene.
proc InitDeviceObjects {} {
global app vertice ft
global asmShader texDolphin texSeafloor texCaustic
global mhDolphin mhSeafloor
global vbDolphin vbSeafloor
global ibDolphin ibSeafloor
global nNum vertice
InitDeviceObjects starts with the declaration of global variables.
$ft(0) init
$ft(1) init
it initializes font objects ft.
# create asm shader
set asmShader(0) [$app shader asm]
set asmShader(1) [$app shader asm]
it creates two assembly shaders.
# create dolphin texture
set texDolphin(0) [$asmShader(0) texture "stripe.bmp"]
set texDolphin(1) [$asmShader(1) texture "dolphin.bmp"]
# create sea floor texture
set texSeafloor [$asmShader(0) texture "seafloor.bmp"]
now we create two shaders. Shader 0 includes a texture for
Dolphin, Seafloor, and a series of caustic textures. Another
shader includes another dolphin texture.
# create caustic textures
for {set i 0} {i < 32} {incr i} {
set fmt [format %02ld $i]
set texCaustic($i) [$asmShader(0) texture "Caust$fmt.tga"]
}
texCaustic(i) is the caustic texture object. Caustic is a method to generate a new curve from a given curve and a point. The light rays from the point are reflected from the curve and their envolve forms a new curve.
# create dolphin meshes
for {set i 0} {i < 3} {incr i} {
set mhDolphin(0,$i) [$app mesh "dolphin[expr i+1].x"]
set mhDolphin(1,$i) [$app mesh "dolphin[expr i+1].x"]
}
# create sea floor mesh
set mhSeafloor [$app mesh "SeaFloor.x"]
it opens the meshes of dolphin and the mesh of seafloor.
# set FVF
for {set i 0} {i < 3} {incr i} {
$mhDolphin(0,$i) setFVF {xyz normal tex1}
$mhDolphin(1,$i) setFVF {xyz normal tex1}
}
$mhSeafloor setFVF {xyz normal tex1}
it sets the FVF of two dolphins and seafloor as {xyz normal text}.
Read D3D document to get more details about the FVF.
# get number of vertices and faces
set nNum(DolphinVertices) [$mhDolphin(0,0) getNumVertices]
set nNum(DolphinFaces) [$mhDolphin(0,0) getNumFaces]
set nNum(SeafloorVertices) [$mhSeafloor getNumVertices]
set nNum(SeafloorFaces) [$mhSeafloor getNumFaces]
get the number of vertices and faces of Dolphin and Seafloor from meshes.
# create vbuffers
for {set i 0} {i < 3} {incr i} {
set vbDolphin(0,$i) [$app vbuffer $nNum(DolphinVertices) \\
[$vertice size] writeonly 0 managed]
set vbDolphin(1,$i) [$app vbuffer $nNum(DolphinVertices) \\
[$vertice size] writeonly 0 managed]
}
set vbSeafloor [$app vbuffer $nNum(SeafloorVertices) \\
[$vertice size] writeonly 0 managed]
it creates 3 vertex buffers for two Dolphins. Seafloor vertex buffer is also created.
[$app vbuffer length vstruct usage fvf pool] is the command to create the vbuffer.
The length argument specefies the vertice size, vstruct is the vertex structure. The usage
is the specification about the vertex buffer usage. The FVF argument specifies the FVF format.
When it is 0 the FVF format is ignored. The pool argument describes the way of memory management.
# create ibuffers
set ibDolphin(0) [$app ibuffer [expr {$nNum(DolphinFaces)*3}] \\
writeonly index16 managed]
set ibDolphin(1) [$app ibuffer [expr {$nNum(DolphinFaces)*3}] \\
writeonly index16 managed]
set ibSeafloor [$app ibuffer [expr {$nNum(SeafloorFaces)*3}] \\
writeonly index16 managed]
[$app ibuffer length usage format pool] creates index buffers for two Dolphins and Seafloor.
The first argument is the byte length of faces. The second argument is the usage of index buffer.
The format argument with two possible value index16/index32 specifies the index unit size.
The index16/index32 represents the item type is a word (16-bit)/a dword (32-bit) respectively.
The pool is method to manage the memory.
# clone dolphins
set size [$vertice size]
for {set i 0} {i < 3} {incr i} {
$mhDolphin(0,$i) vlock
$vbDolphin(0,$i) lock
$mhDolphin(0,$i) vcopy [$vbDolphin(0,$i) getBuffer] \\
[expr {$nNum(DolphinVertices)*size}]
$vbDolphin(0,$i) unlock
$mhDolphin(0,$i) vunlock
}
it copies three vertex buffers of dolphins from three Dolphin models .
for {set i 0} {i < 3} {incr i} {
$mhDolphin(1,$i) vlock
$vbDolphin(1,$i) lock
it locks the vertex buffer of in both the dolphin mesh and the new buffer.
$mhDolphin(1,$i) vcopy [$vbDolphin(1,$i) getBuffer] \\
[expr {$nNum(DolphinVertices)*size}]
$vertice init [$vbDolphin(1,$i) getBuffer]
float3 pos
for {set k 0} {k < $nNum(DolphinVertices)} {incr k} {
set pos [$vertice get position]
Vec3X+= $pos 100.0
Vec3Y+= $pos 100.0
Vec3Z+= $pos 100.0
$vertice set position $pos
$vertice next 1
}
vcopy copies the vertex buffer from a model to a new vertex buffer. [$vertice init ...] sets the
vertice struct pointer to the dolphin's buffer. [$vertice get position] gets the position item from
the vertice. [Vec3X+= $pos 100.0] added the x component of the vector pos with the float 100.0.
[$vertice set position $pos] sets position of vertice as the vector pos. [$vertice next 1] moves the
vertice to next position in the buffer.
$vbDolphin(1,$i) unlock
$mhDolphin(1,$i) vunlock
}
it unlocks both the vertex buffer in the mesh of dolphin and the created vertex buffer.
# set sea floor vertices
$mhSeafloor vlock
$vbSeafloor lock
$mhSeafloor vcopy [$vbSeafloor getBuffer] \\
[expr {$nNum(SeafloorVertices)*size}]
it clones Seafloor in the way similar to Dolphin. lock seafloor vertex buffers of mesh and new buffer. then copy the buffer.
float3 p
float2 t
$vertice init [$vbSeafloor getBuffer]
for {set i 0} {i < $nNum(SeafloorVertices)} {incr i} {
set p [$vertice get position]
set t [$vertice get tex1]
Vec3X+= $p [expr rand()]
Vec3Y+= $p [expr rand()]
Vec3Z+= $p [expr rand()]
Vec2X*= $t 10
Vec2Y*= $t 10
$vertice set position $p
$vertice set tex1 $t
$vertice next 1
}
modify the position and texture items. The accumulated rand() value generates the sand effects under the sea.
$vbSeafloor unlock
$mhSeafloor vunlock
unlock the vbuffer and mesh.
$mhDolphin(0,0) ilock
$ibDolphin(0) lock
$mhDolphin(0,0) icopy [$ibDolphin(0) getBuffer] \\
[expr {$nNum(DolphinFaces)*3*2}]
$ibDolphin(0) unlock
$mhDolphin(0,0) iunlock
it clones index buffer of dolphin(0,0).
$mhDolphin(1,0) ilock
$ibDolphin(1) lock
$mhDolphin(1,0) icopy [$ibDolphin(1) getBuffer] \\
[expr {$nNum(DolphinFaces)*3*2}]
$ibDolphin(1) unlock
$mhDolphin(1,0) iunlock
it colnes index buffer of dolphin(1,0)
$mhSeafloor ilock
$ibSeafloor lock
$mhSeafloor icopy [$ibSeafloor getBuffer] \\
[expr {$nNum(SeafloorFaces)*3*2}]
$ibSeafloor unlock
$mhSeafloor iunlock
}
it clones index buffer of seafloor.
proc RestoreDeviceObjects {} {
global app ft
global water_color mat
global asmShader vtShader
RestoreDeviceObjects will reset matrix and set states.
# set the transform matrices
float3 vEyePt [list 0.0 0.0 -5.0]
float3 vLookatPt [list 0.0 0.0 0.0]
float3 vUpVec [list 0.0 1.0 0.0]
set fBackBufferWidth [expr double([$app getBackBufferWidth])]
set fBackBufferHeight [expr double([$app getBackBufferHeight])]
float fAspectRatio [expr fBackBufferWidth/fBackBufferHeight]
MatrixLookAtLH $mat(View) $vEyePt $vLookatPt $vUpVec
MatrixPerspectiveFovLH $mat(Proj) 60.0 $fAspectRatio 1.0 10000.0
The view matrix mat(View) is generated by vEyePt,
vLookatPt, and vUpVec vectors. The perspective matrix mat(Proj) is generated with the field of view
angle 60 degree, aspect ratio divided back buffer width by back buffer height, 1.0 as z-value of the near view-plane, and 10000.0 as z-value of the far view-plane.
# set states
$app setRenderState lighting false
$app setRenderState cullmode none
to use the pixel shader requires the disabled lighting. Cullmode specifies how back-facing triangles are culled.
none does not cull back faces. cw will cull back faces with clockwise vertices. ccw will cull back faces with counterclockwise vertices
$app setTextureStageState 0 minfilter linear
$app setTextureStageState 0 magfilter linear
[$app setTextureStageState 0 minfilter linear] sets the state value for the currently assigned texture 0.
minfilter and linear indicate the texture minification linear filter to use when rendering the texture onto surface.
magfilter and linear indicate the texture magfication linear filter to use when rendering the texture onto surface.
$app setRenderState zenable true
$app setRenderState fogenable true
$app setRenderState fogcolor $water_color
zenable and fogenable are enabled for zbuffer and fog. The fog color is set to water_color.
# dolphin decl
set vtDolphinDecl {{0 float3 0 float3 3 float2 6}
{1 float3 1 float3 4 float2 7}
{2 float3 2 float3 5 float2 8}}
it specifies the dolphin declaration.
set vtShader(Dolphin,0) \\
[$asmShader(0) vertex "DolphinTween.vsh" $vtDolphinDecl]
set vtShader(Dolphin2,0) \\
[$asmShader(0) vertex "DolphinTween2.vsh" $vtDolphinDecl]
it creates asm vertex shader for dolphin(0) and dolphin2(0).
# create asm vertex shader for dolphin 1
set vtShader(Dolphin,1) \\
[$asmShader(1) vertex "DolphinTween.vsh" $vtDolphinDecl]
set vtShader(Dolphin2,1) \\
[$asmShader(1) vertex "DolphinTween2.vsh" $vtDolphinDecl]
it creates asm vertex shader for dolphin(1) and dolphin2(1).
# seafloor decl
set vtSeafloorDecl { {0 float3 0 float3 3 float2 6} }
# create asm vertex shader for seafloor
set vtShader(Seafloor) \\
[$asmShader(0) vertex "SeaFloor.vsh" $vtSeafloorDecl]
set vtShader(Seafloor2) \\
[$asmShader(0) vertex "SeaFloor2.vsh" $vtSeafloorDecl]
it specifies seafloor declaration adn create asm vertex shader for seafloor.
# restore font
$ft(0) restore
$ft(1) restore
}
restore font objects.
#
# InvalidateDeviceObjects
# close shaders
#
proc InvalidateDeviceObjects {} {
global ft vtShader
$vtShader(Dolphin2,1) release
$vtShader(Dolphin,1) release
$vtShader(Seafloor2) release
$vtShader(Seafloor) release
$vtShader(Dolphin2,0) release
$vtShader(Dolphin,0) release
$ft(1) invalidate
$ft(0) invalidate
}
close vertex shaders and font objects in reverse order.
proc DeleteDeviceObjects {} {
global ibSeafloor ibDolphin
global vbSeafloor vbDolphin
global mhSeafloor mhDolphin
global texCaustic texSeafloor texDolphin
global ft
# ibuffer
$ibSeafloor release
$ibDolphin(1) release
$ibDolphin(0) release
release index buffers.
# vbuffer
$vbSeafloor release
for {set i 2} {i >= 0} {incr i -1} {
$vbDolphin(1,$i) release
$vbDolphin(0,$i) release
}
release vertex buffers
# mesh
$mhSeafloor release
for {set i 2} {i >= 0} {incr i -1} {
$mhDolphin(1,$i) release
$mhDolphin(0,$i) release
}
release meshes
# texture
for {set i 31} {i >= 0} {incr i -1} {
$texCaustic($i) release
}
$texSeafloor release
# release tex
$texDolphin(1) release
$texDolphin(0) release
release textures
# font
$ft(1) delete
$ft(0) delete
}
delete fonts
proc FinalCleanup {} {
global ft
$ft(1) release
$ft(0) release
}
FinalCleanup released the font objects.
proc curpath {} {
return [file join [pwd] [file dirname [info script]]]
}
[info script] returns current path of the MCL script. [file dirname ...] retrives the directory from the full path. [pwd] returns the current path. [file join ...] constructs path with components.
proc getTexture {fname} {
return [file join [curpath] .. media texture $fname]
}
it returns a fname in the texture folder media\texture.
proc getXFile {fname} {
return [file join [curpath] .. media models x $fname]
}
getXFile returns a .x file full path in the media/models/x folder.
proc main {} {
global app ft vertice
# create app
set app [MCL::application]
# create text font
set ft(0) [$app font Vertana 10 0]
set ft(1) [$app font Arial 8 0]
# create vertice struct decl
set vertice [MCL::struct {float3 position float3 normal float2 tex1}]
main starts the application. Where app is the application object created with the MCL::application command. [$app font fontType size style] command creates font objects which are used to display the status.
[MCL::struct {type name ...}] creates a struct declaration with a list of the items of type and name.
# set required vertex shader version 1.1
$app version vertex 1 1
[$app version shader major minor] specifies the required shader version. The shader could be vertex or pixel to represent their versions respectively. The code required vertex shader 1.1. If the hardware supports that version the accelerator will be used. Otherwise the software vertex shader will be used or returns failed. No pixel shader used in this example.
# run
$app create
$app run
}
[$app create] opens an application window and initializes the application through RestoreDeviceObjects. [$app run] starts the message loop of the window.
set PI 3.1415926535897932384626
set vfillmode solid
set water_color 0x00004080
set count 0
Set global constants. PI is the standard constant. vfillmode is used to display wireframe or real shading. water_color names a color value.
matrix mat(World)
matrix mat(View)
matrix mat(Proj)
creates global matrix. mat(World), matr(View), and mat(Proj) are for world, view, and perspective transforms.
matrix mat(Dolphin)
matrix mat(Trans)
matrix mat(Rotate1)
matrix mat(Rotate2)
matrix mat(Temp)
matrix mat(Camera)
matrix mat(Transpose)
matrix mat(CameraTranspose)
matrix mat(ViewTranspose)
matrix mat(ProjTranspose)
these matrix are declared as global to avoid the cost of creation.
main
exit 0
main starts the application. exit 0 will terminate the application.
Future Sea World Project
Different kinds of fishes
Swimming in different paths
Lights under sea
|