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