no display name and no $DISPLAY environment variable
    while executing
"load /enadisk/commun/linux/local/ActiveTcl-8.6.11/lib/libtk8.6.so Tk"
    ("package ifneeded Tk 8.6.11" script)
    invoked from within
"package require Tk"
    (in namespace eval "::request" script line 9)
    invoked from within
"namespace eval ::request $script"
    ("::try" body line 12)

OUTPUT BUFFER:

# cgTeapot.tcl # # Original files from: http://developer.nvidia.com/Cg # This is the example called interfaces_ogl as included in the Cg Toolkit. # # Modified for Tcl3D by Paul Obermeier 2005/11/07 # See www.tcl3d.org for the Tcl3D extension. package require Tk package require tcl3d 0.5.0 if { [info procs tcl3dHaveCg] ne "" } { if { ![tcl3dHaveCg] } { tk_messageBox -icon error -type ok -title "Error" \ -message "You do not have Cg installed." exit } } set M_PI 3.141592 set TWOPI [expr 2.0*$M_PI] set GROUNDWIDTH 20 set pWidth2 [expr $::GROUNDWIDTH / 2.0] set nWidth2 [expr -1.0 * $pWidth2] set g_quadVerts [tcl3dVectorFromArgs GLfloat \ $nWidth2 $nWidth2 0.0 \ $pWidth2 $nWidth2 0.0 \ $pWidth2 $pWidth2 0.0 \ $nWidth2 $pWidth2 0.0] set g_quadNorms [tcl3dVectorFromArgs GLfloat 0 0 1 0 0 1 0 0 1 0 0 1] set g_init 0 # Determine the directory of this script. set g_scriptDir [file dirname [info script]] # Show errors occuring in the Togl callbacks. proc bgerror { msg } { tk_messageBox -icon error -type ok -message "Error: $msg\n\n$::errorInfo" ExitProg } # Print info message into widget a the bottom of the window. proc PrintInfo { msg } { if { [winfo exists .fr.info] } { .fr.info configure -text $msg } } proc DEG2RAD {x} { return [expr $x*$::M_PI/180.0] } array set g_Properties { teapot,ambient {.05 .05 .05} teapot,diffuse {.8 .4 .1} teapot,specular {.4 .2 .2} teapot,exp 10.0 bright,ambient {.05 .05 .05} bright,diffuse {1.9 1.9 1.9} bright,specular {.1 .1 .1} bright,exp 20.0 dark,ambient {.05 .05 .05} dark,diffuse {.1 .1 .1} dark,specular {.4 .4 .4} dark,exp 40.0 } array set g_Objs { "0,r" 9 "0,target" {0 0 0} "0,color" { 0.2 0.2 0.25 } "0,enabled" 0 "0,name" "PointLight" "0,rotateMode" 0 "1,r" 16 "1,target" {0 0 0} "1,color" { 0.6 0.1 0.1 } "1,enabled" 0 "1,name" "SpotLight" "1,rotateMode" 0 "2,r" 45. "2,target" {0 0 0} "2,name" "Camera" "2,rotateMode" 0 } set g_Objs(0,theta) [DEG2RAD -20] set g_Objs(0,phi) [DEG2RAD 60] set g_Objs(1,theta) [DEG2RAD 40] set g_Objs(1,phi) [DEG2RAD 40] set g_Objs(2,theta) [DEG2RAD 30.] set g_Objs(2,phi) [DEG2RAD 60.] set Eye 2 set numLights 2 set numSelections [expr $numLights + 1] set motionSelections { 2 0 1 } set currentSelection 0 set g_WinWidth 300 set g_WinHeight 300 set numRotating 0 set drawLightsMode 1 set literalMode 1 set printMode 1 set moveMode 0 set zoomMode 0 set retargetMode 0 set vertexProfile $::CG_PROFILE_UNKNOWN set fragmentProfile $::CG_PROFILE_UNKNOWN proc ParseArgs { argc argv } { set i 0 while { $i < $argc } { if { 0 == [strcmp [lindex $argv $i] "-nv3x"] } { set ::vertexProfile $::CG_PROFILE_VP30 set ::fragmentProfile $::CG_PROFILE_FP30 } elseif { 0 == [strcmp [lindex $argv $i] "-arb"] } { set ::vertexProfile $::CG_PROFILE_ARBVP1 set ::fragmentProfile $::CG_PROFILE_ARBFP1 } elseif { 0 == [strcmp [lindex $argv $i] "-nv4x"] } { set ::vertexProfile $::CG_PROFILE_VP30 set ::fragmentProfile $::CG_PROFILE_FP40 } elseif { 0 == [strcmp [lindex $argv $i] "-v"] } { set ::printMode 1 } elseif { 0 == [strcmp [lindex $argv $i] "-l"] } { set ::literalMode [expr ! $::literalMode] } else { return $i } incr i } return $i } # Main program; do basic GLUT and Cg setup, but leave most of the work # to the display() function. proc CreateWindow {} { set compilerArgs [ParseArgs $::argc $::argv] frame .fr pack .fr -expand 1 -fill both togl .fr.toglwin -width $::g_WinWidth -height $::g_WinHeight \ -rgba true -double true -depth true \ -createproc CreateCallback \ -reshapeproc ReshapeCallback \ -displayproc DisplayCallback label .fr.info grid .fr.toglwin -row 0 -column 0 -sticky news grid .fr.info -row 1 -column 0 -sticky news grid rowconfigure .fr 0 -weight 1 grid columnconfigure .fr 0 -weight 1 wm title . "Tcl3D demo: Teapot with Cg" bind . "ExitProg" bind . "RotateMode .fr.toglwin" bind . "ToggleLight 0 ; .fr.toglwin postredisplay" bind . "ToggleLight 1 ; .fr.toglwin postredisplay" bind . "ToggleLightsMode .fr.toglwin" bind . "Recenter .fr.toglwin" bind . "CycleSelection .fr.toglwin" bind .fr.toglwin { SetModes 0 0 1 ; MoveStart %W %x %y } bind .fr.toglwin { SetModes 0 1 0 ; MoveStart %W %x %y } bind .fr.toglwin { SetModes 1 0 0 ; MoveStart %W %x %y } bind .fr.toglwin { SetModes 0 0 0 ; MoveEnd %W %x %y } bind .fr.toglwin { MoveCont %W %x %y } } proc Cleanup {} { $::g_quadVerts delete $::g_quadNorms delete if { [info exists ::g_quadric] } { gluDeleteQuadric $::g_quadric } cgDestroyContext $::g_context foreach var [info globals g_*] { uplevel #0 unset $var } } proc ExitProg {} { exit } proc SetModes { move retarget zoom } { set ::moveMode $move set ::retargetMode $retarget set ::zoomMode $zoom } proc MoveStart { W x y } { set ::mouseX $x set ::mouseY $y } proc MoveCont { W x y } { Motion $W $x $y } proc MoveEnd { W x y } { $W postredisplay } proc ToggleLight { which } { set ::g_Objs($which,enabled) [expr ! $::g_Objs($which,enabled)] set param [cgGetNamedStructParameter $::g_Objs($which,handle) "enabled"] cgSetParameter1f $param $::g_Objs($which,enabled) } proc IdleFunc { toglwin } { if { $::numRotating > 0 } { $toglwin postredisplay tcl3dAfterIdle "IdleFunc $toglwin" } } proc BindPrograms { vert frag } { cgGLEnableProfile $::vertexProfile cgGLEnableProfile $::fragmentProfile cgGLBindProgram $vert cgGLBindProgram $frag set param [cgGetNamedProgramParameter $vert CG_PROGRAM "ModelView"] cgGLSetStateMatrixParameter $param \ CG_GL_MODELVIEW_MATRIX \ CG_GL_MATRIX_IDENTITY set param [cgGetNamedProgramParameter $vert CG_PROGRAM "ModelViewIT"] cgGLSetStateMatrixParameter $param \ CG_GL_MODELVIEW_MATRIX \ CG_GL_MATRIX_INVERSE_TRANSPOSE set param [cgGetNamedProgramParameter $vert CG_PROGRAM "ModelViewProj"] cgGLSetStateMatrixParameter $param \ CG_GL_MODELVIEW_PROJECTION_MATRIX \ CG_GL_MATRIX_IDENTITY } proc PolarToCartesian { r phi theta } { return [list \ [expr $r*sin($phi)*sin($theta)] \ [expr $r*sin($phi)*cos($theta)] \ [expr $r*cos($phi)]] } proc TransformPointCart { p m } { set ov0 [expr [$m get 0] * [lindex $p 0] + \ [$m get 4] * [lindex $p 1] + \ [$m get 8] * [lindex $p 2] + \ [$m get 12]] set ov1 [expr [$m get 1] * [lindex $p 0] + \ [$m get 5] * [lindex $p 1] + \ [$m get 9] * [lindex $p 2] + \ [$m get 13]] set ov2 [expr [$m get 2] * [lindex $p 0] + \ [$m get 6] * [lindex $p 1] + \ [$m get 10] * [lindex $p 2] + \ [$m get 14]] set w [expr [$m get 3] * [lindex $p 0] + \ [$m get 7] * [lindex $p 1] + \ [$m get 11] * [lindex $p 2] + \ [$m get 15]] if { $w != 1.0 } { set ov0 [expr $ov0 / $w] set ov1 [expr $ov1 / $w] set ov2 [expr $ov2 / $w] } return [list $ov0 $ov1 $ov2] } proc TransformPointPolar {r phi theta m } { set c [PolarToCartesian $r $phi $theta] return [TransformPointCart $c $m] } proc glPuts { str } { glListBase $::FontBase set len [string length $str] set sa [tcl3dVectorFromString GLubyte $str] glCallLists $len GL_UNSIGNED_BYTE $sa $sa delete } proc DrawLights {} { if { ! [info exists ::g_quadric] } { set ::g_quadric [gluNewQuadric] gluQuadricOrientation $::g_quadric GLU_OUTSIDE } for { set i 0 } { $i < $::numLights } { incr i } { glPushMatrix set vec [PolarToCartesian $::g_Objs($i,r) $::g_Objs($i,phi) $::g_Objs($i,theta)] glTranslatef [lindex $vec 0] [lindex $vec 1] [lindex $vec 2] BindPrograms $::vertexProg $::lightProg set param [cgGetNamedProgramParameter $::lightProg CG_PROGRAM "color"] set vec $::g_Objs($i,color) if { [lindex $::motionSelections $::currentSelection] != $i } { lset vec 0 [expr [lindex $vec 0] * 0.2] lset vec 1 [expr [lindex $vec 1] * 0.2] lset vec 2 [expr [lindex $vec 2] * 0.2] } cgSetParameter3fv $param $vec gluSphere $::g_quadric .2 5 5 glPopMatrix } } proc DrawGround {} { glPushMatrix BindPrograms $::vertexProg $::groundProg glVertexPointer 3 GL_FLOAT 0 $::g_quadVerts glNormalPointer GL_FLOAT 0 $::g_quadNorms glDrawArrays GL_QUADS 0 4 glPopMatrix } proc DrawText {} { cgGLDisableProfile $::vertexProfile cgGLDisableProfile $::fragmentProfile glMatrixMode GL_PROJECTION glLoadIdentity glOrtho -1 1 -1 1 -1 1 glMatrixMode GL_MODELVIEW glLoadIdentity glDisable [expr $::GL_LIGHTING | $::GL_DEPTH_TEST] glColor3f 1 1 1 glPushMatrix glRasterPos2f -.98 -.98 set ind [lindex $::motionSelections $::currentSelection] set buf [format "%s %s" $::g_Objs($ind,name) \ [expr { $::moveMode ? "(move)" : \ ($::zoomMode ? "(zoom)" : \ ($::retargetMode ? "(retarget)" : " ")) } ]] glPuts $buf glEnable [expr $::GL_LIGHTING | $::GL_DEPTH_TEST] glPopMatrix } proc InitCgShader {} { tcl3dCgResetError # Basic Cg setup; register a callback function for any errors # and create an initial context set ::g_context [cgCreateContext] set retVal [tcl3dCgGetError $::g_context] if { $retVal ne "" } { error "cgCreateContext: $retVal" } # initialize programs, etc. InitPrograms } proc CreateCallback { toglwin } { set ::FontBase [$toglwin loadbitmapfont "fixed"] InitCgShader } proc ReshapeCallback { toglwin { w -1 } { h -1 } } { set w [$toglwin width] set h [$toglwin height] glViewport 0 0 $w $h set ::g_WinWidth $w set ::g_WinHeight $h } proc DisplayCallback { toglwin } { if { $::g_init == 0 } { glEnable GL_DEPTH_TEST glDisable GL_CULL_FACE glEnableClientState GL_VERTEX_ARRAY glEnableClientState GL_NORMAL_ARRAY glClearColor .1 .1 .1 1. set ::g_init 1 } for { set i 0 } { $i < $::numSelections } { incr i } { set ind [lindex $::motionSelections $i] if { $::g_Objs($ind,rotateMode) } { set ::g_Objs($ind,theta) [expr $::g_Objs($ind,theta) + 0.02] } } glClear [expr $::GL_COLOR_BUFFER_BIT | $::GL_DEPTH_BUFFER_BIT] # Viewport command is not really needed, but has been inserted for # Mac OSX. Presentation framework (Tk) does not send a reshape event, # when switching from one demo to another. glViewport 0 0 [$toglwin width] [$toglwin height] glMatrixMode GL_PROJECTION glPushMatrix glLoadIdentity gluPerspective 25 [expr double($::g_WinWidth)/double($::g_WinHeight)] .1 1000 glMatrixMode GL_MODELVIEW glLoadIdentity glPushMatrix glLoadIdentity set eyeCoords [PolarToCartesian $::g_Objs($::Eye,r) \ $::g_Objs($::Eye,phi) \ $::g_Objs($::Eye,theta)] gluLookAt [lindex $eyeCoords 0] \ [lindex $eyeCoords 1] \ [lindex $eyeCoords 2] \ [lindex $::g_Objs($::Eye,target) 0] \ [lindex $::g_Objs($::Eye,target) 1] \ [lindex $::g_Objs($::Eye,target) 2] \ [expr -cos($::g_Objs($::Eye,phi))*sin($::g_Objs($::Eye,theta))] \ [expr -cos($::g_Objs($::Eye,phi))*cos($::g_Objs($::Eye,theta))] \ [expr sin($::g_Objs($::Eye,phi))] # Compute eye space light positions UpdateLights if { $::drawLightsMode } { DrawLights } # Draw teapot glPushMatrix BindPrograms $::vertexProg $::teapotProg glutSolidTeapot 2.0 glPopMatrix # Draw ground plane DrawGround glPopMatrix glMatrixMode GL_PROJECTION glPopMatrix DrawText glEnd $toglwin swapbuffers } proc InitPrograms {} { # Do one-time setup only once; setup Cg programs and textures # and set up OpenGL state. if { $::vertexProfile == $::CG_PROFILE_UNKNOWN || \ $::fragmentProfile == $::CG_PROFILE_UNKNOWN } { set ::vertexProfile [cgGLGetLatestProfile CG_GL_VERTEX] set ::fragmentProfile [cgGLGetLatestProfile CG_GL_FRAGMENT] } if { [tcl3dCgFindProfile $::vertexProfile] eq "" } { error "Could not find Cg vertex profile $::vertexProfile" } if { [tcl3dCgFindProfile $::fragmentProfile] eq "" } { error "Could not find Cg fragment profile $::fragmentProfile" } cgGLSetOptimalOptions $::vertexProfile cgGLSetOptimalOptions $::fragmentProfile LoadCgPrograms if { $::printMode } { puts [format "Warnings:\n%s\n" [cgGetLastListing $::g_context]] } } proc CreateLightSource { prog lind } { # Get handle to user-defined type set lightType [cgGetNamedUserType $prog $::g_Objs($lind,name)] # Create parameter of that type set light [cgCreateParameter $::g_context $lightType] if { $light == 0 } { return 0 } # Stash handles to position, target parameters set ::g_Objs($lind,posHandle) [cgGetNamedStructParameter $light "Plight"] set ::g_Objs($lind,targetHandle) [cgGetNamedStructParameter $light "target"] set ::g_Objs($lind,handle) $light # Set light color set param [cgGetNamedStructParameter $light "Clight"] if { $param == 0 } { return 0 } cgSetParameter3fv $param $::g_Objs($lind,color) if { $::literalMode } { cgSetParameterVariability $param CG_LITERAL } return 1 } proc UpdateLights {} { set modelViewMat [tcl3dVector GLfloat 16] glGetFloatv GL_MODELVIEW_MATRIX $modelViewMat # Compute eye-space coords of each light source's # position and (if applicable) target for { set i 0 } { $i < $::numLights } { incr i } { set lightPosEye [TransformPointPolar $::g_Objs($i,r) $::g_Objs($i,phi) \ $::g_Objs($i,theta) $modelViewMat] cgSetParameter3fv $::g_Objs($i,posHandle) $lightPosEye if { $::g_Objs($i,targetHandle) != "NULL" } { set lightTargetEye [TransformPointCart $::g_Objs($i,target) $modelViewMat] cgSetParameter3fv $::g_Objs($i,targetHandle) $lightTargetEye } } $modelViewMat delete } proc SetBlinnProperties { b p } { cgSetParameter3fv [cgGetNamedStructParameter $b "ambient"] $::g_Properties($p,ambient) cgSetParameter3fv [cgGetNamedStructParameter $b "diffuse"] $::g_Properties($p,diffuse) cgSetParameter3fv [cgGetNamedStructParameter $b "specular"] $::g_Properties($p,specular) cgSetParameter1f [cgGetNamedStructParameter $b "sexp"] $::g_Properties($p,exp) if { $::literalMode } { cgSetParameterVariability $b CG_LITERAL } } proc GetFileName { fileName } { return [tcl3dGetExtFile [file join $::g_scriptDir $fileName]] } proc LoadCgPrograms {} { # Create & wire up up a handful of programs. if { ! [cgIsContext $::g_context] } { error "No context specified" } # The Cg source files used later in cgCreateProgramFromFile include other Cg # files. If running from inside a Starpack, we have to copy these files to # the file system. That's what the next lines are for. They do nothing, if # this script is directly run from tclsh or wish. tcl3dGetExtFile [file join $::g_scriptDir "blend.cg"] tcl3dGetExtFile [file join $::g_scriptDir "blinn.cg"] tcl3dGetExtFile [file join $::g_scriptDir "checker.cg"] tcl3dGetExtFile [file join $::g_scriptDir "common.cg"] tcl3dGetExtFile [file join $::g_scriptDir "light.cg"] tcl3dGetExtFile [file join $::g_scriptDir "material.cg"] tcl3dGetExtFile [file join $::g_scriptDir "pointlight.cg"] tcl3dGetExtFile [file join $::g_scriptDir "spotlight.cg"] # First, create programs that don't make use # of shared instances, and thus can be compiled # immediately. # Create vertex program. This is the vertex program # used with all of the fragment shaders. set ::vertexProg [cgCreateProgramFromFile $::g_context CG_SOURCE \ [GetFileName "vertex.cg"] \ $::vertexProfile "main" "NULL"] tcl3dCgPrintProgramInfo $::vertexProg "vertex.cg" cgGLLoadProgram $::vertexProg # Create constant shader, used for light source visualization set ::lightProg [cgCreateProgramFromFile $::g_context CG_SOURCE \ [GetFileName "constant.cg"] \ $::fragmentProfile "main" "NULL"] tcl3dCgPrintProgramInfo $::lightProg "constant.cg" cgGLLoadProgram $::lightProg # Next, create shared instances and the programs that use them. # Turn on manual compilation so the runtime won't try to compile # incomplete programs. cgSetAutoCompile $::g_context CG_COMPILE_MANUAL # Create teapot fragment program set ::teapotProg [cgCreateProgramFromFile $::g_context CG_SOURCE \ [GetFileName "materialmain.cg"] \ $::fragmentProfile "main" "NULL"] # Create metal material for teapot. set metal [cgCreateParameter $::g_context \ [cgGetNamedUserType $::teapotProg "Blinn"]] SetBlinnProperties $metal "teapot" # Connect material parameter of teapot program to metal material set param [cgGetNamedProgramParameter $::teapotProg CG_PROGRAM "material"] cgConnectParameter $metal $param # Create ground fragment program set ::groundProg [cgCreateProgramFromFile $::g_context CG_SOURCE \ [GetFileName "materialmain.cg"] \ $::fragmentProfile "main" "NULL"] # Create checker material set checker [cgCreateParameter $::g_context \ [cgGetNamedUserType $::teapotProg "CheckerBlinn"]] set param [cgGetNamedStructParameter $checker "csize"] cgSetParameter1f $param 1.0 if { $::literalMode } { cgSetParameterVariability $param CG_LITERAL } set param [cgGetNamedStructParameter $checker "mats"] SetBlinnProperties [cgGetArrayParameter $param 0] "bright" SetBlinnProperties [cgGetArrayParameter $param 1] "dark" # Associate checker material with material parameter of ground program cgConnectParameter $checker [cgGetNamedProgramParameter \ $::groundProg CG_PROGRAM "material"] # Next, create shared light sources # Get type handles from any program that includes the # appropriate type definition. set lArray [cgCreateParameterArray $::g_context \ [cgGetNamedUserType $::teapotProg "Light"] $::numLights] for { set i 0 } { $i < $::numLights } { incr i } { # We pass teapotProg here, but could pass any program (compiled or uncompiled) whose # source defines the types. if { [CreateLightSource $::teapotProg $i] == 0 } { error "Cannot create light source" } cgConnectParameter $::g_Objs($i,handle) [cgGetArrayParameter $lArray $i] } # Connect the light source array to each material. cgConnectParameter $lArray [cgGetNamedProgramParameter $::teapotProg CG_PROGRAM "lights"] cgConnectParameter $lArray [cgGetNamedProgramParameter $::groundProg CG_PROGRAM "lights"] # Set the 'enabled' member variable of each light source ToggleLight 0 ToggleLight 1 # Finally, compile and load the programs cgCompileProgram $::teapotProg tcl3dCgPrintProgramInfo $::teapotProg "materialmain.cg" cgGLLoadProgram $::teapotProg cgCompileProgram $::groundProg tcl3dCgPrintProgramInfo $::groundProg "materialmain.cg" cgGLLoadProgram $::groundProg } proc Motion { toglwin x y } { set curInd [lindex $::motionSelections $::currentSelection] if { $::moveMode } { set dtheta [expr double($::mouseX - $x)*$::TWOPI/$::g_WinWidth] set dphi [expr double($y - $::mouseY)*$::TWOPI/$::g_WinHeight] if { $curInd == $::Eye } { set ::g_Objs($curInd,theta) [expr $::g_Objs($curInd,theta) - $dtheta] set ::g_Objs($curInd,phi) [expr $::g_Objs($curInd,phi) - $dphi] } else { set ::g_Objs($curInd,theta) [expr $::g_Objs($curInd,theta) + $dtheta] set ::g_Objs($curInd,phi) [expr $::g_Objs($curInd,phi) + $dphi] } if { $::g_Objs($curInd,theta) < [expr -1.0 * $::TWOPI] } { set ::g_Objs($curInd,theta) [expr $::g_Objs($curInd,theta) + $::TWOPI] } elseif { $::g_Objs($curInd,theta) > $::TWOPI } { set ::g_Objs($curInd,theta) [expr $::g_Objs($curInd,theta) - $::TWOPI] } if { $::g_Objs($curInd,phi) > $::M_PI } { set ::g_Objs($curInd,phi) $::M_PI } elseif { $::g_Objs($curInd,phi) < 0.0 } { set ::g_Objs($curInd,phi) 0.0 } } if { $::zoomMode } { set ::g_Objs($curInd,r) [expr $::g_Objs($curInd,r) + 0.25* ($y-$::mouseY)] if { $::g_Objs($curInd,r) < 0.0 } { set ::g_Objs($curInd,r) 0.0 } } if { $::retargetMode } { if { $curInd == $::Eye } { lset ::g_Objs($curInd,target) 0 \ [expr [lindex $::g_Objs($curInd,target) 0] - 0.1 * ($::mouseX - $x)] lset ::g_Objs($curInd,target) 1 \ [expr [lindex $::g_Objs($curInd,target) 1] + 0.1 * ($::mouseY - $y)] } else { lset ::g_Objs($curInd,target) 0 \ [expr [lindex $::g_Objs($curInd,target) 0] + 0.1 * ($::mouseX - $x)] lset ::g_Objs($curInd,target) 1 \ [expr [lindex $::g_Objs($curInd,target) 1] - 0.1 * ($::mouseY - $y)] } } set ::mouseX $x set ::mouseY $y $toglwin postredisplay } proc RotateMode { toglwin } { set curInd [lindex $::motionSelections $::currentSelection] set ::g_Objs($curInd,rotateMode) [expr ! $::g_Objs($curInd,rotateMode)] if { $::g_Objs($curInd,rotateMode) } { incr ::numRotating } else { incr ::numRotating -1 } if { $::numRotating } { tcl3dAfterIdle "IdleFunc $toglwin" } $toglwin postredisplay } proc ToggleLightsMode { toglwin } { set ::drawLightsMode [expr ! $::drawLightsMode] $toglwin postredisplay } proc CycleSelection { toglwin } { set ::currentSelection [expr ($::currentSelection +1) % $::numSelections] $toglwin postredisplay } proc Recenter { toglwin } { set ind [lindex $::motionSelections $::currentSelection] set ::g_Objs($ind,target) {0 0 0} $toglwin postredisplay } CreateWindow PrintInfo [format "Running on %s with a %s (OpenGL %s, Tcl %s)" \ $tcl_platform(os) [glGetString GL_RENDERER] \ [glGetString GL_VERSION] [info patchlevel]]