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

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

Added modified SAGE sources

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