00001 #include "VolumeBuffer.h"
00002 #include <QtGui>
00003 #include <QtOpenGL>
00004
00005 #include <math.h>
00006
00007 #include "vrglwidget.h"
00008 #include <GL/gl.h>
00009 #include <GL/glu.h>
00010 #include <GL/glut.h>
00011
00012
00013 #define checkImageWidth 64
00014 #define checkImageHeight 64
00015 static GLubyte checkImage[checkImageHeight][checkImageWidth][4];
00016
00017
00018
00019 #ifdef GL_VERSION_1_1
00020 static GLuint texName;
00021 #endif
00022
00023 #include <iostream>
00024 #include <fstream>
00025 using namespace std;
00026
00027
00028 void makeCheckImage(void)
00029 {
00030 int i, j, c;
00031
00032 for (i = 0; i < checkImageHeight; i++) {
00033 for (j = 0; j < checkImageWidth; j++) {
00034 c = ((((i&0x8)==0)^((j&0x8))==0))*255;
00035
00036
00037
00038 checkImage[i][j][0] = (GLubyte) c;
00039 checkImage[i][j][1] = (GLubyte) c;
00040 checkImage[i][j][2] = (GLubyte) c;
00041 checkImage[i][j][3] = (GLubyte) 255;
00042
00043 }
00044 }
00045 }
00046
00047
00048 #define ImageWidth 256
00049 #define ImageHeight 256
00050 #define ImageDepth 256
00051
00052 unsigned char *loadRawFile(char *filename, size_t size)
00053 {
00054 FILE *fp = fopen(filename, "rb");
00055 if (!fp) {
00056 fprintf(stderr, "Error opening file '%s'\n", filename);
00057 return 0;
00058 }
00059
00060 unsigned char *data = (unsigned char *) malloc(size*sizeof(unsigned char));
00061 size_t read = fread(data, sizeof(unsigned char), size, fp);
00062 fclose(fp);
00063 unsigned char *volume_data_rgba = (unsigned char *) malloc(size*sizeof(unsigned char)*3);
00064
00065
00066
00067
00068 int i, j, k, c;
00069
00070 for (i = 0; i < ImageDepth; i++) {
00071 for (j = 0; j < ImageHeight; j++) {
00072 for (k = 0; j < ImageWidth; j++) {
00073
00074 c = data[(ImageHeight*ImageWidth)*k + (ImageWidth)*j + i];
00075
00076 volume_data_rgba[(ImageHeight*ImageWidth)*k*3 + ((ImageWidth)*j + i)*3 + 0] = (GLubyte) c;
00077 volume_data_rgba[(ImageHeight*ImageWidth)*k*3 + ((ImageWidth)*j + i)*3 + 1] = (GLubyte) c;
00078 volume_data_rgba[(ImageHeight*ImageWidth)*k*3 + ((ImageWidth)*j + i)*3 + 2] = (GLubyte) c;
00079
00080 }
00081 }
00082 }
00083
00084
00085
00086
00087 printf("Read '%s', %d bytes\n", filename, read);
00088
00089
00090 return (unsigned char *)volume_data_rgba;
00091 }
00092
00093 CGcontext cgContext;
00094
00095 void cgErrorCallback()
00096 {
00097 CGerror lastError = cgGetError();
00098 if(lastError)
00099 {
00100 printf("%s\n", cgGetErrorString(lastError));
00101 printf("%s\n", cgGetLastListing(cgContext));
00102 exit(1);
00103 }
00104 }
00105
00106 vrGLWidget::vrGLWidget(QWidget *parent)
00107 : QGLWidget(parent)
00108 {
00109 object = 0;
00110 xRot = 0;
00111 yRot = 0;
00112 zRot = 0;
00113
00114 trolltechGreen = QColor::fromCmykF(0.40, 0.0, 1.0, 0.0);
00115 trolltechPurple = QColor::fromCmykF(0.39, 0.39, 0.0, 0.0);
00116
00117 setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
00118 m_tf_texture = new unsigned char [256*256*4];
00119
00120 m_vb = new VolumeBuffer(GL_UNSIGNED_BYTE, 256, 256, 256, 0);
00121 cgContext = cgCreateContext();
00122 cgSetErrorCallback(cgErrorCallback);
00123
00124
00125
00126
00127
00128
00129
00130
00131 m_tfimg = QImage(256, 4, QImage::Format_ARGB32_Premultiplied);
00132 m_tfimg.fill(0);
00133
00134 }
00135
00136 vrGLWidget::~vrGLWidget()
00137 {
00138 makeCurrent();
00139 glDeleteLists(object, 1);
00140
00141
00142 delete [] m_tf_texture;
00143 }
00144
00145 QSize vrGLWidget::minimumSizeHint() const
00146 {
00147 return QSize(50, 50);
00148 }
00149
00150 void vrGLWidget::setXRotation(int angle)
00151 {
00152 normalizeAngle(&angle);
00153 if (angle != xRot) {
00154 xRot = angle;
00155 emit xRotationChanged(angle);
00156 updateGL();
00157 }
00158 }
00159
00160 void vrGLWidget::setYRotation(int angle)
00161 {
00162 normalizeAngle(&angle);
00163 if (angle != yRot) {
00164 yRot = angle;
00165 emit yRotationChanged(angle);
00166 updateGL();
00167 }
00168 }
00169
00170 void vrGLWidget::setZRotation(int angle)
00171 {
00172 normalizeAngle(&angle);
00173 if (angle != zRot) {
00174 zRot = angle;
00175 emit zRotationChanged(angle);
00176 updateGL();
00177 }
00178 }
00179
00180 void vrGLWidget::initializeGL()
00181 {
00182
00183 glewInit();
00184 qglClearColor(trolltechPurple.dark());
00185 glShadeModel (GL_FLAT);
00186
00187
00188
00189
00190
00191
00192 glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
00193
00194
00195
00196
00197 glEnable(GL_BLEND);
00198 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229 m_vr = new VolumeRender(cgContext,m_vb);
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 }
00251
00252 void vrGLWidget::paintGL()
00253 {
00254 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00255
00256 glLoadIdentity();
00257 glTranslated(0.0, 0.0, -2.0);
00258 glRotated(xRot / 16.0, 1.0, 0.0, 0.0);
00259 glRotated(yRot / 16.0, 0.0, 1.0, 0.0);
00260 glRotated(zRot / 16.0, 0.0, 0.0, 1.0);
00261
00262
00263 glEnable(GL_TEXTURE_1D);
00264
00265
00266
00267 deleteTexture(m_vr->m_tfid);
00268
00269
00270 glGenTextures(1, &(m_vr->m_tfid));
00271
00272 int iy = 0;
00273 int ix;
00274
00275 memset(m_tf_texture,0,256*4*sizeof(unsigned char));
00276
00277 ofstream tf_r_file;
00278 tf_r_file.open ("tfvr_red.txt");
00279 ofstream tf_g_file;
00280 tf_g_file.open ("tfvr_green.txt");
00281 ofstream tf_b_file;
00282 tf_b_file.open ("tfvr_blue.txt");
00283 ofstream tf_a_file;
00284 tf_a_file.open ("tfvr_alpha.txt");
00285
00286
00287
00288
00289 for (ix = 0; ix < 256; ix++)
00290 {
00291 QRgb tfc = m_tfimg.pixel(ix,iy);
00292
00293 m_tf_texture[ix*4 + 0] = (GLubyte) qRed(tfc);
00294 m_tf_texture[ix*4 + 1] = (GLubyte) qGreen(tfc);
00295 m_tf_texture[ix*4 + 2] = (GLubyte) qBlue(tfc);
00296 m_tf_texture[ix*4 + 3] = (GLubyte) qAlpha(tfc);
00297
00298
00299 tf_r_file << qRed(tfc) << " ";
00300 tf_g_file << qGreen(tfc) << " ";
00301 tf_b_file << qBlue(tfc) << " ";
00302 tf_a_file << qAlpha(tfc) << " ";
00303
00304 }
00305
00306 tf_r_file.close();
00307 tf_g_file.close();
00308 tf_b_file.close();
00309 tf_a_file.close();
00310
00311
00312 glBindTexture(GL_TEXTURE_1D,m_vr->m_tfid);
00313
00314
00315 glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00316 glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00317
00318 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
00319 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
00320
00321
00322 glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_tf_texture);
00323
00324
00325 glEnable(GL_TEXTURE_1D);
00326
00327
00328
00329 deleteTexture(m_vr->m_tfid_s1);
00330
00331
00332 glGenTextures(1, &(m_vr->m_tfid_s1));
00333
00334
00335 memset(m_tf_texture,0,256*4*sizeof(unsigned char));
00336
00337 tf_r_file.open ("tfvr_red_s1.txt");
00338 tf_g_file.open ("tfvr_green_s1.txt");
00339 tf_b_file.open ("tfvr_blue_s1.txt");
00340 tf_a_file.open ("tfvr_alpha_s1.txt");
00341
00342
00343
00344
00345 for (ix = 0; ix < 256; ix++)
00346 {
00347
00348 QRgb tfc = m_tfimg.pixel(ix,1);
00349
00350 m_tf_texture[ix*4 + 0] = (GLubyte) qRed(tfc);
00351 m_tf_texture[ix*4 + 1] = (GLubyte) qGreen(tfc);
00352 m_tf_texture[ix*4 + 2] = (GLubyte) qBlue(tfc);
00353 m_tf_texture[ix*4 + 3] = (GLubyte) qAlpha(tfc);
00354
00355
00356 tf_r_file << qRed(tfc) << " ";
00357 tf_g_file << qGreen(tfc) << " ";
00358 tf_b_file << qBlue(tfc) << " ";
00359 tf_a_file << qAlpha(tfc) << " ";
00360
00361 }
00362
00363 tf_r_file.close();
00364 tf_g_file.close();
00365 tf_b_file.close();
00366 tf_a_file.close();
00367
00368
00369 glBindTexture(GL_TEXTURE_1D,m_vr->m_tfid_s1);
00370
00371
00372 glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00373 glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00374
00375 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
00376 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
00377
00378
00379 glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_tf_texture);
00380
00381
00382
00383 glEnable(GL_TEXTURE_1D);
00384
00385
00386
00387 deleteTexture(m_vr->m_tfid_s2);
00388
00389
00390 glGenTextures(1, &(m_vr->m_tfid_s2));
00391
00392
00393 memset(m_tf_texture,0,256*4*sizeof(unsigned char));
00394
00395 tf_r_file.open ("tfvr_red_s2.txt");
00396 tf_g_file.open ("tfvr_green_s2.txt");
00397 tf_b_file.open ("tfvr_blue_s2.txt");
00398 tf_a_file.open ("tfvr_alpha_s2.txt");
00399
00400
00401
00402
00403 for (ix = 0; ix < 256; ix++)
00404 {
00405
00406 QRgb tfc = m_tfimg.pixel(ix,2);
00407
00408 m_tf_texture[ix*4 + 0] = (GLubyte) qRed(tfc);
00409 m_tf_texture[ix*4 + 1] = (GLubyte) qGreen(tfc);
00410 m_tf_texture[ix*4 + 2] = (GLubyte) qBlue(tfc);
00411 m_tf_texture[ix*4 + 3] = (GLubyte) qAlpha(tfc);
00412
00413
00414 tf_r_file << qRed(tfc) << " ";
00415 tf_g_file << qGreen(tfc) << " ";
00416 tf_b_file << qBlue(tfc) << " ";
00417 tf_a_file << qAlpha(tfc) << " ";
00418
00419 }
00420
00421 tf_r_file.close();
00422 tf_g_file.close();
00423 tf_b_file.close();
00424 tf_a_file.close();
00425
00426
00427 glBindTexture(GL_TEXTURE_1D,m_vr->m_tfid_s2);
00428
00429
00430 glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00431 glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00432
00433 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
00434 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
00435
00436
00437 glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_tf_texture);
00438
00439
00440
00441 glEnable(GL_TEXTURE_1D);
00442
00443
00444
00445 deleteTexture(m_vr->m_tfid_s3);
00446
00447
00448 glGenTextures(1, &(m_vr->m_tfid_s3));
00449
00450
00451 memset(m_tf_texture,0,256*4*sizeof(unsigned char));
00452
00453 tf_r_file.open ("tfvr_red_s3.txt");
00454 tf_g_file.open ("tfvr_green_s3.txt");
00455 tf_b_file.open ("tfvr_blue_s3.txt");
00456 tf_a_file.open ("tfvr_alpha_s3.txt");
00457
00458
00459
00460
00461 for (ix = 0; ix < 256; ix++)
00462 {
00463
00464 QRgb tfc = m_tfimg.pixel(ix,3);
00465
00466 m_tf_texture[ix*4 + 0] = (GLubyte) qRed(tfc);
00467 m_tf_texture[ix*4 + 1] = (GLubyte) qGreen(tfc);
00468 m_tf_texture[ix*4 + 2] = (GLubyte) qBlue(tfc);
00469 m_tf_texture[ix*4 + 3] = (GLubyte) qAlpha(tfc);
00470
00471
00472 tf_r_file << qRed(tfc) << " ";
00473 tf_g_file << qGreen(tfc) << " ";
00474 tf_b_file << qBlue(tfc) << " ";
00475 tf_a_file << qAlpha(tfc) << " ";
00476
00477 }
00478
00479 tf_r_file.close();
00480 tf_g_file.close();
00481 tf_b_file.close();
00482 tf_a_file.close();
00483
00484
00485 glBindTexture(GL_TEXTURE_1D,m_vr->m_tfid_s3);
00486
00487
00488 glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00489 glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00490
00491 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
00492 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
00493
00494
00495 glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_tf_texture);
00496
00497
00498 glEnable(GL_TEXTURE_2D);
00499 glEnable(GL_BLEND);
00500 glDisable(GL_DEPTH_TEST);
00501
00502 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
00503
00504
00505
00506
00507
00508
00509
00510
00511 m_vr->setVolume(m_vb);
00512 m_vr->render();
00513
00514 glFlush();
00515 glDisable(GL_TEXTURE_2D);
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529 }
00530
00531 void vrGLWidget::resizeGL(int width, int height)
00532 {
00533 int side = qMin(width, height);
00534
00535
00536 glViewport (0, 0, (GLsizei) width, (GLsizei) height);
00537 glMatrixMode (GL_PROJECTION);
00538 glLoadIdentity ();
00539 glFrustum (-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
00540 glMatrixMode (GL_MODELVIEW);
00541 }
00542
00543 void vrGLWidget::mousePressEvent(QMouseEvent *event)
00544 {
00545 lastPos = event->pos();
00546 }
00547
00548 void vrGLWidget::mouseMoveEvent(QMouseEvent *event)
00549 {
00550 int dx = event->x() - lastPos.x();
00551 int dy = event->y() - lastPos.y();
00552
00553 if (event->buttons() & Qt::LeftButton) {
00554 setXRotation(xRot + 8 * dy);
00555 setYRotation(yRot + 8 * dx);
00556 } else if (event->buttons() & Qt::RightButton) {
00557 setXRotation(xRot + 8 * dy);
00558 setZRotation(zRot + 8 * dx);
00559 }
00560 lastPos = event->pos();
00561 }
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582 void vrGLWidget::normalizeAngle(int *angle)
00583 {
00584 while (*angle < 0)
00585 *angle += 360 * 16;
00586 while (*angle > 360 * 16)
00587 *angle -= 360 * 16;
00588 }
00589
00590 void vrGLWidget::vr_load_data1(VolumeBuffer *vb1)
00591 {
00592
00593 makeCurrent();
00594
00595 std::cout << "Data loading...";
00596
00597
00598 glEnable(GL_TEXTURE_2D);
00599 vb1->create2DTextures(GL_UNSIGNED_BYTE);
00600
00601 delete m_vb;
00602 m_vb = vb1;
00603
00604
00605
00606
00607 std::cout << "loaded\n";
00608 updateGL();
00609 }
00610
00611 void vrGLWidget::setTFtexture(QImage &tfimg)
00612 {
00613 makeCurrent();
00614 int ix = 0;
00615
00616 for (ix = 0; ix < m_tfimg.width(); ix++)
00617 m_tfimg.setPixel(ix, 0, tfimg.pixel(ix,0));
00618
00619 updateGL();
00620 }
00621
00622 void vrGLWidget::setTFtexture1(QImage &tfimg)
00623 {
00624 makeCurrent();
00625 int ix = 0;
00626
00627 for (ix = 0; ix < m_tfimg.width(); ix++)
00628 m_tfimg.setPixel(ix, 1, tfimg.pixel(ix,0));
00629
00630 updateGL();
00631 }
00632
00633 void vrGLWidget::setTFtexture2(QImage &tfimg)
00634 {
00635 makeCurrent();
00636 int ix = 0;
00637
00638 for (ix = 0; ix < m_tfimg.width(); ix++)
00639 m_tfimg.setPixel(ix, 2, tfimg.pixel(ix,0));
00640
00641 updateGL();
00642 }
00643
00644 void vrGLWidget::setTFtexture3(QImage &tfimg)
00645 {
00646 makeCurrent();
00647 int ix = 0;
00648
00649 for (ix = 0; ix < m_tfimg.width(); ix++)
00650 m_tfimg.setPixel(ix, 3, tfimg.pixel(ix,0));
00651
00652 updateGL();
00653 }