1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include "VTKViewer_OpenGLRenderer.h"
24 #include "VTKViewer_Texture.h"
26 #include <vtkCuller.h>
27 #include <vtkLightCollection.h>
28 #include <vtkObjectFactory.h>
29 #include <vtkOpenGLCamera.h>
30 #include <vtkOpenGLLight.h>
31 #include <vtkOpenGLProperty.h>
32 #include <vtkRenderWindow.h>
33 #include <vtkOpenGLExtensionManager.h>
34 #include <vtkgl.h> // vtkgl namespace
35 #include <vtkImageImport.h>
36 #include <vtkPNGWriter.h>
37 #include <vtkOpenGLTexture.h>
38 #include <vtkTimerLog.h>
39 #include <vtkOpenGL.h>
40 #include <vtkObjectFactory.h>
42 vtkStandardNewMacro(VTKViewer_OpenGLRenderer);
44 VTKViewer_OpenGLRenderer::VTKViewer_OpenGLRenderer()
46 this->GradientType = HorizontalGradient;
49 VTKViewer_OpenGLRenderer::~VTKViewer_OpenGLRenderer()
53 void VTKViewer_OpenGLRenderer::SetGradientType( const int theGradientType )
55 this->GradientType = theGradientType;
58 void VTKViewer_OpenGLRenderer::Clear(void)
60 GLbitfield clear_mask = 0;
62 if( !this->Transparent() )
64 glClearColor( static_cast<GLclampf>(this->Background[0]),
65 static_cast<GLclampf>(this->Background[1]),
66 static_cast<GLclampf>(this->Background[2]),
67 static_cast<GLclampf>(0.0));
68 clear_mask |= GL_COLOR_BUFFER_BIT;
71 if( !this->GetPreserveDepthBuffer() )
73 glClearDepth(static_cast<GLclampf>(1.0));
74 clear_mask |= GL_DEPTH_BUFFER_BIT;
77 vtkDebugMacro(<< "glClear\n");
80 // If gradient background is turned on, draw it now.
81 if( !this->Transparent() &&
82 ( this->GradientBackground || this->TexturedBackground ) )
84 double aTileViewport[4];
85 this->GetRenderWindow()->GetTileViewport( aTileViewport );
86 glPushAttrib( GL_ENABLE_BIT | GL_TRANSFORM_BIT | GL_TEXTURE_BIT );
87 glDisable( GL_ALPHA_TEST );
88 glDisable( GL_DEPTH_TEST );
89 glDisable( GL_LIGHTING );
90 glDisable( GL_TEXTURE_1D );
91 glDisable( GL_TEXTURE_2D );
92 glDisable( GL_BLEND );
93 glShadeModel( GL_SMOOTH ); // color interpolation
95 glMatrixMode( GL_PROJECTION );
98 glMatrixMode( GL_MODELVIEW );
102 glOrtho( aTileViewport[0], aTileViewport[2], aTileViewport[1], aTileViewport[3], -1.0, 1.0 );
104 if( this->GradientBackground )
113 switch( this->GradientType )
115 case HorizontalGradient:
116 corner1 = this->Background;
117 corner2 = this->Background2;
118 corner3 = this->Background2;
119 corner4 = this->Background;
121 case VerticalGradient:
122 corner1 = this->Background2;
123 corner2 = this->Background2;
124 corner3 = this->Background;
125 corner4 = this->Background;
127 case FirstDiagonalGradient:
128 corner2 = this->Background2;
129 corner4 = this->Background;
130 dcorner1[0] = dcorner2[0] = 0.5F * ( corner2[0] + corner4[0] );
131 dcorner1[1] = dcorner2[1] = 0.5F * ( corner2[1] + corner4[1] );
132 dcorner1[2] = dcorner2[2] = 0.5F * ( corner2[2] + corner4[2] );
136 case SecondDiagonalGradient:
137 corner1 = this->Background2;
138 corner3 = this->Background;
139 dcorner1[0] = dcorner2[0] = 0.5F * ( corner1[0] + corner3[0] );
140 dcorner1[1] = dcorner2[1] = 0.5F * ( corner1[1] + corner3[1] );
141 dcorner1[2] = dcorner2[2] = 0.5F * ( corner1[2] + corner3[2] );
145 case FirstCornerGradient:
146 corner1 = this->Background2;
147 corner2 = this->Background2;
148 corner3 = this->Background2;
149 corner4 = this->Background;
151 case SecondCornerGradient:
152 corner1 = this->Background2;
153 corner2 = this->Background2;
154 corner3 = this->Background;
155 corner4 = this->Background2;
157 case ThirdCornerGradient:
158 corner1 = this->Background2;
159 corner2 = this->Background;
160 corner3 = this->Background2;
161 corner4 = this->Background2;
163 case FourthCornerGradient:
164 corner1 = this->Background;
165 corner2 = this->Background2;
166 corner3 = this->Background2;
167 corner4 = this->Background2;
169 default: // just in case
170 corner1 = this->Background;
171 corner2 = this->Background;
172 corner3 = this->Background;
173 corner4 = this->Background;
177 glBegin( GL_TRIANGLE_FAN );
178 if( this->GradientType != FirstCornerGradient && this->GradientType != ThirdCornerGradient )
180 glColor3f( corner1[0], corner1[1], corner1[2] ); glVertex2f( 0.F, 0.F );
181 glColor3f( corner2[0], corner2[1], corner2[2] ); glVertex2f( 1.F, 0.F );
182 glColor3f( corner3[0], corner3[1], corner3[2] ); glVertex2f( 1.F, 1.F );
183 glColor3f( corner4[0], corner4[1], corner4[2] ); glVertex2f( 0.F, 1.F );
185 else //if( this->GradientType == FirstCornerGradient || this->GradientType == ThirdCornerGradient )
187 glColor3f( corner2[0], corner2[1], corner2[2] ); glVertex2f( 1.F, 0.F );
188 glColor3f( corner3[0], corner3[1], corner3[2] ); glVertex2f( 1.F, 1.F );
189 glColor3f( corner4[0], corner4[1], corner4[2] ); glVertex2f( 0.F, 1.F );
190 glColor3f( corner1[0], corner1[1], corner1[2] ); glVertex2f( 0.F, 0.F );
195 if( this->TexturedBackground && this->BackgroundTexture )
197 if( VTKViewer_Texture* aTexture = VTKViewer_Texture::SafeDownCast( this->BackgroundTexture ) )
199 glEnable( GL_TEXTURE_2D );
201 aTexture->Render( this );
203 // NOTE: By default the mode is GL_MODULATE. Since the user
204 // cannot set the mode, the default is set to replace.
205 glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
206 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
207 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
209 // NOTE: vtkTexture Render enables the alpha test
210 // so that no buffer is affected if alpha of incoming fragment is
211 // below the threshold. Here we have to enable it so that it won't
212 // rejects the fragments of the quad as the alpha is set to 0 on it.
213 glDisable( GL_ALPHA_TEST );
215 GLfloat texX = 1.F; // texture <s> coordinate
216 GLfloat texY = 1.F; // texture <t> coordinate
217 GLfloat x_offset = 0.5, y_offset = 0.5;
220 // OCCT issue 0023102: Change the algorithm of rendering the
221 // 3d viewer background using tiled texture
222 // Setting this coefficient to -1.F allows to tile textures relatively
223 // to the top-left corner of the view (value 1.F corresponds to the
224 // initial behaviour - tiling from the bottom-left corner)
225 GLfloat aCoef = -1.F;
227 int aPosition = aTexture->GetPosition();
228 int aWidth = aTexture->GetWidth();
229 int aHeight = aTexture->GetHeight();
230 int aViewWidth = this->RenderWindow->GetSize()[0];
231 int aViewHeight = this->RenderWindow->GetSize()[1];
232 if( aPosition == VTKViewer_Texture::Centered )
234 x_offset = ( (GLfloat)aWidth / (GLfloat)aViewWidth ) / 2.;
235 y_offset = ( (GLfloat)aHeight / (GLfloat)aViewHeight ) / 2.;
237 else if( aPosition == VTKViewer_Texture::Tiled )
239 texX = (GLfloat)aViewWidth / (GLfloat)aWidth;
240 texY = (GLfloat)aViewHeight / (GLfloat)aHeight;
243 // Note that texture is mapped using GL_REPEAT wrapping mode so integer part
244 // is simply ignored, and negative multiplier is here for convenience only
245 // and does not result e.g. in texture mirroring
247 glTexCoord2f( 0.F, 0.F ); glVertex2f( -x_offset + coeff, -aCoef * y_offset + coeff );
248 glTexCoord2f( texX, 0.F ); glVertex2f( x_offset + coeff, -aCoef * y_offset + coeff );
249 glTexCoord2f( texX, aCoef * texY ); glVertex2f( x_offset + coeff, aCoef * y_offset + coeff );
250 glTexCoord2f( 0.F, aCoef * texY ); glVertex2f( -x_offset + coeff, aCoef * y_offset + coeff );
256 glMatrixMode( GL_PROJECTION );
258 glMatrixMode( GL_MODELVIEW );