00001 #include <string>
00002 #include <vector>
00003 #include <iostream>
00004
00005 #include <GL/glew.h>
00006 #include <GL/glut.h>
00007
00008 #include "VObject.h"
00009 #include "GUIelement.h"
00010 #include "VMenuStarter.h"
00011 #include "VTransferFunctionElement.h"
00012 #include "VSliceElement.h"
00013 #include "VMenu.h"
00014 #include "VRenderMode.h"
00015 #include "VAxisAlignElement.h"
00016 #include "VCamera.h"
00017
00018 using namespace std;
00019
00020 GLfloat light_position[] = { 1000.0, 1000.0, 1000.0, 1.0 };
00021
00022 unsigned int fpsCurrent = 0;
00023 unsigned int fpsCount = 0;
00024 unsigned long tick;
00025
00026 int renderMode;
00027
00028 GLhandleARB p,v,f;
00029
00030 string filename = "data/lobster.dat";
00031
00032 VObject * obj;
00033 VMenu * menu;
00034 VCamera * camera;
00035 vector<GUIelement*> elements;
00036
00037 int width = 800;
00038 int height = 600;
00039
00040 bool dragging = false;
00041 bool alt = false;
00042
00043 bool slicing = false;
00044
00045 bool operator < (const VTransferFunctionNode& n1, const VTransferFunctionNode& n2)
00046 {
00047 return n1.x < n2.x;
00048 }
00049
00050 void drawcoordinate(){
00051
00052
00053 glBegin(GL_LINES);
00054
00055 glColor3f(1,0,0);
00056 glVertex3f(0.0f, 0.0f, 0.0f);
00057 glVertex3f(3.0f, 0.0f, 0.0f);
00058
00059
00060 glColor3f(0,1,0);
00061 glVertex3f(0.0f, 0.0f, 0.0f);
00062 glVertex3f(0.0f, 3.0f, 0.0f);
00063
00064
00065 glColor3f(0,0,1);
00066 glVertex3f(0.0f, 0.0f, 0.0f);
00067 glVertex3f(0.0f, 0.0f, 3.0f);
00068
00069 glEnd( );
00070 }
00071
00072 void draw_cube() {
00073
00074
00075
00076 glBegin(GL_QUADS);
00077 glColor3f( 1.0f, 0.0f, 0.0f );
00078 glVertex3f( 2.5f, -2.5f, -2.5f );
00079 glVertex3f( -2.5f, -2.5f, -2.5f );
00080 glVertex3f( -2.5f, 2.5f, -2.5f );
00081 glVertex3f( 2.5f, 2.5f, -2.5f );
00082
00083 glColor3f( 1.0f, 1.0f, 0.0f );
00084 glVertex3f( -2.5f, -2.5f, 2.5f );
00085 glVertex3f( 2.5f, -2.5f, 2.5f );
00086 glVertex3f( 2.5f, 2.5f, 2.5f );
00087 glVertex3f( -2.5f, 2.5f, 2.5f );
00088
00089 glColor3f( 0.0f, 1.0f, 0.0f );
00090 glVertex3f( 2.5f, 2.5f, -2.5f );
00091 glVertex3f( -2.5f, 2.5f, -2.5f );
00092 glVertex3f( -2.5f, 2.5f, 2.5f );
00093 glVertex3f( 2.5f, 2.5f, 2.5f );
00094
00095 glColor3f( 0.0f, 1.0f, 1.0f );
00096 glVertex3f( -2.5f, -2.5f, -2.5f );
00097 glVertex3f( 2.5f, -2.5f, -2.5f );
00098 glVertex3f( 2.5f, -2.5f, 2.5f );
00099 glVertex3f( -2.5f, -2.5f, 2.5f );
00100
00101 glColor3f( 0.0f, 0.0f, 1.0f );
00102 glVertex3f( -2.5f, -2.5f, -2.5f );
00103 glVertex3f( -2.5f, -2.5f, 2.5f );
00104 glVertex3f( -2.5f, 2.5f, 2.5f );
00105 glVertex3f( -2.5f, 2.5f, -2.5f );
00106
00107 glColor3f( 1.0f, 0.0f, 1.0f );
00108 glVertex3f( 2.5f, -2.5f, 2.5f );
00109 glVertex3f( 2.5f, -2.5f, -2.5f );
00110 glVertex3f( 2.5f, 2.5f, -2.5f );
00111 glVertex3f( 2.5f, 2.5f, 2.5f );
00112 glEnd();
00113
00114 }
00115
00116 void loadVolume(string _file){
00117 menu->showMenu(false);
00118 menu->loadFile(false);
00119 filename = _file;
00120 obj->load(filename);
00121 VTransferFunctionElement * vtfe = new VTransferFunctionElement(&width,&height,&fpsCount,obj->getHistogram());
00122
00123 VSliceElement * vse = new VSliceElement(&width,&height,&fpsCount, obj->getsliceNo());
00124
00125 elements.clear();
00126 elements.push_back(vtfe);
00127 elements.push_back(new VRenderMode(&width,&height,&fpsCount,&renderMode));
00128 elements.push_back(new VAxisAlignElement(&width,&height,&fpsCount,camera));
00129 elements.push_back(vse);
00130 elements.push_back(new VMenuStarter(&width,&height,&fpsCount,elements));
00131 }
00132
00133 string textFileRead(string _file){
00134 FILE * pFile;
00135 pFile = fopen(_file.c_str(),"r");
00136 string Data;
00137 char temp;
00138 while((temp = fgetc(pFile)) != EOF){
00139 Data+= temp;
00140 }
00141 fclose(pFile);
00142 return Data;
00143 }
00144
00145 void printInfoLog(GLhandleARB obj)
00146 {
00147 GLint infologLength = 0;
00148 GLint charsWritten = 0;
00149 char *infoLog;
00150
00151 glGetObjectParameterivARB(obj, GL_OBJECT_INFO_LOG_LENGTH_ARB,
00152 &infologLength);
00153
00154 if (infologLength > 0)
00155 {
00156 infoLog = (char *)malloc(infologLength);
00157 glGetInfoLogARB(obj, infologLength, &charsWritten, infoLog);
00158 printf("%s\n",infoLog);
00159 free(infoLog);
00160 }
00161 }
00162
00163 void setShaders(void){
00164 string vs,fs;
00165
00166 v = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
00167 f = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
00168
00169 vs = textFileRead("shader/vertex.txt");
00170 fs = textFileRead("shader/fragment.txt");
00171
00172 const char * vv = vs.c_str();
00173 const char * ff = fs.c_str();
00174
00175 glShaderSourceARB(v, 1, &vv,NULL);
00176 glShaderSourceARB(f, 1, &ff,NULL);
00177
00178 glCompileShaderARB(v);
00179 glCompileShaderARB(f);
00180
00181 p = glCreateProgramObjectARB();
00182
00183 glAttachObjectARB(p,v);
00184 glAttachObjectARB(p,f);
00185
00186 glLinkProgramARB(p);
00187 glUseProgramObjectARB(p);
00188 printInfoLog(v);
00189 printInfoLog(f);
00190 printInfoLog(p);
00191
00192 }
00193
00194 void countFPS(int value) {
00195 char title[120];
00196 fpsCount = fpsCurrent;
00197 fpsCurrent = 0;
00198
00199 _snprintf_s(title, 120, "%s. FPS: %d", "VISLU", fpsCount);
00200 glutSetWindowTitle(title);
00201 glutTimerFunc(1000, countFPS, 1);
00202 }
00203
00204 void inputKey(unsigned char key, int x, int y){
00205 switch (key) {
00206 case '1': obj->setDirection(0);
00207 obj->setsliceNo(-1);
00208 break;
00209 case '2': obj->setDirection(1); break;
00210 case '3': obj->setDirection(2); break;
00211 case '4': obj->setDirection(3); break;
00212 case '+': obj->changesliceNo(1); break;
00213 case '-': obj->changesliceNo(-1); break;
00214 case 'i': cout << "renderMode: " << renderMode << endl; break;
00215 case 27: if (menu->helpMenu()){
00216 menu->helpMenu(false);
00217 menu->menuPos(0);
00218 }
00219 else if (menu->showMenu()){
00220 exit(0);
00221 }
00222 else {
00223 menu->showMenu(true);
00224 menu->menuPos(0);
00225 }
00226 break;
00227 case 13:
00228 if (menu->loadFile()){
00229 switch (menu->menuPos()){
00230 case 0: loadVolume("data/lobster.dat");
00231 break;
00232 case 1: loadVolume("data/skewed_head.dat");
00233 break;
00234 }
00235 }
00236 if (menu->helpMenu()){
00237 menu->helpMenu(false);
00238 menu->menuPos(0);
00239 }
00240 else if (menu->showMenu()){
00241 switch (menu->menuPos()){
00242 case 0: menu->loadFile(true);
00243 break;
00244 case 1: menu->helpMenu(true);
00245 break;
00246 case 2: exit(0);
00247 break;
00248 }
00249 }
00250 break;
00251 }
00252 }
00253
00254 void inputKeyUp(unsigned char key, int x, int y){
00255 }
00256
00257 void inputSpecialKey(int key, int x, int y) {
00258 switch (key) {
00259 case GLUT_KEY_UP :
00260 if (menu->showMenu() || menu->loadFile()){
00261 menu->decmenuPos();
00262 if (menu->menuPos() < 0){
00263 menu->menuPos(0);
00264 }
00265 }
00266 break;
00267 case GLUT_KEY_DOWN :
00268 if (menu->showMenu()){
00269 menu->incmenuPos();
00270 if (menu->menuPos() > 2){
00271 menu->menuPos(2);
00272 }
00273 }
00274 if (menu->loadFile()){
00275 menu->incmenuPos();
00276 if (menu->menuPos() > 1){
00277 menu->menuPos(1);
00278 }
00279 }
00280 break;
00281 case GLUT_KEY_LEFT :
00282 break;
00283 case GLUT_KEY_RIGHT :
00284 break;
00285 }
00286 }
00287
00288 void inputSpecialKeyUp(int key, int x, int y)
00289 {
00290 switch (key) {
00291 case GLUT_KEY_UP :
00292 case GLUT_KEY_DOWN :
00293 break;
00294 }
00295 }
00296
00297 void mousepos(int x,int y) {
00298 for(vector<GUIelement*>::iterator it=elements.begin(); it!=elements.end(); it++) {
00299 if((*it)->isActive() && (*it)->isInside(x,y))
00300 (*it)->motion(x,y);
00301 }
00302 if (menu->showMenu()){
00303 menu->setMouse((float)x/width,(float)y/height);
00304 }
00305 }
00306
00307 void mousedragging(int x,int y) {
00308 dragging = true;
00309 bool element = false;
00310 for(vector<GUIelement*>::iterator it=elements.begin(); it!=elements.end(); it++) {
00311 if((*it)->isActive() && (*it)->isInside(x,y)) {
00312 element = true;
00313 (*it)->drag(x,y);
00314 }
00315 }
00316 if(alt && !element && !slicing) {
00317 camera->changeDistance(x,y);
00318 } else if(!alt && !element && !slicing) {
00319 camera->changeDirection(x,y);
00320 }
00321 }
00322
00323 void mousebutton(int button, int state, int x, int y) {
00324
00325 int specialKey = glutGetModifiers();
00326 if(specialKey == GLUT_ACTIVE_ALT)
00327 alt = true;
00328 else alt = false;
00329
00330 if(button==GLUT_LEFT_BUTTON && state==GLUT_UP) {
00331 dragging = false;
00332 bool element = false;
00333 for(vector<GUIelement*>::iterator it=elements.begin(); it!=elements.end(); it++) {
00334 if((*it)->isActive() && (*it)->isInside(x,y)) {
00335 element = true;
00336 (*it)->released(x,y);
00337 }
00338 }
00339 if(!element)
00340 camera->deleteFromPoint();
00341
00342 } else if(button==GLUT_LEFT_BUTTON && state==GLUT_DOWN) {
00343 bool element = false;
00344 for(vector<GUIelement*>::iterator it=elements.begin(); it!=elements.end(); it++) {
00345 if((*it)->isActive() && (*it)->isInside(x,y)) {
00346 element = true;
00347 (*it)->pressed(x,y);
00348 }
00349 }
00350 if(!element)
00351 camera->setFromPoint(x,y);
00352
00353
00354 if(!dragging) {
00355
00356 if (menu->showMenu() || menu->helpMenu() || menu->loadFile()){
00357 menu->click();
00358 if (menu->loadFile()){
00359 switch (menu->menuPos()){
00360 case 0: loadVolume("data/lobster.dat");
00361 break;
00362 case 1: loadVolume("data/skewed_head.dat");
00363 break;
00364 case 2: loadVolume("data/beetle.dat");
00365 }
00366 }
00367
00368 if (menu->helpMenu()){
00369 menu->helpMenu(false);
00370 menu->menuPos(0);
00371 }
00372 else if (menu->showMenu()){
00373 switch (menu->menuPos()){
00374 case 0: menu->loadFile(true);
00375 break;
00376 case 1: menu->helpMenu(true);
00377 break;
00378 case 2: exit(0);
00379 break;
00380 }
00381 }
00382 }
00383
00384 }
00385 }
00386 }
00387
00388 void reshape(int w, int h) {
00389
00390 if (h==0)
00391 h=1;
00392
00393 glMatrixMode(GL_PROJECTION);
00394 glLoadIdentity();
00395
00396 glViewport(0,0,w,h);
00397
00398 gluPerspective(45.0,(double)w/h,1.0,20.0);
00399
00400 glMatrixMode(GL_MODELVIEW);
00401
00402 glLoadIdentity();
00403
00404 camera->setCamera();
00405
00406 width = w;
00407 height = h;
00408 }
00409
00410 void load() {
00411 cout << "starting application...." << endl;
00412 GLenum err = glewInit();
00413 if (GLEW_OK != err)
00414 {
00415
00416 fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
00417 }
00418 fprintf(stdout, "Status: Using GLEW %s\n", glewGetString(GLEW_VERSION));
00419 glShadeModel (GL_SMOOTH);
00420 obj = new VObject();
00421 menu = new VMenu();
00422 camera = new VCamera(&width,&height,5.0f);
00423 }
00424
00425 void draw() {
00426
00427 GLenum err = glGetError();
00428 if (err != GL_NO_ERROR)
00429 cout << "GL Error: " << gluErrorString(err) << endl;
00430
00431 glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
00432 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
00433
00434 glMatrixMode(GL_MODELVIEW);
00435 glLoadIdentity();
00436 camera->setCamera();
00437
00438 glPushMatrix();
00439
00440
00441 obj->draw();
00442
00443
00444
00445 glPopMatrix();
00446
00447 GLboolean lightingOn = glIsEnabled(GL_LIGHTING);
00448 if (lightingOn) glDisable(GL_LIGHTING);
00449
00450 GLboolean depthOn = glIsEnabled(GL_DEPTH_TEST);
00451 if (depthOn) glDisable(GL_DEPTH_TEST);
00452
00453 glMatrixMode(GL_PROJECTION);
00454 glPushMatrix();
00455 glLoadIdentity();
00456 glOrtho(0, width, height, 0, -100, 100);
00457 glMatrixMode(GL_MODELVIEW);
00458 glPushMatrix();
00459 glLoadIdentity();
00460
00461 glEnable (GL_BLEND);
00462 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00463
00464 for(vector<GUIelement*>::iterator it=elements.begin(); it!=elements.end(); it++) {
00465 if((*it)->isActive()||(*it)->isBlend()) {
00466 (*it)->render();
00467 }
00468 }
00469 if(elements[3]->isActive()) slicing = true;
00470 else slicing = false;
00471
00472 glPopMatrix();
00473 glMatrixMode(GL_PROJECTION);
00474 glPopMatrix();
00475
00476 glDisable (GL_BLEND);
00477 if (depthOn) glEnable(GL_DEPTH_TEST);
00478 if (lightingOn) glEnable(GL_LIGHTING);
00479 }
00480
00481 void OnDraw(){
00482 if (menu->showMenu()){
00483 menu->draw();
00484 }
00485 else {
00486 draw();
00487 }
00488 fpsCurrent++;
00489 glutSwapBuffers();
00490 }
00491
00492 int main(int argc, char** argv)
00493 {
00494
00495 glutInit(&argc,argv);
00496 glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH);
00497 glutInitWindowSize(width, height);
00498 glutCreateWindow("Volume Ray Caster");
00499
00500 load();
00501
00502
00503 glutIgnoreKeyRepeat(true);
00504 glutKeyboardFunc(inputKey);
00505 glutKeyboardUpFunc(inputKeyUp);
00506 glutSpecialFunc(inputSpecialKey);
00507 glutSpecialUpFunc(inputSpecialKeyUp);
00508 glutMotionFunc(mousedragging);
00509 glutMouseFunc(mousebutton);
00510 glutPassiveMotionFunc(mousepos);
00511
00512 glutDisplayFunc(OnDraw);
00513 glutIdleFunc(OnDraw);
00514 glutReshapeFunc(reshape);
00515
00516 glutTimerFunc(1000, countFPS, 1);
00517
00518 glutMainLoop();
00519
00520 delete camera;
00521 delete obj;
00522 return 0;
00523 }