#!/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 . <Key> {LinksRechtsObenUnten %K %W}
bind .toglwin <Button-4> { MovePos 1 %W}
bind .toglwin <Button-5>  { MovePos -1 %W}
bind .toglwin <ButtonPress-1> {RotStart %x %y %W}
bind .toglwin <B1-Motion> {RotMove %x %y %W}







