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