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