3D IMAGE RENDERING
Multiple Textures.
The following two figures show a hyperspectral image data cube. The
cube has six textures. The front and back textures are two
color composite images. The top, bottom, left and right textures
are the four corresponding image data profiles of the hyperspectral data
cube. The texture at the right side of the cube is blended to generate
a translucent view of the inside cube.
#
# Copyright(c) 1999-2001, Chengye Mao, email: chengye.geo@yahoo.com
#
# imgcube - To render an image-textured cube with a GLW widget,
# using multiple image textures.
Five sides of the cube use
# five solid image textures and one side
of the cube uses
# a blended image texture and is translucent.
The texture
# images were imported, cropped and processed
using
# rimage config, rimage copy,
rimage
section and view from
# an AVIRIS high resolution hyperspectral
image data set
# f960705, which may be either downloaded
or ordered free from:
#
# http://makalu.jpl.nasa.gov/html/ordering_stand.html.
#
# The results were then put into Tk photo
and saved in a gif
# format using Tk photo's write function.
#
# The cropped data set is a hyperspectral
sub-image cube of
# 256/256/224 rows/columns/bands.
The front texture is a RGB
# composition of bands 44, 21 and 15.
The back is composed with
# bands 30, 20 and 8. The top, bottom,
left and right textures
# are the corresponding profiles of the
sub-image spectral cube
# and sectioned into 256x256 profile arrays
by resampling in
# spectral dimension.
#
# Each texture image is prepared by imgcube.createTex
which loads
# the image using glphoto, and sets
up texture data using
# glGenTextures, glBindTexture,
glTexParameter
and glTexImage2D.
# An image texuture is placed at a specified
plane by the
# procedure imgcube.drawTex, which
calls glTexCoord and glVertex
# to map the image texture to its associated
vertices.
#
# Bindings of key press:
# s cube scale
decreases
# S cube scale
increases
# z zoom out the
cube
# Z zoom in the
cube
# f field of view
decreases
# F field of view
increases
# left cube moves left
# right cube moves right
# up cube moves up
# down cube moves down
#
# Binding of mouse motion with the left-button pressed:
# view rotation
#
# Procedures:
# imgcube.createImage - prepare images
for textures
# imgcube.createTex - set up
a texture for an image
# imgcube.init
- initialize
# imgcube.drawTex
- draw an image texture
# imgcube.display
- display textured image cube
# imgcube.button
- handle mouse button press
# imgcube.motion
- handle mouse mouse motion
# imgcube.reshape
- geometric configurate of a GLW widget<
# imgcube.keypress -
handle key press
# imgcube.create
- entry to create an image cube GLW widgget
#
proc imgcube.createImage {} {
global gimgHome
_busyIcon
image create photo front -file \
[file join $gimgHome
gif f960705-1-sub-44-21-15.gif]
image create photo back -file \
[file join $gimgHome
gif f960705-1-sub-30-20-8.gif]
image create photo left -file \
[file join $gimgHome
gif f960705-1-sub-zy0.gif]
image create photo right -file \
[file join $gimgHome
gif f960705-1-sub-zy255.gif]
image create photo top -file \
[file join $gimgHome
gif f960705-1-sub-zx0.gif]
image create photo bottom -file \
[file join $gimgHome
gif f960705-1-sub-zx255.gif]
}
proc imgcube.createTex {imgName} {
GLuint $imgName
glphoto image $imgName
set width [image width $imgName]
set height [image height $imgName]
glGenTextures 1 $imgName
glBindTexture GL_TEXTURE_2D $imgName
glTexParameter GL_TEXTURE_2D GL_TEXTURE_MAG_FILTER
GL_LINEAR
glTexParameter GL_TEXTURE_2D GL_TEXTURE_MIN_FILTER
GL_LINEAR
glTexImage2D GL_TEXTURE_2D 0 GL_RGB $width $height
\
0 GL_RGB GL_UNSIGNED_BYTE
image
gldel image
}
proc imgcube.init w {
set old [glw current $w]
imgcube.createImage
GLint xrot 20
GLint yrot -20
GLint zrot 0
GLint xp
GLint yp
GLint buttonPress
GLint fov 30
GLfloat sz 0.5
GLfloat x0
GLfloat y0
GLfloat z0 -2.0
GLfloat zn 1.0
GLfloat zf 30.0
GLfloat lx
GLfloat ly
GLfloat lz 2.0
glClearColor 0 0 0 0
glShadeModel GL_FLAT
glEnable GL_DEPTH_TEST
glPixelStore GL_UNPACK_ALIGNMENT 1
imgcube.createTex front
imgcube.createTex back
imgcube.createTex left
imgcube.createTex right
imgcube.createTex top
imgcube.createTex bottom
glw current $old
}
proc imgcube.drawTex {tex s x0 y0 z0 x1 y1 z1 x2 y2 z2 x3 y3 z3}
{
glBindTexture GL_TEXTURE_2D $tex
glBegin GL_QUADS
glTexCoord 0 0; glVertex [expr $s*$x0] [expr
$s*$y0] [expr $s*$z0]
glTexCoord 0 1; glVertex [expr $s*$x1] [expr
$s*$y1] [expr $s*$z1]
glTexCoord 1 1; glVertex [expr $s*$x2] [expr
$s*$y2] [expr $s*$z2]
glTexCoord 1 0; glVertex [expr $s*$x3] [expr
$s*$y3] [expr $s*$z3]
glEnd
}
proc imgcube.display w {
set old [glw current $w]
glClear GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
glEnable GL_TEXTURE_2D
glTexEnv GL_TEXTURE_ENV GL_TEXTURE_ENV_MODE
GL_DECAL
glPushMatrix
glTranslate x0 y0 z0
gluLookAt lx ly lz 0 0 0 0 1 0
glRotate xrot 1 0 0
glRotate yrot 0 1 0
glRotate zrot 0 0 1
set s [glv sz]
imgcube.drawTex front $s -1 -1 1
-1 1 1 1 11 1 1 -1
1
imgcube.drawTex back $s -1 -1 -1
-1 1 -1 1 1 -1&nnbsp; 1 -1 -1
imgcube.drawTex left $s -1 -1
1 -1 1 1 -1 1 -1 -1 -1 -1
imgcube.drawTex top $s -1
1 -1 -1 1 1 1 1 1
1 1 -1
imgcube.drawTex bottom $s -1 -1 -1 -1
-1 1 1 -1 1 p; 1 -1 -1
glEnable GL_BLEND
glDepthMask GL_FALSE
glBlendFunc GL_SRC_ALPHA GL_ONE
imgcube.drawTex right $s 1 -1
1 1 1 1 1 1 -1 1
-1 -1
glDepthMask GL_TRUE
glDisable GL_BLEND
glPopMatrix
glFlush
glDisable GL_TEXTURE_2D
glw draw
glw current $old
}
proc imgcube.button {w x y pressStatus} {
set old [glw current $w]
glset xp $x
glset yp $y
glset buttonPress $pressStatus
glw current $old
focus $w
}
proc imgcube.motion {w x y} {
set old [glw current $w]
if {![glv buttonPress]} return
set dx [expr [glv xp] - $x]
set dy [expr [glv yp] - $y]
glset xrot [expr [glv xrot] - 0.5 * $dy]
glset yrot [expr [glv yrot] - 0.5 * $dx]
glset xp $x
glset yp $y
glw current $old
imgcube.display $w
}
proc imgcube.reshape {w width height} {
set old [glw current $w]
glViewport 0 0 $width $height
glMatrixMode GL_PROJECTION
glLoadIdentity
gluPerspective fov [expr $width/double($height)]
zn zf
glMatrixMode GL_MODELVIEW
glLoadIdentity
glw current $old
}
proc imgcube.keypress {w keycode keysym} {
set old [glw current $w]
switch $keysym {
"Prior" { glset
z0 [expr [glv z0]-0.01] }
"Next" {
glset z0 [expr [glv z0]+0.01] }
"Left" {
glset x0 [expr [glv x0]-0.01] }
"Right" { glset
x0 [expr [glv x0]+0.01] }
"Down" {
glset y0 [expr [glv y0]-0.01] }
"Up"
{ glset y0 [expr [glv y0]+0.01] }
"s"
{ glset sz [expr [glv sz]-0.05] }
"S"
{ glset sz [expr [glv sz]+0.05] }
"f"
{ glset fov [expr [glv fov]-1.0] }
"F"
{ glset fov [expr [glv fov]+1.0] }
"x"
{ glset lx [expr [glv lx]-0.02] }
"X"
{ glset lx [expr [glv lx]+0.02] }
"y"
{ glset ly [expr [glv ly]-0.02] }
"Y"
{ glset ly [expr [glv ly]+0.02] }
"z"
{ glset lz [expr [glv lz]-0.05] }
"Z"
{ glset lz [expr [glv lz]+0.05] }
"Escape" { destroy $w
}
}
glw current $old
imgcube.reshape $w [$w cget -width] [$w cget
-height]
imgcube.display $w
}
proc imgcube.create w {
glw $w -width 250 -height 250
imgcube.init $w
bind $w <Configure>
"imgcube.reshape $w %w %h"
bind $w <Expose>
"imgcube.display $w"
bind $w <ButtonPress> "imgcube.button
$w %x %y 1"
bind $w <ButtonRelease> "imgcube.button $w
%x %y 0"
bind $w <Motion>
"imgcube.motion $w %x %y"
bind $w <KeyPress>
"imgcube.keypress $w %k %K"
pack $w -expand 1 -fill both
focus $w
imgcube.display $w
return $w
}
|