00001
00006 #include <iostream>
00007 #include <glui.h>
00008 #include <glut.h>
00009 #include <sstream>
00010
00011 #include "LifeVariables.h"
00012
00013 using namespace std;
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00025 int xResolution = X_RES;
00026
00028 int yResolution = Y_RES;
00029
00031 int mainWindow = 0;
00032
00034 RawReader *reader = NULL;;
00035
00037 MenuBar *menuBar = NULL;;
00038
00040 StateBar *stateBar = NULL;;
00041
00043 FileDialog *fileDialog = NULL;;
00044
00046 OptionPanel *optionPanel = NULL;
00047
00049 Histogram *histogram = NULL;
00050
00052 ViewPort *mainViewPort = NULL;
00053
00055 int mouseBtn = -1;
00056
00059 ColorCubePanel *colorSelector = NULL;
00060
00063 ProgramState currentProgramState = START;
00064
00067 bool debugMode = DEBUG_MODE;
00068
00070 CVolVoxels GVolVoxels;
00071
00073 CDensities GDensities;
00074
00076 CTex GTex;
00077
00079 CScanner GScanner;
00080
00081
00082
00084 bool refresh = true;
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00098 void showGlDebugMessages() {
00099 switch (glGetError()) {
00100 case GL_NO_ERROR: break;
00101 case GL_INVALID_ENUM:
00102 cout << "GL_INVALID_ENUM: An unacceptable value is specified for an enumerated argument." << endl;
00103 break;
00104 case GL_INVALID_VALUE:
00105 cout << "GL_INVALID_VALUE: A numeric argument is out of range." << endl;
00106 break;
00107 case GL_INVALID_OPERATION:
00108 cout << "GL_STACK_OVERFLOW: The specified operation is not allowed in the current state." << endl;
00109 break;
00110 case GL_STACK_OVERFLOW:
00111 cout << "GL_STACK_OVERFLOW: This function would cause a stack overflow." << endl;
00112 break;
00113 case GL_STACK_UNDERFLOW:
00114 cout << "GL_STACK_UNDERFLOW: This function would cause a stack underflow." << endl;
00115 break;
00116 case GL_OUT_OF_MEMORY:
00117 cout << "GL_OUT_OF_MEMORY: There is not enough memory left to execute the function." << endl;
00118 break;
00119 default: break;
00120 }
00121 }
00122
00123
00126 void renderString(int x, int y, void *font, int nr) {
00127 string text="";
00128 ostringstream outStream;
00129 outStream << nr;
00130 text = outStream.str();
00131 renderString(x,y,font,text);
00132 }
00133
00134
00137 void renderString(int x, int y, void *font, string text) {
00138 glRasterPos2i(x, y);
00139 for(int i = 0; i < text.length(); i++) {
00140 glutBitmapCharacter(font, text[i]);
00141 }
00142 }
00143
00144 extern void RenderVolume();
00145
00146
00149 void display() {
00150
00151 glMatrixMode(GL_MODELVIEW);
00152 glLoadIdentity();
00153
00154
00155 glClearColor(0.0,0.0,0.0,0.0);
00156
00157
00158 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00159
00160 glViewport(mainViewPort->x,
00161 mainViewPort->y+HISTOGRAM_WND_HEIGHT/2,
00162 mainViewPort->w,
00163 mainViewPort->h);
00164
00165
00166 switch(currentProgramState) {
00167
00168 case VOLUME_MODE:
00169
00170
00171
00172
00173 colorSelector->render();
00174
00175 histogram->render(mainViewPort->x,
00176 mainViewPort->y,
00177 mainViewPort->w,
00178 HISTOGRAM_WND_HEIGHT);
00179
00180 GScanner.ScanVolume();
00181
00182 GTex.RenderVolumeSubTexture();
00183
00184
00185
00186
00187
00188
00189 break;
00190
00191
00192 case SLICE_MODE:
00193 colorSelector->render();
00194
00195 histogram->render(mainViewPort->x,
00196 mainViewPort->y,
00197 mainViewPort->w,
00198 HISTOGRAM_WND_HEIGHT);
00199
00200
00201
00202 if(GVolVoxels.GetDimX()) {
00203 GTex.RenderSubTexture();
00204 }
00205 break;
00206
00207
00208
00209 case UNLOADING:
00210 break;
00211
00212
00213
00214 case LOADING:
00215 break;
00216
00217
00218 default:
00219 break;
00220
00221 }
00222
00223 if(debugMode) {
00224 showGlDebugMessages();
00225 }
00226
00227 glutSwapBuffers();
00228 }
00229
00230
00231
00234 void reshape(int x, int y) {
00235 GLUI_Master.get_viewport_area(&mainViewPort->x,
00236 &mainViewPort->y,
00237 &mainViewPort->w,
00238 &mainViewPort->h);
00239
00240 glViewport(mainViewPort->x,
00241 mainViewPort->y+HISTOGRAM_WND_HEIGHT/2,
00242 mainViewPort->w,
00243 mainViewPort->h);
00244
00245 glMatrixMode(GL_PROJECTION);
00246 glLoadIdentity();
00247
00248 if (mainViewPort->w <= mainViewPort->h) {
00249 glOrtho(-2.0,
00250 2.0,
00251 -2.0 * (GLfloat) mainViewPort->h / (GLfloat) mainViewPort->w,
00252 2.0 * (GLfloat) mainViewPort->h / (GLfloat) mainViewPort->w,
00253 -3.0,
00254 3.0);
00255 }
00256 else {
00257 glOrtho(-2.0 * (GLfloat) mainViewPort->w / (GLfloat) mainViewPort->h,
00258 2.0 * (GLfloat) mainViewPort->w / (GLfloat) mainViewPort->h,
00259 -2.0,
00260 2.0,
00261 -3.0,
00262 3.0);
00263 }
00264
00265 colorSelector->refreshDragBounds(x, y);
00266 xResolution = x;
00267 yResolution = y;
00268 glutPostRedisplay();
00269 glMatrixMode(GL_MODELVIEW);
00270
00271 }
00272
00273
00276 void idle() {
00277 Sleep(10);
00278 glutSetWindow(mainWindow);
00279 GLUI_Master.sync_live_all();
00280 }
00281
00282
00284 void enterUnloadedMode() throw(Error) {
00285 if(currentProgramState == SLICE_MODE) {
00286
00287 currentProgramState = UNLOADING;
00288 if(debugMode == true) cout << "currentProgramState = UNLOADING" << endl;
00289
00290
00291 optionPanel->disable();
00292
00293
00294
00295 GTex.Shutdown();
00296 GDensities.Shutdown();
00297 GVolVoxels.Shutdown();
00298
00299 currentProgramState = UNLOADED;
00300 if(debugMode == true) cout << "currentProgramState = UNLOADED" << endl;
00301 return;
00302 }
00303
00304 else if(currentProgramState == VOLUME_MODE) {
00305
00306 currentProgramState = UNLOADING;
00307 stateBar->updateRenderInfo("Unloading file");
00308 if(debugMode == true) cout << "currentProgramState = UNLOADING" << endl;
00309
00310
00311 optionPanel->disable();
00312
00313
00314
00315
00316
00317 currentProgramState = UNLOADED;
00318 if(debugMode == true) cout << "currentProgramState = UNLOADED" << endl;
00319 stateBar->updateRenderInfo("Unloading complete");
00320 }
00321
00322 else if (currentProgramState == START ) {
00323 return;
00324 }
00325
00326 else {
00327 throw Error("Can not unload data.");
00328 }
00329 }
00330
00331
00333 void enterLoadedMode() throw (Error) {
00334 if((currentProgramState == START) || (currentProgramState == UNLOADED)) {
00335 currentProgramState = LOADING;
00336 stateBar->updateFileInfo("-");
00337 stateBar->updateRenderInfo("Loading File...");
00338 if(debugMode == true) cout << "currentProgramState = LOADING" << endl;
00339
00340
00341 reader->open(menuBar->selectedFile);
00342 currentProgramState = LOADED;
00343 if(debugMode == true) cout << "currentProgramState = LOADED" << endl;
00344 stateBar->updateRenderInfo("Loading complete");
00345 return;
00346 }
00347 else {
00348 throw Error("Can not load data.");
00349 }
00350 }
00351
00352
00354 void enterSlicingMode() throw (Error) {
00355
00356 if(currentProgramState == LOADED) {
00357 stateBar->updateRenderInfo("Preparing Data...");
00358
00359 GVolVoxels.Init(reader->voxelData,
00360 reader->dimX,
00361 reader->dimY,
00362 reader->dimZ);
00363
00364 histogram->update(reader->voxelData, reader->size);
00365
00366
00367
00368 optionPanel->enableModeSelection();
00369
00370
00371 optionPanel->switchRenderMode(SLICE_VISUALISATION);
00372
00373
00374 optionPanel->updateSliceMax(reader->dimX, reader->dimY, reader->dimZ);
00375
00376
00377 stateBar->updateFileInfo(reader->fileInfoString);
00378 stateBar->updateRenderInfo("Slice Visualisation");
00379
00380 currentProgramState = SLICE_MODE;
00381 if(debugMode == true) cout << "currentProgramState = SLICE_MODE" << endl;
00382 }
00383
00384 else if(currentProgramState == VOLUME_MODE) {
00385
00386 currentProgramState = SWITCHING;
00387 if(debugMode == true) cout << "currentProgramState = SWITCHING" << endl;
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403 optionPanel->switchRenderMode(SLICE_VISUALISATION);
00404 stateBar->updateRenderInfo("Slice Visualisation");
00405
00406 currentProgramState = SLICE_MODE;
00407 if(debugMode == true) cout << "currentProgramState = SLICE_MODE" << endl;
00408 }
00409 else {
00410 throw Error("Can not enter Slice Mode.");
00411 }
00412 }
00413
00414
00416 void enterVolumeMode() throw (Error){
00417 if(currentProgramState == SLICE_MODE) {
00418
00419 currentProgramState = SWITCHING;
00420 if(debugMode == true) cout << "currentProgramState = SWITCHING" << endl;
00421
00422 optionPanel->switchRenderMode(VOLUME_VISUALISATION);
00423 stateBar->updateRenderInfo("Volume Visualisation");
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439 currentProgramState = VOLUME_MODE;
00440 if(debugMode == true) cout << "currentProgramState = VOLUME_MODE" << endl;
00441 eventListener(REFRESH_ID);
00442 }
00443 else {
00444 throw Error("Can not enter Volume Mode.");
00445 }
00446 }
00447
00448
00449
00453 void eventListener(int control) {
00454
00455 ProgramState oldState = currentProgramState;
00456
00457 switch(control) {
00458
00459
00460 case REFRESH_ID:
00461
00462
00463
00464
00465
00466 refresh = true;
00467 GScanner.direction = optionPanel->viewingDirection;
00468 GScanner.Init();
00469 cout << "REFRESH_ID" << endl;
00470 break;
00471
00472
00473 case OPEN_FILE_ID:
00474 try {
00475 enterUnloadedMode();
00476 enterLoadedMode();
00477 enterSlicingMode();
00478 }
00479 catch (Error e){
00480 cout << e.getErrorMsg() << endl;
00481 currentProgramState = oldState;
00482 }
00483 break;
00484
00485
00486 case MODESELECT_ID:
00487 if(currentProgramState == SLICE_MODE) {
00488 enterVolumeMode();
00489 }
00490 else {
00491 enterSlicingMode();
00492 }
00493 break;
00494
00495
00496 case PLANESELECT_ID:
00497 optionPanel->updateSliceMax(reader->dimX, reader->dimY, reader->dimZ);
00498 break;
00499
00500
00501 case TXFUNCTIONSELECT_ID:
00502 if(optionPanel->txFunction == XRAY) {
00503 optionPanel->disableMipSpinners();
00504 }
00505 else if(optionPanel->txFunction == COMPOSITING) {
00506 optionPanel->disableMipSpinners();
00507 }
00508 else if (optionPanel->txFunction == FIRST_HIT) {
00509 optionPanel->enableMipSpinners();
00510 }
00511 else if (optionPanel->txFunction == MIP) {
00512 optionPanel->disableMipSpinners();
00513 }
00514 break;
00515
00516
00517
00518
00519 case VIEWINGDIRECTION_ID:
00520 GScanner.direction = optionPanel->viewingDirection;
00521 cout << GScanner.direction << endl;
00522 break;
00523
00524
00525 case SHOWOPENFILEDLG_ID:
00526 fileDialog->show();
00527 break;
00528
00529
00530 case CONFIRMOPENFILEDLG_ID:
00531 fileDialog->confirm();
00532 try {
00533 reader->openPath(fileDialog->path);
00534 menuBar->updateFileList();
00535 optionPanel->disable();
00536 }
00537 catch (Error e) {
00538 fileDialog->show(e.getError());
00539 }
00540 break;
00541
00542
00543 case CANCELOPENFILEDLG_ID:
00544 fileDialog->hide();
00545 break;
00546
00547
00548 default: break;
00549 }
00550 glutSetWindow(mainWindow);
00551 GLUI_Master.sync_live_all();
00552
00553
00554
00555 display();
00556 }
00557
00558
00559
00561 void deInit() {
00562 delete fileDialog;
00563 delete optionPanel;
00564 delete stateBar;
00565 delete menuBar;
00566 delete reader;
00567 delete histogram;
00568 delete mainViewPort;
00569 }
00570
00571
00575 void keyEvent(unsigned char key, int x, int y) {
00576 switch(key) {
00577 case 27:
00578
00579 exit(0);
00580 case 127:
00581 histogram->updating();
00582 histogram->removeControlPoint();
00583 histogram->enable();
00584 display();
00585 break;
00586 default:
00587 cout << "Key '"<< key <<"' is not assigned! (Press Esc to quit)" << endl;
00588 break;
00589 }
00590 display();
00591 }
00592
00593
00600 void mouseEvent(int button, int state, int x, int y) {
00601
00602
00603 y = yResolution - y;
00604
00605 if((button == GLUT_LEFT_BUTTON)&&(state == GLUT_DOWN)) {
00606 mouseBtn = GLUT_LEFT_BUTTON;
00607 histogram->onLeftMouseClick(x,y);
00608
00609
00610 if(colorSelector->onMouseDown(x,y)) {
00611 histogram->enable();
00612 }
00613 display();
00614 }
00615
00616 else if((button == GLUT_RIGHT_BUTTON)&&(state == GLUT_DOWN)) {
00617 mouseBtn = GLUT_RIGHT_BUTTON;
00618
00619
00620 if(histogram->onRightMouseClick(x,y)) {
00621
00622 colorSelector->moveTo(x,y);
00623
00624 colorSelector->enable();
00625 colorSelector->point = histogram->grabbedPoint;
00626 }
00627 }
00628 else if((button == GLUT_WHEEL_UP)&&(state != GLUT_DOWN)) {
00629 mouseBtn = GLUT_WHEEL_UP;
00630 if(currentProgramState == SLICE_MODE) {
00631 optionPanel->incSlice();
00632 }
00633
00634 }
00635
00636 else if((button == GLUT_WHEEL_DOWN)&&(state != GLUT_DOWN)) {
00637 mouseBtn = GLUT_WHEEL_DOWN;
00638 if(currentProgramState == SLICE_MODE) {
00639 optionPanel->decSlice();
00640 }
00641
00642 }
00643
00644 if(state == GLUT_UP) {
00645 mouseBtn = -1;
00646 }
00647 display();
00648 }
00649
00650
00651 void mouseMotionEvent(int x, int y) {
00652
00653 if(mouseBtn == GLUT_LEFT_BUTTON) {
00654
00655 y = yResolution - y;
00656 histogram->onMouseDrag(x,y);
00657 }
00658 else if(mouseBtn == GLUT_RIGHT_BUTTON) {
00659 colorSelector->onMouseDrag(x,y);
00660 }
00661 display();
00662 }
00663
00664
00670 void main(int argc, char* argv[]) {
00671
00672 glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH );
00673 glutInitWindowPosition(50, 50);
00674
00675 glutInitWindowSize(xResolution, yResolution);
00676 mainWindow = glutCreateWindow("Volume Visualiser 0.2");
00677 glutDisplayFunc(display);
00678 glutReshapeFunc(reshape);
00679 glutKeyboardFunc(keyEvent);
00680 glutMotionFunc(mouseMotionEvent);
00681
00682 GLUI_Master.set_glutReshapeFunc(reshape);
00683 GLUI_Master.set_glutKeyboardFunc(keyEvent);
00684 GLUI_Master.set_glutMouseFunc(mouseEvent);
00685 GLUI_Master.set_glutIdleFunc(idle);
00686
00687 glEnable(GL_DEPTH_TEST);
00688 glEnable(GL_TEXTURE_2D);
00689 glShadeModel(GL_SMOOTH);
00690 glEnable(GL_COLOR_MATERIAL);
00691
00692 reader = new RawReader();
00693
00694 menuBar = new MenuBar(mainWindow,GLUI_SUBWINDOW_TOP);
00695
00696 stateBar = new StateBar(mainWindow,GLUI_SUBWINDOW_BOTTOM);
00697
00698 optionPanel = new OptionPanel(mainWindow,GLUI_SUBWINDOW_LEFT);
00699
00700 mainViewPort = new ViewPort();
00701
00702 histogram = new Histogram();
00703
00704 fileDialog = new FileDialog();
00705 fileDialog->hide();
00706
00707 colorSelector = new ColorCubePanel();
00708
00709 glutMainLoop();
00710 }