Back to index

salome-gui  6.5.0
VTKViewer_OpenGLRenderer.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 #include "VTKViewer_OpenGLRenderer.h"
00024 #include "VTKViewer_Texture.h"
00025 
00026 #include <vtkCuller.h>
00027 #include <vtkLightCollection.h>
00028 #include <vtkObjectFactory.h>
00029 #include <vtkOpenGLCamera.h>
00030 #include <vtkOpenGLLight.h>
00031 #include <vtkOpenGLProperty.h>
00032 #include <vtkRenderWindow.h>
00033 #include <vtkOpenGLExtensionManager.h>
00034 #include <vtkgl.h> // vtkgl namespace
00035 #include <vtkImageImport.h>
00036 #include <vtkPNGWriter.h>
00037 #include <vtkOpenGLTexture.h>
00038 #include <vtkTimerLog.h>
00039 #include <vtkOpenGL.h>
00040 #include <vtkObjectFactory.h>
00041 
00042 vtkStandardNewMacro(VTKViewer_OpenGLRenderer);
00043 
00044 VTKViewer_OpenGLRenderer::VTKViewer_OpenGLRenderer()
00045 {
00046   this->GradientType = HorizontalGradient;
00047 }
00048 
00049 VTKViewer_OpenGLRenderer::~VTKViewer_OpenGLRenderer()
00050 {
00051 }
00052 
00053 void VTKViewer_OpenGLRenderer::SetGradientType( const int theGradientType )
00054 {
00055   this->GradientType = theGradientType;
00056 }
00057 
00058 void VTKViewer_OpenGLRenderer::Clear(void)
00059 {
00060   GLbitfield clear_mask = 0;
00061 
00062   if( !this->Transparent() )
00063   {
00064     glClearColor( static_cast<GLclampf>(this->Background[0]),
00065                   static_cast<GLclampf>(this->Background[1]),
00066                   static_cast<GLclampf>(this->Background[2]),
00067                   static_cast<GLclampf>(0.0));
00068     clear_mask |= GL_COLOR_BUFFER_BIT;
00069   }
00070 
00071   if( !this->GetPreserveDepthBuffer() )
00072   {
00073     glClearDepth(static_cast<GLclampf>(1.0));
00074     clear_mask |= GL_DEPTH_BUFFER_BIT;
00075   }
00076 
00077   vtkDebugMacro(<< "glClear\n");
00078   glClear(clear_mask);
00079 
00080   // If gradient background is turned on, draw it now.
00081   if( !this->Transparent() &&
00082       ( this->GradientBackground || this->TexturedBackground ) )
00083   {
00084     double aTileViewport[4];
00085     this->GetRenderWindow()->GetTileViewport( aTileViewport );
00086     glPushAttrib( GL_ENABLE_BIT | GL_TRANSFORM_BIT | GL_TEXTURE_BIT );
00087     glDisable( GL_ALPHA_TEST );
00088     glDisable( GL_DEPTH_TEST );
00089     glDisable( GL_LIGHTING );
00090     glDisable( GL_TEXTURE_1D );
00091     glDisable( GL_TEXTURE_2D );
00092     glDisable( GL_BLEND );
00093     glShadeModel( GL_SMOOTH ); // color interpolation
00094 
00095     glMatrixMode( GL_PROJECTION );
00096     glPushMatrix();
00097     glLoadIdentity();
00098     glMatrixMode( GL_MODELVIEW );
00099     glPushMatrix();
00100     glLoadIdentity();
00101 
00102     glOrtho( aTileViewport[0], aTileViewport[2], aTileViewport[1], aTileViewport[3], -1.0, 1.0 );
00103 
00104     if( this->GradientBackground )
00105     {
00106       double* corner1 = 0;
00107       double* corner2 = 0;
00108       double* corner3 = 0;
00109       double* corner4 = 0;
00110       double dcorner1[3];
00111       double dcorner2[3];
00112 
00113       switch( this->GradientType )
00114       {
00115         case HorizontalGradient:
00116           corner1 = this->Background;
00117           corner2 = this->Background2;
00118           corner3 = this->Background2;
00119           corner4 = this->Background;
00120           break;
00121         case VerticalGradient:
00122           corner1 = this->Background2;
00123           corner2 = this->Background2;
00124           corner3 = this->Background;
00125           corner4 = this->Background;
00126           break;
00127         case FirstDiagonalGradient:
00128           corner2 = this->Background2;
00129           corner4 = this->Background;
00130           dcorner1[0] = dcorner2[0] = 0.5F * ( corner2[0] + corner4[0] );
00131           dcorner1[1] = dcorner2[1] = 0.5F * ( corner2[1] + corner4[1] );
00132           dcorner1[2] = dcorner2[2] = 0.5F * ( corner2[2] + corner4[2] );
00133           corner1 = dcorner1;
00134           corner3 = dcorner2;
00135           break;
00136         case SecondDiagonalGradient:
00137           corner1 = this->Background2;  
00138           corner3 = this->Background;
00139           dcorner1[0] = dcorner2[0] = 0.5F * ( corner1[0] + corner3[0] );
00140           dcorner1[1] = dcorner2[1] = 0.5F * ( corner1[1] + corner3[1] );
00141           dcorner1[2] = dcorner2[2] = 0.5F * ( corner1[2] + corner3[2] );
00142           corner2 = dcorner1;
00143           corner4 = dcorner2;
00144           break;
00145         case FirstCornerGradient:
00146           corner1 = this->Background2;
00147           corner2 = this->Background2;
00148           corner3 = this->Background2;
00149           corner4 = this->Background;
00150           break;
00151         case SecondCornerGradient:
00152           corner1 = this->Background2;
00153           corner2 = this->Background2;
00154           corner3 = this->Background;
00155           corner4 = this->Background2;
00156           break;
00157         case ThirdCornerGradient:
00158           corner1 = this->Background2;
00159           corner2 = this->Background;
00160           corner3 = this->Background2;
00161           corner4 = this->Background2;
00162           break;
00163         case FourthCornerGradient:
00164           corner1 = this->Background;
00165           corner2 = this->Background2;
00166           corner3 = this->Background2;
00167           corner4 = this->Background2;
00168           break;
00169         default: // just in case
00170           corner1 = this->Background;
00171           corner2 = this->Background;
00172           corner3 = this->Background;
00173           corner4 = this->Background;
00174           break;
00175       }
00176 
00177       glBegin( GL_TRIANGLE_FAN );
00178       if( this->GradientType != FirstCornerGradient && this->GradientType != ThirdCornerGradient )
00179       {
00180         glColor3f( corner1[0], corner1[1], corner1[2] ); glVertex2f( 0.F, 0.F );
00181         glColor3f( corner2[0], corner2[1], corner2[2] ); glVertex2f( 1.F, 0.F );
00182         glColor3f( corner3[0], corner3[1], corner3[2] ); glVertex2f( 1.F, 1.F );
00183         glColor3f( corner4[0], corner4[1], corner4[2] ); glVertex2f( 0.F, 1.F );
00184       }
00185       else //if( this->GradientType == FirstCornerGradient || this->GradientType == ThirdCornerGradient )
00186       {
00187         glColor3f( corner2[0], corner2[1], corner2[2] ); glVertex2f( 1.F, 0.F );
00188         glColor3f( corner3[0], corner3[1], corner3[2] ); glVertex2f( 1.F, 1.F );
00189         glColor3f( corner4[0], corner4[1], corner4[2] ); glVertex2f( 0.F, 1.F );
00190         glColor3f( corner1[0], corner1[1], corner1[2] ); glVertex2f( 0.F, 0.F );
00191       }
00192       glEnd();
00193     }
00194 
00195     if( this->TexturedBackground && this->BackgroundTexture )
00196     {
00197       if( VTKViewer_Texture* aTexture = VTKViewer_Texture::SafeDownCast( this->BackgroundTexture ) )
00198       {
00199         glEnable( GL_TEXTURE_2D );
00200 
00201         aTexture->Render( this );
00202 
00203         // NOTE: By default the mode is GL_MODULATE. Since the user
00204         // cannot set the mode, the default is set to replace.
00205         glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
00206         glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
00207         glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
00208 
00209         // NOTE: vtkTexture Render enables the alpha test
00210         // so that no buffer is affected if alpha of incoming fragment is
00211         // below the threshold. Here we have to enable it so that it won't
00212         // rejects the fragments of the quad as the alpha is set to 0 on it.
00213         glDisable( GL_ALPHA_TEST );
00214 
00215         GLfloat texX = 1.F; // texture <s> coordinate
00216         GLfloat texY = 1.F; // texture <t> coordinate
00217         GLfloat x_offset = 0.5, y_offset = 0.5;
00218         GLfloat coeff = 0.5;
00219 
00220         // OCCT issue 0023102: Change the algorithm of rendering the
00221         // 3d viewer background using tiled texture
00222         // Setting this coefficient to -1.F allows to tile textures relatively
00223         // to the top-left corner of the view (value 1.F corresponds to the
00224         // initial behaviour - tiling from the bottom-left corner)
00225         GLfloat aCoef = -1.F;
00226 
00227         int aPosition = aTexture->GetPosition();
00228         int aWidth = aTexture->GetWidth();
00229         int aHeight = aTexture->GetHeight();
00230         int aViewWidth = this->RenderWindow->GetSize()[0];
00231         int aViewHeight = this->RenderWindow->GetSize()[1];                    
00232         if( aPosition == VTKViewer_Texture::Centered )
00233         {
00234           x_offset = ( (GLfloat)aWidth / (GLfloat)aViewWidth ) / 2.;
00235           y_offset = ( (GLfloat)aHeight / (GLfloat)aViewHeight ) / 2.;
00236         }
00237         else if( aPosition == VTKViewer_Texture::Tiled )
00238         {
00239           texX = (GLfloat)aViewWidth / (GLfloat)aWidth;
00240           texY = (GLfloat)aViewHeight / (GLfloat)aHeight;
00241         }
00242 
00243         // Note that texture is mapped using GL_REPEAT wrapping mode so integer part
00244         // is simply ignored, and negative multiplier is here for convenience only
00245         // and does not result e.g. in texture mirroring
00246         glBegin( GL_QUADS );
00247         glTexCoord2f(  0.F,          0.F ); glVertex2f( -x_offset + coeff, -aCoef * y_offset + coeff );
00248         glTexCoord2f( texX,          0.F ); glVertex2f(  x_offset + coeff, -aCoef * y_offset + coeff );
00249         glTexCoord2f( texX, aCoef * texY ); glVertex2f(  x_offset + coeff,  aCoef * y_offset + coeff );
00250         glTexCoord2f(  0.F, aCoef * texY ); glVertex2f( -x_offset + coeff,  aCoef * y_offset + coeff );
00251         glEnd();
00252       }
00253     }
00254 
00255     glPopMatrix();
00256     glMatrixMode( GL_PROJECTION );
00257     glPopMatrix();
00258     glMatrixMode( GL_MODELVIEW );
00259 
00260     glPopAttrib();
00261   }
00262 }