Salome HOME
Merge branch 'oscar/imps_2017'
[modules/gui.git] / src / VTKViewer / VTKViewer_OpenGLHelper.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
24 #include "VTKViewer_OpenGLHelper.h"
25
26 #ifndef WIN32
27 # ifndef GLX_GLXEXT_LEGACY
28 #  define GLX_GLXEXT_LEGACY
29 # endif
30 # include <GL/glx.h>
31 # include <dlfcn.h>
32 #else
33 # include <wingdi.h>
34 #endif
35
36 #ifndef WIN32
37 #define GL_GetProcAddress( x )   glXGetProcAddressARB( (const GLubyte*)x )
38 #else
39 #define GL_GetProcAddress( x )   wglGetProcAddress( (const LPCSTR)x )
40 #endif 
41
42 // ============================================================================
43 // function : VTKViewer_OpenGLHelper
44 // purpose  :
45 // ============================================================================
46 VTKViewer_OpenGLHelper::VTKViewer_OpenGLHelper()
47 : vglShaderSourceARB             (NULL),
48   vglCreateShaderObjectARB       (NULL),
49   vglCompileShaderARB            (NULL),
50   vglCreateProgramObjectARB      (NULL),
51   vglAttachObjectARB             (NULL),
52   vglLinkProgramARB              (NULL),
53   vglUseProgramObjectARB         (NULL),
54   vglGenBuffersARB               (NULL),
55   vglBindBufferARB               (NULL),
56   vglBufferDataARB               (NULL),
57   vglDeleteBuffersARB            (NULL),
58   vglGetAttribLocationARB        (NULL),
59   vglVertexAttribPointerARB      (NULL),
60   vglEnableVertexAttribArrayARB  (NULL),
61   vglDisableVertexAttribArrayARB (NULL),
62 #ifdef VTK_OPENGL2
63   vglDetachObjectARB             (NULL),
64   vglDeleteObjectARB             (NULL),
65   vglValidateProgramARB          (NULL),
66   vglGetShaderivARB              (NULL),
67   vglGetProgramivARB             (NULL),
68   vglGetShaderInfoLogARB         (NULL),
69   vglUniformMatrix4fvARB         (NULL),
70   vglGenVertexArraysARB          (NULL),
71   vglBindVertexArrayARB          (NULL),
72   vglUniform1iARB                (NULL),
73   vglGetUniformLocationARB       (NULL),
74 #endif
75   mIsInitialized                 (false)
76 {
77   Init();
78 }
79
80 // ============================================================================
81 // function : ~VTKViewer_OpenGLHelper
82 // purpose  :
83 // ============================================================================
84 VTKViewer_OpenGLHelper::~VTKViewer_OpenGLHelper()
85 {
86   //
87 }
88
89 // ============================================================================
90 // function : Init
91 // purpose  :
92 // ============================================================================
93 void VTKViewer_OpenGLHelper::Init()
94 {
95   if (mIsInitialized)
96     return;
97
98   vglShaderSourceARB = (PFNGLSHADERSOURCEARBPROC)GL_GetProcAddress( "glShaderSourceARB" );
99   if( !vglShaderSourceARB )
100     return;
101
102   vglCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC)GL_GetProcAddress( "glCreateShaderObjectARB" );
103   if( !vglCreateShaderObjectARB )
104     return;
105
106   vglCompileShaderARB = (PFNGLCOMPILESHADERARBPROC)GL_GetProcAddress( "glCompileShaderARB" );
107   if( !vglCompileShaderARB )
108     return;
109
110   vglCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC)GL_GetProcAddress( "glCreateProgramObjectARB" );
111   if( !vglCreateProgramObjectARB )
112     return;
113
114   vglAttachObjectARB = (PFNGLATTACHOBJECTARBPROC)GL_GetProcAddress( "glAttachObjectARB" );
115   if( !vglAttachObjectARB )
116     return;
117
118   vglLinkProgramARB = (PFNGLLINKPROGRAMARBPROC)GL_GetProcAddress( "glLinkProgramARB" );
119   if( !vglLinkProgramARB )
120     return;
121
122   vglUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)GL_GetProcAddress( "glUseProgramObjectARB" );
123   if( !vglUseProgramObjectARB )
124     return;
125
126   vglGenBuffersARB = (PFNGLGENBUFFERSARBPROC)GL_GetProcAddress( "glGenBuffersARB" );
127   if( !vglGenBuffersARB )
128     return;
129
130   vglBindBufferARB = (PFNGLBINDBUFFERARBPROC)GL_GetProcAddress( "glBindBufferARB" );
131   if( !vglBindBufferARB )
132     return;
133
134   vglBufferDataARB = (PFNGLBUFFERDATAARBPROC)GL_GetProcAddress( "glBufferDataARB" );
135   if( !vglBufferDataARB )
136     return;
137
138   vglDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)GL_GetProcAddress( "glDeleteBuffersARB" );
139   if( !vglDeleteBuffersARB )
140     return;
141
142   vglGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC)GL_GetProcAddress( "glGetAttribLocation" );
143   if( !vglGetAttribLocationARB )
144     return;
145
146   vglVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC)GL_GetProcAddress( "glVertexAttribPointer" );
147   if( !vglVertexAttribPointerARB )
148     return;
149
150   vglEnableVertexAttribArrayARB = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC)GL_GetProcAddress( "glEnableVertexAttribArray" );
151   if(!vglEnableVertexAttribArrayARB)
152     return;
153
154   vglDisableVertexAttribArrayARB = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC)GL_GetProcAddress( "glDisableVertexAttribArray" );
155   if(!vglDisableVertexAttribArrayARB)
156     return;
157
158 #ifdef VTK_OPENGL2
159   vglDetachObjectARB = (PFNGLDETACHOBJECTARBPROC)GL_GetProcAddress( "glDetachObjectARB" );
160   if( !vglDetachObjectARB )
161     return;
162
163   vglDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC)GL_GetProcAddress( "glDeleteObjectARB" );
164   if( !vglDeleteObjectARB )
165     return;
166
167   vglValidateProgramARB = (PFNGLVALIDATEPROGRAMARBPROC)GL_GetProcAddress( "glValidateProgramARB" );
168   if ( !vglValidateProgramARB )
169     return;
170
171   vglGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC)GL_GetProcAddress( "glGetUniformLocationARB" );
172   if( !vglGetUniformLocationARB )
173     return;
174
175   vglGetShaderivARB = (PFNGLGETSHADERIVPROC)GL_GetProcAddress( "glGetShaderiv" );
176   if( !vglGetShaderivARB )
177     return;
178
179   vglGetProgramivARB = (PFNGLGETPROGRAMIVPROC)GL_GetProcAddress( "glGetProgramiv" );
180   if( !vglGetProgramivARB )
181     return;
182
183   vglGetShaderInfoLogARB = (PFNGLGETSHADERINFOLOGPROC)GL_GetProcAddress( "glGetShaderInfoLog" );
184   if( !vglGetShaderInfoLogARB )
185     return;
186
187   vglUniformMatrix4fvARB = (PFNGLUNIFORMMATRIX4FVARBPROC)GL_GetProcAddress( "glUniformMatrix4fv" );
188   if( !vglUniformMatrix4fvARB )
189     return;
190
191   vglGenVertexArraysARB = (PFNGLGENVERTEXARRAYSARBPROC)GL_GetProcAddress( "glGenVertexArrays" );
192   if( !vglGenVertexArraysARB )
193     return;
194
195   vglBindVertexArrayARB = (PFNGLBINDVERTEXARRAYARBPROC)GL_GetProcAddress( "glBindVertexArray" );
196   if( !vglBindVertexArrayARB )
197     return;
198
199   vglUniform1iARB = (PFNGLUNIFORM1IARBPROC)GL_GetProcAddress( "glUniform1i" );
200   if( !vglUniform1iARB )
201     return;
202 #endif
203
204   mIsInitialized = true;
205   return;
206 }
207
208 namespace GUI_OPENGL
209 {
210         char* readFromFile( std::string fileName )
211         {
212           FILE* file = fopen( fileName.c_str(), "r" );
213
214           char* content = NULL;
215           int count = 0;
216
217           if( file != NULL )
218           {
219                 fseek( file, 0, SEEK_END );
220                 count = ftell( file );
221                 rewind( file );
222
223                 if( count > 0 )
224                 {
225                   content = ( char* )malloc( sizeof( char ) * ( count + 1 ) );
226                   count = fread( content, sizeof( char ), count, file );
227                   content[ count ] = '\0';
228                 }
229                 fclose( file );
230           }
231
232           return content;
233         }
234 }
235 // ============================================================================
236 // function : CreateShaderProgram
237 // purpose  :
238 // ============================================================================
239 bool VTKViewer_OpenGLHelper::CreateShaderProgram (const std::string& theFilePath,
240                                                   GLhandleARB&       theProgram,
241                                                   GLhandleARB&       theVertexShader,
242                                                   GLhandleARB&       theFragmentShader) const
243 {
244 #ifdef VTK_OPENGL2
245   // Create program.
246   theProgram = vglCreateProgramObjectARB();
247   if (theProgram == 0)
248   {
249     std::cerr << "Can't create opengl program." << std::endl;
250     return false;
251   }
252
253   std::string fileName;
254   char*       shaderContent;
255   GLint       linked, compileStatus, validateStatus;
256
257   // Create vertex shader.
258   fileName = theFilePath + ".vs.glsl";
259
260   shaderContent = GUI_OPENGL::readFromFile (fileName);
261
262   theVertexShader = vglCreateShaderObjectARB (GL_VERTEX_SHADER_ARB);
263   vglShaderSourceARB (theVertexShader, 1, (const GLcharARB**)&shaderContent, NULL);
264   vglCompileShaderARB (theVertexShader);
265
266   free( shaderContent );
267
268   vglGetShaderivARB (theVertexShader, GL_COMPILE_STATUS, &compileStatus);
269   if (compileStatus != GL_TRUE)
270   {
271     GLint size;
272     GLchar info[1024];
273
274     vglGetShaderInfoLogARB (theVertexShader, 1024, &size, info);
275     std::cerr << "Can't compile vertex shader." << std::endl;
276     std::cerr << info << std::endl;
277
278     return false;
279   }
280
281   // Create fragment shader.
282   fileName = theFilePath + ".fs.glsl";
283
284   shaderContent = GUI_OPENGL::readFromFile (fileName);
285
286   theFragmentShader = vglCreateShaderObjectARB (GL_FRAGMENT_SHADER_ARB);
287   vglShaderSourceARB (theFragmentShader, 1, (const GLcharARB**)&shaderContent, NULL);
288   vglCompileShaderARB (theFragmentShader);
289
290   free (shaderContent);
291
292   vglGetShaderivARB (theFragmentShader, GL_COMPILE_STATUS, &compileStatus);
293   if (compileStatus != GL_TRUE)
294   {
295     GLint size;
296     GLchar info[1024];
297
298     vglGetShaderInfoLogARB (theVertexShader, 1024, &size, info);
299     std::cerr << "Can't compile fragment shader." << std::endl;
300     std::cerr << info << std::endl;
301     return false;
302   }
303
304   // Attach shaders.
305   vglAttachObjectARB (theProgram, theVertexShader);
306   vglAttachObjectARB (theProgram, theFragmentShader);
307   vglLinkProgramARB  (theProgram);
308
309   vglGetProgramivARB (theProgram, GL_LINK_STATUS, &linked);
310   if (!linked)
311   {
312     std::cerr << "Can't link program." << std::endl;
313     return false;
314   }
315
316   vglValidateProgramARB (theProgram);
317   vglGetProgramivARB (theProgram, GL_VALIDATE_STATUS, &validateStatus);
318
319   if (validateStatus != GL_TRUE)
320   {
321     std::cerr << "Shader program is not validate." << std::endl;
322     return false;
323   }
324
325   return true;
326 #else
327   return false;
328 #endif
329 }
330
331 // ============================================================================
332 // function : DestroyShaderProgram
333 // purpose  :
334 // ============================================================================
335 void VTKViewer_OpenGLHelper::DestroyShaderProgram (GLhandleARB theProgram,
336                                                    GLhandleARB theVertexShader,
337                                                    GLhandleARB theFragmentShader) const
338 {
339 #ifdef VTK_OPENGL2
340   vglDetachObjectARB (theProgram, theVertexShader);
341   vglDetachObjectARB (theProgram, theFragmentShader);
342
343   vglDeleteObjectARB (theVertexShader);
344   vglDeleteObjectARB (theFragmentShader);
345 #endif
346 }
347
348 // ============================================================================
349 // function : SetUniformMatrix
350 // purpose  :
351 // ============================================================================
352 #ifdef VTK_OPENGL2
353 void VTKViewer_OpenGLHelper::SetUniformMatrix (const GLint         theLocation,
354                                                const vtkMatrix4x4* theMatrix) const
355 {
356   float data[16];
357   for (int i = 0; i < 16; ++i)
358   {
359     data[i] = theMatrix->Element[i / 4][i % 4];
360   }
361
362   this->vglUniformMatrix4fvARB (theLocation, 1, GL_FALSE, data);
363 }
364 #endif