00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 #include "QtBaseViewer.hh"
00056 #include <QStatusBar>
00057 #include <QToolButton>
00058
00059 #include <OpenFlipper/common/GlobalOptions.hh>
00060
00061 #include <QGLFramebufferObject>
00062
00063 #include <ACG/ShaderUtils/GLSLShader.hh>
00064 #include <ACG/GL/globjects.hh>
00065
00066 #include <ACG/ShaderUtils/gldebug.h>
00067
00068 #include "crc32.hh"
00069
00070
00071
00072
00073
00074
00075 static const char* customAnaglyphProg = {
00076 "!!ARBfp1.0"
00077 "TEMP left, right, lmul, rmul;"
00078 "TEX left, fragment.texcoord[0], texture[0], RECT;"
00079 "TEX right, fragment.texcoord[0], texture[1], RECT;"
00080 "DP3 lmul.r, left, program.env[0];"
00081 "DP3 lmul.g, left, program.env[1];"
00082 "DP3 lmul.b, left, program.env[2];"
00083 "DP3 rmul.r, right, program.env[3];"
00084 "DP3 rmul.g, right, program.env[4];"
00085 "DP3 rmul.b, right, program.env[5];"
00086 "ADD result.color, lmul, rmul;"
00087 "END"
00088 };
00089
00090
00091
00092
00093 void
00094 glViewer::setStereoMode(bool _b)
00095 {
00096 stereo_ = _b;
00097
00098 if (!stereo_) {
00099 makeCurrent();
00100 glDrawBuffer(GL_BACK);
00101 }
00102
00103 updateProjectionMatrix ();
00104
00105 updateGL();
00106 }
00107
00108
00109
00110
00111 void
00112 glViewer::drawScene_glStereo()
00113 {
00114 double l, r, t, b, w, h, a, radians, wd2, ndfl, zerop, xrange;
00115
00116 w = glWidth();
00117 h = glHeight();
00118 a = w / h;
00119
00120 radians = fovy_ * 0.5 / 180.0 * M_PI;
00121 wd2 = near_ * tan(radians);
00122 zerop = near_ + ((far_ - near_) * OpenFlipper::Options::focalDistance ());
00123 ndfl = near_ / zerop ;
00124 xrange = a * wd2 * 2 * zerop / near_;
00125
00126 l = -a*wd2;
00127 r = a*wd2;
00128 t = wd2;
00129 b = -wd2;
00130
00131 double offset = 0.5 * OpenFlipper::Options::eyeDistance () * xrange;
00132 double offset2 = offset * ndfl;
00133
00134
00135 glMatrixMode(GL_PROJECTION);
00136 glLoadIdentity();
00137 glFrustum(l+offset2, r+offset2, b, t, near_, far_);
00138 glTranslatef(+offset, 0.0, 0.0);
00139 glMatrixMode(GL_MODELVIEW);
00140 glDrawBuffer(GL_BACK_LEFT);
00141 glstate_->clearBuffers ();
00142 glClear(GL_DEPTH_BUFFER_BIT);
00143 drawScene_mono();
00144
00145
00146
00147 glMatrixMode(GL_PROJECTION);
00148 glLoadIdentity();
00149 glFrustum(l-offset2, r-offset2, b, t, near_, far_);
00150 glTranslatef(-offset, 0.0, 0.0);
00151 glMatrixMode(GL_MODELVIEW);
00152 glDrawBuffer(GL_BACK_RIGHT);
00153 glstate_->clearBuffers ();
00154 glClear(GL_DEPTH_BUFFER_BIT);
00155 drawScene_mono();
00156 glDrawBuffer(GL_BACK);
00157 }
00158
00159
00160 void
00161 glViewer::drawScenePhilipsStereo()
00162 {
00163
00164 int vp_l, vp_b, vp_w, vp_h;
00165 glstate_->get_viewport (vp_l, vp_b, vp_w, vp_h);
00166
00167
00168
00169
00170 ACG::Texture2D colorTexture;
00171 colorTexture.enable();
00172 colorTexture.bind();
00173 GLenum texTarget = GL_TEXTURE_2D;
00174 GLenum texInternalFormat = GL_RGBA;
00175 GLenum texFormat = GL_RGBA;
00176 GLenum texType = GL_UNSIGNED_BYTE;
00177 GLenum texFilterMode = GL_NEAREST;
00178 glTexImage2D(texTarget, 0, texInternalFormat, vp_w, vp_h, 0, texFormat, texType, NULL);
00179
00180 glTexParameterf(texTarget, GL_TEXTURE_MIN_FILTER, texFilterMode);
00181 glTexParameterf(texTarget, GL_TEXTURE_MAG_FILTER, texFilterMode);
00182 glTexParameterf(texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
00183 glTexParameterf(texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
00184 glTexParameteri(texTarget, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
00185
00186
00187
00188
00189 ACG::Texture2D depthStencilTexture;
00190 depthStencilTexture.enable();
00191 depthStencilTexture.bind();
00192 texTarget = GL_TEXTURE_2D;
00193 texInternalFormat = GL_DEPTH24_STENCIL8_EXT;
00194 texFormat = GL_DEPTH_STENCIL_EXT;
00195 texType = GL_UNSIGNED_INT_24_8_EXT;
00196 texFilterMode = GL_NEAREST;
00197 glTexImage2D(texTarget, 0, texInternalFormat, vp_w, vp_h, 0, texFormat, texType, NULL);
00198
00199 glTexParameterf(texTarget, GL_TEXTURE_MIN_FILTER, texFilterMode);
00200 glTexParameterf(texTarget, GL_TEXTURE_MAG_FILTER, texFilterMode);
00201 glTexParameterf(texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
00202 glTexParameterf(texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
00203 glTexParameteri(texTarget, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
00204
00205
00206
00207
00208 depthStencilTexture.disable();
00209 colorTexture.disable();
00210
00211
00212
00213
00214 glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
00215 drawScene_mono();
00216
00217
00218
00219
00220 colorTexture.enable();
00221 colorTexture.bind();
00222
00223 glCopyTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, vp_l, vp_b, vp_w, vp_h);
00224
00225 colorTexture.disable();
00226
00227 depthStencilTexture.enable();
00228 depthStencilTexture.bind();
00229
00230 glCopyTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, vp_l, vp_b, vp_w, vp_h);
00231
00232 depthStencilTexture.disable();
00233
00234
00235
00236
00237 GLSL::PtrVertexShader vertexShader;
00238 GLSL::PtrFragmentShader fragmentShader;
00239 GLSL::PtrProgram program;
00240
00241 QString vshaderFile = OpenFlipper::Options::shaderDirStr() + QDir::separator() + "Philips/Vertex.glsl";
00242 QString fshaderFile = OpenFlipper::Options::shaderDirStr() + QDir::separator() + "Philips/Fragment42.glsl";
00243
00245 vertexShader = GLSL::loadVertexShader( vshaderFile.toStdString().c_str() );
00246 fragmentShader = GLSL::loadFragmentShader( fshaderFile.toStdString().c_str() );
00247 program = GLSL::PtrProgram(new GLSL::Program());
00248
00249 if ( (vertexShader == 0) ||
00250 (fragmentShader == 0) ||
00251 (program == 0) ) {
00252 std::cerr << "Unable to load shaders for philips display rendering!";
00253 return;
00254 }
00255
00256 program->attach(vertexShader);
00257 program->attach(fragmentShader);
00258 program->link();
00259 program->use();
00260
00261
00262
00263
00264 glActiveTextureARB(GL_TEXTURE0_ARB);
00265 colorTexture.enable();
00266 colorTexture.bind();
00267
00268 glActiveTextureARB(GL_TEXTURE1_ARB);
00269 depthStencilTexture.enable();
00270 depthStencilTexture.bind();
00271
00272 program->setUniform("ColorTexture",0);
00273 program->setUniform("DepthStencil",1);
00274
00275
00276
00277
00278
00279
00280 glDisable(GL_LIGHTING);
00281 glDisable(GL_COLOR_MATERIAL);
00282 glDisable(GL_DEPTH_TEST);
00283
00284
00285
00286
00287
00288 glstate_->push_projection_matrix();
00289 glstate_->push_modelview_matrix();
00290
00291 glstate_->reset_projection();
00292 glstate_->reset_modelview();
00293
00294 glstate_->ortho(0, vp_w, 0, vp_h, 0, 1);
00295
00296
00297
00298
00299
00300 glColor3f(1.0,1.0,1.0);
00301
00302
00303
00304
00305 glClearColor(.0, .0, .0, 0);
00306 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
00307
00308
00309
00310
00311 glBegin(GL_QUADS);
00312 glTexCoord2f(0.0f, 1.0f); glVertex2i( 0, vp_h);
00313 glTexCoord2f(1.0f, 1.0f); glVertex2i( vp_w, vp_h);
00314 glTexCoord2f(1.0f, 0.0f); glVertex2i( vp_w, 0);
00315 glTexCoord2f(0.0f, 0.0f); glVertex2i( 0, 0);
00316 glEnd();
00317
00318 program->disable();
00319
00320 glBindTexture(GL_TEXTURE_2D, 0);
00321
00322
00323
00324
00325 depthStencilTexture.del();
00326 colorTexture.del();
00327
00328
00329
00330
00331 uchar *header = new uchar[ 6 ];
00332
00333
00334
00335 header[0] = 241;
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347 header[1] = 3;
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 header[2] = 64;
00359
00360
00361
00362
00363
00364
00365
00366
00367 header[3] = 128;
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378 header[4] = 0;
00379
00380
00381 header[5] = 0;
00382
00383
00384
00385
00386
00387
00388 unsigned long checksum = CalcCRC32(&header[0], 6);
00389
00390
00391 std::vector< uchar > bitVector;
00392
00393
00394 for (int i = 0; i < 6; i++) {
00395
00396
00397 for ( int j = 7 ; j >= 0 ; --j ) {
00398
00399
00400 bitVector.push_back(0);
00401 bitVector.push_back(0);
00402
00403
00404
00405 if ( header[i] & (1 << j ) ) {
00406 bitVector.push_back(255);
00407 } else {
00408 bitVector.push_back(0);
00409 }
00410
00411
00412
00413 bitVector.push_back(0);
00414 bitVector.push_back(0);
00415 bitVector.push_back(0);
00416
00417 }
00418
00419 }
00420
00421
00422
00423 for (int i=31; i >= 0; i--) {
00424
00425
00426 bitVector.push_back(0);
00427 bitVector.push_back(0);
00428
00429 if ( checksum & (1 << i ) )
00430 bitVector.push_back( 255 );
00431 else
00432 bitVector.push_back( 0 );
00433
00434
00435
00436 bitVector.push_back(0);
00437 bitVector.push_back(0);
00438 bitVector.push_back(0);
00439 }
00440
00441
00442
00443
00444 glRasterPos2i (0,glHeight()-1);
00445 glDrawPixels(bitVector.size()/3, 1,GL_RGB ,GL_UNSIGNED_BYTE , &bitVector[0]);
00446
00447
00448
00449
00450 glstate_->pop_projection_matrix();
00451 glstate_->pop_modelview_matrix();
00452
00453 }
00454
00455
00456
00457
00458
00459
00460
00461 void
00462 glViewer::drawScene_anaglyphStereo()
00463 {
00464 double l, r, t, b, w, h, a, radians, wd2, ndfl, zerop, xrange;
00465
00466 w = glWidth();
00467 h = glHeight();
00468 a = w / h;
00469
00470 radians = fovy_ * 0.5 / 180.0 * M_PI;
00471 wd2 = near_ * tan(radians);
00472 zerop = near_ + ((far_ - near_) * OpenFlipper::Options::focalDistance ());
00473 ndfl = near_ / zerop ;
00474 xrange = a * wd2 * 2 * zerop / near_;
00475
00476 l = -a*wd2;
00477 r = a*wd2;
00478 t = wd2;
00479 b = -wd2;
00480
00481 double offset = 0.5 * OpenFlipper::Options::eyeDistance () * xrange;
00482 double offset2 = offset * ndfl;
00483
00484
00485 glMatrixMode(GL_PROJECTION);
00486 glLoadIdentity();
00487 glFrustum(l+offset2, r+offset2, b, t, near_, far_);
00488 glTranslatef(offset, 0.0, 0.0);
00489
00490 glMatrixMode(GL_MODELVIEW);
00491 glstate_->clearBuffers ();
00492 glClear(GL_DEPTH_BUFFER_BIT);
00493
00494
00495 glColorMask(GL_TRUE,GL_FALSE,GL_FALSE,GL_TRUE);
00496 drawScene_mono();
00497 glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
00498
00499
00500
00501 glMatrixMode(GL_PROJECTION);
00502 glLoadIdentity();
00503 glFrustum(l-offset2, r-offset2, b, t, near_, far_);
00504 glTranslatef(-offset, 0.0, 0.0);
00505 glMatrixMode(GL_MODELVIEW);
00506 glClear(GL_DEPTH_BUFFER_BIT);
00507
00508
00509 glColorMask(GL_FALSE,GL_TRUE,GL_TRUE,GL_TRUE);
00510 drawScene_mono();
00511 glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
00512
00513 }
00514
00515
00516
00517 void
00518 glViewer::updateCustomAnaglyphStereo()
00519 {
00520 if (!customAnaglyphSupported_)
00521 return;
00522
00523 if (!agProgram_)
00524 {
00525 GLint errorPos;
00526
00527 glGenProgramsARB (1, &agProgram_);
00528
00529 glGetError ();
00530 glBindProgramARB (GL_FRAGMENT_PROGRAM_ARB, agProgram_);
00531 glProgramStringARB (GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
00532 strlen (customAnaglyphProg), customAnaglyphProg);
00533
00534 glGetIntegerv (GL_PROGRAM_ERROR_POSITION_ARB, &errorPos);
00535 if (glGetError () != GL_NO_ERROR || errorPos != -1)
00536 {
00537 printf("Error loading program %d %s\n",errorPos, glGetString(GL_PROGRAM_ERROR_STRING_ARB));
00538 glDeleteProgramsARB (1, &agProgram_);
00539 customAnaglyphSupported_ = false;
00540 return;
00541 }
00542 }
00543
00544 if (!agTexture_[0])
00545 glGenTextures (2, agTexture_);
00546
00547 if (!agTexture_[0])
00548 {
00549 finiCustomAnaglyphStereo ();
00550 customAnaglyphSupported_ = false;
00551 return;
00552 }
00553
00554 if (glstate_->viewport_width () != agTexWidth_ ||
00555 glstate_->viewport_height () != agTexHeight_)
00556 {
00557 glBindTexture (GL_TEXTURE_RECTANGLE_NV, agTexture_[0]);
00558 glTexImage2D (GL_TEXTURE_RECTANGLE_NV, 0, GL_RGB, glstate_->viewport_width (),
00559 glstate_->viewport_height (), 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
00560 glBindTexture (GL_TEXTURE_RECTANGLE_NV, agTexture_[1]);
00561 glTexImage2D (GL_TEXTURE_RECTANGLE_NV, 0, GL_RGB, glstate_->viewport_width (),
00562 glstate_->viewport_height (), 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
00563 glBindTexture (GL_TEXTURE_RECTANGLE_NV, 0);
00564
00565 agTexWidth_ = glstate_->viewport_width ();
00566 agTexHeight_ = glstate_->viewport_height ();
00567 }
00568 }
00569
00570
00571
00572 void
00573 glViewer::finiCustomAnaglyphStereo()
00574 {
00575 if (!customAnaglyphSupported_)
00576 return;
00577
00578 if (agProgram_)
00579 glDeleteProgramsARB (1, &agProgram_);
00580
00581 if (agTexture_[0])
00582 glDeleteTextures (2, agTexture_);
00583 }
00584
00585
00586
00587 void
00588 glViewer::drawScene_customAnaglyphStereo()
00589 {
00590 updateCustomAnaglyphStereo ();
00591
00592 if (!customAnaglyphSupported_)
00593 return;
00594
00595 double l, r, t, b, w, h, a, radians, wd2, ndfl, zerop, xrange;
00596
00597 w = glWidth();
00598 h = glHeight();
00599 a = w / h;
00600
00601 radians = fovy_ * 0.5 / 180.0 * M_PI;
00602 wd2 = near_ * tan(radians);
00603 zerop = near_ + ((far_ - near_) * OpenFlipper::Options::focalDistance ());
00604 ndfl = near_ / zerop ;
00605 xrange = a * wd2 * 2 * zerop / near_;
00606
00607 l = -a*wd2;
00608 r = a*wd2;
00609 t = wd2;
00610 b = -wd2;
00611
00612 double offset = 0.5 * OpenFlipper::Options::eyeDistance () * xrange;
00613 double offset2 = offset * ndfl;
00614
00615 int vp_l, vp_b, vp_w, vp_h;
00616 glstate_->get_viewport (vp_l, vp_b, vp_w, vp_h);
00617
00618 std::vector<float> le = OpenFlipper::Options::anaglyphLeftEyeColorMatrix();
00619 std::vector<float> re = OpenFlipper::Options::anaglyphRightEyeColorMatrix();
00620
00621
00622 glMatrixMode(GL_PROJECTION);
00623 glLoadIdentity();
00624 glFrustum(l+offset2, r+offset2, b, t, near_, far_);
00625 glTranslatef(offset, 0.0, 0.0);
00626 glMatrixMode(GL_MODELVIEW);
00627 glstate_->clearBuffers ();
00628 glClear(GL_DEPTH_BUFFER_BIT);
00629 drawScene_mono();
00630
00631 glBindTexture (GL_TEXTURE_RECTANGLE_NV, agTexture_[0]);
00632 glCopyTexSubImage2D (GL_TEXTURE_RECTANGLE_NV, 0, 0, 0, vp_l, vp_b, vp_w, vp_h);
00633 glBindTexture (GL_TEXTURE_RECTANGLE_NV, 0);
00634
00635
00636 glMatrixMode(GL_PROJECTION);
00637 glLoadIdentity();
00638 glFrustum(l-offset2, r-offset2, b, t, near_, far_);
00639 glTranslatef(-offset, 0.0, 0.0);
00640 glMatrixMode(GL_MODELVIEW);
00641 glstate_->clearBuffers ();
00642 glClear(GL_DEPTH_BUFFER_BIT);
00643 drawScene_mono();
00644
00645 glBindTexture (GL_TEXTURE_RECTANGLE_NV, agTexture_[1]);
00646 glCopyTexSubImage2D (GL_TEXTURE_RECTANGLE_NV, 0, 0, 0, vp_l, vp_b, vp_w, vp_h);
00647 glBindTexture (GL_TEXTURE_RECTANGLE_NV, 0);
00648
00649 glActiveTexture (GL_TEXTURE0);
00650 glBindTexture (GL_TEXTURE_RECTANGLE_NV, agTexture_[0]);
00651 glEnable (GL_TEXTURE_RECTANGLE_NV);
00652
00653 glActiveTexture (GL_TEXTURE1);
00654 glBindTexture (GL_TEXTURE_RECTANGLE_NV, agTexture_[1]);
00655 glEnable (GL_TEXTURE_RECTANGLE_NV);
00656
00657 glEnable (GL_FRAGMENT_PROGRAM_ARB);
00658 glBindProgramARB (GL_FRAGMENT_PROGRAM_ARB, agProgram_);
00659
00660 glProgramEnvParameter4fARB (GL_FRAGMENT_PROGRAM_ARB, 0, le[0], le[3], le[6], 0.0);
00661 glProgramEnvParameter4fARB (GL_FRAGMENT_PROGRAM_ARB, 1, le[1], le[4], le[7], 0.0);
00662 glProgramEnvParameter4fARB (GL_FRAGMENT_PROGRAM_ARB, 2, le[2], le[5], le[8], 0.0);
00663
00664 glProgramEnvParameter4fARB (GL_FRAGMENT_PROGRAM_ARB, 3, re[0], re[3], re[6], 0.0);
00665 glProgramEnvParameter4fARB (GL_FRAGMENT_PROGRAM_ARB, 4, re[1], re[4], re[7], 0.0);
00666 glProgramEnvParameter4fARB (GL_FRAGMENT_PROGRAM_ARB, 5, re[2], re[5], re[8], 0.0);
00667
00668 glMatrixMode(GL_PROJECTION);
00669 glLoadIdentity();
00670 glOrtho(0, vp_w, vp_h, 0, 0, 1.0);
00671 glMatrixMode(GL_MODELVIEW);
00672 glLoadIdentity();
00673
00674 glDisable (GL_DEPTH_TEST);
00675
00676 glBegin (GL_QUADS);
00677 glMultiTexCoord2f (GL_TEXTURE0, 0, vp_h);
00678 glMultiTexCoord2f (GL_TEXTURE1, 0, vp_h);
00679 glVertex2i(0, 0);
00680 glMultiTexCoord2f (GL_TEXTURE0, 0, 0);
00681 glMultiTexCoord2f (GL_TEXTURE1, 0, 0);
00682 glVertex2i(0, vp_h);
00683 glMultiTexCoord2f (GL_TEXTURE0, vp_w, 0);
00684 glMultiTexCoord2f (GL_TEXTURE1, vp_w, 0);
00685 glVertex2i(vp_w, vp_h);
00686 glMultiTexCoord2f (GL_TEXTURE0, vp_w, vp_h);
00687 glMultiTexCoord2f (GL_TEXTURE1, vp_w, vp_h);
00688 glVertex2i(vp_w, 0);
00689 glEnd ();
00690
00691 glEnable (GL_DEPTH_TEST);
00692
00693 glBindProgramARB (GL_FRAGMENT_PROGRAM_ARB, 0);
00694 glDisable (GL_FRAGMENT_PROGRAM_ARB);
00695
00696 glActiveTexture (GL_TEXTURE1);
00697 glBindTexture (GL_TEXTURE_RECTANGLE_NV, 0);
00698 glDisable (GL_TEXTURE_RECTANGLE_NV);
00699
00700 glActiveTexture (GL_TEXTURE0);
00701 glBindTexture (GL_TEXTURE_RECTANGLE_NV, 0);
00702 glDisable (GL_TEXTURE_RECTANGLE_NV);
00703
00704 }
00705
00706
00707
00708