QtBaseViewerStereo.cc

00001 /*===========================================================================*\
00002  *                                                                           *
00003  *                              OpenFlipper                                  *
00004  *      Copyright (C) 2001-2009 by Computer Graphics Group, RWTH Aachen      *
00005  *                           www.openflipper.org                             *
00006  *                                                                           *
00007  *---------------------------------------------------------------------------*
00008  *  This file is part of OpenFlipper.                                        *
00009  *                                                                           *
00010  *  OpenFlipper is free software: you can redistribute it and/or modify      *
00011  *  it under the terms of the GNU Lesser General Public License as           *
00012  *  published by the Free Software Foundation, either version 3 of           *
00013  *  the License, or (at your option) any later version with the              *
00014  *  following exceptions:                                                    *
00015  *                                                                           *
00016  *  If other files instantiate templates or use macros                       *
00017  *  or inline functions from this file, or you compile this file and         *
00018  *  link it with other files to produce an executable, this file does        *
00019  *  not by itself cause the resulting executable to be covered by the        *
00020  *  GNU Lesser General Public License. This exception does not however       *
00021  *  invalidate any other reasons why the executable file might be            *
00022  *  covered by the GNU Lesser General Public License.                        *
00023  *                                                                           *
00024  *  OpenFlipper is distributed in the hope that it will be useful,           *
00025  *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
00026  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
00027  *  GNU Lesser General Public License for more details.                      *
00028  *                                                                           *
00029  *  You should have received a copy of the GNU LesserGeneral Public          *
00030  *  License along with OpenFlipper. If not,                                  *
00031  *  see <http://www.gnu.org/licenses/>.                                      *
00032  *                                                                           *
00033 \*===========================================================================*/
00034 
00035 /*===========================================================================*\
00036  *                                                                           *
00037  *   $Revision: 7500 $                                                         *
00038  *   $Author: moebius $                                                      *
00039  *   $Date: 2009-10-22 09:26:52 +0200 (Do, 22. Okt 2009) $                   *
00040  *                                                                           *
00041 \*===========================================================================*/
00042 
00043 
00044 
00045 
00046 //=============================================================================
00047 //
00048 //  CLASS glViewer - IMPLEMENTATION
00049 //
00050 //=============================================================================
00051 
00052 
00053 //== INCLUDES =================================================================
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 //== NAMESPACES ===============================================================
00071 
00072 
00073 //== IMPLEMENTATION ==========================================================
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   // left eye
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   // right eye
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   // creating a color texture
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   // creating an 24-bit depth + 8-bit stencil texture
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   // Disable textures
00207   // ======================================================================================================
00208   depthStencilTexture.disable();
00209   colorTexture.disable();
00210   
00211   // ======================================================================================================
00212   // Render the scene
00213   // ======================================================================================================
00214   glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
00215   drawScene_mono();
00216   
00217   // ======================================================================================================
00218   // Copy Scene to Textures
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   // Setup the shaders used to render color and depth info next to each other
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   // Bind textures to different texture units and tell shader where to find them
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   // Render plain textured 
00279   // ======================================================================================================
00280   glDisable(GL_LIGHTING);
00281   glDisable(GL_COLOR_MATERIAL);
00282   glDisable(GL_DEPTH_TEST);
00283 
00284   
00285   // ======================================================================================================
00286   // Setup orthogonal projection
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   // Bind textures to different texture units and tell shader where to find them
00299   // ======================================================================================================
00300   glColor3f(1.0,1.0,1.0);
00301   
00302   // ======================================================================================================
00303   // Clear buffers
00304   // ======================================================================================================
00305   glClearColor(.0, .0, .0, 0);
00306   glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
00307 
00308   // ======================================================================================================
00309   // Render a simple quad (rest is done by shader)
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   // Cleanup (color and depth textures)  
00324   // ======================================================================================================
00325   depthStencilTexture.del();
00326   colorTexture.del();
00327 
00328   // ======================================================================================================
00329   // Compute the header required for the display
00330   // ======================================================================================================
00331   uchar *header = new uchar[ 6 ];
00332 
00333   //   Header ID
00334   //   Basic identifier used by the display to verify the header
00335   header[0] = 241; // Header_ID1 = 11110001
00336   
00337   //   Header content type
00338   //   This entry controls the displays internal rendering based on the input data specified here.
00339   //   There is no info about how this changes the rendering
00340   //   Possible values:
00341   //   0 No Depth
00342   //   1 Signage
00343   //   2 Movie
00344   //   3 Game
00345   //   4 CGI
00346   //   5 Still
00347   header[1] = 3;   // Hdr_Content_type (Game) = 00000011 (Gaming Mode)
00348   
00349   //   Header Factor
00350   //   Each 3D Display has a 'Display recommended depth value', which corresponds to an
00351   //   acceptable maximum depth factor value for that specific type of display. This value strongly
00352   //   depends on the lens design. The factor field in the header contains the percentage to be
00353   //   used from the display recommended depth value. The value of 64 corresponds with the 100%
00354   //   of the display recommended depth value. It is allowed to use values higher than 64. The factor
00355   //   works on a linear scale and is multiplied with the factor controlled by the user in the Display
00356   //   Control Tool.
00357   //   Value range: 0-255 (default 64)
00358   header[2] = 64;  // Hdr_Factor
00359   
00360   //   Header Offset CC
00361   //   Values in the Depth map equal to the header-offset value will be located on the plane of the
00362   //   display. All values in the disparity map with a higher value will de displayed in front of the
00363   //   display.
00364   //   Offset_CC is the offset controlled by the Content Creator. In the system there is also an
00365   //   Offset_user present, which is controlled by the user using the Display Control Tool.
00366   //   Value Range: 0-255 (default 128)
00367   header[3] = 128; // Hdr_Offset_CC
00368   
00369   //   Header select
00370   //   When all select signals are low the rendering settings are set to optimal settings for the content
00371   //   type denoted by Hdr_content_type. By making select signals high the settings for Factor and
00372   //   Offset_cc can be controlled individually by the header.
00373   //   Possible Values:
00374   //   0 Use Displays defaults and automatic optimizations
00375   //   1 Use Header provided factor
00376   //   2 Use Header provided offset
00377   //   3 Use both factor and offset
00378   header[4] = 0;   // Hdr_Factor_select(1) + Hdr_Offset_select(1) + reserved(6)
00379   
00380   //   Unused Header entry (leave at 0 !)
00381   header[5] = 0;   // Reserved
00382 
00383   //   Header checksum.
00384   //   The 4-byte EDC field H(6) − H(9) contains an Error Detection Code computed over the first 6
00385   //   header bytes. This EDC uses the standard CRC-32 polynomial as defined in IEEE 802.3 and ITU-T
00386   //   V.42. The initial value and final XOR value are both 0.
00387   //   unsigned long has 32bit = 4Byte
00388   unsigned long checksum = CalcCRC32(&header[0], 6);
00389 
00390   //   Store the complete header in a bit vector
00391   std::vector< uchar > bitVector;
00392 
00393   // For all bytes of the header
00394   for (int i = 0; i < 6; i++) {
00395     
00396     // For each bit of a headers byte
00397     for ( int j = 7 ; j >= 0 ; --j ) {
00398       
00399       // Red and Green component have to be 0
00400       bitVector.push_back(0);
00401       bitVector.push_back(0);
00402       
00403       // If bit is set, the full component will be set to one otherwise zero
00404       // And the order of the bits has to be reversed!
00405       if ( header[i] & (1 << j ) ) {
00406         bitVector.push_back(255);
00407       } else {
00408         bitVector.push_back(0);
00409       }
00410       
00411       // Only every second pixel is used for the header
00412       // Skip every odd one by filling in 0 for RGB
00413       bitVector.push_back(0);
00414       bitVector.push_back(0);
00415       bitVector.push_back(0);
00416         
00417     }
00418     
00419   }
00420 
00421   // Append checksum to header. 
00422   // Reversed bit order!
00423   for (int i=31; i >= 0; i--) {
00424     
00425     // Red and Green component have to be 0
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     // Only every second pixel is used for the header
00435     // Skip every odd one by filling in 0 for RGB    
00436     bitVector.push_back(0);
00437     bitVector.push_back(0);
00438     bitVector.push_back(0);
00439   }
00440 
00441 
00442   // Select the top left of the renderbuffer and
00443   // write complete header into these bits
00444   glRasterPos2i (0,glHeight()-1); 
00445   glDrawPixels(bitVector.size()/3, 1,GL_RGB ,GL_UNSIGNED_BYTE , &bitVector[0]);
00446   
00447   // ======================================================================================================
00448   // Reset projection and modelview
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   // left eye
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   // draw red channel for left eye
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   // right eye
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   // draw green and blue channel for right eye
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   // left eye
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   // right eye
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 //=============================================================================

acg pic Project OpenFlipper, ©  Computer Graphics Group, RWTH Aachen. Documentation generated using doxygen .