Re: ColorTable problem

New Message Reply Date view Thread view Subject view Author view

Dave Akers (dla@sgi.com)
Fri, 10 Sep 1999 10:09:06 -0700


Hi Ballard,

  The lookup table provided with Volumizer isn't specific to textures used with
Volumizer. Internally it uses the glColorTableSGI function to set up a LUT that
applies to _all_ textures. If you just want your object to appear in its own colors
(without a LUT translation), then you need to temporarily disable the lookup table
before you draw the object, then re-enable it to render the volume. This can be
done with the methods voLookupTable::disable() and voLookupTable::enable(). I've
tested this with your example code, and it works just fine..

-Dave

ballard andrews wrote:

> Dave,
>
> I have a problem rendering textured objects with "volumes":
> The volume's color table overides the objects.
> The attached program reuses the demo code.
>
> The first image shows the window when it is first opened.
> voglBasic ${DATAFILE} -sc 1 1 3.2
>
> The second shows that the geometry's texture
> is modified when the volume's grayscale is adjusted.
>
> The third shows that the volume's LUT is applied to the object
> voglBasic ${DATAFILE} -sc 1 1 3.2 -color -lutFile
> ${DATAPATH}/tables/CT1.table
>
> This is probably an OpenGL issue and not a bug in Volumizer -
> tables can be loaded just before the bind operation in the render
> callback using the voLookup::load() method, but how do you get/set
> the objects' texture table?
>
> I attach the file voglMain.cxx which can be compiled
> with the other demo code (add myImage.o).
>
> cheers,
>
> -ba
>
> --
> Dr. A. Ballard Andrews
> Schlumberger Doll Research
> Old Quarry Road
> Ridgefield, CT 06877
> tel: 203-431-5522 fax: 5521
>
> ------------------------------------------------------------------------
> [Image] [Image] [Image]
>
> ------------------------------------------------------------------------
> /**
> * (c) Copyright 1996, 1997, 1998 Silicon Graphics, Inc.
> * ALL RIGHTS RESERVED
> * Permission to use, copy, modify, and distribute this software for
> * any purpose and without fee is hereby granted, provided that the above
> * copyright notice appear in all copies and that both the copyright notice
> * and this permission notice appear in supporting documentation, and that
> * the name of Silicon Graphics, Inc. not be used in advertising
> * or publicity pertaining to distribution of the software without specific,
> * written prior permission.
> *
> * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
> * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
> * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
> * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
> * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
> * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
> * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
> * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
> * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN
> * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
> * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
> * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
> *
> * US Government Users Restricted Rights
> * Use, duplication, or disclosure by the Government is subject to
> * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
> * (c)(1)(ii) of the Rights in Technical Data and Computer Software
> * clause at DFARS 252.227-7013 and/or in similar or successor
> * clauses in the FAR or the DOD or NASA FAR Supplement.
> * Unpublished-- rights reserved under the copyright laws of the
> * United States. Contractor/manufacturer is Silicon Graphics,
> * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
> *
> * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
> */
>
> /*
> @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
> \\\\\\\\\\\\\\\\\\\\ ------------------------------- ////////////////////
>
> Main routine and GUI for Volumizer demos.
>
> Many of the demos in this directory have a similar structure. For
> example, voglBasic and voglRaw provide identical functionality. The only
> difference between them is that voglBasic takes a single 3D TIFF file as
> a command line argument, while voglRaw takes a list of 2D images. Once the
> volume is read in, all the other aspects of their behavior is identical.
> Therefore, voglBasic and voglRaw share the same display routine (namely,
> my_DrawVolume()), but each provides its own implementation of the volume
> construction routine (my_InitAppearance()). On the other hand, voglBasic
> and voglCache construct the volume in the same way, but display it
> differently (voglBasic repolygonizes the model for every frame, while
> voglCache will try to reuse the polygonization from the previous frames
> if possible). Thus, voglBasic and voglCache share all the code but
> my_DrawVolume().
>
> The elements of the shared structure include:
>
> my_InitAppearance() read in voxel data and create a BrickSetCollection
> my_InitGeometry() construct a tetrahedral model of the volume (e.g., cube)
> my_InitTransient() allocate storage for sampling polygons
> my_InitGfx() initialize graphics objects (e.g., luts and texture objects)
> my_DrawVolume() render the volumetric model
>
> In addition to sharing the structure, the demos refer to a single global
> instance of my_DataType object, which is used to maintain the state.
>
> While maintaining similar structure and sharing global data facilitates
> development and maintenance of the demo code base it does introduce
> a certain element of coupling between unrelated componenets.
> Consult voglSimple for example that is free of such dependecies (albeit
> at the expense of limited functionality).
>
> \\\\\\\\\\\\\\\\\\\\ ------------------------------- ////////////////////
> @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
> */
>
> #include <X11/X.h>
> #include <X11/Intrinsic.h>
> #include <X11/keysym.h>
> #include <Xm/Xm.h>
> #include <GL/gl.h>
> #ifdef SOLARIS_251
> #include <GLw/GLwMDrawA.h>
> #else
> #include <GL/GLwMDrawA.h>
> #endif
> #include <iostream.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <math.h>
>
> #include <vo/AppearanceActions.h>
> #include <vo/GeometryActions.h>
>
> #include "voglDemos.h"
> #include "trackball.h"
>
> GLuint floorTextureObjectId[1];
> unsigned int* read_texture(const char *, int *, int *, int *);
> void drawfloor(GLfloat );
> char *floorFileName;
> unsigned *floortex;
> int texcomps, texwid, texht;
>
> my_DataType my_Data = {
> voRenderingModeScope::MONOCHROME, // renderingMode
> voInterpolationTypeScope::DEFAULT, // interpolationType
> voInterleavedArrayTypeScope::V3F, // interleavedArrayFormat
> { 64.0, 64.0, 32.0 }, // modelCentroid
> { 128.0, 128.0, 128.0 }, // modelSize
> { 1.0, 1.0, 1.0 }, // modelScale
> -1.0, -1.0, // dataRangeLo, dataRangeHi
> 256, 0, // lutLength, lutSupplied
> 127, 255, NULL, // lutCenter, lutWidth, lutFileName
> 1.0, // samplingRate
> VO_TRUE, // wireframe
> 256, // maxSamplesNumber
> 1, // maxBrickCount
> NULL, // allVertexData
> NULL, // aPolygonSetArray
> 8, 40.0, 255.0, // tesselation Size MinValue, MaxValue
> NULL, // aTransientGeometryCache
> 0.75, // transient geometry cache threshold
> VO_FALSE, // report fill rate flag
> NULL, // aButton3CallbackPtr routine
> NULL, // volume's geometry
> NULL, // volume's appearance
> NULL, // for voglSpaceleap: aSpaceLeapState
> };
>
> // BEGIN LOCAL GUI STATE
>
> static int buttonReleased;
> static float cumulativeQuaternion[4], deltaQuaternion[4];
> static int windowSizeX = 400, windowSizeY = 400;
>
> // END LOCAL GUI STATE
>
> enum myProjectionType { myORTHO, myPERSPECTIVE };
>
> void
> GinitCB(Widget w, XtPointer /* clientData */ , XtPointer /* cal */ )
> {
> Arg arg;
> XVisualInfo *vip;
> GLXContext glCtxt;
>
> XtSetArg(arg, GLwNvisualInfo, &vip);
> XtGetValues(w, &arg, 1);
> glCtxt = glXCreateContext(XtDisplay(w), vip, NULL, GL_TRUE);
> glXMakeCurrent(XtDisplay(w), XtWindow(w), glCtxt);
>
> my_InitGfx(my_Data.aTetraSet, my_Data.aVolume);
>
> }
>
> void
> Draw(Widget widget)
> {
>
> glEnable(GL_DEPTH_TEST);
>
> glClearColor(0.0, 0.0, 0.0, 1.0);
> glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
>
> float m[4][4];
> build_rotmatrix(m, cumulativeQuaternion);
> glMatrixMode(GL_MODELVIEW);
> glLoadIdentity();
> glMultMatrixf(&(m[0][0]));
> glRotatef(180, 0, 1, 0); // initial rotations
> glRotatef( 90, 1, 0, 0); // initial rotations
>
> drawfloor(0.5f); /* draw the floor */
>
> /* draw the volume */
> glScalef(
> my_Data.modelScale[0], my_Data.modelScale[1], my_Data.modelScale[2]);
> glTranslatef(
> -my_Data.modelCentroid[0],
> -my_Data.modelCentroid[1],
> -my_Data.modelCentroid[2]);
>
> my_DrawVolume(my_Data.aTetraSet, my_Data.aVolume);
>
> GLwDrawingAreaSwapBuffers(widget);
>
> }
>
> void
> SetUpProjection(myProjectionType type, int width, int height)
> {
>
> glViewport(0,0,width,height);
>
> switch( type ) {
> case myPERSPECTIVE:
> glMatrixMode(GL_PROJECTION);
> glLoadIdentity();
> glFrustum(
> -0.0025, 0.0025, -0.0025, 0.0025, 0.01, my_Data.modelSize[2]*4);
> glTranslatef(0, 0, -my_Data.modelSize[2]*3);
> glMatrixMode(GL_MODELVIEW);
> break;
> case myORTHO:
> glMatrixMode(GL_PROJECTION);
> glLoadIdentity();
> glOrtho(
> -my_Data.modelSize[0] * 0.8, my_Data.modelSize[0] * 0.8,
> -my_Data.modelSize[1] * 0.8, my_Data.modelSize[1] * 0.8,
> -my_Data.modelSize[2] * 0.8, my_Data.modelSize[2] * 0.8);
> glMatrixMode(GL_MODELVIEW);
> break;
> }
>
> }
>
> void
> ExposeCB(Widget widget, XtPointer /* clientData */ , XtPointer cal)
> {
> GLwDrawingAreaCallbackStruct *csp = (GLwDrawingAreaCallbackStruct *) cal;
>
> SetUpProjection(myPERSPECTIVE,csp->width, csp->height);
>
> Draw(widget);
>
> }
>
> void
> ResizeCB(Widget widget, XtPointer /* clientData */ , XtPointer cal)
> {
> GLwDrawingAreaCallbackStruct *csp = (GLwDrawingAreaCallbackStruct *) cal;
>
> SetUpProjection(myPERSPECTIVE,csp->width, csp->height);
>
> Draw(widget);
>
> windowSizeX = csp->width;
> windowSizeY = csp->height;
>
> }
>
> void
> KeybdInput(XKeyEvent * keyEvent)
> {
> const float DELTA = 0.1;
> KeySym keySym;
> char buf[32];
>
> XLookupString(keyEvent, buf, 32, &keySym, NULL);
>
> switch (keySym) {
> case XK_o: // use orthographics projection
> SetUpProjection(myORTHO,windowSizeX, windowSizeY);
> break;
> case XK_p: // use perspective projection
> SetUpProjection(myPERSPECTIVE,windowSizeX, windowSizeY);
> break;
> case XK_h: // reset to initial view (home)
> trackball(cumulativeQuaternion, 0.0, 0.0, 0.0, 0.0);
> break;
> case XK_w:
> my_Data.wireframe = my_Data.wireframe ^ 1;
> break;
> case XK_Right:
> trackball(deltaQuaternion,0.0,0.0,DELTA,0.0);
> add_quats(deltaQuaternion, cumulativeQuaternion, cumulativeQuaternion);
> break;
> case XK_Left:
> trackball(deltaQuaternion,0.0,0.0,-DELTA,0.0);
> add_quats(deltaQuaternion, cumulativeQuaternion, cumulativeQuaternion);
> break;
> case XK_Up:
> trackball(deltaQuaternion,0.0,0.0,0.0,DELTA);
> add_quats(deltaQuaternion, cumulativeQuaternion, cumulativeQuaternion);
> break;
> case XK_Down:
> trackball(deltaQuaternion,0.0,0.0,0.0,-DELTA);
> add_quats(deltaQuaternion, cumulativeQuaternion, cumulativeQuaternion);
> break;
> case XK_Escape:
> my_Cleanup(my_Data.aTetraSet,my_Data.aVolume);
> exit(0);
> }
> }
>
> void
> MotionInput(XMotionEvent * motionEvent)
> {
> static int prevX = 0, prevY=0;
> static int currX = 0, currY=0;
>
> switch ( motionEvent->state ) {
>
> case Button1MotionMask:
> prevX = currX;
> prevY = currY;
> currX = motionEvent->x;
> currY = motionEvent->y;
>
> if( ! buttonReleased ) {
> prevX = motionEvent->x;
> prevY = motionEvent->y;
> buttonReleased = 1;
> }
>
> trackball(deltaQuaternion,
> (2.0*prevX-windowSizeX)/(float)windowSizeX,
> (windowSizeY-2.0*prevY)/(float)windowSizeY,
> (2.0*currX-windowSizeX)/(float)windowSizeX,
> (windowSizeY-2.0*currY)/(float)windowSizeY);
>
> add_quats(deltaQuaternion, cumulativeQuaternion, cumulativeQuaternion);
>
> break;
> case Button2MotionMask:
> my_Button2Callback(motionEvent->x, motionEvent->y, my_Data.aVolume);
> break;
> case Button3MotionMask:
> if( my_Data.aButton3CallbackPtr )
> (*my_Data.aButton3CallbackPtr)(
> motionEvent->x, motionEvent->y, my_Data.aVolume);
> break;
> default:
> break;
>
> }
>
> }
>
> void
> InputCB(Widget widget, XtPointer /* clientData */ , XtPointer callData)
> {
> XmDrawingAreaCallbackStruct *dacs = (XmDrawingAreaCallbackStruct *)callData;
>
> switch (dacs->event->type) {
> case ButtonPress:
> buttonReleased = 0;
> break;
> case ButtonRelease:
> return;
> case MotionNotify:
> MotionInput((XMotionEvent *) dacs->event);
> break;
> case KeyPress:
> KeybdInput((XKeyEvent *) dacs->event);
> break;
> case KeyRelease:
> return; // do not redraw on key release
> default:
> break;
> }
>
> Draw(widget);
>
> }
>
> void
> main(int argc, char **argv)
> {
> fprintf(stderr,"%s\n",voVersion());
>
> fprintf(stderr,
> "\nLeft mouse button to rotate, right to adjust lookup table.\n\n");
>
> myParseArgs(argc, argv);
>
> voError::setDebugLevel( my_Data.reportFillRateFlag == VO_TRUE ? 2 : 1);
>
> /* load pattern for current 2d texture */
>
> floorFileName = "plank.rgb";
> floortex = read_texture("plank.rgb", &texwid, &texht, &texcomps);
> if (floortex == NULL) {
> printf("Bad file name.\n");
> exit(1);
> }
>
>
> my_Data.aVolume = my_InitAppearance(argc, argv);
> my_Data.aTetraSet = my_InitGeometry(my_Data.aVolume);
> my_Data.aPolygonSetArray =
> my_InitTransient(my_Data.aTetraSet,my_Data.aVolume);
>
> Widget toplevel;
> XtAppContext appCtxt;
> XVisualInfo *visual;
> Cardinal n1 = 0;
> Arg args[4];
>
> GLint attribs[] =
> {GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 1,
> GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DEPTH_SIZE, 1, None};
>
> toplevel =
> XtAppInitialize(&appCtxt, "Lean", NULL, 0, &argc, argv, NULL, NULL, 0);
> XtSetArg(args[n1], XmNwidth, (int)windowSizeX); n1++;
> XtSetArg(args[n1], XmNheight, (int)windowSizeY); n1++;
> XtSetArg(args[n1], GLwNattribList, attribs); n1++;
> Widget drawArea = GLwCreateMDrawingArea(toplevel, "pb", args, n1);
>
> visual = glXChooseVisual(XtDisplay(toplevel), 0, attribs);
> if (!visual)
> fprintf(stderr, "Bad visual\n");
>
> XtAddCallback(drawArea, GLwNinputCallback, InputCB, NULL);
> XtAddCallback(drawArea, GLwNginitCallback, GinitCB, NULL);
> XtAddCallback(drawArea, GLwNexposeCallback, ExposeCB, NULL);
> XtAddCallback(drawArea, GLwNresizeCallback, ResizeCB, NULL);
>
> XtManageChild(drawArea);
>
> trackball(cumulativeQuaternion, 0.0, 0.0, 0.0, 0.0);
>
> XtRealizeWidget(toplevel);
> XtAppMainLoop(appCtxt);
>
> }
>
> void
> drawfloor(GLfloat alpha)
> {
>
> static GLfloat floor_mat[] = {.5f, .5f, .5f, 1.f};
>
>
> floor_mat[3] = alpha;
> glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, floor_mat);
>
> glGenTexturesEXT(1, floorTextureObjectId);
> glBindTextureEXT(GL_TEXTURE_2D, floorTextureObjectId[0]);
> glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texwid, texht, 0, GL_RGBA,
> GL_UNSIGNED_BYTE, floortex);
>
> /* makes texturing faster, and looks better than GL_LINEAR */
> glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
> glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
> glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
>
> glEnable(GL_TEXTURE_2D);
>
> glBegin(GL_QUADS);
>
> /* floor */
> glNormal3f(0.f, 1.f, 0.f);
> glTexCoord2i(0, 0);
> glVertex3f(-100.f, 0.f, 100.f);
> glTexCoord2i(2, 0);
> glVertex3f( 100.f, 0.f, 100.f);
> glTexCoord2i(2, 2);
> glVertex3f( 100.f, 0.f, -100.f);
> glTexCoord2i(0, 2);
> glVertex3f(-100.f, 0.f, -100.f);
>
> glEnd();
>
> glDisable(GL_TEXTURE_2D);
>
> }


New Message Reply Date view Thread view Subject view Author view

This archive was generated by hypermail 2.0b2 on Mon Nov 01 1999 - 14:25:43 PST