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