#!/bin/sh # Einfaches Beispiel für Tcl3d, # Zeigt das Lesen von ObjectWavefront (.obj) Dateien # \ exec wish $0 $@ package require tcl3d 0.2 # Window size. set winWidth 640 set winHeight 480 set Posx 0 set Posy 0 set Posz -10 set Rotx -10 set Roty 0 set Rotz 0 set PI [ expr 2* asin(1)] # Stellt Hintergrundfehler in einem Dialog dar proc bgerror { msg } { tk_messageBox -icon error -type ok -message "Error: $msg" exit } # Liest OBJ ein proc ReadObj { toglwin fileName } { global gPo if { [info exists ::objId] } { glmDelete $::objId } set ::objId [glmReadOBJ $fileName] glmFacetNormals $::objId glmVertexNormals $::objId 90.0 } # Setzt ein paar Startwerte und erzeugt die Displayliste #, wird beim Erzeugen des Fensters augerufen proc tclCreateFunc { toglwin } { # Schwarzer Hintergrund glClearColor 0.1 0.7 1 0.5 ;# Hintergrundfarbe # Ein bischen Tuning glClearDepth 1.0 glEnable GL_DEPTH_TEST glShadeModel GL_SMOOTH glDepthFunc GL_LEQUAL glHint GL_PERSPECTIVE_CORRECTION_HINT GL_NICEST glEnable GL_DEPTH_TEST glEnable GL_LIGHTING glEnable GL_LIGHT0 ReadObj $toglwin "untitled.obj" } # In dieser Funktion wird das 3D Modell angezeigt proc tclDisplayFunc { toglwin } { # Screen And Depth Buffer Löschen glClear [expr $::GL_COLOR_BUFFER_BIT | $::GL_DEPTH_BUFFER_BIT] # Anfangsposition setzen glLoadIdentity glTranslatef $::Posx $::Posy $::Posz glRotatef $::Rotx 1.0 0.0 0.0 glRotatef $::Roty 0.0 1.0 0.0 glRotatef $::Rotz 0.0 0.0 1.0 glmDraw $::objId [expr $::GLM_SMOOTH | $::GLM_MATERIAL] $toglwin swapbuffers } # Berechnet eine passende Ansicht auf das Model, # wird aufgerufen wenn sich die Fenstergröße ändert proc tclReshapeFunc { toglwin b h } { # verhindert Teilen durch Null set h [ expr $h < 1 ? 1 : $h ] # Viewport neu berechnen glViewport 0 0 $b $h glMatrixMode GL_PROJECTION # wieder Einheitsmatrix setzen glLoadIdentity # Perspektive berechnen lassen und aktive machen set winkel 45 set verhaeltnis [ expr double($b)/double($h)] set von 0.1 set bis 5000 gluPerspective $winkel $verhaeltnis $von $bis glMatrixMode GL_MODELVIEW } # speichert die Mausposition beim Drücken der # linken Maustaste proc RotStart {x y W } { global startx starty set startx $x set starty $y } # berechnet die neue Rotation nach dem Loslassen # der linken Maustaste proc RotMove {x y W} { global startx starty set ::Rotx [expr $::Rotx + 0.1 * ($x - $startx)] set ::Roty [expr $::Roty + 0.1 * ($y - $starty)] $W postredisplay } # Bewegt das Modell beim drehen des Mausrads proc MovePos { dist W } { # Berechne neue Position set ::Posx 0 set ::Posy 0 set ::Posz [ expr int($::Posz +$dist) ] $W postredisplay } # Bewegt das Modell mit den Pfeiltasten proc LinksRechtsObenUnten { key W } { if {[string match Left $key] } { incr ::Posx -10 } elseif {[string match Right $key] } { incr ::Posx 10 } elseif {[string match Up $key] } { incr ::Posy 10 } elseif {[string match Down $key] } { incr ::Posy -10 } .toglwin postredisplay } # Create Our OpenGL Window wm title . "Listing 6: Kitty Hawk aus .obj Datei" togl .toglwin -width $::winWidth -height $::winHeight \ -double true -depth true \ -reshapeproc tclReshapeFunc \ -displayproc tclDisplayFunc \ -createproc tclCreateFunc pack .toglwin -expand 1 -fill both # An Events binden bind . {LinksRechtsObenUnten %K %W} bind .toglwin { MovePos 1 %W} bind .toglwin { MovePos -1 %W} bind .toglwin {RotStart %x %y %W} bind .toglwin {RotMove %x %y %W}