0023172: Added workaround for BUGs in Intel OpenGL drivers
[occt.git] / src / OpenGl / OpenGl_Context.cxx
1 // Created on: 2012-01-26
2 // Created by: Kirill GAVRILOV
3 // Copyright (c) 2012-2012 OPEN CASCADE SAS
4 //
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
9 //
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 //
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
19
20
21 #if (defined(_WIN32) || defined(__WIN32__))
22   #include <windows.h>
23 #endif
24
25 #include <OpenGl_Context.hxx>
26
27 #include <OpenGl_ArbVBO.hxx>
28 #include <OpenGl_ExtFBO.hxx>
29 #include <OpenGl_GlCore20.hxx>
30
31 #include <Standard_ProgramError.hxx>
32
33 #if (defined(_WIN32) || defined(__WIN32__))
34   //
35 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
36   #include <dlfcn.h>
37 #else
38   #include <GL/glx.h> // glXGetProcAddress()
39 #endif
40
41 // GL_NVX_gpu_memory_info
42 #ifndef GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX
43   enum
44   {
45     GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX         = 0x9047,
46     GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX   = 0x9048,
47     GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX = 0x9049,
48     GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX           = 0x904A,
49     GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX           = 0x904B
50   };
51 #endif
52
53 IMPLEMENT_STANDARD_HANDLE (OpenGl_Context, Standard_Transient)
54 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Context, Standard_Transient)
55
56 //! Make record shorter to retrieve function pointer using variable with same name
57 #define FindProcShort(theStruct, theFunc) FindProc(#theFunc, theStruct->theFunc)
58
59 // =======================================================================
60 // function : OpenGl_Context
61 // purpose  :
62 // =======================================================================
63 OpenGl_Context::OpenGl_Context()
64 : core12 (NULL),
65   core13 (NULL),
66   core14 (NULL),
67   core15 (NULL),
68   core20 (NULL),
69   arbVBO (NULL),
70   extFBO (NULL),
71   atiMem (Standard_False),
72   nvxMem (Standard_False),
73   myGlLibHandle (NULL),
74   myGlCore20 (NULL),
75   myGlVerMajor (0),
76   myGlVerMinor (0),
77   myIsFeedback (Standard_False),
78   myIsInitialized (Standard_False)
79 {
80 #if defined(MAC_OS_X_VERSION_10_3) && !defined(MACOSX_USE_GLX)
81   // Vendors can not extend functionality on this system
82   // and developers are limited to OpenGL support provided by Mac OS X SDK.
83   // We retrieve function pointers from system library
84   // to generalize extensions support on all platforms.
85   // In this way we also reach binary compatibility benefit between OS releases
86   // if some newest functionality is optionally used.
87   // Notice that GL version / extension availability checks are required
88   // because function pointers may be available but not functionality itself
89   // (depends on renderer).
90   myGlLibHandle = dlopen ("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
91 #endif
92 }
93
94 // =======================================================================
95 // function : ~OpenGl_Context
96 // purpose  :
97 // =======================================================================
98 OpenGl_Context::~OpenGl_Context()
99 {
100   delete myGlCore20;
101   delete arbVBO;
102   delete extFBO;
103 }
104
105 // =======================================================================
106 // function : IsCurrent
107 // purpose  :
108 // =======================================================================
109 Standard_Boolean OpenGl_Context::IsCurrent() const
110 {
111 #if (defined(_WIN32) || defined(__WIN32__))
112   if (myWindowDC == NULL || myGContext == NULL)
113   {
114     return Standard_False;
115   }
116   return (( (HDC )myWindowDC == wglGetCurrentDC())
117       && ((HGLRC )myGContext == wglGetCurrentContext()));
118 #else
119   if (myDisplay == NULL || myWindow == 0 || myGContext == 0)
120   {
121     return Standard_False;
122   }
123
124   return (   ((Display* )myDisplay  == glXGetCurrentDisplay())
125        &&  ((GLXContext )myGContext == glXGetCurrentContext())
126        && ((GLXDrawable )myWindow   == glXGetCurrentDrawable()));
127 #endif
128 }
129
130 // =======================================================================
131 // function : MakeCurrent
132 // purpose  :
133 // =======================================================================
134 Standard_Boolean OpenGl_Context::MakeCurrent()
135 {
136 #if (defined(_WIN32) || defined(__WIN32__))
137   if (myWindowDC == NULL || myGContext == NULL)
138   {
139     Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
140     return Standard_False;
141   }
142
143   // technically it should be safe to activate already bound GL context
144   // however some drivers (Intel etc.) may FAIL doing this for unknown reason
145   if (IsCurrent())
146   {
147     return Standard_True;
148   }
149   else if (wglMakeCurrent ((HDC )myWindowDC, (HGLRC )myGContext) != TRUE)
150   {
151     // notice that glGetError() couldn't be used here!
152     wchar_t* aMsgBuff = NULL;
153     DWORD anErrorCode = GetLastError();
154     FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
155                     NULL, anErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (wchar_t* )&aMsgBuff, 0, NULL);
156     if (aMsgBuff != NULL)
157     {
158       std::wcerr << L"OpenGL interface: wglMakeCurrent() failed. " << aMsgBuff << L" (" << int(anErrorCode) << L")\n";
159       LocalFree (aMsgBuff);
160     }
161     else
162     {
163       std::wcerr << L"OpenGL interface: wglMakeCurrent() failed with #" << int(anErrorCode) << L" error code\n";
164     }
165     return Standard_False;
166   }
167 #else
168   if (myDisplay == NULL || myWindow == 0 || myGContext == 0)
169   {
170     Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
171     return Standard_False;
172   }
173
174   if (!glXMakeCurrent ((Display* )myDisplay, (GLXDrawable )myWindow, (GLXContext )myGContext))
175   {
176     // if there is no current context it might be impossible to use glGetError() correctly
177     //std::cerr << "glXMakeCurrent() failed!\n";
178     return Standard_False;
179   }
180 #endif
181   return Standard_True;
182 }
183
184 // =======================================================================
185 // function : findProc
186 // purpose  :
187 // =======================================================================
188 void* OpenGl_Context::findProc (const char* theFuncName)
189 {
190 #if (defined(_WIN32) || defined(__WIN32__))
191   return wglGetProcAddress (theFuncName);
192 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
193   return (myGlLibHandle != NULL) ? dlsym (myGlLibHandle, theFuncName) : NULL;
194 #else
195   return (void* )glXGetProcAddress ((const GLubyte* )theFuncName);
196 #endif
197 }
198
199 // =======================================================================
200 // function : CheckExtension
201 // purpose  :
202 // =======================================================================
203 Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtName) const
204 {
205   if (theExtName  == NULL)
206   {
207     std::cerr << "CheckExtension called with NULL string!\n";
208     return Standard_False;
209   }
210   int anExtNameLen = strlen (theExtName);
211
212   // available since OpenGL 3.0
213   // and the ONLY way to check extensions with OpenGL 3.1+ core profile
214   /**if (IsGlGreaterEqual (3, 0))
215   {
216     GLint anExtNb = 0;
217     glGetIntegerv (GL_NUM_EXTENSIONS, &anExtNb);
218     for (GLint anIter = 0; anIter < anExtNb; ++anIter)
219     {
220       const char* anExtension = (const char* )core30->glGetStringi (GL_EXTENSIONS, (GLuint )anIter);
221       if (anExtension[anExtNameLen] == '\0' &&
222           strncmp (anExtension, theExtName, anExtNameLen) == 0)
223       {
224         return Standard_True;
225       }
226     }
227     return Standard_False;
228   }*/
229
230   // use old way with huge string for all extensions
231   const char* anExtString = (const char* )glGetString (GL_EXTENSIONS);
232   if (anExtString == NULL)
233   {
234     std::cerr << "glGetString (GL_EXTENSIONS) returns NULL! No GL context?\n";
235     return Standard_False;
236   }
237
238   // Search for theExtName in the extensions string.
239   // Use of strstr() is not sufficient because extension names can be prefixes of other extension names.
240   char* aPtrIter = (char* )anExtString;
241   const char* aPtrEnd = aPtrIter + strlen (anExtString);
242   while (aPtrIter < aPtrEnd)
243   {
244     int n = strcspn (aPtrIter, " ");
245     if ((n == anExtNameLen) && (strncmp (aPtrIter, theExtName, anExtNameLen) == 0))
246     {
247       return Standard_True;
248     }
249     aPtrIter += (n + 1);
250   }
251   return Standard_False;
252 }
253
254 // =======================================================================
255 // function : Init
256 // purpose  :
257 // =======================================================================
258 Standard_Boolean OpenGl_Context::Init()
259 {
260   if (myIsInitialized)
261   {
262     return Standard_True;
263   }
264
265 #if (defined(_WIN32) || defined(__WIN32__))
266   myWindowDC = (Aspect_Handle )wglGetCurrentDC();
267   myGContext = (Aspect_RenderingContext )wglGetCurrentContext();
268 #else
269   myDisplay  = (Aspect_Display )glXGetCurrentDisplay();
270   myGContext = (Aspect_RenderingContext )glXGetCurrentContext();
271   myWindow   = (Aspect_Drawable )glXGetCurrentDrawable();
272 #endif
273   if (myGContext == NULL)
274   {
275     return Standard_False;
276   }
277
278   init();
279   myIsInitialized = Standard_True;
280   return Standard_True;
281 }
282
283 // =======================================================================
284 // function : Init
285 // purpose  :
286 // =======================================================================
287 #if (defined(_WIN32) || defined(__WIN32__))
288 Standard_Boolean OpenGl_Context::Init (const Aspect_Handle           theWindow,
289                                        const Aspect_Handle           theWindowDC,
290                                        const Aspect_RenderingContext theGContext)
291 #else
292 Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable         theWindow,
293                                        const Aspect_Display          theDisplay,
294                                        const Aspect_RenderingContext theGContext)
295 #endif
296 {
297   Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called only once!");
298
299   myWindow   = theWindow;
300   myGContext = theGContext;
301 #if (defined(_WIN32) || defined(__WIN32__))
302   myWindowDC = theWindowDC;
303 #else
304   myDisplay  = theDisplay;
305 #endif
306   if (myGContext == NULL || !MakeCurrent())
307   {
308     return Standard_False;
309   }
310
311   init();
312   myIsInitialized = Standard_True;
313   return Standard_True;
314 }
315
316 // =======================================================================
317 // function : ResetErrors
318 // purpose  :
319 // =======================================================================
320 void OpenGl_Context::ResetErrors()
321 {
322   while (glGetError() != GL_NO_ERROR)
323   {
324     //
325   }
326 }
327
328 // =======================================================================
329 // function : readGlVersion
330 // purpose  :
331 // =======================================================================
332 void OpenGl_Context::readGlVersion()
333 {
334   // reset values
335   myGlVerMajor = 0;
336   myGlVerMinor = 0;
337
338   // available since OpenGL 3.0
339   GLint aMajor, aMinor;
340   glGetIntegerv (GL_MAJOR_VERSION, &aMajor);
341   glGetIntegerv (GL_MINOR_VERSION, &aMinor);
342   if (glGetError() == GL_NO_ERROR)
343   {
344     myGlVerMajor = aMajor;
345     myGlVerMinor = aMinor;
346     return;
347   }
348   ResetErrors();
349
350   // Read version string.
351   // Notice that only first two numbers splitted by point '2.1 XXXXX' are significant.
352   // Following trash (after space) is vendor-specific.
353   // New drivers also returns micro version of GL like '3.3.0' which has no meaning
354   // and should be considered as vendor-specific too.
355   const char* aVerStr = (const char* )glGetString (GL_VERSION);
356   if (aVerStr == NULL || *aVerStr == '\0')
357   {
358     // invalid GL context
359     return;
360   }
361
362   // parse string for major number
363   char aMajorStr[32];
364   char aMinorStr[32];
365   size_t aMajIter = 0;
366   while (aVerStr[aMajIter] >= '0' && aVerStr[aMajIter] <= '9')
367   {
368     ++aMajIter;
369   }
370   if (aMajIter == 0 || aMajIter >= sizeof(aMajorStr))
371   {
372     return;
373   }
374   memcpy (aMajorStr, aVerStr, aMajIter);
375   aMajorStr[aMajIter] = '\0';
376
377   // parse string for minor number
378   size_t aMinIter = aMajIter + 1;
379   while (aVerStr[aMinIter] >= '0' && aVerStr[aMinIter] <= '9')
380   {
381     ++aMinIter;
382   }
383   size_t aMinLen = aMinIter - aMajIter - 1;
384   if (aMinLen == 0 || aMinLen >= sizeof(aMinorStr))
385   {
386     return;
387   }
388   memcpy (aMinorStr, aVerStr, aMinLen);
389   aMinorStr[aMinLen] = '\0';
390
391   // read numbers
392   myGlVerMajor = atoi (aMajorStr);
393   myGlVerMinor = atoi (aMinorStr);
394
395   if (myGlVerMajor <= 0)
396   {
397     myGlVerMajor = 0;
398     myGlVerMinor = 0;
399   }
400 }
401
402 // =======================================================================
403 // function : init
404 // purpose  :
405 // =======================================================================
406 void OpenGl_Context::init()
407 {
408   // read version
409   readGlVersion();
410
411   atiMem = CheckExtension ("GL_ATI_meminfo");
412   nvxMem = CheckExtension ("GL_NVX_gpu_memory_info");
413
414   // initialize VBO extension (ARB)
415   if (CheckExtension ("GL_ARB_vertex_buffer_object"))
416   {
417     arbVBO = new OpenGl_ArbVBO();
418     memset (arbVBO, 0, sizeof(OpenGl_ArbVBO)); // nullify whole structure
419     if (!FindProcShort (arbVBO, glGenBuffersARB)
420      || !FindProcShort (arbVBO, glBindBufferARB)
421      || !FindProcShort (arbVBO, glBufferDataARB)
422      || !FindProcShort (arbVBO, glDeleteBuffersARB))
423     {
424       delete arbVBO;
425       arbVBO = NULL;
426     }
427   }
428
429   // initialize FBO extension (EXT)
430   if (CheckExtension ("GL_EXT_framebuffer_object"))
431   {
432     extFBO = new OpenGl_ExtFBO();
433     memset (extFBO, 0, sizeof(OpenGl_ExtFBO)); // nullify whole structure
434     if (!FindProcShort (extFBO, glGenFramebuffersEXT)
435      || !FindProcShort (extFBO, glDeleteFramebuffersEXT)
436      || !FindProcShort (extFBO, glBindFramebufferEXT)
437      || !FindProcShort (extFBO, glFramebufferTexture2DEXT)
438      || !FindProcShort (extFBO, glCheckFramebufferStatusEXT)
439      || !FindProcShort (extFBO, glGenRenderbuffersEXT)
440      || !FindProcShort (extFBO, glDeleteRenderbuffersEXT)
441      || !FindProcShort (extFBO, glBindRenderbufferEXT)
442      || !FindProcShort (extFBO, glRenderbufferStorageEXT)
443      || !FindProcShort (extFBO, glFramebufferRenderbufferEXT))
444     {
445       delete extFBO;
446       extFBO = NULL;
447     }
448   }
449
450   myGlCore20 = new OpenGl_GlCore20();
451   memset (myGlCore20, 0, sizeof(OpenGl_GlCore20)); // nullify whole structure
452
453   // initialize OpenGL 1.2 core functionality
454   if (IsGlGreaterEqual (1, 2))
455   {
456     if (!FindProcShort (myGlCore20, glBlendColor)
457      || !FindProcShort (myGlCore20, glBlendEquation)
458      || !FindProcShort (myGlCore20, glDrawRangeElements)
459      || !FindProcShort (myGlCore20, glTexImage3D)
460      || !FindProcShort (myGlCore20, glTexSubImage3D)
461      || !FindProcShort (myGlCore20, glCopyTexSubImage3D))
462     {
463       myGlVerMajor = 1;
464       myGlVerMinor = 1;
465     }
466   }
467
468   // initialize OpenGL 1.3 core functionality
469   if (IsGlGreaterEqual (1, 3))
470   {
471     if (!FindProcShort (myGlCore20, glActiveTexture)
472      || !FindProcShort (myGlCore20, glSampleCoverage)
473      || !FindProcShort (myGlCore20, glCompressedTexImage3D)
474      || !FindProcShort (myGlCore20, glCompressedTexImage2D)
475      || !FindProcShort (myGlCore20, glCompressedTexImage1D)
476      || !FindProcShort (myGlCore20, glCompressedTexSubImage3D)
477      || !FindProcShort (myGlCore20, glCompressedTexSubImage2D)
478      || !FindProcShort (myGlCore20, glCompressedTexSubImage1D)
479      || !FindProcShort (myGlCore20, glGetCompressedTexImage)
480      // deprecated
481      || !FindProcShort (myGlCore20, glClientActiveTexture)
482      || !FindProcShort (myGlCore20, glMultiTexCoord1d)
483      || !FindProcShort (myGlCore20, glMultiTexCoord1dv)
484      || !FindProcShort (myGlCore20, glMultiTexCoord1f)
485      || !FindProcShort (myGlCore20, glMultiTexCoord1fv)
486      || !FindProcShort (myGlCore20, glMultiTexCoord1i)
487      || !FindProcShort (myGlCore20, glMultiTexCoord1iv)
488      || !FindProcShort (myGlCore20, glMultiTexCoord1s)
489      || !FindProcShort (myGlCore20, glMultiTexCoord1sv)
490      || !FindProcShort (myGlCore20, glMultiTexCoord2d)
491      || !FindProcShort (myGlCore20, glMultiTexCoord2dv)
492      || !FindProcShort (myGlCore20, glMultiTexCoord2f)
493      || !FindProcShort (myGlCore20, glMultiTexCoord2fv)
494      || !FindProcShort (myGlCore20, glMultiTexCoord2i)
495      || !FindProcShort (myGlCore20, glMultiTexCoord2iv)
496      || !FindProcShort (myGlCore20, glMultiTexCoord2s)
497      || !FindProcShort (myGlCore20, glMultiTexCoord2sv)
498      || !FindProcShort (myGlCore20, glMultiTexCoord3d)
499      || !FindProcShort (myGlCore20, glMultiTexCoord3dv)
500      || !FindProcShort (myGlCore20, glMultiTexCoord3f)
501      || !FindProcShort (myGlCore20, glMultiTexCoord3fv)
502      || !FindProcShort (myGlCore20, glMultiTexCoord3i)
503      || !FindProcShort (myGlCore20, glMultiTexCoord3iv)
504      || !FindProcShort (myGlCore20, glMultiTexCoord3s)
505      || !FindProcShort (myGlCore20, glMultiTexCoord3sv)
506      || !FindProcShort (myGlCore20, glMultiTexCoord4d)
507      || !FindProcShort (myGlCore20, glMultiTexCoord4dv)
508      || !FindProcShort (myGlCore20, glMultiTexCoord4f)
509      || !FindProcShort (myGlCore20, glMultiTexCoord4fv)
510      || !FindProcShort (myGlCore20, glMultiTexCoord4i)
511      || !FindProcShort (myGlCore20, glMultiTexCoord4iv)
512      || !FindProcShort (myGlCore20, glMultiTexCoord4s)
513      || !FindProcShort (myGlCore20, glMultiTexCoord4sv)
514      || !FindProcShort (myGlCore20, glLoadTransposeMatrixf)
515      || !FindProcShort (myGlCore20, glLoadTransposeMatrixd)
516      || !FindProcShort (myGlCore20, glMultTransposeMatrixf)
517      || !FindProcShort (myGlCore20, glMultTransposeMatrixd))
518     {
519       myGlVerMajor = 1;
520       myGlVerMinor = 2;
521       core12 = myGlCore20;
522     }
523   }
524
525   // initialize OpenGL 1.4 core functionality
526   if (IsGlGreaterEqual (1, 4))
527   {
528     if (!FindProcShort (myGlCore20, glBlendFuncSeparate)
529      || !FindProcShort (myGlCore20, glMultiDrawArrays)
530      || !FindProcShort (myGlCore20, glMultiDrawElements)
531      || !FindProcShort (myGlCore20, glPointParameterf)
532      || !FindProcShort (myGlCore20, glPointParameterfv)
533      || !FindProcShort (myGlCore20, glPointParameteri)
534      || !FindProcShort (myGlCore20, glPointParameteriv))
535     {
536       myGlVerMajor = 1;
537       myGlVerMinor = 3;
538       core12 = myGlCore20;
539       core13 = myGlCore20;
540     }
541   }
542
543   // initialize OpenGL 1.5 core functionality
544   if (IsGlGreaterEqual (1, 5))
545   {
546     if (!FindProcShort (myGlCore20, glGenQueries)
547      || !FindProcShort (myGlCore20, glDeleteQueries)
548      || !FindProcShort (myGlCore20, glIsQuery)
549      || !FindProcShort (myGlCore20, glBeginQuery)
550      || !FindProcShort (myGlCore20, glEndQuery)
551      || !FindProcShort (myGlCore20, glGetQueryiv)
552      || !FindProcShort (myGlCore20, glGetQueryObjectiv)
553      || !FindProcShort (myGlCore20, glGetQueryObjectuiv)
554      || !FindProcShort (myGlCore20, glBindBuffer)
555      || !FindProcShort (myGlCore20, glDeleteBuffers)
556      || !FindProcShort (myGlCore20, glGenBuffers)
557      || !FindProcShort (myGlCore20, glIsBuffer)
558      || !FindProcShort (myGlCore20, glBufferData)
559      || !FindProcShort (myGlCore20, glBufferSubData)
560      || !FindProcShort (myGlCore20, glGetBufferSubData)
561      || !FindProcShort (myGlCore20, glMapBuffer)
562      || !FindProcShort (myGlCore20, glUnmapBuffer)
563      || !FindProcShort (myGlCore20, glGetBufferParameteriv)
564      || !FindProcShort (myGlCore20, glGetBufferPointerv))
565     {
566       myGlVerMajor = 1;
567       myGlVerMinor = 4;
568       core12 = myGlCore20;
569       core13 = myGlCore20;
570       core14 = myGlCore20;
571     }
572   }
573
574   // initialize OpenGL 2.0 core functionality
575   if (IsGlGreaterEqual (2, 0))
576   {
577     if (!FindProcShort (myGlCore20, glBlendEquationSeparate)
578      || !FindProcShort (myGlCore20, glDrawBuffers)
579      || !FindProcShort (myGlCore20, glStencilOpSeparate)
580      || !FindProcShort (myGlCore20, glStencilFuncSeparate)
581      || !FindProcShort (myGlCore20, glStencilMaskSeparate)
582      || !FindProcShort (myGlCore20, glAttachShader)
583      || !FindProcShort (myGlCore20, glBindAttribLocation)
584      || !FindProcShort (myGlCore20, glCompileShader)
585      || !FindProcShort (myGlCore20, glCreateProgram)
586      || !FindProcShort (myGlCore20, glCreateShader)
587      || !FindProcShort (myGlCore20, glDeleteProgram)
588      || !FindProcShort (myGlCore20, glDeleteShader)
589      || !FindProcShort (myGlCore20, glDetachShader)
590      || !FindProcShort (myGlCore20, glDisableVertexAttribArray)
591      || !FindProcShort (myGlCore20, glEnableVertexAttribArray)
592      || !FindProcShort (myGlCore20, glGetActiveAttrib)
593      || !FindProcShort (myGlCore20, glGetActiveUniform)
594      || !FindProcShort (myGlCore20, glGetAttachedShaders)
595      || !FindProcShort (myGlCore20, glGetAttribLocation)
596      || !FindProcShort (myGlCore20, glGetProgramiv)
597      || !FindProcShort (myGlCore20, glGetProgramInfoLog)
598      || !FindProcShort (myGlCore20, glGetShaderiv)
599      || !FindProcShort (myGlCore20, glGetShaderInfoLog)
600      || !FindProcShort (myGlCore20, glGetShaderSource)
601      || !FindProcShort (myGlCore20, glGetUniformLocation)
602      || !FindProcShort (myGlCore20, glGetUniformfv)
603      || !FindProcShort (myGlCore20, glGetUniformiv)
604      || !FindProcShort (myGlCore20, glGetVertexAttribdv)
605      || !FindProcShort (myGlCore20, glGetVertexAttribfv)
606      || !FindProcShort (myGlCore20, glGetVertexAttribiv)
607      || !FindProcShort (myGlCore20, glGetVertexAttribPointerv)
608      || !FindProcShort (myGlCore20, glIsProgram)
609      || !FindProcShort (myGlCore20, glIsShader)
610      || !FindProcShort (myGlCore20, glLinkProgram)
611      || !FindProcShort (myGlCore20, glShaderSource)
612      || !FindProcShort (myGlCore20, glUseProgram)
613      || !FindProcShort (myGlCore20, glUniform1f)
614      || !FindProcShort (myGlCore20, glUniform2f)
615      || !FindProcShort (myGlCore20, glUniform3f)
616      || !FindProcShort (myGlCore20, glUniform4f)
617      || !FindProcShort (myGlCore20, glUniform1i)
618      || !FindProcShort (myGlCore20, glUniform2i)
619      || !FindProcShort (myGlCore20, glUniform3i)
620      || !FindProcShort (myGlCore20, glUniform4i)
621      || !FindProcShort (myGlCore20, glUniform1fv)
622      || !FindProcShort (myGlCore20, glUniform2fv)
623      || !FindProcShort (myGlCore20, glUniform3fv)
624      || !FindProcShort (myGlCore20, glUniform4fv)
625      || !FindProcShort (myGlCore20, glUniform1iv)
626      || !FindProcShort (myGlCore20, glUniform2iv)
627      || !FindProcShort (myGlCore20, glUniform3iv)
628      || !FindProcShort (myGlCore20, glUniform4iv)
629      || !FindProcShort (myGlCore20, glUniformMatrix2fv)
630      || !FindProcShort (myGlCore20, glUniformMatrix3fv)
631      || !FindProcShort (myGlCore20, glUniformMatrix4fv)
632      || !FindProcShort (myGlCore20, glValidateProgram)
633      || !FindProcShort (myGlCore20, glVertexAttrib1d)
634      || !FindProcShort (myGlCore20, glVertexAttrib1dv)
635      || !FindProcShort (myGlCore20, glVertexAttrib1f)
636      || !FindProcShort (myGlCore20, glVertexAttrib1fv)
637      || !FindProcShort (myGlCore20, glVertexAttrib1s)
638      || !FindProcShort (myGlCore20, glVertexAttrib1sv)
639      || !FindProcShort (myGlCore20, glVertexAttrib2d)
640      || !FindProcShort (myGlCore20, glVertexAttrib2dv)
641      || !FindProcShort (myGlCore20, glVertexAttrib2f)
642      || !FindProcShort (myGlCore20, glVertexAttrib2fv)
643      || !FindProcShort (myGlCore20, glVertexAttrib2s)
644      || !FindProcShort (myGlCore20, glVertexAttrib2sv)
645      || !FindProcShort (myGlCore20, glVertexAttrib3d)
646      || !FindProcShort (myGlCore20, glVertexAttrib3dv)
647      || !FindProcShort (myGlCore20, glVertexAttrib3f)
648      || !FindProcShort (myGlCore20, glVertexAttrib3fv)
649      || !FindProcShort (myGlCore20, glVertexAttrib3s)
650      || !FindProcShort (myGlCore20, glVertexAttrib3sv)
651      || !FindProcShort (myGlCore20, glVertexAttrib4Nbv)
652      || !FindProcShort (myGlCore20, glVertexAttrib4Niv)
653      || !FindProcShort (myGlCore20, glVertexAttrib4Nsv)
654      || !FindProcShort (myGlCore20, glVertexAttrib4Nub)
655      || !FindProcShort (myGlCore20, glVertexAttrib4Nubv)
656      || !FindProcShort (myGlCore20, glVertexAttrib4Nuiv)
657      || !FindProcShort (myGlCore20, glVertexAttrib4Nusv)
658      || !FindProcShort (myGlCore20, glVertexAttrib4bv)
659      || !FindProcShort (myGlCore20, glVertexAttrib4d)
660      || !FindProcShort (myGlCore20, glVertexAttrib4dv)
661      || !FindProcShort (myGlCore20, glVertexAttrib4f)
662      || !FindProcShort (myGlCore20, glVertexAttrib4fv)
663      || !FindProcShort (myGlCore20, glVertexAttrib4iv)
664      || !FindProcShort (myGlCore20, glVertexAttrib4s)
665      || !FindProcShort (myGlCore20, glVertexAttrib4sv)
666      || !FindProcShort (myGlCore20, glVertexAttrib4ubv)
667      || !FindProcShort (myGlCore20, glVertexAttrib4uiv)
668      || !FindProcShort (myGlCore20, glVertexAttrib4usv)
669      || !FindProcShort (myGlCore20, glVertexAttribPointer))
670     {
671       myGlVerMajor = 1;
672       myGlVerMinor = 5;
673       core12 = myGlCore20;
674       core13 = myGlCore20;
675       core14 = myGlCore20;
676       core15 = myGlCore20;
677     }
678   }
679
680   if (IsGlGreaterEqual (2, 0))
681   {
682     core12 = myGlCore20;
683     core13 = myGlCore20;
684     core14 = myGlCore20;
685     core15 = myGlCore20;
686     core20 = myGlCore20;
687   }
688 }
689 // =======================================================================
690 // function : IsFeedback
691 // purpose  :
692 // =======================================================================
693 Standard_Boolean OpenGl_Context::IsFeedback() const
694 {
695   return myIsFeedback;
696 }
697
698 // =======================================================================
699 // function : SetFeedback
700 // purpose  :
701 // =======================================================================
702 void OpenGl_Context::SetFeedback (const Standard_Boolean theFeedbackOn)
703 {
704   myIsFeedback = theFeedbackOn;
705 }
706
707 // =======================================================================
708 // function : MemoryInfo
709 // purpose  :
710 // =======================================================================
711 Standard_Size OpenGl_Context::AvailableMemory() const
712 {
713   if (atiMem)
714   {
715     // this is actually information for VBO pool
716     // however because pools are mostly shared
717     // it can be used for total GPU memory estimations
718     GLint aMemInfo[4];
719     aMemInfo[0] = 0;
720     glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aMemInfo);
721     // returned value is in KiB, however this maybe changed in future
722     return Standard_Size(aMemInfo[0]) * 1024;
723   }
724   else if (nvxMem)
725   {
726     // current available dedicated video memory (in KiB), currently unused GPU memory
727     GLint aMemInfo = 0;
728     glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aMemInfo);
729     return Standard_Size(aMemInfo) * 1024;
730   }
731   return 0;
732 }
733
734 // =======================================================================
735 // function : MemoryInfo
736 // purpose  :
737 // =======================================================================
738 TCollection_AsciiString OpenGl_Context::MemoryInfo() const
739 {
740   TCollection_AsciiString anInfo;
741   if (atiMem)
742   {
743     GLint aValues[4];
744     memset (aValues, 0, sizeof(aValues));
745     glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aValues);
746
747     // total memory free in the pool
748     anInfo += TCollection_AsciiString ("  GPU free memory:    ") + (aValues[0] / 1024) + " MiB\n";
749
750     // largest available free block in the pool
751     anInfo += TCollection_AsciiString ("  Largest free block: ") + (aValues[1] / 1024) + " MiB\n";
752     if (aValues[2] != aValues[0])
753     {
754       // total auxiliary memory free
755       anInfo += TCollection_AsciiString ("  Free memory:        ") + (aValues[2] / 1024) + " MiB\n";
756     }
757   }
758   else if (nvxMem)
759   {
760     //current available dedicated video memory (in KiB), currently unused GPU memory
761     GLint aValue = 0;
762     glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aValue);
763     anInfo += TCollection_AsciiString ("  GPU free memory:    ") + (aValue / 1024) + " MiB\n";
764
765     // dedicated video memory, total size (in KiB) of the GPU memory
766     GLint aDedicated = 0;
767     glGetIntegerv (GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &aDedicated);
768     anInfo += TCollection_AsciiString ("  GPU memory:         ") + (aDedicated / 1024) + " MiB\n";
769
770     // total available memory, total size (in KiB) of the memory available for allocations
771     glGetIntegerv (GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &aValue);
772     if (aValue != aDedicated)
773     {
774       // different only for special configurations
775       anInfo += TCollection_AsciiString ("  Total memory:       ") + (aValue / 1024) + " MiB\n";
776     }
777   }
778   return anInfo;
779 }