[HOME] [CONTENTS][DOWNLOAD][PREV][NEXT]


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
}
 

[HOME] [CONTENTS][DOWNLOAD]