Salome HOME
Start potring to the VTK OpenGL2 backend.
[modules/gui.git] / src / VTKViewer / VTKViewer_OpenGLRenderer.cxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
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.
10 //
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.
15 //
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
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "VTKViewer_OpenGLRenderer.h"
24 #include "VTKViewer_Texture.h"
25
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 #ifndef VTK_OPENGL2
34 #include <vtkOpenGLExtensionManager.h>
35 #include <vtkgl.h> // vtkgl namespace
36 #endif
37 #include <vtkImageImport.h>
38 #include <vtkPNGWriter.h>
39 #include <vtkOpenGLTexture.h>
40 #include <vtkTimerLog.h>
41 #include <vtkOpenGL.h>
42 #include <vtkObjectFactory.h>
43
44 vtkStandardNewMacro(VTKViewer_OpenGLRenderer);
45
46 VTKViewer_OpenGLRenderer::VTKViewer_OpenGLRenderer()
47 {
48   this->GradientType = HorizontalGradient;
49 }
50
51 VTKViewer_OpenGLRenderer::~VTKViewer_OpenGLRenderer()
52 {
53 }
54
55 void VTKViewer_OpenGLRenderer::SetGradientType( const int theGradientType )
56 {
57   this->GradientType = theGradientType;
58 }
59
60 void VTKViewer_OpenGLRenderer::Clear(void)
61 {
62   GLbitfield clear_mask = 0;
63
64   if( !this->Transparent() )
65   {
66     glClearColor( static_cast<GLclampf>(this->Background[0]),
67                   static_cast<GLclampf>(this->Background[1]),
68                   static_cast<GLclampf>(this->Background[2]),
69                   static_cast<GLclampf>(0.0));
70     clear_mask |= GL_COLOR_BUFFER_BIT;
71   }
72
73   if( !this->GetPreserveDepthBuffer() )
74   {
75     glClearDepth(static_cast<GLclampf>(1.0));
76     clear_mask |= GL_DEPTH_BUFFER_BIT;
77   }
78
79   vtkDebugMacro(<< "glClear\n");
80   glClear(clear_mask);
81
82   // If gradient background is turned on, draw it now.
83   if( !this->Transparent() &&
84       ( this->GradientBackground || this->TexturedBackground ) )
85   {
86     double aTileViewport[4];
87     this->GetRenderWindow()->GetTileViewport( aTileViewport );
88     glPushAttrib( GL_ENABLE_BIT | GL_TRANSFORM_BIT | GL_TEXTURE_BIT );
89     glDisable( GL_ALPHA_TEST );
90     glDisable( GL_DEPTH_TEST );
91     glDisable( GL_LIGHTING );
92     glDisable( GL_TEXTURE_1D );
93     glDisable( GL_TEXTURE_2D );
94     glDisable( GL_BLEND );
95     glShadeModel( GL_SMOOTH ); // color interpolation
96
97     glMatrixMode( GL_PROJECTION );
98     glPushMatrix();
99     glLoadIdentity();
100     glMatrixMode( GL_MODELVIEW );
101     glPushMatrix();
102     glLoadIdentity();
103
104     glOrtho( aTileViewport[0], aTileViewport[2], aTileViewport[1], aTileViewport[3], -1.0, 1.0 );
105
106     if( this->GradientBackground )
107     {
108       double* corner1 = 0;
109       double* corner2 = 0;
110       double* corner3 = 0;
111       double* corner4 = 0;
112       double dcorner1[3];
113       double dcorner2[3];
114
115       switch( this->GradientType )
116       {
117         case HorizontalGradient:
118           corner1 = this->Background;
119           corner2 = this->Background2;
120           corner3 = this->Background2;
121           corner4 = this->Background;
122           break;
123         case VerticalGradient:
124           corner1 = this->Background2;
125           corner2 = this->Background2;
126           corner3 = this->Background;
127           corner4 = this->Background;
128           break;
129         case FirstDiagonalGradient:
130           corner2 = this->Background2;
131           corner4 = this->Background;
132           dcorner1[0] = dcorner2[0] = 0.5F * ( corner2[0] + corner4[0] );
133           dcorner1[1] = dcorner2[1] = 0.5F * ( corner2[1] + corner4[1] );
134           dcorner1[2] = dcorner2[2] = 0.5F * ( corner2[2] + corner4[2] );
135           corner1 = dcorner1;
136           corner3 = dcorner2;
137           break;
138         case SecondDiagonalGradient:
139           corner1 = this->Background2;  
140           corner3 = this->Background;
141           dcorner1[0] = dcorner2[0] = 0.5F * ( corner1[0] + corner3[0] );
142           dcorner1[1] = dcorner2[1] = 0.5F * ( corner1[1] + corner3[1] );
143           dcorner1[2] = dcorner2[2] = 0.5F * ( corner1[2] + corner3[2] );
144           corner2 = dcorner1;
145           corner4 = dcorner2;
146           break;
147         case FirstCornerGradient:
148           corner1 = this->Background2;
149           corner2 = this->Background2;
150           corner3 = this->Background2;
151           corner4 = this->Background;
152           break;
153         case SecondCornerGradient:
154           corner1 = this->Background2;
155           corner2 = this->Background2;
156           corner3 = this->Background;
157           corner4 = this->Background2;
158           break;
159         case ThirdCornerGradient:
160           corner1 = this->Background2;
161           corner2 = this->Background;
162           corner3 = this->Background2;
163           corner4 = this->Background2;
164           break;
165         case FourthCornerGradient:
166           corner1 = this->Background;
167           corner2 = this->Background2;
168           corner3 = this->Background2;
169           corner4 = this->Background2;
170           break;
171         default: // just in case
172           corner1 = this->Background;
173           corner2 = this->Background;
174           corner3 = this->Background;
175           corner4 = this->Background;
176           break;
177       }
178
179       glBegin( GL_TRIANGLE_FAN );
180       if( this->GradientType != FirstCornerGradient && this->GradientType != ThirdCornerGradient )
181       {
182         glColor3f( corner1[0], corner1[1], corner1[2] ); glVertex2f( 0.F, 0.F );
183         glColor3f( corner2[0], corner2[1], corner2[2] ); glVertex2f( 1.F, 0.F );
184         glColor3f( corner3[0], corner3[1], corner3[2] ); glVertex2f( 1.F, 1.F );
185         glColor3f( corner4[0], corner4[1], corner4[2] ); glVertex2f( 0.F, 1.F );
186       }
187       else //if( this->GradientType == FirstCornerGradient || this->GradientType == ThirdCornerGradient )
188       {
189         glColor3f( corner2[0], corner2[1], corner2[2] ); glVertex2f( 1.F, 0.F );
190         glColor3f( corner3[0], corner3[1], corner3[2] ); glVertex2f( 1.F, 1.F );
191         glColor3f( corner4[0], corner4[1], corner4[2] ); glVertex2f( 0.F, 1.F );
192         glColor3f( corner1[0], corner1[1], corner1[2] ); glVertex2f( 0.F, 0.F );
193       }
194       glEnd();
195     }
196
197     if( this->TexturedBackground && this->BackgroundTexture )
198     {
199       if( VTKViewer_Texture* aTexture = VTKViewer_Texture::SafeDownCast( this->BackgroundTexture ) )
200       {
201         glEnable( GL_TEXTURE_2D );
202
203         aTexture->Render( this );
204
205         // NOTE: By default the mode is GL_MODULATE. Since the user
206         // cannot set the mode, the default is set to replace.
207         glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
208         glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
209         glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
210
211         // NOTE: vtkTexture Render enables the alpha test
212         // so that no buffer is affected if alpha of incoming fragment is
213         // below the threshold. Here we have to enable it so that it won't
214         // rejects the fragments of the quad as the alpha is set to 0 on it.
215         glDisable( GL_ALPHA_TEST );
216
217         GLfloat texX = 1.F; // texture <s> coordinate
218         GLfloat texY = 1.F; // texture <t> coordinate
219         GLfloat x_offset = 0.5, y_offset = 0.5;
220         GLfloat coeff = 0.5;
221
222         // OCCT issue 0023102: Change the algorithm of rendering the
223         // 3d viewer background using tiled texture
224         // Setting this coefficient to -1.F allows to tile textures relatively
225         // to the top-left corner of the view (value 1.F corresponds to the
226         // initial behaviour - tiling from the bottom-left corner)
227         GLfloat aCoef = -1.F;
228
229         int aPosition = aTexture->GetPosition();
230         int aWidth = aTexture->GetWidth();
231         int aHeight = aTexture->GetHeight();
232         int aViewWidth = this->RenderWindow->GetSize()[0];
233         int aViewHeight = this->RenderWindow->GetSize()[1];                    
234         if( aPosition == VTKViewer_Texture::Centered )
235         {
236           x_offset = ( (GLfloat)aWidth / (GLfloat)aViewWidth ) / 2.;
237           y_offset = ( (GLfloat)aHeight / (GLfloat)aViewHeight ) / 2.;
238         }
239         else if( aPosition == VTKViewer_Texture::Tiled )
240         {
241           texX = (GLfloat)aViewWidth / (GLfloat)aWidth;
242           texY = (GLfloat)aViewHeight / (GLfloat)aHeight;
243         }
244
245         // Note that texture is mapped using GL_REPEAT wrapping mode so integer part
246         // is simply ignored, and negative multiplier is here for convenience only
247         // and does not result e.g. in texture mirroring
248         glBegin( GL_QUADS );
249         glTexCoord2f(  0.F,          0.F ); glVertex2f( -x_offset + coeff, -aCoef * y_offset + coeff );
250         glTexCoord2f( texX,          0.F ); glVertex2f(  x_offset + coeff, -aCoef * y_offset + coeff );
251         glTexCoord2f( texX, aCoef * texY ); glVertex2f(  x_offset + coeff,  aCoef * y_offset + coeff );
252         glTexCoord2f(  0.F, aCoef * texY ); glVertex2f( -x_offset + coeff,  aCoef * y_offset + coeff );
253         glEnd();
254       }
255     }
256
257     glPopMatrix();
258     glMatrixMode( GL_PROJECTION );
259     glPopMatrix();
260     glMatrixMode( GL_MODELVIEW );
261
262     glPopAttrib();
263   }
264 }