Demo 10 of 19 in category CodeSampler
 |
#-----------------------------------------------------------------------------
# Name: ogl_material.cpp
# Author: Kevin Harris (kevin@codesampler.com)
# Last Modified: 04/28/05
# Description: This sample demonstrates how to use materials with lighting
# to produce different surface effects.
#
# Control Keys: Left Mouse Button - Spin the view
#-----------------------------------------------------------------------------
#
# Original C++ code by Kevin Harris (kevin@codesampler.com)
# See www.codesampler.com for the original files
# OpenGL samples page 5: Materials
# http://www.codesampler.com/oglsrc/oglsrc_5.htm#ogl_material
#
# Modified for Tcl3D by Paul Obermeier 2008/04/28
# See www.tcl3d.org for the Tcl3D extension.
package require Tk
package require tcl3d
# Font to be used in the Tk listbox.
set g_listFont {-family {Courier} -size 10}
set g_WinWidth 640
set g_WinHeight 480
set g_fSpinZ(1) 0.0
set g_fSpinY(1) 0.0
set g_EnableColorMaterial 0
# 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
}
}
proc ToggleColorMaterial {} {
set ::g_EnableColorMaterial [expr ! $::g_EnableColorMaterial]
.fr.toglwin postredisplay
}
proc SetMouseInput { btn x y } {
set ::g_LastMousePosX($btn) $x
set ::g_LastMousePosY($btn) $y
}
proc GetMouseInput { btn x y } {
set nXDiff [expr ($x - $::g_LastMousePosX($btn))]
set nYDiff [expr ($y - $::g_LastMousePosY($btn))]
set ::g_fSpinZ($btn) [expr $::g_fSpinZ($btn) - $nXDiff]
set ::g_fSpinY($btn) [expr $::g_fSpinY($btn) - $nYDiff]
set ::g_LastMousePosX($btn) $x
set ::g_LastMousePosY($btn) $y
.fr.toglwin postredisplay
}
proc CreateCallback { toglwin } {
glClearColor 0.0 0.0 0.0 1.0
glEnable GL_DEPTH_TEST
glEnable GL_LIGHTING
glMatrixMode GL_PROJECTION
glLoadIdentity
gluPerspective 45.0 [expr double($::g_WinWidth)/double($::g_WinHeight)] \
0.1 1000.0
set ::g_default_diffuse { 0.8 0.8 0.8 1.0 }
set ::g_default_ambient { 0.2 0.2 0.2 1.0 }
set ::g_default_emission { 0.0 0.0 0.0 1.0 }
set ::g_default_specular { 0.0 0.0 0.0 1.0 }
set ::g_default_shininess 0.0
#-------------------------------------------------------------------------
# Setup material - Used to create a reddish clay teapot
#-------------------------------------------------------------------------
# A matte clay look is easy. All we really have to do is set the color to
# look like clay pottery.
set ::g_redClayMtrl_diffuse { 1.0 0.5 0.2 1.0 }
#-------------------------------------------------------------------------
# Setup material - Used to create a green plastic teapot
#-------------------------------------------------------------------------
# Set the material's main color to green.
set ::g_greenPlasticMtrl_diffuse { 0.0 1.0 0.0 1.0 }
# Lets favor the ambient's green over the other colors. Why? I don't know.
# It just looks better to me. Using materials is some what more artistic
# than scientific, so just play around till you get what you want.
set ::g_greenPlasticMtrl_ambient { 0.5 1.0 0.5 1.0 }
# Plastic can be shiny, but we don't want it too shiny are it will look
# more like glass or metal. We'll have the material reflect back more
# green than red and blue so the highlights won't be pure white.
set ::g_greenPlasticMtrl_specular { 0.5 1.0 0.5 1.0 }
# It seems backwards, but increasing the shininess value reduces the
# highlight's size
set ::g_greenPlasticMtrl_shininess 40.0
#-------------------------------------------------------------------------
# Setup material - Used to create a silver metallic teapot
#-------------------------------------------------------------------------
# Set the material's main color to a silver-like gray color.
set ::g_silverMetalMtrl_diffuse { 0.5 0.5 0.5 1.0 }
# A silver metal would be very shiny, so we'll reflect back all ambient.
set ::g_silverMetalMtrl_ambient { 1.0 1.0 1.0 1.0 }
# We can make it seem extra shiny by having it actually emit some light
# of its own... but not too much are we'll wash the color out.
set ::g_silverMetalMtrl_emission { 0.1 0.1 0.1 1.0 }
# Polished silver can reflect back pure white highlights, so set the
# specular to pure white.
set ::g_silverMetalMtrl_specular { 1.0 1.0 1.0 1.0 }
# Set the Power value to a small number to make the highlight's size bigger.
set ::g_silverMetalMtrl_shininess 5.0
#-------------------------------------------------------------------------
# Setup a simple directional light and some ambient...
#-------------------------------------------------------------------------
glEnable GL_LIGHT0
set position_light0 { -1.0 0.0 1.0 0.0 }
set diffuse_light0 { 1.0 1.0 1.0 1.0 }
set specular_light0 { 1.0 1.0 1.0 1.0 }
glLightfv GL_LIGHT0 GL_POSITION $position_light0
glLightfv GL_LIGHT0 GL_DIFFUSE $diffuse_light0
glLightfv GL_LIGHT0 GL_SPECULAR $specular_light0
# Be careful when setting up ambient lighting. You can very easily wash
# out the material's specular highlights.
set ambient_lightModel { 0.1 0.1 0.1 1.0 }
glLightModelfv GL_LIGHT_MODEL_AMBIENT $ambient_lightModel
}
proc ReshapeCallback { toglwin { w -1 } { h -1 } } {
set w [$toglwin width]
set h [$toglwin height]
glViewport 0 0 $w $h
glMatrixMode GL_PROJECTION
glLoadIdentity
gluPerspective 45.0 [expr double($w)/double($h)] 0.1 1000.0
}
proc DisplayCallback { toglwin } {
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_MODELVIEW
glLoadIdentity
glTranslatef 0.0 0.0 -6.5
# -------------------------------------------------------------------------
# When using a material, its possible to have a color set by glColor3f
# override one or more material colors by enabling GL_COLOR_MATERIAL.
# Once that's done, you can and ID the material color or colors to
# override using glColorMaterial.
# Uncomment this to use the teapot's color, which is blue, as a
# replacement for one or more material colors.
if { $::g_EnableColorMaterial } {
glEnable GL_COLOR_MATERIAL
} else {
glDisable GL_COLOR_MATERIAL
}
# Uncomment one or more of these to ID the material color or colors you
# would like to override?
# glColorMaterial GL_FRONT_AND_BACK GL_AMBIENT
# glColorMaterial GL_FRONT_AND_BACK GL_AMBIENT_AND_DIFFUSE
# glColorMaterial GL_FRONT_AND_BACK GL_DIFFUSE
# glColorMaterial GL_FRONT_AND_BACK GL_SPECULAR
# -------------------------------------------------------------------------
# Render the first teapot using a red clay material
glMaterialfv GL_FRONT_AND_BACK GL_DIFFUSE $::g_redClayMtrl_diffuse
glPushMatrix
glTranslatef 0.0 1.2 0.0
glRotatef [expr -1.0 * $::g_fSpinY(1)] 1.0 0.0 0.0
glRotatef [expr -1.0 * $::g_fSpinZ(1)] 0.0 0.0 1.0
# This color won't get used unless we enable GL_COLOR_MATERIAL
glColor3f 0.0 0.0 1.0
glutSolidTeapot 1.0
glPopMatrix
# Render the second teapot using a green plastic material
glMaterialfv GL_FRONT_AND_BACK GL_DIFFUSE $::g_greenPlasticMtrl_diffuse
glMaterialfv GL_FRONT_AND_BACK GL_AMBIENT $::g_greenPlasticMtrl_ambient
glMaterialfv GL_FRONT_AND_BACK GL_SPECULAR $::g_greenPlasticMtrl_specular
glMaterialf GL_FRONT_AND_BACK GL_SHININESS $::g_greenPlasticMtrl_shininess
glPushMatrix
glTranslatef 1.7 -0.8 0.0
glRotatef [expr -1.0 * $::g_fSpinY(1)] 1.0 0.0 0.0
glRotatef [expr -1.0 * $::g_fSpinZ(1)] 0.0 0.0 1.0
# This color won't get used unless we enable GL_COLOR_MATERIAL
glColor3f 0.0 0.0 1.0
glutSolidTeapot 1.0
glPopMatrix
# Render the third teapot using a silver metallic material
glMaterialfv GL_FRONT_AND_BACK GL_DIFFUSE $::g_silverMetalMtrl_diffuse
glMaterialfv GL_FRONT_AND_BACK GL_AMBIENT $::g_silverMetalMtrl_ambient
glMaterialfv GL_FRONT_AND_BACK GL_EMISSION $::g_silverMetalMtrl_emission
glMaterialfv GL_FRONT_AND_BACK GL_SPECULAR $::g_silverMetalMtrl_specular
glMaterialf GL_FRONT_AND_BACK GL_SHININESS $::g_silverMetalMtrl_shininess
glPushMatrix
glTranslatef -1.7 -0.8 0.0
glRotatef [expr -1.0 * $::g_fSpinY(1)] 1.0 0.0 0.0
glRotatef [expr -1.0 * $::g_fSpinZ(1)] 0.0 0.0 1.0
# This color won't get used unless we enable GL_COLOR_MATERIAL
glColor3f 0.0 0.0 1.0
glutSolidTeapot 1.0
glPopMatrix
# Set all the material properties back to their default values...
glMaterialfv GL_FRONT_AND_BACK GL_DIFFUSE $::g_default_diffuse
glMaterialfv GL_FRONT_AND_BACK GL_AMBIENT $::g_default_ambient
glMaterialfv GL_FRONT_AND_BACK GL_EMISSION $::g_default_emission
glMaterialfv GL_FRONT_AND_BACK GL_SPECULAR $::g_default_specular
glMaterialf GL_FRONT_AND_BACK GL_SHININESS $::g_default_shininess
$toglwin swapbuffers
}
proc Cleanup {} {
foreach var [info globals g_*] {
uplevel #0 unset $var
}
}
proc ExitProg {} {
exit
}
frame .fr
pack .fr -expand 1 -fill both
togl .fr.toglwin -width $g_WinWidth -height $g_WinHeight \
-double true -depth true \
-createcommand CreateCallback \
-reshapecommand ReshapeCallback \
-displaycommand DisplayCallback
listbox .fr.usage -font $::g_listFont -height 3
label .fr.info
grid .fr.toglwin -row 0 -column 0 -sticky news
grid .fr.usage -row 1 -column 0 -sticky news
grid .fr.info -row 2 -column 0 -sticky news
grid rowconfigure .fr 0 -weight 1
grid columnconfigure .fr 0 -weight 1
wm title . "Tcl3D demo: CodeSampler's Material Demo"
# Watch For ESC Key And Quit Messages
wm protocol . WM_DELETE_WINDOW "ExitProg"
bind . <Key-Escape> "ExitProg"
bind . <Key-c> "ToggleColorMaterial"
bind .fr.toglwin <1> "SetMouseInput 1 %x %y"
bind .fr.toglwin <B1-Motion> "GetMouseInput 1 %x %y"
.fr.usage insert end "Key-Escape Exit"
.fr.usage insert end "Key-c Toggle GL_COLOR_MATERIAL"
.fr.usage insert end "Mouse-L Rotate teapots"
.fr.usage configure -state disabled
PrintInfo [tcl3dOglGetInfoString]
|
