source: trunk/src/testing/app/volvis/main.cpp @ 4

Revision 4, 30.8 KB checked in by ajaworski, 13 years ago (diff)

Added modified SAGE sources

Line 
1/********************************************************************************
2 * Volatile - Volume Visualization Software for SAGE
3 * Copyright (C) 2004 Electronic Visualization Laboratory,
4 * University of Illinois at Chicago
5 *
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 *  * Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 *  * Redistributions in binary form must reproduce the above
14 *    copyright notice, this list of conditions and the following disclaimer
15 *    in the documentation and/or other materials provided with the distribution.
16 *  * Neither the name of the University of Illinois at Chicago nor
17 *    the names of its contributors may be used to endorse or promote
18 *    products derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 * Direct questions, comments etc about Volatile to www.evl.uic.edu/cavern/forum
33 *********************************************************************************/
34
35#include <string.h>
36#include <stdlib.h>
37#include <time.h>
38#include <vector>
39#ifdef WIN32
40#include <windows.h>            //  must be included before any OpenGL
41#endif
42
43#if defined(__APPLE__)
44#include <GLUT/glut.h>
45#else
46#include <GL/glut.h>
47#endif
48
49
50#include "Trackball.h"     //SGI quaternion trackball
51#include "VectorMath.h"    //usefull vector/matrix operations
52#include "global.h"         //global definitions
53#include "glUE.h"          //gl utilities and extensions
54#include "CCmdLine.h"
55#include "vFPSText.h"
56#include "vRenderer.h"     //standard renderer
57#include "vPrimitive.h"
58#include "vGeometry.h"
59#include "vNet.h"
60#include "vUI.h"
61#include "vSliceView.h"
62
63#if defined(ADDCGGL)
64#include "vCG.h"
65#endif
66#if defined(ADDARBGL)
67#include "vARB.h"
68#endif
69
70#if defined(V_DISTRIBUTED)
71#include "mpi.h"
72#include "vNet.h"
73#endif
74
75#if defined(V_NETTF)
76#include "vTF.h"
77#endif
78vector<vPrimitive*>   renderList; //all renderables attatch to this one
79vGlobal         global; //the global v data structure (global.h)
80Trackball       cutTrack;       //global trackball
81
82/* Atul June 8 2004. Commented out the # since vNet is required for
83 * stand alone version also */
84#if defined(V_DISTRIBUTED)
85vNet* net = 0;  //The volvis controller
86#endif
87/* Atul June 8 2004 */
88
89#if defined(V_NETTF)
90vTF * tfNet = 0;        //The tfcontroller
91#endif
92
93#if defined(V_SAGE)
94        // headers for SAGE
95#include "sail.h"
96#include "misc.h"
97int winWidth, winHeight;
98GLubyte *rgbBuffer = 0;
99sail sageInf; // sail object
100#endif
101
102
103
104enum {
105        MENU_ROAM = 1,
106        MENU_PROBE,
107        MENU_CUT,
108        MENU_ISOSURFACE,
109        MENU_ISOPOINTS,
110        MENU_BOUNDBOX,
111        MENU_FPS,
112        MENU_SAMPLERATE,
113        MENU_SAVEVOLUME,
114        MENU_SAVEGRADIENT,
115        MENU_HELP,
116        MENU_EXIT
117};
118
119void menuCallback(int idCommand)
120{
121        switch (idCommand)
122        {
123                case MENU_ROAM:
124                        setRoam();
125                        break;
126                case MENU_PROBE:
127                        setProbe();
128                        break;
129                case MENU_CUT:
130                        toggleCutPlane();
131                        break;
132                case MENU_ISOSURFACE:
133                        genIsosurface(100,100);
134                        break;
135                case MENU_ISOPOINTS:
136                        //genIsopoint(100,100);
137                        break;
138                case MENU_BOUNDBOX:
139                        toggleBoundBox();
140                        break;
141                case MENU_FPS:
142                        togglePrintFPS();
143                        break;
144                case MENU_SAMPLERATE:
145                        break;
146                case MENU_SAVEVOLUME:
147                        if (global.volume)
148                                global.volume->saveVolume("out");
149                        break;
150                case MENU_SAVEGRADIENT:
151                        saveGradientVolume();
152                        break;
153                case MENU_HELP:
154                        printUsage();
155                        break;
156                case MENU_EXIT:
157                        doExit();
158                        break;
159        }
160}
161
162int buildPopupMenu (void)
163{
164        int menu;
165        menu = glutCreateMenu(menuCallback);
166        glutAddMenuEntry ("Roam", MENU_ROAM);
167        glutAddMenuEntry ("Probe", MENU_PROBE);
168        glutAddMenuEntry ("Enable Cut Plane", MENU_CUT);
169        glutAddMenuEntry ("Gen Isosurface", MENU_ISOSURFACE);
170        glutAddMenuEntry ("Boundbox Toggle", MENU_BOUNDBOX);
171        glutAddMenuEntry ("FPS Toggle", MENU_FPS);
172        glutAddMenuEntry ("Sample Rate", MENU_SAMPLERATE);
173        glutAddMenuEntry ("Save Volume", MENU_SAVEVOLUME);
174        glutAddMenuEntry ("Save Gradient Volume", MENU_SAVEGRADIENT);
175        glutAddMenuEntry ("Print Help", MENU_HELP);
176        glutAddMenuEntry ("Exit", MENU_EXIT);
177        return menu;
178}
179
180void calcFrustum() {
181        float fov = 45.0f*3.1415/180.0f;
182        float b = global.env.clip[0] * (float) tan(fov * 0.5);
183        float r = b * global.win.aspect;
184        for (int i=0;i<global.env.frustumList.size();i++) {
185                global.env.frustumList[i].left *= r;  //left
186                global.env.frustumList[i].right *= r;   //right
187                global.env.frustumList[i].bottom *= b;  //bottom
188                global.env.frustumList[i].top *= b;   //top
189        }
190}
191
192//loads the data in dtex to the handle associated with the dependant texture
193//sent to CG
194void loadDepTex(unsigned int deptexName, unsigned char *dtex)
195{
196#if defined(ADDCGGL)
197        if (fprofile == CG_PROFILE_FP30) {
198                // 1D tex
199                glEnable(GL_TEXTURE_1D);
200                glBindTexture(GL_TEXTURE_1D, deptexName);
201                glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
202                glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP);
203                glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
204                glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
205                glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA8, depX, 0, GL_RGBA, GL_UNSIGNED_BYTE, dtex);
206                GlErr("vRenderer", "loadDepTex - loading scaled dependant texture");
207                glDisable(GL_TEXTURE_1D);
208        }
209        else if (fprofile == CG_PROFILE_FP20) {
210                // 2D tex for FP20
211                glEnable(GL_TEXTURE_2D);
212                glBindTexture(GL_TEXTURE_2D, deptexName);
213                glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
214                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
215                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
216                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
217                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, depX, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, dtex);
218                GlErr("vRenderer", "loadDepTex - loading scaled dependant texture");
219                glDisable(GL_TEXTURE_2D);
220        }
221#endif
222
223#if defined(ADDARBGL)
224        // 2D tex for FP20
225        glEnable(GL_TEXTURE_2D);
226        glBindTexture(GL_TEXTURE_2D, deptexName);
227        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
228        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
229        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
230        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
231        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, depX, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, dtex);
232        GlErr("vRenderer", "loadDepTex - loading scaled dependant texture");
233        glDisable(GL_TEXTURE_2D);
234#endif
235}
236
237//takes the data from the 2d texture sent from the UI and copies it to the dependant texture
238//that will be passed to CG
239//the dependant texture is 1D but the UI texture is 2d, so for now,
240//just extract the first row of the UI 2d texture to the dependant texture
241void copyScale(float sampleRate, unsigned char *cgTex)
242{
243        float alphaScale = 1.0/sampleRate;
244        for(int j=0; j<depX; ++j){
245                cgTex[j*4 + 0] = global.volren.deptex[j*4 + 0];
246                cgTex[j*4 + 1] = global.volren.deptex[j*4 + 1];
247                cgTex[j*4 + 2] = global.volren.deptex[j*4 + 2];
248                cgTex[j*4 + 3] = (1.0 - ::pow((1.0-(global.volren.deptex[j*4 + 3]/255.0)), alphaScale))*255;
249
250        }
251}
252
253void update() {
254        //set the current sampling rate based on the interaction mode
255        if (global.volren.lowRes)
256                global.volren.sampleRate = global.volren.interactSamp;
257        else
258                global.volren.sampleRate = global.volren.goodSamp;
259
260        //Re-Scale Alpha values depending on no of slices
261        //if we need to load a new TF, load it here (from the remote UI)
262        if(global.volren.scaleAlphas){
263                if((global.volren.lastSamp != global.volren.sampleRate)||(global.volren.loadTLUT)){  //see if the sample rate changed
264                        if((global.volren.lastGoodSamp != global.volren.goodSamp) || global.volren.loadTLUT){ //good sample rate changed
265                                copyScale(global.volren.goodSamp * 1/global.volren.gamma, global.volren.gDeptex);
266                                global.volren.lastGoodSamp = global.volren.goodSamp;
267                        }
268                        if((global.volren.lastInteSamp != global.volren.interactSamp) || global.volren.loadTLUT){ //interact samp rate changed
269                                copyScale(global.volren.interactSamp * 1/global.volren.gamma, global.volren.iDeptex);
270                                global.volren.lastInteSamp = global.volren.interactSamp;
271                        }
272                        if(global.volren.sampleRate == global.volren.goodSamp){ //which one do we load (good)
273                                loadDepTex(global.volren.scaledDeptexName,global.volren.gDeptex);
274                                global.volren.lastSamp = global.volren.goodSamp;
275                        }
276                        else if(global.volren.sampleRate == global.volren.interactSamp){ //(interactive)
277                                loadDepTex(global.volren.scaledDeptexName,global.volren.iDeptex);
278                                global.volren.lastSamp = global.volren.interactSamp;
279                        }
280                        copyScale(0.3, global.volren.nDeptex);
281                        loadDepTex(global.volren.origDeptexName, global.volren.nDeptex);
282                        global.volren.loadTLUT = 0;
283                }
284        } else {  //just do gamma scale, don't update for the sample rate (for testing purposes)
285                if(global.volren.loadTLUT){
286                        copyScale(1/global.volren.gamma, global.volren.gDeptex);
287                        loadDepTex(global.volren.scaledDeptexName, global.volren.gDeptex);
288                        global.volren.loadTLUT = 0;
289                }
290        }
291
292}
293
294void deallocateAll() {
295        if (global.volume);
296                delete global.volume;
297        if (global.fullVolume)
298                delete global.fullVolume;
299        for (int i=0;i<renderList.size();i++)
300                delete renderList[i];
301
302        delete [] global.volren.deptex ;
303        delete [] global.volren.nDeptex;
304        delete [] global.volren.gDeptex;
305        delete [] global.volren.iDeptex;
306
307}
308int main(int argc, char **argv) {
309        initGlobal(); //init global variables
310
311        //init network related - MPI will change argc and argv
312        // so pass as ref
313        QUANTAinit();
314        srand( (unsigned)time(NULL)); //initialise randon number generator
315/* Atul June 8 2004. Commented out the # since vNet is required for
316 * stand alone version also */
317#if defined(V_DISTRIBUTED)
318        net = new vNet();
319        net->init(argc,argv);
320#endif
321/* Atul June 8 2004 */
322
323#if defined(V_NETTF) //want transfer functions
324#if defined (V_DISTRIBUTED) //in distributed mode, only master has this instance
325        if (net->isActiveTile()) {
326                tfNet = new vTF();
327                tfNet->init();
328        }
329#else //in standalone instantiate it
330         tfNet = new vTF();
331         tfNet->init();
332#endif
333#endif
334
335        //command line parsing - stores argumenents in global.*
336        parseCmdLine(argc,argv);
337
338#ifdef V_DISTRIBUTED
339        if (net->isActiveTile()) {
340               setenv("DISPLAY", getenv("VOLATILE_DISPLAY"), 1);
341        }
342#endif
343
344        glutInit(&argc, argv);
345        glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
346        glutInitWindowSize(global.win.width, global.win.height);
347        glutInitWindowPosition(global.win.xPos, global.win.yPos);
348        global.mainWindow =     glutCreateWindow("Vol-a-Tile");
349
350#if defined(V_SAGE)
351#if defined (V_DISTRIBUTED)
352        if (!net->isActiveTile())
353        {
354                sageInf.init("sail.conf", "volatile", net->getRank()-1,
355                     global.win.width, global.win.height, 24, TVPIXFMT_888, BOTTOM_TO_TOP);
356                fprintf(stderr, "SAIL width %d height %d\n", global.win.width, global.win.height);
357        }
358#else
359    sageInf.init("sail.conf", "volatile", 0,
360                 global.win.width, global.win.height, 24, TVPIXFMT_888, BOTTOM_TO_TOP);
361#endif
362#endif
363
364#ifdef WIN32
365        LoadAllExtensions();
366#endif
367
368        initGL(); //opengl init stuff
369        //init the dependant textures
370        //initialize the dependant texture for transfer functions
371        //copy the good and interactive dependant textures
372        copyScale(global.volren.goodSamp, global.volren.gDeptex);
373        copyScale(global.volren.interactSamp, global.volren.iDeptex);
374        copyScale(0.3, global.volren.nDeptex);
375        global.volren.lastSamp = global.volren.goodSamp;
376        global.volren.lastGoodSamp = global.volren.goodSamp;
377        global.volren.lastInteSamp = global.volren.interactSamp;
378
379        loadDepTex(global.volren.scaledDeptexName,global.volren.gDeptex);
380        loadDepTex(global.volren.origDeptexName,global.volren.nDeptex);
381        //load the given 1D texture to CG
382
383
384#if defined(ADDCGGL)
385        //init the CG library
386#if defined (V_DISTRIBUTED)
387    if (!net->isActiveTile())
388#endif
389        initCG();  // Master doesn't need CG
390#endif
391
392#if defined(ADDARBGL)
393#if defined (V_DISTRIBUTED)
394    if (!net->isActiveTile())
395#endif
396        initARB(); //init the ARB OpenGL
397#endif
398
399        //start creating our objects
400        //creating renderer object
401        if (global.volume) {
402                vRenderer* renderer = new vRenderer();
403                renderer->setVolume(global.volume);
404                renderList.push_back(renderer);
405
406                if (global.fullVolume) {
407                        vRenderer* fullRenderer = new vRenderer;
408                        fullRenderer->setVolume(global.fullVolume);
409                        fullRenderer->disableCut();
410                        fullRenderer->enableShowOverview();
411                        fullRenderer->setTranslation(2.0,0.0,0.0);
412                        renderList.push_back(fullRenderer);
413                }
414                //slice view
415                vSliceView* view = new vSliceView;
416                renderList.push_back(view);
417                //the info
418                vVolText* text = new vVolText;
419                renderList.push_back(text);
420
421        }
422
423
424        //now create the FPS text
425        vFPSText* timerText = new vFPSText;
426        renderList.push_back(timerText);
427         //now create the pointer
428        //vPointer* ptr = new vPointer;
429        //renderList.push_back(ptr);
430
431        //initialise all the objects
432        for (int i=0;i<renderList.size();i++) {
433                renderList[i]->init();
434        }
435
436        GlErr("vRenderer", "init");
437
438#ifdef V_DISTRIBUTED
439        if (net->isActiveTile()) {
440                global.win.width  = 800;
441                global.win.height = 600;
442        }
443        else {
444        if (global.env.gameMode)
445            glutFullScreen();
446                glutSetCursor(GLUT_CURSOR_NONE);
447        }
448#else
449        if (global.env.gameMode)
450                glutFullScreen();
451#endif
452
453        glutDisplayFunc(display);
454        glutReshapeFunc(reshape);
455        glutMouseFunc(mouse);
456        glutMotionFunc(motion);
457        glutPassiveMotionFunc(passiveMotion);
458        glutKeyboardFunc(key);
459        glutSpecialFunc(special);
460        //only use idle when we are in standalone mode
461#ifndef V_DISTRIBUTED
462        glutIdleFunc(idle);
463#endif
464        buildPopupMenu ();
465    glutAttachMenu (GLUT_RIGHT_BUTTON);
466        //only master does the update and broadcasts it to client
467        //so that everyone is syncronized
468#ifdef V_DISTRIBUTED
469        //if (net->isActiveTile())
470        glutTimerFunc(50, updateAnim, 1);
471#else
472        glutTimerFunc(50, updateAnim, 1);
473#endif
474        glutMainLoop();
475        return 0;
476}
477
478void    initGlobal() {
479        global.volume = 0;
480        global.fullVolume = 0;
481
482        global.win.width  = 1024;      //size
483        global.win.height = 768;
484        global.win.xPos   = 0;      //position
485        global.win.yPos   = 0;
486        global.win.aspect = 1.0f;
487
488        global.env.eye[0]     = 0;    //eye
489        global.env.eye[1]     = 0;
490        global.env.eye[2]     = 10.0;
491        global.env.at[0]      = 0;    //at
492        global.env.at[1]      = 0;
493        global.env.at[2]      = 0;
494        global.env.up[0]      = 0;    //up
495        global.env.up[1]      = 1;
496        global.env.up[2]      = 0;
497        global.env.renderOn = true;
498
499        //create a default frustum
500        vFrustum newFrustum;
501        newFrustum.left = newFrustum.bottom = -1.0;
502        newFrustum.right= newFrustum.top = 1.0;
503        global.env.frustumList.push_back(newFrustum);
504
505        //create a default viewpoert
506        vViewport newViewport;
507        newViewport.x = newViewport.y = 0.0f;
508        newViewport.width = newViewport.height = 1.0f;
509        global.env.viewportList.push_back(newViewport);
510
511        global.env.clip[0]    = 1;    //front
512        global.env.clip[1]    = 50;   //back
513        global.env.bgColor    = 0;    //white background
514
515        global.mouse.alt     = 0;
516        global.mouse.ctrl    = 0;
517        global.mouse.shift   = 0;
518
519        //lighting
520        global.light.startpos[0] = -1.0f;
521        global.light.startpos[1] = -1.0f;
522        global.light.startpos[2] =-1.0f;
523        global.light.startpos[3] = 0.0f;
524
525        global.volren.interactSamp= .1;      //Interactive sample rate
526        global.volren.goodSamp    = 1.5;     //High quality sample ..
527        global.volren.sampleRate  = global.volren.goodSamp; //samples per voxel
528        global.volren.lowRes   = 0; //highres rendering
529        global.volren.deptex = new unsigned char[256*256*4];
530        for(int j=0; j<256; ++j){
531                for(int k=0; k<256; ++k){
532                        global.volren.deptex[j*256*4 + k*4 + 0] =  (unsigned char)(k/(float)255*255);
533                        global.volren.deptex[j*256*4 + k*4 + 1] =  (unsigned char)(255 - k/(float)255*255);
534                        global.volren.deptex[j*256*4 + k*4 + 2] =  (unsigned char)( k/(float)255*255);
535                        global.volren.deptex[j*256*4 + k*4 + 3] =  (unsigned char)(k/(float)255*255/(float)2);
536                }
537        }
538        global.volren.nDeptex = new unsigned char[256*4];
539        global.volren.gDeptex   = new unsigned char[256*4];
540        global.volren.iDeptex = new unsigned char[256*4];
541        global.volren.loadTLUT    = 1;       //first time - need to load LUT
542        global.volren.loadVolume = 0;           //no need to load the volume
543        global.volren.scaleAlphas = 1;       //scale alphas to the sample rate
544        global.volren.gamma       = 1;       //gamma identitiy
545        global.volren.probe[0] = global.volren.probe[1] = global.volren.probe[2] = 0;
546
547        identityMatrix(global.cut.transform);  //init the rotation
548        global.cut.user[0] = 1.0;
549        global.cut.user[1] = global.cut.user[2] = 0.0;
550        global.cut.user[3] = 0.5f;
551        global.cut.update = false;
552
553        global.ui.printFPS = false;
554        global.ui.printSlices = false;
555        global.ui.cutEnabled = false;
556        global.ui.bboxEnabled = true;
557        global.ui.navMode = V_ROAM;
558        global.ui.animate = false;
559
560        global.pointerPos[0] = global.pointerPos[1] = 0.0f;
561        global.pointerPos[2] = 1.0f;
562        global.curPrimIdx = 0;
563        cutTrack.clear();
564}
565
566
567void initGL( void )
568{
569        glClearColor(0.0, 0.0, 0.0, 1.0);
570        glShadeModel(GL_SMOOTH);
571        glEnable(GL_DEPTH_TEST);
572        glDepthFunc(GL_LEQUAL);
573        glLineWidth(3);
574        glGenTextures(1, &global.volren.scaledDeptexName);   //the dep tex that we use for the tf- passed to CG
575        glGenTextures(1, &global.volren.origDeptexName);   //the dep tex that we use for the tf- passed to CG
576        GlErr("v::","initGL()");
577}
578
579void display()
580{
581#ifdef V_DISTRIBUTED
582        net->process();
583#endif
584        update();
585        if (global.env.renderOn) {
586                int vpx, vpy, vpwidth, vpheight;
587                glEnable (GL_SCISSOR_TEST); //dont draw outside viewpott
588                //depending on no of viewports
589                for (int i=0;i<global.env.viewportList.size();i++) {
590                        vpx = global.env.viewportList[i].x*global.win.width;
591                        vpy = global.env.viewportList[i].y*global.win.height;
592                        vpwidth = global.env.viewportList[i].width*global.win.width;
593                        vpheight = global.env.viewportList[i].height*global.win.height;
594                        glViewport(vpx,vpy,vpwidth,vpheight);
595                        //cout<<"Viewport "<<vpx<<" "<<vpy<<" "<<vpwidth<<" "<<vpheight<<endl;
596                        glScissor (vpx,vpy,vpwidth,vpheight);
597                        displayOneEye(1,i); // our local display function
598                }
599                glDisable (GL_SCISSOR_TEST); //dont draw outside viewpott
600        }
601        else
602                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
603#ifdef V_DISTRIBUTED
604        net->sync();
605#endif
606
607
608#if defined(V_SAGE)
609#if defined (V_DISTRIBUTED)
610        if (!net->isActiveTile())
611#endif
612        if (winWidth > 0)
613        {
614            glReadPixels(0, 0, winWidth, winHeight, GL_RGB, GL_UNSIGNED_BYTE, rgbBuffer);
615            sageInf.swapBuffer((void *)rgbBuffer);
616        }
617#endif
618
619        glutSwapBuffers();
620        GlErr("v:","disp()");
621}
622
623void displayOneEye(int eye, int vpIndex)
624{
625        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
626        //dont draw anything on the master
627        glPushMatrix();
628        {
629                glMatrixMode(GL_MODELVIEW);
630                glLoadIdentity();
631                gluLookAt(global.env.eye[0],  //eye
632                                global.env.eye[1],
633                                global.env.eye[2],
634                                global.env.at[0],   //at
635                                global.env.at[1],
636                                global.env.at[2],
637                                global.env.up[0],
638                                global.env.up[1],
639                                global.env.up[2]);          //up
640
641                GLfloat light_pos[] = { 5.0, 5.0, 5.0,1.0 };
642                glEnable(GL_LIGHTING);
643                glEnable(GL_LIGHT0);
644                glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
645                glMatrixMode(GL_PROJECTION);
646                glLoadIdentity();
647                glFrustum(global.env.frustumList[vpIndex].left, //left
648                        global.env.frustumList[vpIndex].right, //right
649                        global.env.frustumList[vpIndex].bottom , //bottom
650                        global.env.frustumList[vpIndex].top, //top
651                        global.env.clip[0],    //front
652                        global.env.clip[1]);   //back
653
654                /*cout<<"Frustrum "<<global.env.frustumList[vpIndex].left<<" "
655                        <<global.env.frustumList[vpIndex].right<<" "
656                        <<global.env.frustumList[vpIndex].bottom<<" "
657                        <<global.env.frustumList[vpIndex].top<<" "
658                        <<endl;
659                        */
660                glMatrixMode(GL_MODELVIEW);
661                for (int i=0;i<renderList.size();i++) {
662                        renderList[i]->draw();
663                }
664                renderList[global.curPrimIdx]->setSelected(true);
665
666        } glPopMatrix();
667}
668
669void mouse(int button, int state, int x, int y)
670{
671        y = global.win.height - y;
672        global.mouse.button = button;
673        global.mouse.state  = state;
674
675        if(glutGetModifiers() & GLUT_ACTIVE_CTRL) global.mouse.ctrl = 1;
676        else global.mouse.ctrl = 0;
677        if(glutGetModifiers() & GLUT_ACTIVE_SHIFT) global.mouse.shift = 1;
678        else global.mouse.shift = 0;
679        if(glutGetModifiers() & GLUT_ACTIVE_ALT) global.mouse.alt = 1;
680        else global.mouse.alt = 0;
681        if(state == GLUT_UP){
682                global.mouse.button = -1;
683        }
684        //get the global coords
685
686#if defined(V_DISTRIBUTED)
687        if (!net->cmdFlushed)
688                return;
689#endif
690        //standard button actions...
691        switch(button){
692        case GLUT_LEFT_BUTTON:
693                {
694                        if (global.mouse.ctrl) { //emulate right button
695                                switch(state)
696                                {
697                                case GLUT_UP:
698                                        endInteract();
699                                        break;
700                                case GLUT_DOWN:
701                                        startZoom(x,y);
702                                        break;
703                                }
704                        }
705                        else {
706                                switch(state)
707                                {
708                                case GLUT_UP:
709                                        endInteract();
710                                        break;
711                                case GLUT_DOWN:
712                                        startRotation(x,y);
713                                        break;
714                                }
715                        }
716                }
717                break;
718        case GLUT_RIGHT_BUTTON:
719                {
720                        switch(state)
721                        {
722                        case GLUT_UP:
723                                endInteract();
724                                break;
725                        case GLUT_DOWN:
726                                startZoom(x,y);
727                                break;
728                        }
729                }
730                break;
731        case GLUT_MIDDLE_BUTTON:
732                {
733                        switch(state)
734                        {
735                        case GLUT_UP:
736                                endInteract();
737                                break;
738                        case GLUT_DOWN:
739                                startTranslate(x,y);
740                                break;
741                        }
742                }
743                break;
744        default:
745                break;
746        }
747}
748
749void passiveMotion(int x, int y) {
750global.mouse.pos[0] = x;
751y = global.win.height-y;
752
753        //get the global coords
754//      doSelect(x,y);
755}
756
757void motion(int x, int y)
758{
759#if defined(V_DISTRIBUTED)
760        if (!net->cmdFlushed)
761                return;
762#endif
763        y = global.win.height-y;
764        //get the global coords
765        switch(global.mouse.button)     {
766        case GLUT_LEFT_BUTTON:
767                {
768                        if (global.mouse.ctrl) { //emulate right button
769                                switch(global.mouse.state)
770                                {
771                                case GLUT_DOWN:
772                                        doZoom(x,y);
773                                        break;
774                                case GLUT_UP:
775                                        break;
776                                }
777                        }
778                        else {
779                                switch(global.mouse.state)
780                                {
781                                case GLUT_DOWN:
782                                        doRotation(x,y);
783                                        break;
784                                case GLUT_UP:
785                                        break;
786                                }
787                        }
788                }
789                break;
790        case GLUT_RIGHT_BUTTON:
791                {
792                        switch(global.mouse.state)
793                        {
794                        case GLUT_DOWN:
795                                doZoom(x,y);
796                                break;
797                        case GLUT_UP:
798                                break;
799                        }
800                }
801                break;
802        case GLUT_MIDDLE_BUTTON:
803                {
804                        switch(global.mouse.state)
805                        {
806                        case GLUT_DOWN:
807                                doTranslate(x,y);
808                                break;
809                        case GLUT_UP:
810                                break;
811                        }
812                }
813                break;
814        default:
815                break;
816        }
817}
818
819void key(unsigned char key, int x, int y)
820{
821#if defined(V_DISTRIBUTED)
822        if (!net->cmdFlushed)
823                return;
824#endif
825
826        y = global.win.height-y;
827        switch(key) {
828        case '\033': //escape
829                doExit();
830                break;
831        case 'b':
832        case 'B':
833                toggleBoundBox();
834                break;
835        case 'c':
836        case 'C':
837                toggleCutPlane();
838                break;
839        case 'f':
840        case 'F':
841                togglePrintFPS();
842                break;
843        case 'g':
844        case 'G':
845                saveGradientVolume();
846                break;
847        case 'h':
848        case 'H':
849                printUsage();
850                break;
851        case 'i':
852        case 'I':
853                genIsosurface(x,y);
854                break;
855        case 'j':
856        case 'J':
857                //genIsopoint(x,y);
858                break;
859//      case 'n':
860//      case 'N':
861//              global.ui.printSlices = !global.ui.printSlices;
862//              break;
863        case 'o':
864        case 'O':
865                global.volume->saveVolume("out");
866                break;
867        case 'p': //to probe volumes
868        case 'P':
869                setProbe();
870                break;
871        case 'r':
872        case 'R':
873                setRoam();
874                break;
875        case '+':
876                //increase the number of slices
877                scaleSampleRate(1.1);
878                break;
879        case '-':
880                //decrease the number of slices
881                scaleSampleRate(0.9);
882                break;
883        case '.':
884                //increase isosurface value
885                incIsoValue(15);
886                break;
887        case ',':
888                //decrease isosurface value
889                incIsoValue(-15);
890                break;
891        case ' ':
892                animateVolume();
893                break;
894        case 8: //backspace key
895                global.curPrimIdx--;
896                if (global.curPrimIdx < 0)
897                        global.curPrimIdx = renderList.size()-1;
898                doSelect(global.curPrimIdx);
899                break;
900
901        case 9: //tab key
902                global.curPrimIdx++;
903                if (global.curPrimIdx >= renderList.size())
904                        global.curPrimIdx = 0;
905                doSelect(global.curPrimIdx);
906                break;
907
908        }
909}
910
911
912void special(int key, int x, int y)
913{
914        int ROAM = global.volume->maxDim/2;
915
916#if defined(V_DISTRIBUTED)
917        if (!net->cmdFlushed)
918                return;
919#endif
920        switch(key){
921    case GLUT_KEY_UP:
922                if (global.ui.navMode == V_ROAM)
923                        roamVolume(0,ROAM,0);
924                else if (global.ui.navMode == V_PROBE) {
925                        probeVolume(0,1,0);
926                }
927                else
928                        doAxisRotation(-1.0f,'x');
929                break;
930    case GLUT_KEY_DOWN:
931                if (global.ui.navMode == V_ROAM)
932                        roamVolume(0,-ROAM,0);
933                else if (global.ui.navMode == V_PROBE)
934                        probeVolume(0,-1,0);
935                else
936                        doAxisRotation(1.0f,'x');
937                break;
938    case GLUT_KEY_RIGHT:
939                if (global.ui.navMode == V_ROAM)
940                        roamVolume(ROAM,0,0);
941                else if (global.ui.navMode == V_PROBE)
942                        probeVolume(1,0,0);
943                else
944                        doAxisRotation(1.0f,'y');
945                break;
946    case GLUT_KEY_LEFT:
947                if (global.ui.navMode == V_ROAM)
948                        roamVolume(-ROAM,0,0);
949                else if (global.ui.navMode == V_PROBE)
950                        probeVolume(-1,0,0);
951                else
952                        doAxisRotation(-1.0f,'y');
953                break;
954    case GLUT_KEY_PAGE_UP: //increase eye sep
955                if (global.ui.navMode == V_ROAM)
956                        roamVolume(0,0,-ROAM);
957                else if (global.ui.navMode == V_PROBE)
958                        probeVolume(0,0,-1);
959                else if (global.env.stereoType)
960                        global.stereo.halfEyeSep +=0.05;
961                break;
962    case GLUT_KEY_PAGE_DOWN: //decrease eye sep
963                if (global.ui.navMode == V_ROAM)
964                        roamVolume(0,0,ROAM);
965                else if (global.ui.navMode == V_PROBE)
966                        probeVolume(0,0,1);
967                else if (global.env.stereoType)
968                        global.stereo.halfEyeSep -=0.05;
969                break;
970        }
971}
972
973void idle() {
974        display();
975        QUANTAusleep(100);
976}
977
978void reshape(int w, int h)
979{
980        GlErr("vRenderer","testing");
981        glMatrixMode(GL_MODELVIEW);
982        global.win.width  = w;
983        global.win.height = h;
984#ifndef V_DISTRIBUTED
985        global.win.aspect = (float)global.win.width/(float)global.win.height;
986#endif
987
988#if defined(V_SAGE)
989    winWidth = w;
990    winHeight = h;
991    if (rgbBuffer)
992        delete [] rgbBuffer;
993    rgbBuffer = new GLubyte[w*h*3];
994#endif
995
996        glutPostRedisplay();
997}
998
999void parseCmdLine(int argc, char **argv)
1000{
1001        CCmdLine cmdLine; // our cmd line parser object
1002        if (cmdLine.SplitLine(argc, argv) < 1) {
1003                // no switches were given on the command line, abort
1004                exit(-1);
1005        }
1006        // test for the 'help' case
1007        if (cmdLine.HasSwitch("-h")) {
1008                printUsage();
1009                exit(0);
1010        }
1011#if defined(V_NETDATA)
1012        bool ok = false;
1013        // remote data - get IP and volume symbolic name
1014        if (cmdLine.HasSwitch("-v")) {
1015                //get the symbolic name of the volume
1016                string volName = cmdLine.GetArgument("-v",0);
1017                //get the server IP
1018                string serverIPFile = cmdLine.GetSafeArgument("-v",1,"optiserver.dat");
1019                //open the file check the server IP for my rank
1020                char serverIP[256];
1021
1022#ifdef V_DISTRIBUTED
1023                strcpy(serverIP,getServerIP(net->getRank(),serverIPFile.c_str()));
1024#else
1025                strcpy(serverIP, serverIPFile.c_str());
1026#endif
1027
1028                global.volume = new vOptiVolume(volName.c_str(), serverIP);
1029                if (cmdLine.GetArgumentCount("-v") > 2) {//also have thumbnail volume
1030                        string fullVolName= cmdLine.GetArgument("-v",2);
1031                        global.fullVolume = new vOptiVolume(fullVolName.c_str(), serverIP);
1032                }
1033                ok = true;
1034
1035        }
1036        if (cmdLine.HasSwitch("-i")) {
1037                string wild = cmdLine.GetArgument("-i",0);
1038                cerr <<"wildcard "<<wild<<endl;
1039                //the numFiles arg is the server IP
1040                string serverIPFile = cmdLine.GetSafeArgument("-v",1,"optiserver.dat");
1041                //open the file check the server IP for my rank
1042                char serverIP[256];
1043
1044#ifdef V_DISTRIBUTED
1045                strcpy(serverIP,getServerIP(net->getRank(),serverIPFile.c_str()));
1046#else
1047                strcpy(serverIP, serverIPFile.c_str());
1048#endif
1049
1050                float scale = 1.0f;
1051                if (cmdLine.GetArgumentCount("-i") > 2) {//also have thumbnail volume
1052                        string scaleStr = cmdLine.GetArgument("-i",2);
1053                        scale = atof(scaleStr.c_str());
1054                }
1055
1056                vGeometry* newGeom = new vGeometry((char*)wild.c_str(),(char*)serverIP,scale);
1057                renderList.push_back(newGeom);
1058                ok = true;
1059        }
1060        if (!ok) {
1061                fprintf(stderr,"Specify -v or -i option\n");
1062                exit(-1);
1063        }
1064
1065
1066#else
1067        //local, specify filename and filedimensions
1068        try {
1069                string filename = cmdLine.GetArgument("-f", 0);
1070                string x, y, z;
1071                x = cmdLine.GetArgument( "-f", 1);
1072                y = cmdLine.GetArgument( "-f", 2);
1073                z = cmdLine.GetArgument( "-f", 3);
1074                global.volume = new vFileVolume(filename.c_str(),
1075                                atoi(x.c_str()), atoi(y.c_str()), atoi(z.c_str()));
1076        }
1077        catch (...)
1078        {
1079                // one of the required arguments was missing, abort
1080                exit(-1);
1081        }
1082
1083        //load gradient volume
1084        if (cmdLine.HasSwitch("-g")) {
1085                ((vFileVolume*)global.volume)->gradientFile = strdup(cmdLine.GetArgument("-g",0).c_str());
1086        }
1087#endif
1088        if (global.volume) {
1089                //now get the volume offset, if any - 0 by default
1090                global.volume->offsetX= atoi(cmdLine.GetSafeArgument( "-o", 0, "0").c_str());
1091                global.volume->offsetY = atoi(cmdLine.GetSafeArgument( "-o", 1, "0").c_str());
1092                global.volume->offsetZ = atoi(cmdLine.GetSafeArgument( "-o", 2, "0").c_str());
1093        }
1094
1095        //get screen width and height
1096        if (cmdLine.HasSwitch("-w")) {
1097                global.win.width  = atoi(cmdLine.GetSafeArgument("-w", 0, "512").c_str());
1098                global.win.height = atoi(cmdLine.GetSafeArgument("-w", 1, "512").c_str());
1099                global.win.aspect = (float)global.win.width/(float)global.win.height;
1100        }
1101        else
1102                global.env.gameMode = true;
1103
1104#ifdef V_DISTRIBUTED
1105        if (cmdLine.HasSwitch("-a")) {
1106                global.win.aspect = atof(cmdLine.GetSafeArgument("-a", 0, "1.0").c_str());
1107        }
1108#endif
1109        calcFrustum();
1110        //get the voxel spacing
1111        if (cmdLine.HasSwitch("-sp")) {
1112                if (global.volume) {
1113                        //now get the volume offset, if any - 0 by default
1114                        global.volume->spacingX= atof(cmdLine.GetSafeArgument( "-sp", 0, "0").c_str());
1115                        global.volume->spacingY = atof(cmdLine.GetSafeArgument( "-sp", 1, "0").c_str());
1116                        global.volume->spacingZ = atof(cmdLine.GetSafeArgument( "-sp", 2, "0").c_str());
1117                }
1118                if (global.fullVolume) {
1119                        //now get the volume offset, if any - 0 by default
1120                        global.fullVolume->spacingX= atof(cmdLine.GetSafeArgument( "-sp", 0, "0").c_str());
1121                        global.fullVolume->spacingY = atof(cmdLine.GetSafeArgument( "-sp", 1, "0").c_str());
1122                        global.fullVolume->spacingZ = atof(cmdLine.GetSafeArgument( "-sp", 2, "0").c_str());
1123                }
1124        }
1125
1126        //get the texture volume dimensions
1127        if (global.volume) {
1128                try
1129                {
1130                        string x = cmdLine.GetArgument("-d", 0);
1131                        string y = cmdLine.GetArgument( "-d", 1);
1132                        string z = cmdLine.GetArgument( "-d", 2);
1133                        global.volume->load(atoi(x.c_str()), atoi(y.c_str()), atoi(z.c_str()));
1134                }
1135                catch (...)
1136                {
1137                        fprintf(stderr,"Missing args to -d command line option\n");
1138                        exit(-1);
1139                }
1140        }
1141        if (global.fullVolume) //load full volume
1142                global.fullVolume->load();
1143
1144
1145#if defined(V_DISTRIBUTED)
1146        char tileConfigFile[256];
1147        try
1148        {   // if any of these GetArgument calls fail,
1149                // we'll end up in the catch() block
1150                // filename
1151                strcpy(tileConfigFile, cmdLine.GetArgument("-n", 0).c_str());
1152        }
1153        catch (...)
1154        {
1155                // one of the required arguments was missing, abort
1156                exit(-1);
1157        }
1158        //init mpi related stuff
1159        net->readTileConfig(tileConfigFile);
1160        if (net->isActiveTile()) { //master
1161                global.env.renderOn = false;
1162        }
1163#endif
1164
1165        global.env.stereoType = (vStereoType)(atoi(cmdLine.GetSafeArgument( "-s", 0, "0").c_str()));
1166        global.stereo.halfEyeSep = 0.25;
1167}
1168
Note: See TracBrowser for help on using the repository browser.