0025369: Visualization, Image_AlienPixMap - handle UTF-8 names in image read/save...
[occt.git] / src / OpenGl / OpenGl_Context.cxx
1 // Created on: 2012-01-26
2 // Created by: Kirill GAVRILOV
3 // Copyright (c) 2012-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #if defined(_WIN32)
17   #include <windows.h>
18 #endif
19
20 #include <OpenGl_Context.hxx>
21
22 #include <OpenGl_ArbTBO.hxx>
23 #include <OpenGl_ArbIns.hxx>
24 #include <OpenGl_ArbDbg.hxx>
25 #include <OpenGl_ArbFBO.hxx>
26 #include <OpenGl_ExtGS.hxx>
27 #include <OpenGl_GlCore20.hxx>
28 #include <OpenGl_ShaderManager.hxx>
29
30 #include <Message_Messenger.hxx>
31
32 #include <NCollection_Vector.hxx>
33
34 #include <Standard_ProgramError.hxx>
35
36 #if defined(HAVE_EGL)
37   #include <EGL/egl.h>
38   #ifdef _MSC_VER
39     #pragma comment(lib, "libEGL.lib")
40   #endif
41 #elif defined(_WIN32)
42   //
43 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
44   #include <dlfcn.h>
45 #else
46   #include <GL/glx.h> // glXGetProcAddress()
47 #endif
48
49 // GL_NVX_gpu_memory_info
50 #ifndef GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX
51   enum
52   {
53     GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX         = 0x9047,
54     GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX   = 0x9048,
55     GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX = 0x9049,
56     GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX           = 0x904A,
57     GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX           = 0x904B
58   };
59 #endif
60
61 IMPLEMENT_STANDARD_HANDLE (OpenGl_Context, Standard_Transient)
62 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Context, Standard_Transient)
63
64 namespace
65 {
66   static const Handle(OpenGl_Resource) NULL_GL_RESOURCE;
67 }
68
69 // =======================================================================
70 // function : OpenGl_Context
71 // purpose  :
72 // =======================================================================
73 OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
74 : core11     (NULL),
75   core11fwd  (NULL),
76   core15     (NULL),
77   core15fwd  (NULL),
78   core20     (NULL),
79   core20fwd  (NULL),
80   core32     (NULL),
81   core32back (NULL),
82   core41     (NULL),
83   core41back (NULL),
84   core42     (NULL),
85   core42back (NULL),
86   core43     (NULL),
87   core43back (NULL),
88   core44     (NULL),
89   core44back (NULL),
90   caps   (!theCaps.IsNull() ? theCaps : new OpenGl_Caps()),
91 #if defined(GL_ES_VERSION_2_0)
92   hasHighp   (Standard_False),
93   hasTexRGBA8(Standard_False),
94 #else
95   hasHighp   (Standard_True),
96   hasTexRGBA8(Standard_True),
97 #endif
98   arbNPTW(Standard_False),
99   arbTBO (NULL),
100   arbIns (NULL),
101   arbDbg (NULL),
102   arbFBO (NULL),
103   extGS  (NULL),
104   extBgra(Standard_False),
105   extAnis(Standard_False),
106   extPDS (Standard_False),
107   atiMem (Standard_False),
108   nvxMem (Standard_False),
109   mySharedResources (new OpenGl_ResourcesMap()),
110   myDelayed         (new OpenGl_DelayReleaseMap()),
111   myUnusedResources (new OpenGl_ResourcesStack()),
112   myClippingState (),
113   myGlLibHandle (NULL),
114   myFuncs (new OpenGl_GlFunctions()),
115   myAnisoMax   (1),
116   myTexClamp   (GL_CLAMP_TO_EDGE),
117   myMaxTexDim  (1024),
118   myMaxClipPlanes (6),
119   myGlVerMajor (0),
120   myGlVerMinor (0),
121   myIsInitialized (Standard_False),
122   myIsStereoBuffers (Standard_False),
123   myIsGlNormalizeEnabled (Standard_False),
124 #if !defined(GL_ES_VERSION_2_0)
125   myRenderMode (GL_RENDER),
126 #else
127   myRenderMode (0),
128 #endif
129   myDrawBuffer (0)
130 {
131 #if defined(MAC_OS_X_VERSION_10_3) && !defined(MACOSX_USE_GLX)
132   // Vendors can not extend functionality on this system
133   // and developers are limited to OpenGL support provided by Mac OS X SDK.
134   // We retrieve function pointers from system library
135   // to generalize extensions support on all platforms.
136   // In this way we also reach binary compatibility benefit between OS releases
137   // if some newest functionality is optionally used.
138   // Notice that GL version / extension availability checks are required
139   // because function pointers may be available but not functionality itself
140   // (depends on renderer).
141   myGlLibHandle = dlopen ("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
142 #endif
143   memset (myFuncs.operator->(), 0, sizeof(OpenGl_GlFunctions));
144   myShaderManager = new OpenGl_ShaderManager (this);
145 }
146
147 // =======================================================================
148 // function : ~OpenGl_Context
149 // purpose  :
150 // =======================================================================
151 OpenGl_Context::~OpenGl_Context()
152 {
153   // release clean up queue
154   ReleaseDelayed();
155
156   // release shared resources if any
157   if (((const Handle(Standard_Transient)& )mySharedResources)->GetRefCount() <= 1)
158   {
159     myShaderManager.Nullify();
160     for (NCollection_DataMap<TCollection_AsciiString, Handle(OpenGl_Resource)>::Iterator anIter (*mySharedResources);
161          anIter.More(); anIter.Next())
162     {
163       anIter.Value()->Release (this);
164     }
165   }
166   else
167   {
168     myShaderManager->SetContext (NULL);
169   }
170   mySharedResources.Nullify();
171   myDelayed.Nullify();
172
173 #if !defined(GL_ES_VERSION_2_0)
174   if (arbDbg != NULL
175    && caps->contextDebug
176    && IsValid())
177   {
178     // reset callback
179     void* aPtr = NULL;
180     glGetPointerv (GL_DEBUG_CALLBACK_USER_PARAM_ARB, &aPtr);
181     if (aPtr == this)
182     {
183       arbDbg->glDebugMessageCallbackARB (NULL, NULL);
184     }
185   }
186 #endif
187 }
188
189 // =======================================================================
190 // function : MaxDegreeOfAnisotropy
191 // purpose  :
192 // =======================================================================
193 Standard_Integer OpenGl_Context::MaxDegreeOfAnisotropy() const
194 {
195   return myAnisoMax;
196 }
197
198 // =======================================================================
199 // function : MaxTextureSize
200 // purpose  :
201 // =======================================================================
202 Standard_Integer OpenGl_Context::MaxTextureSize() const
203 {
204   return myMaxTexDim;
205 }
206
207 // =======================================================================
208 // function : MaxClipPlanes
209 // purpose  :
210 // =======================================================================
211 Standard_Integer OpenGl_Context::MaxClipPlanes() const
212 {
213   return myMaxClipPlanes;
214 }
215
216 // =======================================================================
217 // function : SetDrawBufferLeft
218 // purpose  :
219 // =======================================================================
220 void OpenGl_Context::SetDrawBufferLeft()
221 {
222 #if !defined(GL_ES_VERSION_2_0)
223   switch (myDrawBuffer)
224   {
225     case GL_BACK_RIGHT :
226     case GL_BACK :
227       glDrawBuffer (GL_BACK_LEFT);
228       myDrawBuffer = GL_BACK_LEFT;
229       break;
230
231     case GL_FRONT_RIGHT :
232     case GL_FRONT :
233       glDrawBuffer (GL_FRONT_LEFT);
234       myDrawBuffer = GL_FRONT_LEFT;
235       break;
236
237     case GL_FRONT_AND_BACK :
238     case GL_RIGHT :
239       glDrawBuffer (GL_LEFT);
240       myDrawBuffer = GL_LEFT;
241       break;
242   }
243 #endif
244 }
245
246 // =======================================================================
247 // function : SetDrawBufferRight
248 // purpose  :
249 // =======================================================================
250 void OpenGl_Context::SetDrawBufferRight()
251 {
252 #if !defined(GL_ES_VERSION_2_0)
253   switch (myDrawBuffer)
254   {
255     case GL_BACK_LEFT :
256     case GL_BACK :
257       glDrawBuffer (GL_BACK_RIGHT);
258       myDrawBuffer = GL_BACK_RIGHT;
259       break;
260
261     case GL_FRONT_LEFT :
262     case GL_FRONT :
263       glDrawBuffer (GL_FRONT_RIGHT);
264       myDrawBuffer = GL_FRONT_RIGHT;
265       break;
266
267     case GL_FRONT_AND_BACK :
268     case GL_LEFT :
269       glDrawBuffer (GL_RIGHT);
270       myDrawBuffer = GL_RIGHT;
271       break;
272   }
273 #endif
274 }
275
276 // =======================================================================
277 // function : SetDrawBufferMono
278 // purpose  :
279 // =======================================================================
280 void OpenGl_Context::SetDrawBufferMono()
281 {
282 #if !defined(GL_ES_VERSION_2_0)
283   switch (myDrawBuffer)
284   {
285     case GL_BACK_LEFT :
286     case GL_BACK_RIGHT :
287       glDrawBuffer (GL_BACK);
288       myDrawBuffer = GL_BACK;
289       break;
290
291     case GL_FRONT_LEFT :
292     case GL_FRONT_RIGHT :
293       glDrawBuffer (GL_FRONT);
294       myDrawBuffer = GL_FRONT;
295       break;
296
297     case GL_LEFT :
298     case GL_RIGHT :
299       glDrawBuffer (GL_FRONT_AND_BACK);
300       myDrawBuffer = GL_FRONT_AND_BACK;
301       break;
302   }
303 #endif
304 }
305
306 // =======================================================================
307 // function : FetchState
308 // purpose  :
309 // =======================================================================
310 void OpenGl_Context::FetchState()
311 {
312 #if !defined(GL_ES_VERSION_2_0)
313   // cache feedback mode state
314   glGetIntegerv (GL_RENDER_MODE, &myRenderMode);
315
316   // cache draw buffer state
317   glGetIntegerv (GL_DRAW_BUFFER, &myDrawBuffer);
318 #endif
319 }
320
321 // =======================================================================
322 // function : Share
323 // purpose  :
324 // =======================================================================
325 void OpenGl_Context::Share (const Handle(OpenGl_Context)& theShareCtx)
326 {
327   if (!theShareCtx.IsNull())
328   {
329     mySharedResources = theShareCtx->mySharedResources;
330     myDelayed         = theShareCtx->myDelayed;
331     myUnusedResources = theShareCtx->myUnusedResources;
332     myShaderManager   = theShareCtx->myShaderManager;
333   }
334 }
335
336 #if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
337
338 // =======================================================================
339 // function : IsCurrent
340 // purpose  :
341 // =======================================================================
342 Standard_Boolean OpenGl_Context::IsCurrent() const
343 {
344 #if defined(HAVE_EGL)
345   if ((EGLDisplay )myDisplay  == EGL_NO_DISPLAY
346    || (EGLSurface )myWindow   == EGL_NO_SURFACE
347    || (EGLContext )myGContext == EGL_NO_CONTEXT)
348   {
349     return Standard_False;
350   }
351
352   return (((EGLDisplay )myDisplay  == eglGetCurrentDisplay())
353        && ((EGLContext )myGContext == eglGetCurrentContext())
354        && ((EGLSurface )myWindow   == eglGetCurrentSurface (EGL_DRAW)));
355 #elif defined(_WIN32)
356   if (myWindowDC == NULL || myGContext == NULL)
357   {
358     return Standard_False;
359   }
360   return (( (HDC )myWindowDC == wglGetCurrentDC())
361       && ((HGLRC )myGContext == wglGetCurrentContext()));
362 #else
363   if (myDisplay == NULL || myWindow == 0 || myGContext == 0)
364   {
365     return Standard_False;
366   }
367
368   return (   ((Display* )myDisplay  == glXGetCurrentDisplay())
369        &&  ((GLXContext )myGContext == glXGetCurrentContext())
370        && ((GLXDrawable )myWindow   == glXGetCurrentDrawable()));
371 #endif
372 }
373
374 // =======================================================================
375 // function : MakeCurrent
376 // purpose  :
377 // =======================================================================
378 Standard_Boolean OpenGl_Context::MakeCurrent()
379 {
380 #if defined(HAVE_EGL)
381   if ((EGLDisplay )myDisplay  == EGL_NO_DISPLAY
382    || (EGLSurface )myWindow   == EGL_NO_SURFACE
383    || (EGLContext )myGContext == EGL_NO_CONTEXT)
384   {
385     Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
386     return Standard_False;
387   }
388
389   if (eglMakeCurrent ((EGLDisplay )myDisplay, (EGLSurface )myWindow, (EGLSurface )myWindow, (EGLContext )myGContext) != EGL_TRUE)
390   {
391     // if there is no current context it might be impossible to use glGetError() correctly
392     PushMessage (GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB, GL_DEBUG_TYPE_ERROR_ARB, 0, GL_DEBUG_SEVERITY_HIGH_ARB,
393                  "eglMakeCurrent() has failed!");
394     myIsInitialized = Standard_False;
395     return Standard_False;
396   }
397 #elif defined(_WIN32)
398   if (myWindowDC == NULL || myGContext == NULL)
399   {
400     Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
401     return Standard_False;
402   }
403
404   // technically it should be safe to activate already bound GL context
405   // however some drivers (Intel etc.) may FAIL doing this for unknown reason
406   if (IsCurrent())
407   {
408     myShaderManager->SetContext (this);
409     return Standard_True;
410   }
411   else if (wglMakeCurrent ((HDC )myWindowDC, (HGLRC )myGContext) != TRUE)
412   {
413     // notice that glGetError() couldn't be used here!
414     wchar_t* aMsgBuff = NULL;
415     DWORD anErrorCode = GetLastError();
416     FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
417                     NULL, anErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (wchar_t* )&aMsgBuff, 0, NULL);
418     TCollection_ExtendedString aMsg ("wglMakeCurrent() has failed. ");
419     if (aMsgBuff != NULL)
420     {
421       aMsg += (Standard_ExtString )aMsgBuff;
422       LocalFree (aMsgBuff);
423     }
424     PushMessage (GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB, GL_DEBUG_TYPE_ERROR_ARB, (unsigned int )anErrorCode, GL_DEBUG_SEVERITY_HIGH_ARB, aMsg);
425     myIsInitialized = Standard_False;
426     return Standard_False;
427   }
428 #else
429   if (myDisplay == NULL || myWindow == 0 || myGContext == 0)
430   {
431     Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
432     return Standard_False;
433   }
434
435   if (!glXMakeCurrent ((Display* )myDisplay, (GLXDrawable )myWindow, (GLXContext )myGContext))
436   {
437     // if there is no current context it might be impossible to use glGetError() correctly
438     PushMessage (GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB, GL_DEBUG_TYPE_ERROR_ARB, 0, GL_DEBUG_SEVERITY_HIGH_ARB,
439                  "glXMakeCurrent() has failed!");
440     myIsInitialized = Standard_False;
441     return Standard_False;
442   }
443 #endif
444   myShaderManager->SetContext (this);
445   return Standard_True;
446 }
447
448 // =======================================================================
449 // function : SwapBuffers
450 // purpose  :
451 // =======================================================================
452 void OpenGl_Context::SwapBuffers()
453 {
454 #if defined(HAVE_EGL)
455   if ((EGLSurface )myWindow != EGL_NO_SURFACE)
456   {
457     eglSwapBuffers ((EGLDisplay )myDisplay, (EGLSurface )myWindow);
458   }
459 #elif defined(_WIN32)
460   if ((HDC )myWindowDC != NULL)
461   {
462     ::SwapBuffers ((HDC )myWindowDC);
463     glFlush();
464   }
465 #else
466   if ((Display* )myDisplay != NULL)
467   {
468     glXSwapBuffers ((Display* )myDisplay, (GLXDrawable )myWindow);
469   }
470 #endif
471 }
472
473 #endif // __APPLE__
474
475 // =======================================================================
476 // function : findProc
477 // purpose  :
478 // =======================================================================
479 void* OpenGl_Context::findProc (const char* theFuncName)
480 {
481 #if defined(HAVE_EGL)
482   return (void* )eglGetProcAddress (theFuncName);
483 #elif defined(_WIN32)
484   return wglGetProcAddress (theFuncName);
485 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
486   return (myGlLibHandle != NULL) ? dlsym (myGlLibHandle, theFuncName) : NULL;
487 #else
488   return (void* )glXGetProcAddress ((const GLubyte* )theFuncName);
489 #endif
490 }
491
492 // =======================================================================
493 // function : CheckExtension
494 // purpose  :
495 // =======================================================================
496 Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtName) const
497 {
498   if (theExtName  == NULL)
499   {
500     std::cerr << "CheckExtension called with NULL string!\n";
501     return Standard_False;
502   }
503
504   // available since OpenGL 3.0
505   // and the ONLY way to check extensions with OpenGL 3.1+ core profile
506   /**if (IsGlGreaterEqual (3, 0))
507   {
508     GLint anExtNb = 0;
509     glGetIntegerv (GL_NUM_EXTENSIONS, &anExtNb);
510     for (GLint anIter = 0; anIter < anExtNb; ++anIter)
511     {
512       const char* anExtension = (const char* )core30->glGetStringi (GL_EXTENSIONS, (GLuint )anIter);
513       if (anExtension[anExtNameLen] == '\0' &&
514           strncmp (anExtension, theExtName, anExtNameLen) == 0)
515       {
516         return Standard_True;
517       }
518     }
519     return Standard_False;
520   }*/
521
522   // use old way with huge string for all extensions
523   const char* anExtString = (const char* )glGetString (GL_EXTENSIONS);
524   if (anExtString == NULL)
525   {
526     Messenger()->Send ("TKOpenGL: glGetString (GL_EXTENSIONS) has returned NULL! No GL context?", Message_Warning);
527     return Standard_False;
528   }
529   return CheckExtension (anExtString, theExtName);
530 }
531
532 // =======================================================================
533 // function : CheckExtension
534 // purpose  :
535 // =======================================================================
536 Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtString,
537                                                  const char* theExtName)
538 {
539   if (theExtString == NULL)
540   {
541     return Standard_False;
542   }
543
544   // Search for theExtName in the extensions string.
545   // Use of strstr() is not sufficient because extension names can be prefixes of other extension names.
546   char* aPtrIter = (char* )theExtString;
547   const char*  aPtrEnd      = aPtrIter + strlen (theExtString);
548   const size_t anExtNameLen = strlen (theExtName);
549   while (aPtrIter < aPtrEnd)
550   {
551     const size_t n = strcspn (aPtrIter, " ");
552     if ((n == anExtNameLen) && (strncmp (aPtrIter, theExtName, anExtNameLen) == 0))
553     {
554       return Standard_True;
555     }
556     aPtrIter += (n + 1);
557   }
558   return Standard_False;
559 }
560
561 #if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
562
563 // =======================================================================
564 // function : Init
565 // purpose  :
566 // =======================================================================
567 Standard_Boolean OpenGl_Context::Init()
568 {
569   if (myIsInitialized)
570   {
571     return Standard_True;
572   }
573
574 #if defined(HAVE_EGL)
575   myDisplay  = (Aspect_Display )eglGetCurrentDisplay();
576   myGContext = (Aspect_RenderingContext )eglGetCurrentContext();
577   myWindow   = (Aspect_Drawable )eglGetCurrentSurface(EGL_DRAW);
578 #elif defined(_WIN32)
579   myWindowDC = (Aspect_Handle )wglGetCurrentDC();
580   myGContext = (Aspect_RenderingContext )wglGetCurrentContext();
581 #else
582   myDisplay  = (Aspect_Display )glXGetCurrentDisplay();
583   myGContext = (Aspect_RenderingContext )glXGetCurrentContext();
584   myWindow   = (Aspect_Drawable )glXGetCurrentDrawable();
585 #endif
586   if (myGContext == NULL)
587   {
588     return Standard_False;
589   }
590
591   init();
592   myIsInitialized = Standard_True;
593   return Standard_True;
594 }
595
596 #endif // __APPLE__
597
598 // =======================================================================
599 // function : Init
600 // purpose  :
601 // =======================================================================
602 #if defined(HAVE_EGL)
603 Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable         theEglSurface,
604                                        const Aspect_Display          theEglDisplay,
605                                        const Aspect_RenderingContext theEglContext)
606 #elif defined(_WIN32)
607 Standard_Boolean OpenGl_Context::Init (const Aspect_Handle           theWindow,
608                                        const Aspect_Handle           theWindowDC,
609                                        const Aspect_RenderingContext theGContext)
610 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
611 Standard_Boolean OpenGl_Context::Init (const void*                   theGContext)
612 #else
613 Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable         theWindow,
614                                        const Aspect_Display          theDisplay,
615                                        const Aspect_RenderingContext theGContext)
616 #endif
617 {
618   Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called only once!");
619 #if defined(HAVE_EGL)
620   myWindow   = theEglSurface;
621   myGContext = theEglContext;
622   myDisplay  = theEglDisplay;
623 #elif defined(_WIN32)
624   myWindow   = theWindow;
625   myGContext = theGContext;
626   myWindowDC = theWindowDC;
627 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
628   myGContext = (void* )theGContext;
629 #else
630   myWindow   = theWindow;
631   myGContext = theGContext;
632   myDisplay  = theDisplay;
633 #endif
634   if (myGContext == NULL || !MakeCurrent())
635   {
636     return Standard_False;
637   }
638
639   init();
640   myIsInitialized = Standard_True;
641   return Standard_True;
642 }
643
644 // =======================================================================
645 // function : ResetErrors
646 // purpose  :
647 // =======================================================================
648 void OpenGl_Context::ResetErrors()
649 {
650   while (glGetError() != GL_NO_ERROR)
651   {
652     //
653   }
654 }
655
656 // =======================================================================
657 // function : readGlVersion
658 // purpose  :
659 // =======================================================================
660 void OpenGl_Context::readGlVersion()
661 {
662   // reset values
663   myGlVerMajor = 0;
664   myGlVerMinor = 0;
665
666 #ifdef GL_MAJOR_VERSION
667   // available since OpenGL 3.0 and OpenGL 3.0 ES
668   GLint aMajor = 0, aMinor = 0;
669   glGetIntegerv (GL_MAJOR_VERSION, &aMajor);
670   glGetIntegerv (GL_MINOR_VERSION, &aMinor);
671   // glGetError() sometimes does not report an error here even if
672   // GL does not know GL_MAJOR_VERSION and GL_MINOR_VERSION constants.
673   // This happens on some renderers like e.g. Cygwin MESA.
674   // Thus checking additionally if GL has put anything to
675   // the output variables.
676   if (glGetError() == GL_NO_ERROR && aMajor != 0 && aMinor != 0)
677   {
678     myGlVerMajor = aMajor;
679     myGlVerMinor = aMinor;
680     return;
681   }
682   ResetErrors();
683 #endif
684
685   // Read version string.
686   // Notice that only first two numbers split by point '2.1 XXXXX' are significant.
687   // Following trash (after space) is vendor-specific.
688   // New drivers also returns micro version of GL like '3.3.0' which has no meaning
689   // and should be considered as vendor-specific too.
690   const char* aVerStr = (const char* )glGetString (GL_VERSION);
691   if (aVerStr == NULL || *aVerStr == '\0')
692   {
693     // invalid GL context
694     return;
695   }
696
697 //#if defined(GL_ES_VERSION_2_0)
698   // skip "OpenGL ES-** " section
699   for (; *aVerStr != '\0'; ++aVerStr)
700   {
701     if (*aVerStr >= '0' && *aVerStr <= '9')
702     {
703       break;
704     }
705   }
706 //#endif
707
708   // parse string for major number
709   char aMajorStr[32];
710   char aMinorStr[32];
711   size_t aMajIter = 0;
712   while (aVerStr[aMajIter] >= '0' && aVerStr[aMajIter] <= '9')
713   {
714     ++aMajIter;
715   }
716   if (aMajIter == 0 || aMajIter >= sizeof(aMajorStr))
717   {
718     return;
719   }
720   memcpy (aMajorStr, aVerStr, aMajIter);
721   aMajorStr[aMajIter] = '\0';
722
723   // parse string for minor number
724   aVerStr += aMajIter + 1;
725   size_t aMinIter = 0;
726   while (aVerStr[aMinIter] >= '0' && aVerStr[aMinIter] <= '9')
727   {
728     ++aMinIter;
729   }
730   if (aMinIter == 0 || aMinIter >= sizeof(aMinorStr))
731   {
732     return;
733   }
734   memcpy (aMinorStr, aVerStr, aMinIter);
735   aMinorStr[aMinIter] = '\0';
736
737   // read numbers
738   myGlVerMajor = atoi (aMajorStr);
739   myGlVerMinor = atoi (aMinorStr);
740
741   if (myGlVerMajor <= 0)
742   {
743     myGlVerMajor = 0;
744     myGlVerMinor = 0;
745   }
746 }
747
748 static Standard_CString THE_DBGMSG_UNKNOWN = "UNKNOWN";
749 static Standard_CString THE_DBGMSG_SOURCES[] =
750 {
751   ".OpenGL",    // GL_DEBUG_SOURCE_API_ARB
752   ".WinSystem", // GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB
753   ".GLSL",      // GL_DEBUG_SOURCE_SHADER_COMPILER_ARB
754   ".3rdParty",  // GL_DEBUG_SOURCE_THIRD_PARTY_ARB
755   "",           // GL_DEBUG_SOURCE_APPLICATION_ARB
756   ".Other"      // GL_DEBUG_SOURCE_OTHER_ARB
757 };
758
759 static Standard_CString THE_DBGMSG_TYPES[] =
760 {
761   "Error",           // GL_DEBUG_TYPE_ERROR_ARB
762   "Deprecated",      // GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB
763   "Undef. behavior", // GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB
764   "Portability",     // GL_DEBUG_TYPE_PORTABILITY_ARB
765   "Performance",     // GL_DEBUG_TYPE_PERFORMANCE_ARB
766   "Other"            // GL_DEBUG_TYPE_OTHER_ARB
767 };
768
769 static Standard_CString THE_DBGMSG_SEV_HIGH   = "High";   // GL_DEBUG_SEVERITY_HIGH_ARB
770 static Standard_CString THE_DBGMSG_SEV_MEDIUM = "Medium"; // GL_DEBUG_SEVERITY_MEDIUM_ARB
771 static Standard_CString THE_DBGMSG_SEV_LOW    = "Low";    // GL_DEBUG_SEVERITY_LOW_ARB
772
773 #if !defined(GL_ES_VERSION_2_0)
774 //! Callback for GL_ARB_debug_output extension
775 static void APIENTRY debugCallbackWrap(unsigned int theSource,
776                                        unsigned int theType,
777                                        unsigned int theId,
778                                        unsigned int theSeverity,
779                                        int          /*theLength*/,
780                                        const char*  theMessage,
781                                        const void*  theUserParam)
782 {
783   OpenGl_Context* aCtx = (OpenGl_Context* )theUserParam;
784   aCtx->PushMessage (theSource, theType, theId, theSeverity, theMessage);
785 }
786 #endif
787
788 // =======================================================================
789 // function : PushMessage
790 // purpose  :
791 // =======================================================================
792 void OpenGl_Context::PushMessage (const unsigned int theSource,
793                                   const unsigned int theType,
794                                   const unsigned int theId,
795                                   const unsigned int theSeverity,
796                                   const TCollection_ExtendedString& theMessage)
797 {
798   //OpenGl_Context* aCtx = (OpenGl_Context* )theUserParam;
799   Standard_CString& aSrc = (theSource >= GL_DEBUG_SOURCE_API_ARB
800                         && theSource <= GL_DEBUG_SOURCE_OTHER_ARB)
801                          ? THE_DBGMSG_SOURCES[theSource - GL_DEBUG_SOURCE_API_ARB]
802                          : THE_DBGMSG_UNKNOWN;
803   Standard_CString& aType = (theType >= GL_DEBUG_TYPE_ERROR_ARB
804                          && theType <= GL_DEBUG_TYPE_OTHER_ARB)
805                           ? THE_DBGMSG_TYPES[theType - GL_DEBUG_TYPE_ERROR_ARB]
806                           : THE_DBGMSG_UNKNOWN;
807   Standard_CString& aSev = theSeverity == GL_DEBUG_SEVERITY_HIGH_ARB
808                          ? THE_DBGMSG_SEV_HIGH
809                          : (theSeverity == GL_DEBUG_SEVERITY_MEDIUM_ARB
810                           ? THE_DBGMSG_SEV_MEDIUM
811                           : THE_DBGMSG_SEV_LOW);
812   Message_Gravity aGrav = theSeverity == GL_DEBUG_SEVERITY_HIGH_ARB
813                         ? Message_Alarm
814                         : (theSeverity == GL_DEBUG_SEVERITY_MEDIUM_ARB
815                          ? Message_Warning
816                          : Message_Info);
817
818   TCollection_ExtendedString aMsg;
819   aMsg += "TKOpenGl"; aMsg += aSrc;
820   aMsg += " | Type: ";        aMsg += aType;
821   aMsg += " | ID: ";          aMsg += (Standard_Integer )theId;
822   aMsg += " | Severity: ";    aMsg += aSev;
823   aMsg += " | Message:\n  ";
824   aMsg += theMessage;
825   Messenger()->Send (aMsg, aGrav);
826 }
827
828 // =======================================================================
829 // function : init
830 // purpose  :
831 // =======================================================================
832 void OpenGl_Context::init()
833 {
834   // read version
835   readGlVersion();
836
837   core11     = (OpenGl_GlCore11*    )(&(*myFuncs));
838   core11fwd  = (OpenGl_GlCore11Fwd* )(&(*myFuncs));
839   core15     = NULL;
840   core15fwd  = NULL;
841   core20     = NULL;
842   core20fwd  = NULL;
843   core32     = NULL;
844   core32back = NULL;
845   core41     = NULL;
846   core41back = NULL;
847   core42     = NULL;
848   core42back = NULL;
849   core43     = NULL;
850   core43back = NULL;
851   core44     = NULL;
852   core44back = NULL;
853   arbTBO     = NULL;
854   arbIns     = NULL;
855   arbDbg     = NULL;
856   arbFBO     = NULL;
857   extGS      = NULL;
858
859 #if defined(GL_ES_VERSION_2_0)
860
861   hasTexRGBA8 = IsGlGreaterEqual (3, 0)
862              || CheckExtension ("GL_OES_rgb8_rgba8");
863   arbNPTW     = IsGlGreaterEqual (3, 0)
864              || CheckExtension ("GL_OES_texture_npot");
865   arbTexRG    = IsGlGreaterEqual (3, 0)
866              || CheckExtension ("GL_EXT_texture_rg");
867   extBgra     = CheckExtension ("GL_EXT_texture_format_BGRA8888");
868   extAnis = CheckExtension ("GL_EXT_texture_filter_anisotropic");
869   extPDS  = CheckExtension ("GL_OES_packed_depth_stencil");
870
871   core11fwd = (OpenGl_GlCore11Fwd* )(&(*myFuncs));
872   if (IsGlGreaterEqual (2, 0))
873   {
874     // enable compatible functions
875     core20    = (OpenGl_GlCore20*    )(&(*myFuncs));
876     core20fwd = (OpenGl_GlCore20Fwd* )(&(*myFuncs));
877     core15fwd = (OpenGl_GlCore15Fwd* )(&(*myFuncs));
878     arbFBO    = (OpenGl_ArbFBO* )(&(*myFuncs));
879   }
880
881   hasHighp = CheckExtension ("OES_fragment_precision_high");
882   GLint aRange[2] = {0, 0};
883   GLint aPrec [2] = {0, 0};
884   ::glGetShaderPrecisionFormat (GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, aRange, aPrec);
885   if (aPrec[1] != 0)
886   {
887     hasHighp = Standard_True;
888   }
889 #else
890
891   myTexClamp = IsGlGreaterEqual (1, 2) ? GL_CLAMP_TO_EDGE : GL_CLAMP;
892
893   hasTexRGBA8 = Standard_True;
894   arbNPTW = CheckExtension ("GL_ARB_texture_non_power_of_two");
895   extBgra = CheckExtension ("GL_EXT_bgra");
896   extAnis = CheckExtension ("GL_EXT_texture_filter_anisotropic");
897   extPDS  = CheckExtension ("GL_EXT_packed_depth_stencil");
898   atiMem  = CheckExtension ("GL_ATI_meminfo");
899   nvxMem  = CheckExtension ("GL_NVX_gpu_memory_info");
900
901   GLint aStereo = GL_FALSE;
902   glGetIntegerv (GL_STEREO, &aStereo);
903   myIsStereoBuffers = aStereo == 1;
904
905   // get number of maximum clipping planes
906   glGetIntegerv (GL_MAX_CLIP_PLANES,  &myMaxClipPlanes);
907 #endif
908
909   glGetIntegerv (GL_MAX_TEXTURE_SIZE, &myMaxTexDim);
910
911   if (extAnis)
912   {
913     glGetIntegerv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &myAnisoMax);
914   }
915
916   myClippingState.Init (myMaxClipPlanes);
917
918 #if !defined(GL_ES_VERSION_2_0)
919
920   bool has12 = false;
921   bool has13 = false;
922   bool has14 = false;
923   bool has15 = false;
924   bool has20 = false;
925   bool has21 = false;
926   bool has30 = false;
927   bool has31 = false;
928   bool has32 = false;
929   bool has33 = false;
930   bool has40 = false;
931   bool has41 = false;
932   bool has42 = false;
933   bool has43 = false;
934   bool has44 = false;
935
936   //! Make record shorter to retrieve function pointer using variable with same name
937   #define FindProcShort(theFunc) FindProc(#theFunc, myFuncs->theFunc)
938
939     // retrieve platform-dependent extensions
940 #if defined(_WIN32) && !defined(HAVE_EGL)
941   if (FindProcShort (wglGetExtensionsStringARB))
942   {
943     const char* aWglExts = myFuncs->wglGetExtensionsStringARB (wglGetCurrentDC());
944     if (CheckExtension (aWglExts, "WGL_EXT_swap_control"))
945     {
946       FindProcShort (wglSwapIntervalEXT);
947     }
948     if (CheckExtension (aWglExts, "WGL_ARB_pixel_format"))
949     {
950       FindProcShort (wglChoosePixelFormatARB);
951     }
952     if (CheckExtension (aWglExts, "WGL_ARB_create_context_profile"))
953     {
954       FindProcShort (wglCreateContextAttribsARB);
955     }
956     if (CheckExtension (aWglExts, "WGL_NV_DX_interop"))
957     {
958       FindProcShort (wglDXSetResourceShareHandleNV);
959       FindProcShort (wglDXOpenDeviceNV);
960       FindProcShort (wglDXCloseDeviceNV);
961       FindProcShort (wglDXRegisterObjectNV);
962       FindProcShort (wglDXUnregisterObjectNV);
963       FindProcShort (wglDXObjectAccessNV);
964       FindProcShort (wglDXLockObjectsNV);
965       FindProcShort (wglDXUnlockObjectsNV);
966     }
967   }
968 #endif
969
970   // initialize debug context extension
971   if (CheckExtension ("GL_ARB_debug_output"))
972   {
973     arbDbg = NULL;
974     if (FindProcShort (glDebugMessageControlARB)
975      && FindProcShort (glDebugMessageInsertARB)
976      && FindProcShort (glDebugMessageCallbackARB)
977      && FindProcShort (glGetDebugMessageLogARB))
978     {
979       arbDbg = (OpenGl_ArbDbg* )(&(*myFuncs));
980     }
981     if (arbDbg != NULL
982      && caps->contextDebug)
983     {
984       // setup default callback
985       arbDbg->glDebugMessageCallbackARB (debugCallbackWrap, this);
986     #ifdef DEB
987       glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
988     #endif
989     }
990   }
991
992   // load OpenGL 1.2 new functions
993   has12 = IsGlGreaterEqual (1, 2)
994        && FindProcShort (glBlendColor)
995        && FindProcShort (glBlendEquation)
996        && FindProcShort (glDrawRangeElements)
997        && FindProcShort (glTexImage3D)
998        && FindProcShort (glTexSubImage3D)
999        && FindProcShort (glCopyTexSubImage3D);
1000
1001   // load OpenGL 1.3 new functions
1002   has13 = IsGlGreaterEqual (1, 3)
1003        && FindProcShort (glActiveTexture)
1004        && FindProcShort (glSampleCoverage)
1005        && FindProcShort (glCompressedTexImage3D)
1006        && FindProcShort (glCompressedTexImage2D)
1007        && FindProcShort (glCompressedTexImage1D)
1008        && FindProcShort (glCompressedTexSubImage3D)
1009        && FindProcShort (glCompressedTexSubImage2D)
1010        && FindProcShort (glCompressedTexSubImage1D)
1011        && FindProcShort (glGetCompressedTexImage)
1012        && FindProcShort (glClientActiveTexture)
1013        && FindProcShort (glMultiTexCoord1d)
1014        && FindProcShort (glMultiTexCoord1dv)
1015        && FindProcShort (glMultiTexCoord1f)
1016        && FindProcShort (glMultiTexCoord1fv)
1017        && FindProcShort (glMultiTexCoord1i)
1018        && FindProcShort (glMultiTexCoord1iv)
1019        && FindProcShort (glMultiTexCoord1s)
1020        && FindProcShort (glMultiTexCoord1sv)
1021        && FindProcShort (glMultiTexCoord2d)
1022        && FindProcShort (glMultiTexCoord2dv)
1023        && FindProcShort (glMultiTexCoord2f)
1024        && FindProcShort (glMultiTexCoord2fv)
1025        && FindProcShort (glMultiTexCoord2i)
1026        && FindProcShort (glMultiTexCoord2iv)
1027        && FindProcShort (glMultiTexCoord2s)
1028        && FindProcShort (glMultiTexCoord2sv)
1029        && FindProcShort (glMultiTexCoord3d)
1030        && FindProcShort (glMultiTexCoord3dv)
1031        && FindProcShort (glMultiTexCoord3f)
1032        && FindProcShort (glMultiTexCoord3fv)
1033        && FindProcShort (glMultiTexCoord3i)
1034        && FindProcShort (glMultiTexCoord3iv)
1035        && FindProcShort (glMultiTexCoord3s)
1036        && FindProcShort (glMultiTexCoord3sv)
1037        && FindProcShort (glMultiTexCoord4d)
1038        && FindProcShort (glMultiTexCoord4dv)
1039        && FindProcShort (glMultiTexCoord4f)
1040        && FindProcShort (glMultiTexCoord4fv)
1041        && FindProcShort (glMultiTexCoord4i)
1042        && FindProcShort (glMultiTexCoord4iv)
1043        && FindProcShort (glMultiTexCoord4s)
1044        && FindProcShort (glMultiTexCoord4sv)
1045        && FindProcShort (glLoadTransposeMatrixf)
1046        && FindProcShort (glLoadTransposeMatrixd)
1047        && FindProcShort (glMultTransposeMatrixf)
1048        && FindProcShort (glMultTransposeMatrixd);
1049
1050   // load OpenGL 1.4 new functions
1051   has14 = IsGlGreaterEqual (1, 4)
1052        && FindProcShort (glBlendFuncSeparate)
1053        && FindProcShort (glMultiDrawArrays)
1054        && FindProcShort (glMultiDrawElements)
1055        && FindProcShort (glPointParameterf)
1056        && FindProcShort (glPointParameterfv)
1057        && FindProcShort (glPointParameteri)
1058        && FindProcShort (glPointParameteriv);
1059
1060   // load OpenGL 1.5 new functions
1061   has15 = IsGlGreaterEqual (1, 5)
1062        && FindProcShort (glGenQueries)
1063        && FindProcShort (glDeleteQueries)
1064        && FindProcShort (glIsQuery)
1065        && FindProcShort (glBeginQuery)
1066        && FindProcShort (glEndQuery)
1067        && FindProcShort (glGetQueryiv)
1068        && FindProcShort (glGetQueryObjectiv)
1069        && FindProcShort (glGetQueryObjectuiv)
1070        && FindProcShort (glBindBuffer)
1071        && FindProcShort (glDeleteBuffers)
1072        && FindProcShort (glGenBuffers)
1073        && FindProcShort (glIsBuffer)
1074        && FindProcShort (glBufferData)
1075        && FindProcShort (glBufferSubData)
1076        && FindProcShort (glGetBufferSubData)
1077        && FindProcShort (glMapBuffer)
1078        && FindProcShort (glUnmapBuffer)
1079        && FindProcShort (glGetBufferParameteriv)
1080        && FindProcShort (glGetBufferPointerv);
1081
1082   // load OpenGL 2.0 new functions
1083   has20 = IsGlGreaterEqual (2, 0)
1084        && FindProcShort (glBlendEquationSeparate)
1085        && FindProcShort (glDrawBuffers)
1086        && FindProcShort (glStencilOpSeparate)
1087        && FindProcShort (glStencilFuncSeparate)
1088        && FindProcShort (glStencilMaskSeparate)
1089        && FindProcShort (glAttachShader)
1090        && FindProcShort (glBindAttribLocation)
1091        && FindProcShort (glCompileShader)
1092        && FindProcShort (glCreateProgram)
1093        && FindProcShort (glCreateShader)
1094        && FindProcShort (glDeleteProgram)
1095        && FindProcShort (glDeleteShader)
1096        && FindProcShort (glDetachShader)
1097        && FindProcShort (glDisableVertexAttribArray)
1098        && FindProcShort (glEnableVertexAttribArray)
1099        && FindProcShort (glGetActiveAttrib)
1100        && FindProcShort (glGetActiveUniform)
1101        && FindProcShort (glGetAttachedShaders)
1102        && FindProcShort (glGetAttribLocation)
1103        && FindProcShort (glGetProgramiv)
1104        && FindProcShort (glGetProgramInfoLog)
1105        && FindProcShort (glGetShaderiv)
1106        && FindProcShort (glGetShaderInfoLog)
1107        && FindProcShort (glGetShaderSource)
1108        && FindProcShort (glGetUniformLocation)
1109        && FindProcShort (glGetUniformfv)
1110        && FindProcShort (glGetUniformiv)
1111        && FindProcShort (glGetVertexAttribdv)
1112        && FindProcShort (glGetVertexAttribfv)
1113        && FindProcShort (glGetVertexAttribiv)
1114        && FindProcShort (glGetVertexAttribPointerv)
1115        && FindProcShort (glIsProgram)
1116        && FindProcShort (glIsShader)
1117        && FindProcShort (glLinkProgram)
1118        && FindProcShort (glShaderSource)
1119        && FindProcShort (glUseProgram)
1120        && FindProcShort (glUniform1f)
1121        && FindProcShort (glUniform2f)
1122        && FindProcShort (glUniform3f)
1123        && FindProcShort (glUniform4f)
1124        && FindProcShort (glUniform1i)
1125        && FindProcShort (glUniform2i)
1126        && FindProcShort (glUniform3i)
1127        && FindProcShort (glUniform4i)
1128        && FindProcShort (glUniform1fv)
1129        && FindProcShort (glUniform2fv)
1130        && FindProcShort (glUniform3fv)
1131        && FindProcShort (glUniform4fv)
1132        && FindProcShort (glUniform1iv)
1133        && FindProcShort (glUniform2iv)
1134        && FindProcShort (glUniform3iv)
1135        && FindProcShort (glUniform4iv)
1136        && FindProcShort (glUniformMatrix2fv)
1137        && FindProcShort (glUniformMatrix3fv)
1138        && FindProcShort (glUniformMatrix4fv)
1139        && FindProcShort (glValidateProgram)
1140        && FindProcShort (glVertexAttrib1d)
1141        && FindProcShort (glVertexAttrib1dv)
1142        && FindProcShort (glVertexAttrib1f)
1143        && FindProcShort (glVertexAttrib1fv)
1144        && FindProcShort (glVertexAttrib1s)
1145        && FindProcShort (glVertexAttrib1sv)
1146        && FindProcShort (glVertexAttrib2d)
1147        && FindProcShort (glVertexAttrib2dv)
1148        && FindProcShort (glVertexAttrib2f)
1149        && FindProcShort (glVertexAttrib2fv)
1150        && FindProcShort (glVertexAttrib2s)
1151        && FindProcShort (glVertexAttrib2sv)
1152        && FindProcShort (glVertexAttrib3d)
1153        && FindProcShort (glVertexAttrib3dv)
1154        && FindProcShort (glVertexAttrib3f)
1155        && FindProcShort (glVertexAttrib3fv)
1156        && FindProcShort (glVertexAttrib3s)
1157        && FindProcShort (glVertexAttrib3sv)
1158        && FindProcShort (glVertexAttrib4Nbv)
1159        && FindProcShort (glVertexAttrib4Niv)
1160        && FindProcShort (glVertexAttrib4Nsv)
1161        && FindProcShort (glVertexAttrib4Nub)
1162        && FindProcShort (glVertexAttrib4Nubv)
1163        && FindProcShort (glVertexAttrib4Nuiv)
1164        && FindProcShort (glVertexAttrib4Nusv)
1165        && FindProcShort (glVertexAttrib4bv)
1166        && FindProcShort (glVertexAttrib4d)
1167        && FindProcShort (glVertexAttrib4dv)
1168        && FindProcShort (glVertexAttrib4f)
1169        && FindProcShort (glVertexAttrib4fv)
1170        && FindProcShort (glVertexAttrib4iv)
1171        && FindProcShort (glVertexAttrib4s)
1172        && FindProcShort (glVertexAttrib4sv)
1173        && FindProcShort (glVertexAttrib4ubv)
1174        && FindProcShort (glVertexAttrib4uiv)
1175        && FindProcShort (glVertexAttrib4usv)
1176        && FindProcShort (glVertexAttribPointer);
1177
1178   // load OpenGL 2.1 new functions
1179   has21 = IsGlGreaterEqual (2, 1)
1180        && FindProcShort (glUniformMatrix2x3fv)
1181        && FindProcShort (glUniformMatrix3x2fv)
1182        && FindProcShort (glUniformMatrix2x4fv)
1183        && FindProcShort (glUniformMatrix4x2fv)
1184        && FindProcShort (glUniformMatrix3x4fv)
1185        && FindProcShort (glUniformMatrix4x3fv);
1186
1187   // load GL_ARB_framebuffer_object (added to OpenGL 3.0 core)
1188   const bool hasFBO = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_framebuffer_object"))
1189        && FindProcShort (glIsRenderbuffer)
1190        && FindProcShort (glBindRenderbuffer)
1191        && FindProcShort (glDeleteRenderbuffers)
1192        && FindProcShort (glGenRenderbuffers)
1193        && FindProcShort (glRenderbufferStorage)
1194        && FindProcShort (glGetRenderbufferParameteriv)
1195        && FindProcShort (glIsFramebuffer)
1196        && FindProcShort (glBindFramebuffer)
1197        && FindProcShort (glDeleteFramebuffers)
1198        && FindProcShort (glGenFramebuffers)
1199        && FindProcShort (glCheckFramebufferStatus)
1200        && FindProcShort (glFramebufferTexture1D)
1201        && FindProcShort (glFramebufferTexture2D)
1202        && FindProcShort (glFramebufferTexture3D)
1203        && FindProcShort (glFramebufferRenderbuffer)
1204        && FindProcShort (glGetFramebufferAttachmentParameteriv)
1205        && FindProcShort (glGenerateMipmap)
1206        && FindProcShort (glBlitFramebuffer)
1207        && FindProcShort (glRenderbufferStorageMultisample)
1208        && FindProcShort (glFramebufferTextureLayer);
1209
1210   // load GL_ARB_vertex_array_object (added to OpenGL 3.0 core)
1211   const bool hasVAO = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_vertex_array_object"))
1212        && FindProcShort (glBindVertexArray)
1213        && FindProcShort (glDeleteVertexArrays)
1214        && FindProcShort (glGenVertexArrays)
1215        && FindProcShort (glIsVertexArray);
1216
1217   // load GL_ARB_map_buffer_range (added to OpenGL 3.0 core)
1218   const bool hasMapBufferRange = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_map_buffer_range"))
1219        && FindProcShort (glMapBufferRange)
1220        && FindProcShort (glFlushMappedBufferRange);
1221
1222   // load OpenGL 3.0 new functions
1223   has30 = IsGlGreaterEqual (3, 0)
1224        && hasFBO
1225        && hasVAO
1226        && hasMapBufferRange
1227        && FindProcShort (glColorMaski)
1228        && FindProcShort (glGetBooleani_v)
1229        && FindProcShort (glGetIntegeri_v)
1230        && FindProcShort (glEnablei)
1231        && FindProcShort (glDisablei)
1232        && FindProcShort (glIsEnabledi)
1233        && FindProcShort (glBeginTransformFeedback)
1234        && FindProcShort (glEndTransformFeedback)
1235        && FindProcShort (glBindBufferRange)
1236        && FindProcShort (glBindBufferBase)
1237        && FindProcShort (glTransformFeedbackVaryings)
1238        && FindProcShort (glGetTransformFeedbackVarying)
1239        && FindProcShort (glClampColor)
1240        && FindProcShort (glBeginConditionalRender)
1241        && FindProcShort (glEndConditionalRender)
1242        && FindProcShort (glVertexAttribIPointer)
1243        && FindProcShort (glGetVertexAttribIiv)
1244        && FindProcShort (glGetVertexAttribIuiv)
1245        && FindProcShort (glVertexAttribI1i)
1246        && FindProcShort (glVertexAttribI2i)
1247        && FindProcShort (glVertexAttribI3i)
1248        && FindProcShort (glVertexAttribI4i)
1249        && FindProcShort (glVertexAttribI1ui)
1250        && FindProcShort (glVertexAttribI2ui)
1251        && FindProcShort (glVertexAttribI3ui)
1252        && FindProcShort (glVertexAttribI4ui)
1253        && FindProcShort (glVertexAttribI1iv)
1254        && FindProcShort (glVertexAttribI2iv)
1255        && FindProcShort (glVertexAttribI3iv)
1256        && FindProcShort (glVertexAttribI4iv)
1257        && FindProcShort (glVertexAttribI1uiv)
1258        && FindProcShort (glVertexAttribI2uiv)
1259        && FindProcShort (glVertexAttribI3uiv)
1260        && FindProcShort (glVertexAttribI4uiv)
1261        && FindProcShort (glVertexAttribI4bv)
1262        && FindProcShort (glVertexAttribI4sv)
1263        && FindProcShort (glVertexAttribI4ubv)
1264        && FindProcShort (glVertexAttribI4usv)
1265        && FindProcShort (glGetUniformuiv)
1266        && FindProcShort (glBindFragDataLocation)
1267        && FindProcShort (glGetFragDataLocation)
1268        && FindProcShort (glUniform1ui)
1269        && FindProcShort (glUniform2ui)
1270        && FindProcShort (glUniform3ui)
1271        && FindProcShort (glUniform4ui)
1272        && FindProcShort (glUniform1uiv)
1273        && FindProcShort (glUniform2uiv)
1274        && FindProcShort (glUniform3uiv)
1275        && FindProcShort (glUniform4uiv)
1276        && FindProcShort (glTexParameterIiv)
1277        && FindProcShort (glTexParameterIuiv)
1278        && FindProcShort (glGetTexParameterIiv)
1279        && FindProcShort (glGetTexParameterIuiv)
1280        && FindProcShort (glClearBufferiv)
1281        && FindProcShort (glClearBufferuiv)
1282        && FindProcShort (glClearBufferfv)
1283        && FindProcShort (glClearBufferfi)
1284        && FindProcShort (glGetStringi);
1285
1286   // load GL_ARB_uniform_buffer_object (added to OpenGL 3.1 core)
1287   const bool hasUBO = (IsGlGreaterEqual (3, 1) || CheckExtension ("GL_ARB_uniform_buffer_object"))
1288        && FindProcShort (glGetUniformIndices)
1289        && FindProcShort (glGetActiveUniformsiv)
1290        && FindProcShort (glGetActiveUniformName)
1291        && FindProcShort (glGetUniformBlockIndex)
1292        && FindProcShort (glGetActiveUniformBlockiv)
1293        && FindProcShort (glGetActiveUniformBlockName)
1294        && FindProcShort (glUniformBlockBinding);
1295
1296   // load GL_ARB_copy_buffer (added to OpenGL 3.1 core)
1297   const bool hasCopyBufSubData = (IsGlGreaterEqual (3, 1) || CheckExtension ("GL_ARB_copy_buffer"))
1298        && FindProcShort (glCopyBufferSubData);
1299
1300   if (has30)
1301   {
1302     // NPOT textures are required by OpenGL 2.0 specifications
1303     // but doesn't hardware accelerated by some ancient OpenGL 2.1 hardware (GeForce FX, RadeOn 9700 etc.)
1304     arbNPTW  = Standard_True;
1305     arbTexRG = Standard_True;
1306   }
1307
1308   // load OpenGL 3.1 new functions
1309   has31 = IsGlGreaterEqual (3, 1)
1310        && hasUBO
1311        && hasCopyBufSubData
1312        && FindProcShort (glDrawArraysInstanced)
1313        && FindProcShort (glDrawElementsInstanced)
1314        && FindProcShort (glTexBuffer)
1315        && FindProcShort (glPrimitiveRestartIndex);
1316
1317   // load GL_ARB_draw_elements_base_vertex (added to OpenGL 3.2 core)
1318   const bool hasDrawElemsBaseVert = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_draw_elements_base_vertex"))
1319        && FindProcShort (glDrawElementsBaseVertex)
1320        && FindProcShort (glDrawRangeElementsBaseVertex)
1321        && FindProcShort (glDrawElementsInstancedBaseVertex)
1322        && FindProcShort (glMultiDrawElementsBaseVertex);
1323
1324   // load GL_ARB_provoking_vertex (added to OpenGL 3.2 core)
1325   const bool hasProvokingVert = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_provoking_vertex"))
1326        && FindProcShort (glProvokingVertex);
1327
1328   // load GL_ARB_sync (added to OpenGL 3.2 core)
1329   const bool hasSync = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_sync"))
1330        && FindProcShort (glFenceSync)
1331        && FindProcShort (glIsSync)
1332        && FindProcShort (glDeleteSync)
1333        && FindProcShort (glClientWaitSync)
1334        && FindProcShort (glWaitSync)
1335        && FindProcShort (glGetInteger64v)
1336        && FindProcShort (glGetSynciv);
1337
1338   // load GL_ARB_texture_multisample (added to OpenGL 3.2 core)
1339   const bool hasTextureMultisample = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_texture_multisample"))
1340        && FindProcShort (glTexImage2DMultisample)
1341        && FindProcShort (glTexImage3DMultisample)
1342        && FindProcShort (glGetMultisamplefv)
1343        && FindProcShort (glSampleMaski);
1344
1345   // load OpenGL 3.2 new functions
1346   has32 = IsGlGreaterEqual (3, 2)
1347        && hasDrawElemsBaseVert
1348        && hasProvokingVert
1349        && hasSync
1350        && hasTextureMultisample
1351        && FindProcShort (glGetInteger64i_v)
1352        && FindProcShort (glGetBufferParameteri64v)
1353        && FindProcShort (glFramebufferTexture);
1354
1355   // load GL_ARB_blend_func_extended (added to OpenGL 3.3 core)
1356   const bool hasBlendFuncExtended = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_blend_func_extended"))
1357        && FindProcShort (glBindFragDataLocationIndexed)
1358        && FindProcShort (glGetFragDataIndex);
1359
1360   // load GL_ARB_sampler_objects (added to OpenGL 3.3 core)
1361   const bool hasSamplerObjects = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_sampler_objects"))
1362        && FindProcShort (glGenSamplers)
1363        && FindProcShort (glDeleteSamplers)
1364        && FindProcShort (glIsSampler)
1365        && FindProcShort (glBindSampler)
1366        && FindProcShort (glSamplerParameteri)
1367        && FindProcShort (glSamplerParameteriv)
1368        && FindProcShort (glSamplerParameterf)
1369        && FindProcShort (glSamplerParameterfv)
1370        && FindProcShort (glSamplerParameterIiv)
1371        && FindProcShort (glSamplerParameterIuiv)
1372        && FindProcShort (glGetSamplerParameteriv)
1373        && FindProcShort (glGetSamplerParameterIiv)
1374        && FindProcShort (glGetSamplerParameterfv)
1375        && FindProcShort (glGetSamplerParameterIuiv);
1376
1377   // load GL_ARB_timer_query (added to OpenGL 3.3 core)
1378   const bool hasTimerQuery = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_timer_query"))
1379        && FindProcShort (glQueryCounter)
1380        && FindProcShort (glGetQueryObjecti64v)
1381        && FindProcShort (glGetQueryObjectui64v);
1382
1383   // load GL_ARB_vertex_type_2_10_10_10_rev (added to OpenGL 3.3 core)
1384   const bool hasVertType21010101rev = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_vertex_type_2_10_10_10_rev"))
1385        && FindProcShort (glVertexP2ui)
1386        && FindProcShort (glVertexP2uiv)
1387        && FindProcShort (glVertexP3ui)
1388        && FindProcShort (glVertexP3uiv)
1389        && FindProcShort (glVertexP4ui)
1390        && FindProcShort (glVertexP4uiv)
1391        && FindProcShort (glTexCoordP1ui)
1392        && FindProcShort (glTexCoordP1uiv)
1393        && FindProcShort (glTexCoordP2ui)
1394        && FindProcShort (glTexCoordP2uiv)
1395        && FindProcShort (glTexCoordP3ui)
1396        && FindProcShort (glTexCoordP3uiv)
1397        && FindProcShort (glTexCoordP4ui)
1398        && FindProcShort (glTexCoordP4uiv)
1399        && FindProcShort (glMultiTexCoordP1ui)
1400        && FindProcShort (glMultiTexCoordP1uiv)
1401        && FindProcShort (glMultiTexCoordP2ui)
1402        && FindProcShort (glMultiTexCoordP2uiv)
1403        && FindProcShort (glMultiTexCoordP3ui)
1404        && FindProcShort (glMultiTexCoordP3uiv)
1405        && FindProcShort (glMultiTexCoordP4ui)
1406        && FindProcShort (glMultiTexCoordP4uiv)
1407        && FindProcShort (glNormalP3ui)
1408        && FindProcShort (glNormalP3uiv)
1409        && FindProcShort (glColorP3ui)
1410        && FindProcShort (glColorP3uiv)
1411        && FindProcShort (glColorP4ui)
1412        && FindProcShort (glColorP4uiv)
1413        && FindProcShort (glSecondaryColorP3ui)
1414        && FindProcShort (glSecondaryColorP3uiv)
1415        && FindProcShort (glVertexAttribP1ui)
1416        && FindProcShort (glVertexAttribP1uiv)
1417        && FindProcShort (glVertexAttribP2ui)
1418        && FindProcShort (glVertexAttribP2uiv)
1419        && FindProcShort (glVertexAttribP3ui)
1420        && FindProcShort (glVertexAttribP3uiv)
1421        && FindProcShort (glVertexAttribP4ui)
1422        && FindProcShort (glVertexAttribP4uiv);
1423
1424   // load OpenGL 3.3 extra functions
1425   has33 = IsGlGreaterEqual (3, 3)
1426        && hasBlendFuncExtended
1427        && hasSamplerObjects
1428        && hasTimerQuery
1429        && hasVertType21010101rev
1430        && FindProcShort (glVertexAttribDivisor);
1431
1432   // load GL_ARB_draw_indirect (added to OpenGL 4.0 core)
1433   const bool hasDrawIndirect = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_draw_indirect"))
1434        && FindProcShort (glDrawArraysIndirect)
1435        && FindProcShort (glDrawElementsIndirect);
1436
1437   // load GL_ARB_gpu_shader_fp64 (added to OpenGL 4.0 core)
1438   const bool hasShaderFP64 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_gpu_shader_fp64"))
1439        && FindProcShort (glUniform1d)
1440        && FindProcShort (glUniform2d)
1441        && FindProcShort (glUniform3d)
1442        && FindProcShort (glUniform4d)
1443        && FindProcShort (glUniform1dv)
1444        && FindProcShort (glUniform2dv)
1445        && FindProcShort (glUniform3dv)
1446        && FindProcShort (glUniform4dv)
1447        && FindProcShort (glUniformMatrix2dv)
1448        && FindProcShort (glUniformMatrix3dv)
1449        && FindProcShort (glUniformMatrix4dv)
1450        && FindProcShort (glUniformMatrix2x3dv)
1451        && FindProcShort (glUniformMatrix2x4dv)
1452        && FindProcShort (glUniformMatrix3x2dv)
1453        && FindProcShort (glUniformMatrix3x4dv)
1454        && FindProcShort (glUniformMatrix4x2dv)
1455        && FindProcShort (glUniformMatrix4x3dv)
1456        && FindProcShort (glGetUniformdv);
1457
1458   // load GL_ARB_shader_subroutine (added to OpenGL 4.0 core)
1459   const bool hasShaderSubroutine = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_shader_subroutine"))
1460        && FindProcShort (glGetSubroutineUniformLocation)
1461        && FindProcShort (glGetSubroutineIndex)
1462        && FindProcShort (glGetActiveSubroutineUniformiv)
1463        && FindProcShort (glGetActiveSubroutineUniformName)
1464        && FindProcShort (glGetActiveSubroutineName)
1465        && FindProcShort (glUniformSubroutinesuiv)
1466        && FindProcShort (glGetUniformSubroutineuiv)
1467        && FindProcShort (glGetProgramStageiv);
1468
1469   // load GL_ARB_tessellation_shader (added to OpenGL 4.0 core)
1470   const bool hasTessellationShader = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_tessellation_shader"))
1471        && FindProcShort (glPatchParameteri)
1472        && FindProcShort (glPatchParameterfv);
1473
1474   // load GL_ARB_transform_feedback2 (added to OpenGL 4.0 core)
1475   const bool hasTrsfFeedback2 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_transform_feedback2"))
1476        && FindProcShort (glBindTransformFeedback)
1477        && FindProcShort (glDeleteTransformFeedbacks)
1478        && FindProcShort (glGenTransformFeedbacks)
1479        && FindProcShort (glIsTransformFeedback)
1480        && FindProcShort (glPauseTransformFeedback)
1481        && FindProcShort (glResumeTransformFeedback)
1482        && FindProcShort (glDrawTransformFeedback);
1483
1484   // load GL_ARB_transform_feedback3 (added to OpenGL 4.0 core)
1485   const bool hasTrsfFeedback3 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_transform_feedback3"))
1486        && FindProcShort (glDrawTransformFeedbackStream)
1487        && FindProcShort (glBeginQueryIndexed)
1488        && FindProcShort (glEndQueryIndexed)
1489        && FindProcShort (glGetQueryIndexediv);
1490
1491   // load OpenGL 4.0 new functions
1492   has40 = IsGlGreaterEqual (4, 0)
1493       && hasDrawIndirect
1494       && hasShaderFP64
1495       && hasShaderSubroutine
1496       && hasTessellationShader
1497       && hasTrsfFeedback2
1498       && hasTrsfFeedback3
1499       && FindProcShort (glMinSampleShading)
1500       && FindProcShort (glBlendEquationi)
1501       && FindProcShort (glBlendEquationSeparatei)
1502       && FindProcShort (glBlendFunci)
1503       && FindProcShort (glBlendFuncSeparatei);
1504
1505   // load GL_ARB_ES2_compatibility (added to OpenGL 4.1 core)
1506   const bool hasES2Compatibility = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_ES2_compatibility"))
1507        && FindProcShort (glReleaseShaderCompiler)
1508        && FindProcShort (glShaderBinary)
1509        && FindProcShort (glGetShaderPrecisionFormat)
1510        && FindProcShort (glDepthRangef)
1511        && FindProcShort (glClearDepthf);
1512
1513   // load GL_ARB_get_program_binary (added to OpenGL 4.1 core)
1514   const bool hasGetProgramBinary = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_get_program_binary"))
1515        && FindProcShort (glGetProgramBinary)
1516        && FindProcShort (glProgramBinary)
1517        && FindProcShort (glProgramParameteri);
1518
1519
1520   // load GL_ARB_separate_shader_objects (added to OpenGL 4.1 core)
1521   const bool hasSeparateShaderObjects = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_separate_shader_objects"))
1522        && FindProcShort (glUseProgramStages)
1523        && FindProcShort (glActiveShaderProgram)
1524        && FindProcShort (glCreateShaderProgramv)
1525        && FindProcShort (glBindProgramPipeline)
1526        && FindProcShort (glDeleteProgramPipelines)
1527        && FindProcShort (glGenProgramPipelines)
1528        && FindProcShort (glIsProgramPipeline)
1529        && FindProcShort (glGetProgramPipelineiv)
1530        && FindProcShort (glProgramUniform1i)
1531        && FindProcShort (glProgramUniform1iv)
1532        && FindProcShort (glProgramUniform1f)
1533        && FindProcShort (glProgramUniform1fv)
1534        && FindProcShort (glProgramUniform1d)
1535        && FindProcShort (glProgramUniform1dv)
1536        && FindProcShort (glProgramUniform1ui)
1537        && FindProcShort (glProgramUniform1uiv)
1538        && FindProcShort (glProgramUniform2i)
1539        && FindProcShort (glProgramUniform2iv)
1540        && FindProcShort (glProgramUniform2f)
1541        && FindProcShort (glProgramUniform2fv)
1542        && FindProcShort (glProgramUniform2d)
1543        && FindProcShort (glProgramUniform2dv)
1544        && FindProcShort (glProgramUniform2ui)
1545        && FindProcShort (glProgramUniform2uiv)
1546        && FindProcShort (glProgramUniform3i)
1547        && FindProcShort (glProgramUniform3iv)
1548        && FindProcShort (glProgramUniform3f)
1549        && FindProcShort (glProgramUniform3fv)
1550        && FindProcShort (glProgramUniform3d)
1551        && FindProcShort (glProgramUniform3dv)
1552        && FindProcShort (glProgramUniform3ui)
1553        && FindProcShort (glProgramUniform3uiv)
1554        && FindProcShort (glProgramUniform4i)
1555        && FindProcShort (glProgramUniform4iv)
1556        && FindProcShort (glProgramUniform4f)
1557        && FindProcShort (glProgramUniform4fv)
1558        && FindProcShort (glProgramUniform4d)
1559        && FindProcShort (glProgramUniform4dv)
1560        && FindProcShort (glProgramUniform4ui)
1561        && FindProcShort (glProgramUniform4uiv)
1562        && FindProcShort (glProgramUniformMatrix2fv)
1563        && FindProcShort (glProgramUniformMatrix3fv)
1564        && FindProcShort (glProgramUniformMatrix4fv)
1565        && FindProcShort (glProgramUniformMatrix2dv)
1566        && FindProcShort (glProgramUniformMatrix3dv)
1567        && FindProcShort (glProgramUniformMatrix4dv)
1568        && FindProcShort (glProgramUniformMatrix2x3fv)
1569        && FindProcShort (glProgramUniformMatrix3x2fv)
1570        && FindProcShort (glProgramUniformMatrix2x4fv)
1571        && FindProcShort (glProgramUniformMatrix4x2fv)
1572        && FindProcShort (glProgramUniformMatrix3x4fv)
1573        && FindProcShort (glProgramUniformMatrix4x3fv)
1574        && FindProcShort (glProgramUniformMatrix2x3dv)
1575        && FindProcShort (glProgramUniformMatrix3x2dv)
1576        && FindProcShort (glProgramUniformMatrix2x4dv)
1577        && FindProcShort (glProgramUniformMatrix4x2dv)
1578        && FindProcShort (glProgramUniformMatrix3x4dv)
1579        && FindProcShort (glProgramUniformMatrix4x3dv)
1580        && FindProcShort (glValidateProgramPipeline)
1581        && FindProcShort (glGetProgramPipelineInfoLog);
1582
1583   // load GL_ARB_vertex_attrib_64bit (added to OpenGL 4.1 core)
1584   const bool hasVertAttrib64bit = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_vertex_attrib_64bit"))
1585        && FindProcShort (glVertexAttribL1d)
1586        && FindProcShort (glVertexAttribL2d)
1587        && FindProcShort (glVertexAttribL3d)
1588        && FindProcShort (glVertexAttribL4d)
1589        && FindProcShort (glVertexAttribL1dv)
1590        && FindProcShort (glVertexAttribL2dv)
1591        && FindProcShort (glVertexAttribL3dv)
1592        && FindProcShort (glVertexAttribL4dv)
1593        && FindProcShort (glVertexAttribLPointer)
1594        && FindProcShort (glGetVertexAttribLdv);
1595
1596   // load GL_ARB_viewport_array (added to OpenGL 4.1 core)
1597   const bool hasViewportArray = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_viewport_array"))
1598        && FindProcShort (glViewportArrayv)
1599        && FindProcShort (glViewportIndexedf)
1600        && FindProcShort (glViewportIndexedfv)
1601        && FindProcShort (glScissorArrayv)
1602        && FindProcShort (glScissorIndexed)
1603        && FindProcShort (glScissorIndexedv)
1604        && FindProcShort (glDepthRangeArrayv)
1605        && FindProcShort (glDepthRangeIndexed)
1606        && FindProcShort (glGetFloati_v)
1607        && FindProcShort (glGetDoublei_v);
1608
1609   has41 = IsGlGreaterEqual (4, 1)
1610        && hasES2Compatibility
1611        && hasGetProgramBinary
1612        && hasSeparateShaderObjects
1613        && hasVertAttrib64bit
1614        && hasViewportArray;
1615
1616   // load GL_ARB_base_instance (added to OpenGL 4.2 core)
1617   const bool hasBaseInstance = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_base_instance"))
1618        && FindProcShort (glDrawArraysInstancedBaseInstance)
1619        && FindProcShort (glDrawElementsInstancedBaseInstance)
1620        && FindProcShort (glDrawElementsInstancedBaseVertexBaseInstance);
1621
1622   // load GL_ARB_transform_feedback_instanced (added to OpenGL 4.2 core)
1623   const bool hasTrsfFeedbackInstanced = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_transform_feedback_instanced"))
1624        && FindProcShort (glDrawTransformFeedbackInstanced)
1625        && FindProcShort (glDrawTransformFeedbackStreamInstanced);
1626
1627   // load GL_ARB_internalformat_query (added to OpenGL 4.2 core)
1628   const bool hasInternalFormatQuery = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_internalformat_query"))
1629        && FindProcShort (glGetInternalformativ);
1630
1631   // load GL_ARB_shader_atomic_counters (added to OpenGL 4.2 core)
1632   const bool hasShaderAtomicCounters = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_shader_atomic_counters"))
1633        && FindProcShort (glGetActiveAtomicCounterBufferiv);
1634
1635   // load GL_ARB_shader_image_load_store (added to OpenGL 4.2 core)
1636   const bool hasShaderImgLoadStore = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_shader_image_load_store"))
1637        && FindProcShort (glBindImageTexture)
1638        && FindProcShort (glMemoryBarrier);
1639
1640   // load GL_ARB_texture_storage (added to OpenGL 4.2 core)
1641   const bool hasTextureStorage = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_texture_storage"))
1642        && FindProcShort (glTexStorage1D)
1643        && FindProcShort (glTexStorage2D)
1644        && FindProcShort (glTexStorage3D)
1645        && FindProcShort (glTextureStorage1DEXT)
1646        && FindProcShort (glTextureStorage2DEXT)
1647        && FindProcShort (glTextureStorage3DEXT);
1648
1649   has42 = IsGlGreaterEqual (4, 2)
1650        && hasBaseInstance
1651        && hasTrsfFeedbackInstanced
1652        && hasInternalFormatQuery
1653        && hasShaderAtomicCounters
1654        && hasShaderImgLoadStore
1655        && hasTextureStorage;
1656
1657   has43 = IsGlGreaterEqual (4, 3)
1658        && FindProcShort (glClearBufferData)
1659        && FindProcShort (glClearBufferSubData)
1660        && FindProcShort (glDispatchCompute)
1661        && FindProcShort (glDispatchComputeIndirect)
1662        && FindProcShort (glCopyImageSubData)
1663        && FindProcShort (glFramebufferParameteri)
1664        && FindProcShort (glGetFramebufferParameteriv)
1665        && FindProcShort (glGetInternalformati64v)
1666        && FindProcShort (glInvalidateTexSubImage)
1667        && FindProcShort (glInvalidateTexImage)
1668        && FindProcShort (glInvalidateBufferSubData)
1669        && FindProcShort (glInvalidateBufferData)
1670        && FindProcShort (glInvalidateFramebuffer)
1671        && FindProcShort (glInvalidateSubFramebuffer)
1672        && FindProcShort (glMultiDrawArraysIndirect)
1673        && FindProcShort (glMultiDrawElementsIndirect)
1674        && FindProcShort (glGetProgramInterfaceiv)
1675        && FindProcShort (glGetProgramResourceIndex)
1676        && FindProcShort (glGetProgramResourceName)
1677        && FindProcShort (glGetProgramResourceiv)
1678        && FindProcShort (glGetProgramResourceLocation)
1679        && FindProcShort (glGetProgramResourceLocationIndex)
1680        && FindProcShort (glShaderStorageBlockBinding)
1681        && FindProcShort (glTexBufferRange)
1682        && FindProcShort (glTexStorage2DMultisample)
1683        && FindProcShort (glTexStorage3DMultisample)
1684        && FindProcShort (glTextureView)
1685        && FindProcShort (glBindVertexBuffer)
1686        && FindProcShort (glVertexAttribFormat)
1687        && FindProcShort (glVertexAttribIFormat)
1688        && FindProcShort (glVertexAttribLFormat)
1689        && FindProcShort (glVertexAttribBinding)
1690        && FindProcShort (glVertexBindingDivisor)
1691        && FindProcShort (glDebugMessageControl)
1692        && FindProcShort (glDebugMessageInsert)
1693        && FindProcShort (glDebugMessageCallback)
1694        && FindProcShort (glGetDebugMessageLog)
1695        && FindProcShort (glPushDebugGroup)
1696        && FindProcShort (glPopDebugGroup)
1697        && FindProcShort (glObjectLabel)
1698        && FindProcShort (glGetObjectLabel)
1699        && FindProcShort (glObjectPtrLabel)
1700        && FindProcShort (glGetObjectPtrLabel);
1701
1702   // load GL_ARB_clear_texture (added to OpenGL 4.4 core)
1703   bool arbTexClear = (IsGlGreaterEqual (4, 4) || CheckExtension ("GL_ARB_clear_texture"))
1704        && FindProcShort (glClearTexImage)
1705        && FindProcShort (glClearTexSubImage);
1706
1707   has44 = IsGlGreaterEqual (4, 4)
1708        && arbTexClear
1709        && FindProcShort (glBufferStorage)
1710        && FindProcShort (glBindBuffersBase)
1711        && FindProcShort (glBindBuffersRange)
1712        && FindProcShort (glBindTextures)
1713        && FindProcShort (glBindSamplers)
1714        && FindProcShort (glBindImageTextures)
1715        && FindProcShort (glBindVertexBuffers);
1716
1717   // initialize TBO extension (ARB)
1718   if (!has31
1719    && CheckExtension ("GL_ARB_texture_buffer_object")
1720    && FindProc ("glTexBufferARB", myFuncs->glTexBuffer))
1721   {
1722     arbTBO = (OpenGl_ArbTBO* )(&(*myFuncs));
1723   }
1724
1725   // initialize hardware instancing extension (ARB)
1726   if (!has31
1727    && CheckExtension ("GL_ARB_draw_instanced")
1728    && FindProc ("glDrawArraysInstancedARB",   myFuncs->glDrawArraysInstanced)
1729    && FindProc ("glDrawElementsInstancedARB", myFuncs->glDrawElementsInstanced))
1730   {
1731     arbIns = (OpenGl_ArbIns* )(&(*myFuncs));
1732   }
1733
1734   // initialize FBO extension (ARB)
1735   if (hasFBO)
1736   {
1737     arbFBO = (OpenGl_ArbFBO* )(&(*myFuncs));
1738     extPDS = Standard_True; // extension for EXT, but part of ARB
1739   }
1740
1741   // initialize GS extension (EXT)
1742   if (CheckExtension ("GL_EXT_geometry_shader4")
1743    && FindProcShort (glProgramParameteriEXT))
1744   {
1745     extGS = (OpenGl_ExtGS* )(&(*myFuncs));
1746   }
1747
1748   if (!has12)
1749   {
1750     myGlVerMajor = 1;
1751     myGlVerMinor = 1;
1752     return;
1753   }
1754   else if (!has13)
1755   {
1756     myGlVerMajor = 1;
1757     myGlVerMinor = 2;
1758     return;
1759   }
1760   else if (!has14)
1761   {
1762     myGlVerMajor = 1;
1763     myGlVerMinor = 3;
1764     return;
1765   }
1766   else if (!has15)
1767   {
1768     myGlVerMajor = 1;
1769     myGlVerMinor = 4;
1770     return;
1771   }
1772   core15    = (OpenGl_GlCore15*    )(&(*myFuncs));
1773   core15fwd = (OpenGl_GlCore15Fwd* )(&(*myFuncs));
1774
1775   if (!has20)
1776   {
1777     myGlVerMajor = 1;
1778     myGlVerMinor = 5;
1779     return;
1780   }
1781
1782   core20    = (OpenGl_GlCore20*    )(&(*myFuncs));
1783   core20fwd = (OpenGl_GlCore20Fwd* )(&(*myFuncs));
1784
1785   if (!has21)
1786   {
1787     myGlVerMajor = 2;
1788     myGlVerMinor = 0;
1789     return;
1790   }
1791
1792   if (!has30)
1793   {
1794     myGlVerMajor = 2;
1795     myGlVerMinor = 1;
1796     return;
1797   }
1798
1799   if (!has31)
1800   {
1801     myGlVerMajor = 3;
1802     myGlVerMinor = 0;
1803     return;
1804   }
1805   arbTBO = (OpenGl_ArbTBO* )(&(*myFuncs));
1806   arbIns = (OpenGl_ArbIns* )(&(*myFuncs));
1807
1808   if (!has32)
1809   {
1810     myGlVerMajor = 3;
1811     myGlVerMinor = 1;
1812     return;
1813   }
1814   core32     = (OpenGl_GlCore32*     )(&(*myFuncs));
1815   core32back = (OpenGl_GlCore32Back* )(&(*myFuncs));
1816
1817   if (!has33)
1818   {
1819     myGlVerMajor = 3;
1820     myGlVerMinor = 2;
1821     return;
1822   }
1823
1824   if (!has40)
1825   {
1826     myGlVerMajor = 3;
1827     myGlVerMinor = 3;
1828     return;
1829   }
1830
1831   if (!has41)
1832   {
1833     myGlVerMajor = 4;
1834     myGlVerMinor = 0;
1835     return;
1836   }
1837   core41     = (OpenGl_GlCore41*     )(&(*myFuncs));
1838   core41back = (OpenGl_GlCore41Back* )(&(*myFuncs));
1839
1840   if(!has42)
1841   {
1842     myGlVerMajor = 4;
1843     myGlVerMinor = 1;
1844     return;
1845   }
1846   core42     = (OpenGl_GlCore42*     )(&(*myFuncs));
1847   core42back = (OpenGl_GlCore42Back* )(&(*myFuncs));
1848
1849   if(!has43)
1850   {
1851     myGlVerMajor = 4;
1852     myGlVerMinor = 2;
1853     return;
1854   }
1855   core43     = (OpenGl_GlCore43*     )(&(*myFuncs));
1856   core43back = (OpenGl_GlCore43Back* )(&(*myFuncs));
1857
1858   if (!has44)
1859   {
1860     myGlVerMajor = 4;
1861     myGlVerMinor = 3;
1862     return;
1863   }
1864   core44     = (OpenGl_GlCore44*     )(&(*myFuncs));
1865   core44back = (OpenGl_GlCore44Back* )(&(*myFuncs));
1866 #endif
1867 }
1868
1869 // =======================================================================
1870 // function : MemoryInfo
1871 // purpose  :
1872 // =======================================================================
1873 Standard_Size OpenGl_Context::AvailableMemory() const
1874 {
1875 #if !defined(GL_ES_VERSION_2_0)
1876   if (atiMem)
1877   {
1878     // this is actually information for VBO pool
1879     // however because pools are mostly shared
1880     // it can be used for total GPU memory estimations
1881     GLint aMemInfo[4];
1882     aMemInfo[0] = 0;
1883     glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aMemInfo);
1884     // returned value is in KiB, however this maybe changed in future
1885     return Standard_Size(aMemInfo[0]) * 1024;
1886   }
1887   else if (nvxMem)
1888   {
1889     // current available dedicated video memory (in KiB), currently unused GPU memory
1890     GLint aMemInfo = 0;
1891     glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aMemInfo);
1892     return Standard_Size(aMemInfo) * 1024;
1893   }
1894 #endif
1895   return 0;
1896 }
1897
1898 // =======================================================================
1899 // function : MemoryInfo
1900 // purpose  :
1901 // =======================================================================
1902 TCollection_AsciiString OpenGl_Context::MemoryInfo() const
1903 {
1904   TCollection_AsciiString anInfo;
1905 #if !defined(GL_ES_VERSION_2_0)
1906   if (atiMem)
1907   {
1908     GLint aValues[4];
1909     memset (aValues, 0, sizeof(aValues));
1910     glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aValues);
1911
1912     // total memory free in the pool
1913     anInfo += TCollection_AsciiString ("  GPU free memory:    ") + (aValues[0] / 1024) + " MiB\n";
1914
1915     // largest available free block in the pool
1916     anInfo += TCollection_AsciiString ("  Largest free block: ") + (aValues[1] / 1024) + " MiB\n";
1917     if (aValues[2] != aValues[0])
1918     {
1919       // total auxiliary memory free
1920       anInfo += TCollection_AsciiString ("  Free memory:        ") + (aValues[2] / 1024) + " MiB\n";
1921     }
1922   }
1923   else if (nvxMem)
1924   {
1925     //current available dedicated video memory (in KiB), currently unused GPU memory
1926     GLint aValue = 0;
1927     glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aValue);
1928     anInfo += TCollection_AsciiString ("  GPU free memory:    ") + (aValue / 1024) + " MiB\n";
1929
1930     // dedicated video memory, total size (in KiB) of the GPU memory
1931     GLint aDedicated = 0;
1932     glGetIntegerv (GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &aDedicated);
1933     anInfo += TCollection_AsciiString ("  GPU memory:         ") + (aDedicated / 1024) + " MiB\n";
1934
1935     // total available memory, total size (in KiB) of the memory available for allocations
1936     glGetIntegerv (GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &aValue);
1937     if (aValue != aDedicated)
1938     {
1939       // different only for special configurations
1940       anInfo += TCollection_AsciiString ("  Total memory:       ") + (aValue / 1024) + " MiB\n";
1941     }
1942   }
1943 #endif
1944   return anInfo;
1945 }
1946
1947
1948 // =======================================================================
1949 // function : GetResource
1950 // purpose  :
1951 // =======================================================================
1952 const Handle(OpenGl_Resource)& OpenGl_Context::GetResource (const TCollection_AsciiString& theKey) const
1953 {
1954   return mySharedResources->IsBound (theKey) ? mySharedResources->Find (theKey) : NULL_GL_RESOURCE;
1955 }
1956
1957 // =======================================================================
1958 // function : ShareResource
1959 // purpose  :
1960 // =======================================================================
1961 Standard_Boolean OpenGl_Context::ShareResource (const TCollection_AsciiString& theKey,
1962                                                 const Handle(OpenGl_Resource)& theResource)
1963 {
1964   if (theKey.IsEmpty() || theResource.IsNull())
1965   {
1966     return Standard_False;
1967   }
1968   return mySharedResources->Bind (theKey, theResource);
1969 }
1970
1971 // =======================================================================
1972 // function : ReleaseResource
1973 // purpose  :
1974 // =======================================================================
1975 void OpenGl_Context::ReleaseResource (const TCollection_AsciiString& theKey,
1976                                       const Standard_Boolean         theToDelay)
1977 {
1978   if (!mySharedResources->IsBound (theKey))
1979   {
1980     return;
1981   }
1982   const Handle(OpenGl_Resource)& aRes = mySharedResources->Find (theKey);
1983   if (aRes->GetRefCount() > 1)
1984   {
1985     return;
1986   }
1987
1988   if (theToDelay)
1989   {
1990     myDelayed->Bind (theKey, 1);
1991   }
1992   else
1993   {
1994     aRes->Release (this);
1995     mySharedResources->UnBind (theKey);
1996   }
1997 }
1998
1999 // =======================================================================
2000 // function : DelayedRelease
2001 // purpose  :
2002 // =======================================================================
2003 void OpenGl_Context::DelayedRelease (Handle(OpenGl_Resource)& theResource)
2004 {
2005   myUnusedResources->Prepend (theResource);
2006   theResource.Nullify();
2007 }
2008
2009 // =======================================================================
2010 // function : ReleaseDelayed
2011 // purpose  :
2012 // =======================================================================
2013 void OpenGl_Context::ReleaseDelayed()
2014 {
2015   // release queued elements
2016   while (!myUnusedResources->IsEmpty())
2017   {
2018     myUnusedResources->First()->Release (this);
2019     myUnusedResources->RemoveFirst();
2020   }
2021
2022   // release delayed shared resources
2023   NCollection_Vector<TCollection_AsciiString> aDeadList;
2024   for (NCollection_DataMap<TCollection_AsciiString, Standard_Integer>::Iterator anIter (*myDelayed);
2025        anIter.More(); anIter.Next())
2026   {
2027     if (++anIter.ChangeValue() <= 2)
2028     {
2029       continue; // postpone release one more frame to ensure noone use it periodically
2030     }
2031
2032     const TCollection_AsciiString& aKey = anIter.Key();
2033     if (!mySharedResources->IsBound (aKey))
2034     {
2035       // mixed unshared strategy delayed/undelayed was used!
2036       aDeadList.Append (aKey);
2037       continue;
2038     }
2039
2040     Handle(OpenGl_Resource)& aRes = mySharedResources->ChangeFind (aKey);
2041     if (aRes->GetRefCount() > 1)
2042     {
2043       // should be only 1 instance in mySharedResources
2044       // if not - resource was reused again
2045       aDeadList.Append (aKey);
2046       continue;
2047     }
2048
2049     // release resource if no one requiested it more than 2 redraw calls
2050     aRes->Release (this);
2051     mySharedResources->UnBind (aKey);
2052     aDeadList.Append (aKey);
2053   }
2054
2055   for (Standard_Integer anIter = 0; anIter < aDeadList.Length(); ++anIter)
2056   {
2057     myDelayed->UnBind (aDeadList.Value (anIter));
2058   }
2059 }
2060
2061 // =======================================================================
2062 // function : BindProgram
2063 // purpose  :
2064 // =======================================================================
2065 Standard_Boolean OpenGl_Context::BindProgram (const Handle(OpenGl_ShaderProgram)& theProgram)
2066 {
2067   if (core20fwd == NULL)
2068   {
2069     return Standard_False;
2070   }
2071
2072   if (theProgram.IsNull()
2073   || !theProgram->IsValid())
2074   {
2075     if (!myActiveProgram.IsNull())
2076     {
2077       core20fwd->glUseProgram (OpenGl_ShaderProgram::NO_PROGRAM);
2078       myActiveProgram.Nullify();
2079     }
2080     return Standard_False;
2081   }
2082
2083   myActiveProgram = theProgram;
2084   core20fwd->glUseProgram (theProgram->ProgramId());
2085   return Standard_True;
2086 }
2087
2088 // =======================================================================
2089 // function : SetColor4fv
2090 // purpose  :
2091 // =======================================================================
2092 void OpenGl_Context::SetColor4fv (const OpenGl_Vec4& theColor)
2093 {
2094   if (!myActiveProgram.IsNull())
2095   {
2096     myActiveProgram->SetUniform (this, myActiveProgram->GetStateLocation (OpenGl_OCCT_COLOR), theColor);
2097   }
2098 #if !defined(GL_ES_VERSION_2_0)
2099   else if (core11 != NULL)
2100   {
2101     core11->glColor4fv (theColor.GetData());
2102   }
2103 #endif
2104 }
2105
2106 // =======================================================================
2107 // function : SetPointSize
2108 // purpose  :
2109 // =======================================================================
2110 void OpenGl_Context::SetPointSize (const Standard_ShortReal theSize)
2111 {
2112   if (!myActiveProgram.IsNull())
2113   {
2114     myActiveProgram->SetUniform (this, myActiveProgram->GetStateLocation (OpenGl_OCCT_POINT_SIZE), theSize);
2115   #if !defined(GL_ES_VERSION_2_0)
2116     //myContext->core11fwd->glEnable (GL_VERTEX_PROGRAM_POINT_SIZE);
2117   #endif
2118   }
2119 #if !defined(GL_ES_VERSION_2_0)
2120   //else
2121   {
2122     core11fwd->glPointSize (theSize);
2123     if (core20fwd != NULL)
2124     {
2125       //myContext->core11fwd->glDisable (GL_VERTEX_PROGRAM_POINT_SIZE);
2126     }
2127   }
2128 #endif
2129 }
2130
2131 // =======================================================================
2132 // function : SetGlNormalizeEnabled
2133 // purpose  :
2134 // =======================================================================
2135 Standard_Boolean OpenGl_Context::SetGlNormalizeEnabled (Standard_Boolean isEnabled)
2136 {
2137   if (isEnabled == myIsGlNormalizeEnabled)
2138   {
2139     return myIsGlNormalizeEnabled;
2140   }
2141
2142   Standard_Boolean anOldGlNormalize = myIsGlNormalizeEnabled;
2143
2144   myIsGlNormalizeEnabled = isEnabled;
2145
2146 #if !defined(GL_ES_VERSION_2_0)
2147   if (isEnabled)
2148   {
2149     glEnable (GL_NORMALIZE);
2150   }
2151   else
2152   {
2153     glDisable (GL_NORMALIZE);
2154   }
2155 #endif
2156
2157   return anOldGlNormalize;
2158 }