# Tutorial OpenGL Transformation
# Original C++ code by Song Ho Ahn (song.ahn@gmail.com)
# See www.songho.ca/opengl/gl_transform.html for the original files
#
# Modified for Tcl3D by Paul Obermeier 2009/09/13
# See www.tcl3d.org for the Tcl3D extension.
package require Tk
package require tcl3d
tcl3dAddEvents
array set gState {
fovY 60.0
nearPlane 1.0
farPlane 100.0
windowWidth 200
windowHeight 400
drawModeChanged false
drawMode 0
cameraAngleX 45.0
cameraAngleY -45.0
cameraDistance 25.0
view,pos,x 0
view,pos,y 0
view,pos,z 0
view,angle,x 0
view,angle,y 0
view,angle,z 0
model,pos,x 0
model,pos,y 0
model,pos,z 0
model,angle,x 0
model,angle,y 0
model,angle,z 0
bgColor { 0.0 0.0 0.0 0.0 }
textFont {-family {Courier} -size 10}
}
# Show errors occuring in the Togl callbacks.
proc bgerror { msg } {
tk_messageBox -icon error -type ok -message "Error: $msg\n\n$::errorInfo"
exit
}
# Print info message into widget a the bottom of the window.
proc PrintInfo { msg } {
if { [winfo exists .fr.info] } {
.fr.info configure -text $msg
}
}
# Set the camera position and rotation
proc SetViewMatrix { x y z pitch heading roll } {
global gState
set gState(view,pos,x) $x
set gState(view,pos,y) $y
set gState(view,pos,z) $z
set gState(view,angle,x) $pitch
set gState(view,angle,y) $heading
set gState(view,angle,z) $roll
}
# Set the object position and rotation
proc SetModelMatrix { x y z rx ry rz } {
global gState
set gState(model,pos,x) $x
set gState(model,pos,y) $y
set gState(model,pos,z) $z
set gState(model,angle,x) $rx
set gState(model,angle,y) $ry
set gState(model,angle,z) $rz
}
proc SetLeftMouse { x y } {
global gState
set gState(mouseX) $x
set gState(mouseY) $y
}
proc RotateCamera { toglwin x y } {
global gState
set diffX [expr {$x - $gState(mouseX)}]
set diffY [expr {$y - $gState(mouseY)}]
set gState(cameraAngleY) [expr {$gState(cameraAngleY) + $diffX}]
set gState(cameraAngleX) [expr {$gState(cameraAngleX) + $diffY}]
set gState(mouseX) $x
set gState(mouseY) $y
$toglwin postredisplay
}
proc SetRightMouse { x y } {
global gState
set gState(mouseY) $y
}
proc ZoomCamera { toglwin x y } {
global gState
set diffY [expr {($y - $gState(mouseY)) * 0.05}]
set gState(cameraDistance) [expr {$gState(cameraDistance) + $diffY}]
set gState(mouseY) $y
$toglwin postredisplay
}
proc ToggleDrawMode {} {
global gState
incr gState(drawMode)
if { $gState(drawMode) > 2 } {
set gState(drawMode) 0
}
set gState(drawModeChanged) true
DisplayCallback .fr.toglwin
DisplayCallback .fr.toglwin
}
# Configure projection and viewport of sub window
proc SetViewportSub { x y w h nearPlane farPlane } {
global gState
# set viewport
glViewport $x $y $w $h
glScissor $x $y $w $h
# set perspective viewing frustum
glMatrixMode GL_PROJECTION
glLoadIdentity
# FOV, AspectRatio, NearClip, FarClip
gluPerspective $gState(fovY) [expr {double($w)/double($h)}] \
$nearPlane $farPlane
# switch to modelview matrix in order to set scene
glMatrixMode GL_MODELVIEW
glLoadIdentity
}
proc DrawCamera {} {
set shininess 32.0
set diffuseColor {1.0 1.0 1.0}
set specularColor {1.0 1.0 1.0 1.0}
# set specular and shiniess using glMaterial
glMaterialf GL_FRONT_AND_BACK GL_SHININESS $shininess ; # range 0 ~ 128
glMaterialfv GL_FRONT_AND_BACK GL_SPECULAR $specularColor
# set ambient and diffuse color using glColorMaterial (gold-yellow)
glColorMaterial GL_FRONT_AND_BACK GL_AMBIENT_AND_DIFFUSE
glColor3fv $diffuseColor
tcl3dCameraModel
}
proc DrawTeapot {} {
set shininess 15.0
set diffuseColor {0.929524 0.796542 0.178823 }
set specularColor {1.00000 0.980392 0.549020 1.0 }
# set specular and shiniess using glMaterial (gold-yellow)
glMaterialf GL_FRONT_AND_BACK GL_SHININESS $shininess ; # range 0 ~ 128
glMaterialfv GL_FRONT_AND_BACK GL_SPECULAR $specularColor
# set ambient and diffuse color using glColorMaterial (gold-yellow)
glColorMaterial GL_FRONT_AND_BACK GL_AMBIENT_AND_DIFFUSE
glColor3fv $diffuseColor
tcl3dTeapotModel
}
# Draw a grid on the xz plane
proc DrawGrid { size step } {
glDisable GL_LIGHTING
glBegin GL_LINES
glColor3f 0.3 0.3 0.3
for { set i $step } { $i <= $size } { set i [expr {$i + $step}] } {
glVertex3f -$size 0 $i ; # lines parallel to X-axis
glVertex3f $size 0 $i
glVertex3f -$size 0 -$i ; # lines parallel to X-axis
glVertex3f $size 0 -$i
glVertex3f $i 0 -$size ; # lines parallel to Z-axis
glVertex3f $i 0 $size
glVertex3f -$i 0 -$size ; # lines parallel to Z-axis
glVertex3f -$i 0 $size
}
# x-axis
glColor3f 0.5 0 0
glVertex3f -$size 0 0
glVertex3f $size 0 0
# z-axis
glColor3f 0 0 0.5
glVertex3f 0 0 -$size
glVertex3f 0 0 $size
glEnd
# enable lighting back
glEnable GL_LIGHTING
}
# Draw the local axis of an object
proc DrawAxis { size } {
glDepthFunc GL_ALWAYS ; # to avoid visual artifacts with grid lines
glDisable GL_LIGHTING
# draw axis
glLineWidth 3
glBegin GL_LINES
glColor3f 1 0 0
glVertex3f 0 0 0
glVertex3f $size 0 0
glColor3f 0 1 0
glVertex3f 0 0 0
glVertex3f 0 $size 0
glColor3f 0 0 1
glVertex3f 0 0 0
glVertex3f 0 0 $size
glEnd
glLineWidth 1
# draw arrows (actually big square dots)
glPointSize 5
glBegin GL_POINTS
glColor3f 1 0 0
glVertex3f $size 0 0
glColor3f 0 1 0
glVertex3f 0 $size 0
glColor3f 0 0 1
glVertex3f 0 0 $size
glEnd
glPointSize 1
# restore default settings
glEnable GL_LIGHTING
glDepthFunc GL_LEQUAL
}
# Draw frustum
proc DrawFrustum { fovY aspectRatio nearPlane farPlane } {
set tangent [expr {tan ([tcl3dDegToRad [expr {$fovY/2}]])}]
set nearHeight [expr {$nearPlane * $tangent}]
set nearWidth [expr {$nearHeight * $aspectRatio}]
set farHeight [expr {$farPlane * $tangent}]
set farWidth [expr {$farHeight * $aspectRatio}]
# compute 8 vertices of the frustum
# near top right
set vertices(0) [list $nearWidth $nearHeight -$nearPlane]
# near top left
set vertices(1) [list -$nearWidth $nearHeight -$nearPlane]
# near bottom left
set vertices(2) [list -$nearWidth -$nearHeight -$nearPlane]
# near bottom right
set vertices(3) [list $nearWidth -$nearHeight -$nearPlane]
# far top right
set vertices(4) [list $farWidth $farHeight -$farPlane]
# far top left
set vertices(5) [list -$farWidth $farHeight -$farPlane]
# far bottom left
set vertices(6) [list -$farWidth -$farHeight -$farPlane]
# far bottom right
set vertices(7) [list $farWidth -$farHeight -$farPlane]
set colorLine1 { 0.7 0.7 0.7 0.7 }
set colorLine2 { 0.2 0.2 0.2 0.7 }
set colorPlane { 0.5 0.5 0.5 0.5 }
glDisable GL_LIGHTING
glDisable GL_CULL_FACE
glBlendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA
glBegin GL_LINES
glColor4fv $colorLine2
glVertex3f 0 0 0
glColor4fv $colorLine1
glVertex3fv $vertices(4)
glColor4fv $colorLine2
glVertex3f 0 0 0
glColor4fv $colorLine1
glVertex3fv $vertices(5)
glColor4fv $colorLine2
glVertex3f 0 0 0
glColor4fv $colorLine1
glVertex3fv $vertices(6)
glColor4fv $colorLine2
glVertex3f 0 0 0
glColor4fv $colorLine1
glVertex3fv $vertices(7)
glEnd
glColor4fv $colorLine1
glBegin GL_LINE_LOOP
glVertex3fv $vertices(4)
glVertex3fv $vertices(5)
glVertex3fv $vertices(6)
glVertex3fv $vertices(7)
glEnd
glColor4fv $colorLine1
glBegin GL_LINE_LOOP
glVertex3fv $vertices(0)
glVertex3fv $vertices(1)
glVertex3fv $vertices(2)
glVertex3fv $vertices(3)
glEnd
glColor4fv $colorPlane
glBegin GL_QUADS
glVertex3fv $vertices(0)
glVertex3fv $vertices(1)
glVertex3fv $vertices(2)
glVertex3fv $vertices(3)
glVertex3fv $vertices(4)
glVertex3fv $vertices(5)
glVertex3fv $vertices(6)
glVertex3fv $vertices(7)
glEnd
glEnable GL_CULL_FACE
glEnable GL_LIGHTING
}
# Draw upper window (view from the camera)
proc DrawSub1 {} {
global gState
# set upper viewport
SetViewportSub 0 [expr {$gState(windowHeight)/2}] $gState(windowWidth) \
[expr {$gState(windowHeight)/2}] 1 10
# clear buffer
glClearColor 0.1 0.1 0.1 1
glClear [expr $::GL_COLOR_BUFFER_BIT | \
$::GL_DEPTH_BUFFER_BIT | \
$::GL_STENCIL_BUFFER_BIT]
# initialize ModelView matrix
glPushMatrix
glLoadIdentity
# ModelView matrix is product of viewing matrix and modeling matrix
# ModelView_M = View_M * Model_M
# First, transform the camera (viewing matrix) from world space to eye space
# Notice all values are negated, because we move the whole scene with the
# inverse of camera transform
glRotatef [expr {-1.0 * $gState(view,angle,x)}] 1 0 0 ; # pitch
glRotatef [expr {-1.0 * $gState(view,angle,y)}] 0 1 0 ; # heading
glRotatef [expr {-1.0 * $gState(view,angle,z)}] 0 0 1 ; # roll
glTranslatef [expr {-1.0 * $gState(view,pos,x)}] \
[expr {-1.0 * $gState(view,pos,y)}] \
[expr {-1.0 * $gState(view,pos,z)}]
# we have set viewing matrix up to this point.
# (Matrix from world space to eye space)
# save the view matrix only
set gState(matrixView) [tcl3dOglGetFloatState GL_MODELVIEW_MATRIX 16]
# always draw the grid at the origin (before any modeling transform)
DrawGrid 10 1
# In order to get the modeling matrix only, reset GL_MODELVIEW matrix
glLoadIdentity
# transform the object
# From now, all transform will be for modeling matrix only.
# (transform from object space to world space)
glTranslatef $gState(model,pos,x) $gState(model,pos,y) $gState(model,pos,z)
glRotatef $gState(model,angle,x) 1 0 0
glRotatef $gState(model,angle,y) 0 1 0
glRotatef $gState(model,angle,z) 0 0 1
# save modeling matrix
set gState(matrixModel) [tcl3dOglGetFloatState GL_MODELVIEW_MATRIX 16]
# restore GL_MODELVIEW matrix by multiplying matrixView and matrixModel
# before drawing the object
# ModelView_M = View_M * Model_M
glLoadMatrixf $gState(matrixView) ; # Mmv = Mv
glMultMatrixf $gState(matrixModel) ; # Mmv *= Mm
# save ModelView matrix
set gState(matrixModelView) [tcl3dOglGetFloatState GL_MODELVIEW_MATRIX 16]
# draw a teapot after ModelView transform
# v' = Mmv * v
DrawAxis 4
DrawTeapot
glPopMatrix
}
# Draw bottom window (3rd person view)
proc DrawSub2 {} {
global gState
# set bottom viewport
SetViewportSub 0 0 $gState(windowWidth) [expr {$gState(windowHeight)/2}] \
$gState(nearPlane) $gState(farPlane)
# clear buffer
glClearColor [lindex $gState(bgColor) 0] [lindex $gState(bgColor) 1] \
[lindex $gState(bgColor) 2] [lindex $gState(bgColor) 3]
glClear [expr $::GL_COLOR_BUFFER_BIT | \
$::GL_DEPTH_BUFFER_BIT | \
$::GL_STENCIL_BUFFER_BIT]
glPushMatrix
# First, transform the camera (viewing matrix) from world space to eye space
glTranslatef 0 0 [expr {-1.0 * $gState(cameraDistance)}]
glRotatef $gState(cameraAngleX) 1 0 0 ; # pitch
glRotatef $gState(cameraAngleY) 0 1 0 ; # heading
# draw grid
DrawGrid 10 1
# draw a teapot
glPushMatrix
glTranslatef $gState(model,pos,x) $gState(model,pos,y) $gState(model,pos,z)
glRotatef $gState(model,angle,x) 1 0 0
glRotatef $gState(model,angle,y) 0 1 0
glRotatef $gState(model,angle,z) 0 0 1
DrawAxis 4
DrawTeapot
glPopMatrix
# draw the camera
glPushMatrix
glTranslatef $gState(view,pos,x) $gState(view,pos,y) $gState(view,pos,z)
glRotatef $gState(view,angle,x) 1 0 0
glRotatef $gState(view,angle,y) 0 1 0
glRotatef $gState(view,angle,z) 0 0 1
DrawCamera
DrawFrustum $gState(fovY) 1 1 10
glPopMatrix
glPopMatrix
}
proc InitLights {} {
# set up light colors (ambient, diffuse, specular)
set lightKa {0.0 0.0 0.0 1.0} ; # ambient light
set lightKd {0.9 0.9 0.9 1.0} ; # diffuse light
set lightKs {1 1 1 1} ; # specular light
glLightfv GL_LIGHT0 GL_AMBIENT $lightKa
glLightfv GL_LIGHT0 GL_DIFFUSE $lightKd
glLightfv GL_LIGHT0 GL_SPECULAR $lightKs
# position the light
set lightPos {0 5 5 0}
glLightfv GL_LIGHT0 GL_POSITION $lightPos
glEnable GL_LIGHT0 ; # MUST enable each light source after configuration
}
# Initialize OpenGL states and scene
proc CreateCallback { toglwin } {
global gState
glShadeModel GL_SMOOTH ; # shading mathod: GL_SMOOTH or GL_FLAT
glPixelStorei GL_UNPACK_ALIGNMENT 4 ; # 4-byte pixel alignment
# enable /disable features
glHint GL_PERSPECTIVE_CORRECTION_HINT GL_NICEST
glEnable GL_DEPTH_TEST
glEnable GL_LIGHTING
glEnable GL_TEXTURE_2D
glEnable GL_CULL_FACE
glEnable GL_BLEND
glEnable GL_SCISSOR_TEST
# track material ambient and diffuse from surface color,
# call it before glEnable(GL_COLOR_MATERIAL)
glColorMaterial GL_FRONT_AND_BACK GL_AMBIENT_AND_DIFFUSE
glEnable GL_COLOR_MATERIAL
glClearColor [lindex $gState(bgColor) 0] [lindex $gState(bgColor) 1] \
[lindex $gState(bgColor) 2] [lindex $gState(bgColor) 3]
glClearStencil 0
glClearDepth 1.0 ; # 0 is near, 1 is far
glDepthFunc GL_LEQUAL
InitLights
SetViewMatrix 0 0 10 0 0 0
set gState(matrixView) [tcl3dOglGetFloatState GL_MODELVIEW_MATRIX 16]
set gState(matrixModel) [tcl3dOglGetFloatState GL_MODELVIEW_MATRIX 16]
set gState(matrixModelView) [tcl3dOglGetFloatState GL_MODELVIEW_MATRIX 16]
}
# Set rendering window size
proc ReshapeCallback { toglwin { w -1 } { h -1 } } {
global gState
set w [$toglwin width]
set h [$toglwin height]
# assign the width/height of viewport
set gState(windowWidth) $w
set gState(windowHeight) $h
}
# draw 2D/3D scene
proc DisplayCallback { toglwin } {
global gState
DrawSub1
DrawSub2
if { $gState(drawModeChanged) } {
if { $gState(drawMode) == 0 } {
# fill mode
glPolygonMode GL_FRONT_AND_BACK GL_FILL
glEnable GL_DEPTH_TEST
glEnable GL_CULL_FACE
} elseif { $gState(drawMode) == 1 } {
# wireframe mode
glPolygonMode GL_FRONT_AND_BACK GL_LINE
glDisable GL_DEPTH_TEST
glDisable GL_CULL_FACE
} elseif { $gState(drawMode) == 2 } {
# point mode
glPolygonMode GL_FRONT_AND_BACK GL_POINT
glDisable GL_DEPTH_TEST
glDisable GL_CULL_FACE
}
set gState(drawModeChanged) false
}
glFinish
$toglwin swapbuffers
}
# Transpose then return matrix values
proc GetViewMatrix {} {
global gState
for { set i 0 } { $i < 16 } { incr i } {
lappend m 0.0
}
lset m 0 [lindex $gState(matrixView) 0]
lset m 1 [lindex $gState(matrixView) 4]
lset m 2 [lindex $gState(matrixView) 8]
lset m 3 [lindex $gState(matrixView) 12]
lset m 4 [lindex $gState(matrixView) 1]
lset m 5 [lindex $gState(matrixView) 5]
lset m 6 [lindex $gState(matrixView) 9]
lset m 7 [lindex $gState(matrixView) 13]
lset m 8 [lindex $gState(matrixView) 2]
lset m 9 [lindex $gState(matrixView) 6]
lset m 10 [lindex $gState(matrixView) 10]
lset m 11 [lindex $gState(matrixView) 14]
lset m 12 [lindex $gState(matrixView) 3]
lset m 13 [lindex $gState(matrixView) 7]
lset m 14 [lindex $gState(matrixView) 11]
lset m 15 [lindex $gState(matrixView) 15]
return $m
}
proc GetModelMatrix {} {
global gState
for { set i 0 } { $i < 16 } { incr i } {
lappend m 0.0
}
lset m 0 [lindex $gState(matrixModel) 0]
lset m 1 [lindex $gState(matrixModel) 4]
lset m 2 [lindex $gState(matrixModel) 8]
lset m 3 [lindex $gState(matrixModel) 12]
lset m 4 [lindex $gState(matrixModel) 1]
lset m 5 [lindex $gState(matrixModel) 5]
lset m 6 [lindex $gState(matrixModel) 9]
lset m 7 [lindex $gState(matrixModel) 13]
lset m 8 [lindex $gState(matrixModel) 2]
lset m 9 [lindex $gState(matrixModel) 6]
lset m 10 [lindex $gState(matrixModel) 10]
lset m 11 [lindex $gState(matrixModel) 14]
lset m 12 [lindex $gState(matrixModel) 3]
lset m 13 [lindex $gState(matrixModel) 7]
lset m 14 [lindex $gState(matrixModel) 11]
lset m 15 [lindex $gState(matrixModel) 15]
return $m
}
proc GetModelViewMatrix {} {
global gState
for { set i 0 } { $i < 16 } { incr i } {
lappend m 0.0
}
lset m 0 [lindex $gState(matrixModelView) 0]
lset m 1 [lindex $gState(matrixModelView) 4]
lset m 2 [lindex $gState(matrixModelView) 8]
lset m 3 [lindex $gState(matrixModelView) 12]
lset m 4 [lindex $gState(matrixModelView) 1]
lset m 5 [lindex $gState(matrixModelView) 5]
lset m 6 [lindex $gState(matrixModelView) 9]
lset m 7 [lindex $gState(matrixModelView) 13]
lset m 8 [lindex $gState(matrixModelView) 2]
lset m 9 [lindex $gState(matrixModelView) 6]
lset m 10 [lindex $gState(matrixModelView) 10]
lset m 11 [lindex $gState(matrixModelView) 14]
lset m 12 [lindex $gState(matrixModelView) 3]
lset m 13 [lindex $gState(matrixModelView) 7]
lset m 14 [lindex $gState(matrixModelView) 11]
lset m 15 [lindex $gState(matrixModelView) 15]
return $m
}
proc ResetMatrix { type } {
if { $type eq "model" } {
SetModelMatrix 0 0 0 0 0 0
} else {
SetViewMatrix 0 0 10 0 0 0
}
Update
}
#
# GUI specific part
#
proc CreateMatrixWidget { widget name { numRows 4 } { numCols 4 } } {
labelframe $widget -text $name -labelanchor n -foreground blue \
-padx 1 -pady 3
for { set row 0 } { $row < $numRows } { incr row } {
for { set col 0 } { $col < $numCols } { incr col } {
label $widget.l_${row}_${col} -text "$row.$col" -anchor e -width 5
grid $widget.l_${row}_${col} -row $row -column $col -sticky nse
}
}
return $widget
}
proc SetMatrixWidgetValue { widget row col value } {
$widget.l_${row}_${col} configure -text [format "%4.2f" $value]
}
proc GetMatrixWidgetValue { widget row col } {
return [$widget.l_${row}_${col} cget -text]
}
proc SetMatrixWidget { widget matList { numRows 4 } { numCols 4 } } {
set count 0
for { set row 0 } { $row < $numRows } { incr row } {
for { set col 0 } { $col < $numCols } { incr col } {
SetMatrixWidgetValue $widget $row $col [lindex $matList $count]
incr count
}
}
}
proc CreateModelViewFrame { parent } {
set matMV $parent.matMV
set matV $parent.matV
set matM $parent.matM
set numRows 4
set numCols 4
frame $parent.frEqual
label $parent.frEqual.l -text "="
pack $parent.frEqual.l
frame $parent.frOp
label $parent.frOp.l -text "X"
pack $parent.frOp.l
CreateMatrixWidget $matMV "ModelView Matrix" $numRows $numCols
CreateMatrixWidget $matV "View Matrix" $numRows $numCols
CreateMatrixWidget $matM "Model Matrix" $numRows $numCols
pack $matMV -side left
pack $parent.frEqual -side left
pack $matV -side left
pack $parent.frOp -side left
pack $matM -side left
return [list $matMV $matV $matM]
}
proc UpdateGLCmds {} {
global gState
set widget $gState(viewGLTextWidget)
$widget delete 1.0 end
$widget insert end [format "glRotatef %4.0f 1 0 0\n" \
[expr {-1.0 * $gState(view,angle,x)}]]
$widget insert end [format "glRotatef %4.0f 0 1 0\n" \
[expr {-1.0 * $gState(view,angle,y)}]]
$widget insert end [format "glRotatef %4.0f 0 0 1\n" \
[expr {-1.0 * $gState(view,angle,z)}]]
$widget insert end [format "glTranslatef %3.0f %3.0f %3.0f\n" \
[expr {-1.0 * $gState(view,pos,x)}] \
[expr {-1.0 * $gState(view,pos,y)}] \
[expr {-1.0 * $gState(view,pos,z)}]]
set widget $gState(modelGLTextWidget)
$widget delete 1.0 end
$widget insert end [format "glTranslatef %3.0f %3.0f %3.0f\n" \
$gState(model,pos,x) \
$gState(model,pos,y) \
$gState(model,pos,z)]
$widget insert end [format "glRotatef %4.0f 1 0 0\n" $gState(model,angle,x)]
$widget insert end [format "glRotatef %4.0f 0 1 0\n" $gState(model,angle,y)]
$widget insert end [format "glRotatef %4.0f 0 0 1\n" $gState(model,angle,z)]
SetMatrixWidget $gState(matV) [GetViewMatrix]
SetMatrixWidget $gState(matM) [GetModelMatrix]
SetMatrixWidget $gState(matMV) [GetModelViewMatrix]
}
proc Update { args } {
global gState
DisplayCallback .fr.toglwin
UpdateGLCmds
}
proc Cleanup {} {
uplevel #0 unset gState
}
proc ExitProg {} {
exit
}
frame .fr
pack .fr -expand 1 -fill both
togl .fr.toglwin \
-width $gState(windowWidth) -height $gState(windowHeight) \
-double true -depth true -stencil true \
-createcommand CreateCallback \
-reshapecommand ReshapeCallback \
-displaycommand DisplayCallback
frame .fr.guiFr
label .fr.info
grid .fr.toglwin -row 0 -column 0 -sticky news
grid .fr.guiFr -row 0 -column 1 -sticky news
grid .fr.info -row 1 -column 0 -sticky news -columnspan 2
grid rowconfigure .fr 0 -weight 1
grid columnconfigure .fr 0 -weight 1
frame .fr.guiFr.topFr
frame .fr.guiFr.frMatrix
pack .fr.guiFr.topFr .fr.guiFr.frMatrix -side top -padx 2
set viewFr .fr.guiFr.topFr.frView
set modelFr .fr.guiFr.topFr.frModel
labelframe $viewFr -text "View (Camera)" -foreground blue
labelframe $modelFr -text "Model" -foreground blue
pack $viewFr $modelFr -side left -expand 1 -fill x
button $viewFr.reset -command "ResetMatrix view" -text "Reset"
grid $viewFr.reset -row 0 -column 0 -sticky news -columnspan 3
set row 1
foreach from { -10 -10 -10 -360 -360 -360 } \
to { 10 10 10 360 360 360 } \
type { pos,x pos,y pos,z angle,x angle,y angle,z } \
msg { "Pos (X)" "Pos (Y)" "Pos (Z)" "Pitch (X)" "Heading (Y)" "Roll (Z)" } {
label $viewFr.l_$row -text $msg
label $viewFr.v_$row -textvariable gState(view,$type) -width 4 -anchor e
scale $viewFr.s_$row -from $from -to $to -resolution 1 -orient horizontal \
-variable gState(view,$type) -showvalue false -command Update
grid $viewFr.l_$row -row $row -column 0 -sticky sw
grid $viewFr.v_$row -row $row -column 1 -sticky sw
grid $viewFr.s_$row -row $row -column 2 -sticky news
incr row
}
text $viewFr.cmds -height 4 -width 25 -font $gState(textFont)
grid $viewFr.cmds -row $row -column 0 -sticky news -columnspan 3
set gState(viewGLTextWidget) $viewFr.cmds
button $modelFr.reset -command "ResetMatrix model" -text "Reset"
grid $modelFr.reset -row 0 -column 0 -sticky news -columnspan 3
set row 1
foreach from { -10 -10 -10 -360 -360 -360 } \
to { 10 10 10 360 360 360 } \
type { pos,x pos,y pos,z angle,x angle,y angle,z } \
msg { "Pos (X)" "Pos (Y)" "Pos (Z)" "Rotation (X)" "Rotation (Y)" "Rotation (Z)" } {
label $modelFr.l_$row -text $msg
label $modelFr.v_$row -textvariable gState(model,$type) -width 4 -anchor e
scale $modelFr.s_$row -from $from -to $to -resolution 1 -orient horizontal \
-variable gState(model,$type) -showvalue false -command Update
grid $modelFr.l_$row -row $row -column 0 -sticky sw
grid $modelFr.v_$row -row $row -column 1 -sticky sw
grid $modelFr.s_$row -row $row -column 2 -sticky news
incr row
}
text $modelFr.cmds -height 4 -width 25 -font $gState(textFont)
grid $modelFr.cmds -row $row -column 0 -sticky news -columnspan 3
set gState(modelGLTextWidget) $modelFr.cmds
set widgetList [CreateModelViewFrame .fr.guiFr.frMatrix]
foreach { gState(matMV) gState(matV) gState(matM) } $widgetList break
set appTitle "Tcl3D demo: Song Ho Ahn's ModelView Matrix Tutorial"
wm title . $appTitle
# Watch For ESC Key And Quit Messages
wm protocol . WM_DELETE_WINDOW "ExitProg"
bind . <Key-Escape> "ExitProg"
bind . <Key-w> "ToggleDrawMode"
bind .fr.toglwin <<LeftMousePress>> "SetLeftMouse %x %y"
bind .fr.toglwin <<LeftMouseMotion>> "RotateCamera .fr.toglwin %x %y"
bind .fr.toglwin <<RightMousePress>> "SetRightMouse %x %y"
bind .fr.toglwin <<RightMouseMotion>> "ZoomCamera .fr.toglwin %x %y"
PrintInfo [tcl3dOglGetInfoString]
|