5a1a4e7d9721bca9e0055f043c5bae895b38d355
[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 (glVertexAttribP1ui)
1643        && FindProcShort (glVertexAttribP1uiv)
1644        && FindProcShort (glVertexAttribP2ui)
1645        && FindProcShort (glVertexAttribP2uiv)
1646        && FindProcShort (glVertexAttribP3ui)
1647        && FindProcShort (glVertexAttribP3uiv)
1648        && FindProcShort (glVertexAttribP4ui)
1649        && FindProcShort (glVertexAttribP4uiv);
1650
1651   if ( hasVertType21010101rev
1652    && !isCoreProfile)
1653   {
1654     // load deprecated functions
1655     const bool hasVertType21010101revExt =
1656           FindProcShort (glVertexP2ui)
1657        && FindProcShort (glVertexP2uiv)
1658        && FindProcShort (glVertexP3ui)
1659        && FindProcShort (glVertexP3uiv)
1660        && FindProcShort (glVertexP4ui)
1661        && FindProcShort (glVertexP4uiv)
1662        && FindProcShort (glTexCoordP1ui)
1663        && FindProcShort (glTexCoordP1uiv)
1664        && FindProcShort (glTexCoordP2ui)
1665        && FindProcShort (glTexCoordP2uiv)
1666        && FindProcShort (glTexCoordP3ui)
1667        && FindProcShort (glTexCoordP3uiv)
1668        && FindProcShort (glTexCoordP4ui)
1669        && FindProcShort (glTexCoordP4uiv)
1670        && FindProcShort (glMultiTexCoordP1ui)
1671        && FindProcShort (glMultiTexCoordP1uiv)
1672        && FindProcShort (glMultiTexCoordP2ui)
1673        && FindProcShort (glMultiTexCoordP2uiv)
1674        && FindProcShort (glMultiTexCoordP3ui)
1675        && FindProcShort (glMultiTexCoordP3uiv)
1676        && FindProcShort (glMultiTexCoordP4ui)
1677        && FindProcShort (glMultiTexCoordP4uiv)
1678        && FindProcShort (glNormalP3ui)
1679        && FindProcShort (glNormalP3uiv)
1680        && FindProcShort (glColorP3ui)
1681        && FindProcShort (glColorP3uiv)
1682        && FindProcShort (glColorP4ui)
1683        && FindProcShort (glColorP4uiv)
1684        && FindProcShort (glSecondaryColorP3ui)
1685        && FindProcShort (glSecondaryColorP3uiv);
1686     (void )hasVertType21010101revExt;
1687   }
1688
1689   // load OpenGL 3.3 extra functions
1690   has33 = IsGlGreaterEqual (3, 3)
1691        && hasBlendFuncExtended
1692        && hasSamplerObjects
1693        && hasTimerQuery
1694        && hasVertType21010101rev
1695        && FindProcShort (glVertexAttribDivisor);
1696
1697   // load GL_ARB_draw_indirect (added to OpenGL 4.0 core)
1698   const bool hasDrawIndirect = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_draw_indirect"))
1699        && FindProcShort (glDrawArraysIndirect)
1700        && FindProcShort (glDrawElementsIndirect);
1701
1702   // load GL_ARB_gpu_shader_fp64 (added to OpenGL 4.0 core)
1703   const bool hasShaderFP64 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_gpu_shader_fp64"))
1704        && FindProcShort (glUniform1d)
1705        && FindProcShort (glUniform2d)
1706        && FindProcShort (glUniform3d)
1707        && FindProcShort (glUniform4d)
1708        && FindProcShort (glUniform1dv)
1709        && FindProcShort (glUniform2dv)
1710        && FindProcShort (glUniform3dv)
1711        && FindProcShort (glUniform4dv)
1712        && FindProcShort (glUniformMatrix2dv)
1713        && FindProcShort (glUniformMatrix3dv)
1714        && FindProcShort (glUniformMatrix4dv)
1715        && FindProcShort (glUniformMatrix2x3dv)
1716        && FindProcShort (glUniformMatrix2x4dv)
1717        && FindProcShort (glUniformMatrix3x2dv)
1718        && FindProcShort (glUniformMatrix3x4dv)
1719        && FindProcShort (glUniformMatrix4x2dv)
1720        && FindProcShort (glUniformMatrix4x3dv)
1721        && FindProcShort (glGetUniformdv);
1722
1723   // load GL_ARB_shader_subroutine (added to OpenGL 4.0 core)
1724   const bool hasShaderSubroutine = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_shader_subroutine"))
1725        && FindProcShort (glGetSubroutineUniformLocation)
1726        && FindProcShort (glGetSubroutineIndex)
1727        && FindProcShort (glGetActiveSubroutineUniformiv)
1728        && FindProcShort (glGetActiveSubroutineUniformName)
1729        && FindProcShort (glGetActiveSubroutineName)
1730        && FindProcShort (glUniformSubroutinesuiv)
1731        && FindProcShort (glGetUniformSubroutineuiv)
1732        && FindProcShort (glGetProgramStageiv);
1733
1734   // load GL_ARB_tessellation_shader (added to OpenGL 4.0 core)
1735   const bool hasTessellationShader = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_tessellation_shader"))
1736        && FindProcShort (glPatchParameteri)
1737        && FindProcShort (glPatchParameterfv);
1738
1739   // load GL_ARB_transform_feedback2 (added to OpenGL 4.0 core)
1740   const bool hasTrsfFeedback2 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_transform_feedback2"))
1741        && FindProcShort (glBindTransformFeedback)
1742        && FindProcShort (glDeleteTransformFeedbacks)
1743        && FindProcShort (glGenTransformFeedbacks)
1744        && FindProcShort (glIsTransformFeedback)
1745        && FindProcShort (glPauseTransformFeedback)
1746        && FindProcShort (glResumeTransformFeedback)
1747        && FindProcShort (glDrawTransformFeedback);
1748
1749   // load GL_ARB_transform_feedback3 (added to OpenGL 4.0 core)
1750   const bool hasTrsfFeedback3 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_transform_feedback3"))
1751        && FindProcShort (glDrawTransformFeedbackStream)
1752        && FindProcShort (glBeginQueryIndexed)
1753        && FindProcShort (glEndQueryIndexed)
1754        && FindProcShort (glGetQueryIndexediv);
1755
1756   // load OpenGL 4.0 new functions
1757   has40 = IsGlGreaterEqual (4, 0)
1758       && hasDrawIndirect
1759       && hasShaderFP64
1760       && hasShaderSubroutine
1761       && hasTessellationShader
1762       && hasTrsfFeedback2
1763       && hasTrsfFeedback3
1764       && FindProcShort (glMinSampleShading)
1765       && FindProcShort (glBlendEquationi)
1766       && FindProcShort (glBlendEquationSeparatei)
1767       && FindProcShort (glBlendFunci)
1768       && FindProcShort (glBlendFuncSeparatei);
1769
1770   // load GL_ARB_ES2_compatibility (added to OpenGL 4.1 core)
1771   const bool hasES2Compatibility = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_ES2_compatibility"))
1772        && FindProcShort (glReleaseShaderCompiler)
1773        && FindProcShort (glShaderBinary)
1774        && FindProcShort (glGetShaderPrecisionFormat)
1775        && FindProcShort (glDepthRangef)
1776        && FindProcShort (glClearDepthf);
1777
1778   // load GL_ARB_get_program_binary (added to OpenGL 4.1 core)
1779   const bool hasGetProgramBinary = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_get_program_binary"))
1780        && FindProcShort (glGetProgramBinary)
1781        && FindProcShort (glProgramBinary)
1782        && FindProcShort (glProgramParameteri);
1783
1784
1785   // load GL_ARB_separate_shader_objects (added to OpenGL 4.1 core)
1786   const bool hasSeparateShaderObjects = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_separate_shader_objects"))
1787        && FindProcShort (glUseProgramStages)
1788        && FindProcShort (glActiveShaderProgram)
1789        && FindProcShort (glCreateShaderProgramv)
1790        && FindProcShort (glBindProgramPipeline)
1791        && FindProcShort (glDeleteProgramPipelines)
1792        && FindProcShort (glGenProgramPipelines)
1793        && FindProcShort (glIsProgramPipeline)
1794        && FindProcShort (glGetProgramPipelineiv)
1795        && FindProcShort (glProgramUniform1i)
1796        && FindProcShort (glProgramUniform1iv)
1797        && FindProcShort (glProgramUniform1f)
1798        && FindProcShort (glProgramUniform1fv)
1799        && FindProcShort (glProgramUniform1d)
1800        && FindProcShort (glProgramUniform1dv)
1801        && FindProcShort (glProgramUniform1ui)
1802        && FindProcShort (glProgramUniform1uiv)
1803        && FindProcShort (glProgramUniform2i)
1804        && FindProcShort (glProgramUniform2iv)
1805        && FindProcShort (glProgramUniform2f)
1806        && FindProcShort (glProgramUniform2fv)
1807        && FindProcShort (glProgramUniform2d)
1808        && FindProcShort (glProgramUniform2dv)
1809        && FindProcShort (glProgramUniform2ui)
1810        && FindProcShort (glProgramUniform2uiv)
1811        && FindProcShort (glProgramUniform3i)
1812        && FindProcShort (glProgramUniform3iv)
1813        && FindProcShort (glProgramUniform3f)
1814        && FindProcShort (glProgramUniform3fv)
1815        && FindProcShort (glProgramUniform3d)
1816        && FindProcShort (glProgramUniform3dv)
1817        && FindProcShort (glProgramUniform3ui)
1818        && FindProcShort (glProgramUniform3uiv)
1819        && FindProcShort (glProgramUniform4i)
1820        && FindProcShort (glProgramUniform4iv)
1821        && FindProcShort (glProgramUniform4f)
1822        && FindProcShort (glProgramUniform4fv)
1823        && FindProcShort (glProgramUniform4d)
1824        && FindProcShort (glProgramUniform4dv)
1825        && FindProcShort (glProgramUniform4ui)
1826        && FindProcShort (glProgramUniform4uiv)
1827        && FindProcShort (glProgramUniformMatrix2fv)
1828        && FindProcShort (glProgramUniformMatrix3fv)
1829        && FindProcShort (glProgramUniformMatrix4fv)
1830        && FindProcShort (glProgramUniformMatrix2dv)
1831        && FindProcShort (glProgramUniformMatrix3dv)
1832        && FindProcShort (glProgramUniformMatrix4dv)
1833        && FindProcShort (glProgramUniformMatrix2x3fv)
1834        && FindProcShort (glProgramUniformMatrix3x2fv)
1835        && FindProcShort (glProgramUniformMatrix2x4fv)
1836        && FindProcShort (glProgramUniformMatrix4x2fv)
1837        && FindProcShort (glProgramUniformMatrix3x4fv)
1838        && FindProcShort (glProgramUniformMatrix4x3fv)
1839        && FindProcShort (glProgramUniformMatrix2x3dv)
1840        && FindProcShort (glProgramUniformMatrix3x2dv)
1841        && FindProcShort (glProgramUniformMatrix2x4dv)
1842        && FindProcShort (glProgramUniformMatrix4x2dv)
1843        && FindProcShort (glProgramUniformMatrix3x4dv)
1844        && FindProcShort (glProgramUniformMatrix4x3dv)
1845        && FindProcShort (glValidateProgramPipeline)
1846        && FindProcShort (glGetProgramPipelineInfoLog);
1847
1848   // load GL_ARB_vertex_attrib_64bit (added to OpenGL 4.1 core)
1849   const bool hasVertAttrib64bit = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_vertex_attrib_64bit"))
1850        && FindProcShort (glVertexAttribL1d)
1851        && FindProcShort (glVertexAttribL2d)
1852        && FindProcShort (glVertexAttribL3d)
1853        && FindProcShort (glVertexAttribL4d)
1854        && FindProcShort (glVertexAttribL1dv)
1855        && FindProcShort (glVertexAttribL2dv)
1856        && FindProcShort (glVertexAttribL3dv)
1857        && FindProcShort (glVertexAttribL4dv)
1858        && FindProcShort (glVertexAttribLPointer)
1859        && FindProcShort (glGetVertexAttribLdv);
1860
1861   // load GL_ARB_viewport_array (added to OpenGL 4.1 core)
1862   const bool hasViewportArray = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_viewport_array"))
1863        && FindProcShort (glViewportArrayv)
1864        && FindProcShort (glViewportIndexedf)
1865        && FindProcShort (glViewportIndexedfv)
1866        && FindProcShort (glScissorArrayv)
1867        && FindProcShort (glScissorIndexed)
1868        && FindProcShort (glScissorIndexedv)
1869        && FindProcShort (glDepthRangeArrayv)
1870        && FindProcShort (glDepthRangeIndexed)
1871        && FindProcShort (glGetFloati_v)
1872        && FindProcShort (glGetDoublei_v);
1873
1874   has41 = IsGlGreaterEqual (4, 1)
1875        && hasES2Compatibility
1876        && hasGetProgramBinary
1877        && hasSeparateShaderObjects
1878        && hasVertAttrib64bit
1879        && hasViewportArray;
1880
1881   // load GL_ARB_base_instance (added to OpenGL 4.2 core)
1882   const bool hasBaseInstance = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_base_instance"))
1883        && FindProcShort (glDrawArraysInstancedBaseInstance)
1884        && FindProcShort (glDrawElementsInstancedBaseInstance)
1885        && FindProcShort (glDrawElementsInstancedBaseVertexBaseInstance);
1886
1887   // load GL_ARB_transform_feedback_instanced (added to OpenGL 4.2 core)
1888   const bool hasTrsfFeedbackInstanced = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_transform_feedback_instanced"))
1889        && FindProcShort (glDrawTransformFeedbackInstanced)
1890        && FindProcShort (glDrawTransformFeedbackStreamInstanced);
1891
1892   // load GL_ARB_internalformat_query (added to OpenGL 4.2 core)
1893   const bool hasInternalFormatQuery = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_internalformat_query"))
1894        && FindProcShort (glGetInternalformativ);
1895
1896   // load GL_ARB_shader_atomic_counters (added to OpenGL 4.2 core)
1897   const bool hasShaderAtomicCounters = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_shader_atomic_counters"))
1898        && FindProcShort (glGetActiveAtomicCounterBufferiv);
1899
1900   // load GL_ARB_shader_image_load_store (added to OpenGL 4.2 core)
1901   const bool hasShaderImgLoadStore = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_shader_image_load_store"))
1902        && FindProcShort (glBindImageTexture)
1903        && FindProcShort (glMemoryBarrier);
1904
1905   // load GL_ARB_texture_storage (added to OpenGL 4.2 core)
1906   const bool hasTextureStorage = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_texture_storage"))
1907        && FindProcShort (glTexStorage1D)
1908        && FindProcShort (glTexStorage2D)
1909        && FindProcShort (glTexStorage3D);
1910
1911   has42 = IsGlGreaterEqual (4, 2)
1912        && hasBaseInstance
1913        && hasTrsfFeedbackInstanced
1914        && hasInternalFormatQuery
1915        && hasShaderAtomicCounters
1916        && hasShaderImgLoadStore
1917        && hasTextureStorage;
1918
1919   has43 = IsGlGreaterEqual (4, 3)
1920        && FindProcShort (glClearBufferData)
1921        && FindProcShort (glClearBufferSubData)
1922        && FindProcShort (glDispatchCompute)
1923        && FindProcShort (glDispatchComputeIndirect)
1924        && FindProcShort (glCopyImageSubData)
1925        && FindProcShort (glFramebufferParameteri)
1926        && FindProcShort (glGetFramebufferParameteriv)
1927        && FindProcShort (glGetInternalformati64v)
1928        && FindProcShort (glInvalidateTexSubImage)
1929        && FindProcShort (glInvalidateTexImage)
1930        && FindProcShort (glInvalidateBufferSubData)
1931        && FindProcShort (glInvalidateBufferData)
1932        && FindProcShort (glInvalidateFramebuffer)
1933        && FindProcShort (glInvalidateSubFramebuffer)
1934        && FindProcShort (glMultiDrawArraysIndirect)
1935        && FindProcShort (glMultiDrawElementsIndirect)
1936        && FindProcShort (glGetProgramInterfaceiv)
1937        && FindProcShort (glGetProgramResourceIndex)
1938        && FindProcShort (glGetProgramResourceName)
1939        && FindProcShort (glGetProgramResourceiv)
1940        && FindProcShort (glGetProgramResourceLocation)
1941        && FindProcShort (glGetProgramResourceLocationIndex)
1942        && FindProcShort (glShaderStorageBlockBinding)
1943        && FindProcShort (glTexBufferRange)
1944        && FindProcShort (glTexStorage2DMultisample)
1945        && FindProcShort (glTexStorage3DMultisample)
1946        && FindProcShort (glTextureView)
1947        && FindProcShort (glBindVertexBuffer)
1948        && FindProcShort (glVertexAttribFormat)
1949        && FindProcShort (glVertexAttribIFormat)
1950        && FindProcShort (glVertexAttribLFormat)
1951        && FindProcShort (glVertexAttribBinding)
1952        && FindProcShort (glVertexBindingDivisor)
1953        && FindProcShort (glDebugMessageControl)
1954        && FindProcShort (glDebugMessageInsert)
1955        && FindProcShort (glDebugMessageCallback)
1956        && FindProcShort (glGetDebugMessageLog)
1957        && FindProcShort (glPushDebugGroup)
1958        && FindProcShort (glPopDebugGroup)
1959        && FindProcShort (glObjectLabel)
1960        && FindProcShort (glGetObjectLabel)
1961        && FindProcShort (glObjectPtrLabel)
1962        && FindProcShort (glGetObjectPtrLabel);
1963
1964   // load GL_ARB_clear_texture (added to OpenGL 4.4 core)
1965   bool arbTexClear = (IsGlGreaterEqual (4, 4) || CheckExtension ("GL_ARB_clear_texture"))
1966        && FindProcShort (glClearTexImage)
1967        && FindProcShort (glClearTexSubImage);
1968
1969   has44 = IsGlGreaterEqual (4, 4)
1970        && arbTexClear
1971        && FindProcShort (glBufferStorage)
1972        && FindProcShort (glBindBuffersBase)
1973        && FindProcShort (glBindBuffersRange)
1974        && FindProcShort (glBindTextures)
1975        && FindProcShort (glBindSamplers)
1976        && FindProcShort (glBindImageTextures)
1977        && FindProcShort (glBindVertexBuffers);
1978
1979   // initialize TBO extension (ARB)
1980   if (!has31
1981    && CheckExtension ("GL_ARB_texture_buffer_object")
1982    && FindProc ("glTexBufferARB", myFuncs->glTexBuffer))
1983   {
1984     arbTBO = (OpenGl_ArbTBO* )(&(*myFuncs));
1985   }
1986   arbTboRGB32 = CheckExtension ("GL_ARB_texture_buffer_object_rgb32");
1987
1988   // initialize hardware instancing extension (ARB)
1989   if (!has31
1990    && CheckExtension ("GL_ARB_draw_instanced")
1991    && FindProc ("glDrawArraysInstancedARB",   myFuncs->glDrawArraysInstanced)
1992    && FindProc ("glDrawElementsInstancedARB", myFuncs->glDrawElementsInstanced))
1993   {
1994     arbIns = (OpenGl_ArbIns* )(&(*myFuncs));
1995   }
1996
1997   // initialize FBO extension (ARB)
1998   if (hasFBO)
1999   {
2000     arbFBO     = (OpenGl_ArbFBO*     )(&(*myFuncs));
2001     arbFBOBlit = (OpenGl_ArbFBOBlit* )(&(*myFuncs));
2002     extPDS = Standard_True; // extension for EXT, but part of ARB
2003   }
2004
2005   // initialize GS extension (EXT)
2006   if (CheckExtension ("GL_EXT_geometry_shader4")
2007    && FindProcShort (glProgramParameteriEXT))
2008   {
2009     extGS = (OpenGl_ExtGS* )(&(*myFuncs));
2010   }
2011
2012   // initialize bindless texture extension (ARB)
2013   if (CheckExtension ("GL_ARB_bindless_texture")
2014    && FindProcShort (glGetTextureHandleARB)
2015    && FindProcShort (glGetTextureSamplerHandleARB)
2016    && FindProcShort (glMakeTextureHandleResidentARB)
2017    && FindProcShort (glMakeTextureHandleNonResidentARB)
2018    && FindProcShort (glGetImageHandleARB)
2019    && FindProcShort (glMakeImageHandleResidentARB)
2020    && FindProcShort (glMakeImageHandleNonResidentARB)
2021    && FindProcShort (glUniformHandleui64ARB)
2022    && FindProcShort (glUniformHandleui64vARB)
2023    && FindProcShort (glProgramUniformHandleui64ARB)
2024    && FindProcShort (glProgramUniformHandleui64vARB)
2025    && FindProcShort (glIsTextureHandleResidentARB)
2026    && FindProcShort (glIsImageHandleResidentARB)
2027    && FindProcShort (glVertexAttribL1ui64ARB)
2028    && FindProcShort (glVertexAttribL1ui64vARB)
2029    && FindProcShort (glGetVertexAttribLui64vARB))
2030   {
2031     arbTexBindless = (OpenGl_ArbTexBindless* )(&(*myFuncs));
2032   }
2033
2034   if (!has12)
2035   {
2036     checkWrongVersion (1, 2);
2037     myGlVerMajor = 1;
2038     myGlVerMinor = 1;
2039     return;
2040   }
2041   else if (!has13)
2042   {
2043     checkWrongVersion (1, 3);
2044     myGlVerMajor = 1;
2045     myGlVerMinor = 2;
2046     return;
2047   }
2048   else if (!has14)
2049   {
2050     checkWrongVersion (1, 4);
2051     myGlVerMajor = 1;
2052     myGlVerMinor = 3;
2053     return;
2054   }
2055   else if (!has15)
2056   {
2057     checkWrongVersion (1, 5);
2058     myGlVerMajor = 1;
2059     myGlVerMinor = 4;
2060     return;
2061   }
2062   if (!isCoreProfile)
2063   {
2064     core15 = (OpenGl_GlCore15* )(&(*myFuncs));
2065   }
2066   core15fwd = (OpenGl_GlCore15Fwd* )(&(*myFuncs));
2067
2068   if (!has20)
2069   {
2070     checkWrongVersion (2, 0);
2071     myGlVerMajor = 1;
2072     myGlVerMinor = 5;
2073     return;
2074   }
2075
2076   const char* aGlslVer = (const char* )::glGetString (GL_SHADING_LANGUAGE_VERSION);
2077   if (aGlslVer == NULL
2078   || *aGlslVer == '\0')
2079   {
2080     // broken context has been detected
2081     TCollection_ExtendedString aMsg = TCollection_ExtendedString()
2082       + "Error! OpenGL context reports version "
2083       + myGlVerMajor  + "." + myGlVerMinor
2084       + " but reports wrong GLSL version";
2085     PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
2086                  GL_DEBUG_TYPE_ERROR_ARB,
2087                  0,
2088                  GL_DEBUG_SEVERITY_HIGH_ARB,
2089                  aMsg);
2090     myGlVerMajor = 1;
2091     myGlVerMinor = 5;
2092     return;
2093   }
2094
2095   if (!isCoreProfile)
2096   {
2097     core20  = (OpenGl_GlCore20*    )(&(*myFuncs));
2098   }
2099   core20fwd = (OpenGl_GlCore20Fwd* )(&(*myFuncs));
2100
2101   if (!has21)
2102   {
2103     checkWrongVersion (2, 1);
2104     myGlVerMajor = 2;
2105     myGlVerMinor = 0;
2106     return;
2107   }
2108
2109   if (!has30)
2110   {
2111     checkWrongVersion (3, 0);
2112     myGlVerMajor = 2;
2113     myGlVerMinor = 1;
2114     return;
2115   }
2116
2117   if (!has31)
2118   {
2119     checkWrongVersion (3, 1);
2120     myGlVerMajor = 3;
2121     myGlVerMinor = 0;
2122     return;
2123   }
2124   arbTBO = (OpenGl_ArbTBO* )(&(*myFuncs));
2125   arbIns = (OpenGl_ArbIns* )(&(*myFuncs));
2126
2127   if (!has32)
2128   {
2129     checkWrongVersion (3, 2);
2130     myGlVerMajor = 3;
2131     myGlVerMinor = 1;
2132     return;
2133   }
2134   core32 = (OpenGl_GlCore32* )(&(*myFuncs));
2135   if (isCoreProfile)
2136   {
2137     core32->glGenVertexArrays (1, &myDefaultVao);
2138   }
2139   else
2140   {
2141     core32back = (OpenGl_GlCore32Back* )(&(*myFuncs));
2142   }
2143
2144   if (!has33)
2145   {
2146     checkWrongVersion (3, 3);
2147     myGlVerMajor = 3;
2148     myGlVerMinor = 2;
2149     return;
2150   }
2151   core33 = (OpenGl_GlCore33* )(&(*myFuncs));
2152   if (!isCoreProfile)
2153   {
2154     core33back = (OpenGl_GlCore33Back* )(&(*myFuncs));
2155   }
2156
2157   // initialize sampler object
2158   myTexSampler = new OpenGl_Sampler();
2159   myTexSampler->Init (*this);
2160
2161   if (!has40)
2162   {
2163     checkWrongVersion (4, 0);
2164     myGlVerMajor = 3;
2165     myGlVerMinor = 3;
2166     return;
2167   }
2168   arbTboRGB32 = Standard_True; // in core since OpenGL 4.0
2169
2170   if (!has41)
2171   {
2172     checkWrongVersion (4, 1);
2173     myGlVerMajor = 4;
2174     myGlVerMinor = 0;
2175     return;
2176   }
2177   core41 = (OpenGl_GlCore41* )(&(*myFuncs));
2178   if (!isCoreProfile)
2179   {
2180     core41back = (OpenGl_GlCore41Back* )(&(*myFuncs));
2181   }
2182
2183   if(!has42)
2184   {
2185     checkWrongVersion (4, 2);
2186     myGlVerMajor = 4;
2187     myGlVerMinor = 1;
2188     return;
2189   }
2190   core42 = (OpenGl_GlCore42* )(&(*myFuncs));
2191   if (!isCoreProfile)
2192   {
2193     core42back = (OpenGl_GlCore42Back* )(&(*myFuncs));
2194   }
2195
2196   if (!has43)
2197   {
2198     checkWrongVersion (4, 3);
2199     myGlVerMajor = 4;
2200     myGlVerMinor = 2;
2201     return;
2202   }
2203   core43 = (OpenGl_GlCore43* )(&(*myFuncs));
2204   if (!isCoreProfile)
2205   {
2206     core43back = (OpenGl_GlCore43Back* )(&(*myFuncs));
2207   }
2208
2209   if (!has44)
2210   {
2211     checkWrongVersion (4, 4);
2212     myGlVerMajor = 4;
2213     myGlVerMinor = 3;
2214     return;
2215   }
2216   core44 = (OpenGl_GlCore44* )(&(*myFuncs));
2217   if (!isCoreProfile)
2218   {
2219     core44back = (OpenGl_GlCore44Back* )(&(*myFuncs));
2220   }
2221 #endif
2222 }
2223
2224 // =======================================================================
2225 // function : MemoryInfo
2226 // purpose  :
2227 // =======================================================================
2228 Standard_Size OpenGl_Context::AvailableMemory() const
2229 {
2230 #if !defined(GL_ES_VERSION_2_0)
2231   if (atiMem)
2232   {
2233     // this is actually information for VBO pool
2234     // however because pools are mostly shared
2235     // it can be used for total GPU memory estimations
2236     GLint aMemInfo[4];
2237     aMemInfo[0] = 0;
2238     glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aMemInfo);
2239     // returned value is in KiB, however this maybe changed in future
2240     return Standard_Size(aMemInfo[0]) * 1024;
2241   }
2242   else if (nvxMem)
2243   {
2244     // current available dedicated video memory (in KiB), currently unused GPU memory
2245     GLint aMemInfo = 0;
2246     glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aMemInfo);
2247     return Standard_Size(aMemInfo) * 1024;
2248   }
2249 #endif
2250   return 0;
2251 }
2252
2253 // =======================================================================
2254 // function : MemoryInfo
2255 // purpose  :
2256 // =======================================================================
2257 TCollection_AsciiString OpenGl_Context::MemoryInfo() const
2258 {
2259   TCollection_AsciiString anInfo;
2260 #if !defined(GL_ES_VERSION_2_0)
2261   if (atiMem)
2262   {
2263     GLint aValues[4];
2264     memset (aValues, 0, sizeof(aValues));
2265     glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aValues);
2266
2267     // total memory free in the pool
2268     anInfo += TCollection_AsciiString ("  GPU free memory:    ") + (aValues[0] / 1024) + " MiB\n";
2269
2270     // largest available free block in the pool
2271     anInfo += TCollection_AsciiString ("  Largest free block: ") + (aValues[1] / 1024) + " MiB\n";
2272     if (aValues[2] != aValues[0])
2273     {
2274       // total auxiliary memory free
2275       anInfo += TCollection_AsciiString ("  Free memory:        ") + (aValues[2] / 1024) + " MiB\n";
2276     }
2277   }
2278   else if (nvxMem)
2279   {
2280     //current available dedicated video memory (in KiB), currently unused GPU memory
2281     GLint aValue = 0;
2282     glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aValue);
2283     anInfo += TCollection_AsciiString ("  GPU free memory:    ") + (aValue / 1024) + " MiB\n";
2284
2285     // dedicated video memory, total size (in KiB) of the GPU memory
2286     GLint aDedicated = 0;
2287     glGetIntegerv (GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &aDedicated);
2288     anInfo += TCollection_AsciiString ("  GPU memory:         ") + (aDedicated / 1024) + " MiB\n";
2289
2290     // total available memory, total size (in KiB) of the memory available for allocations
2291     glGetIntegerv (GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &aValue);
2292     if (aValue != aDedicated)
2293     {
2294       // different only for special configurations
2295       anInfo += TCollection_AsciiString ("  Total memory:       ") + (aValue / 1024) + " MiB\n";
2296     }
2297   }
2298 #endif
2299   return anInfo;
2300 }
2301
2302
2303 // =======================================================================
2304 // function : GetResource
2305 // purpose  :
2306 // =======================================================================
2307 const Handle(OpenGl_Resource)& OpenGl_Context::GetResource (const TCollection_AsciiString& theKey) const
2308 {
2309   return mySharedResources->IsBound (theKey) ? mySharedResources->Find (theKey) : NULL_GL_RESOURCE;
2310 }
2311
2312 // =======================================================================
2313 // function : ShareResource
2314 // purpose  :
2315 // =======================================================================
2316 Standard_Boolean OpenGl_Context::ShareResource (const TCollection_AsciiString& theKey,
2317                                                 const Handle(OpenGl_Resource)& theResource)
2318 {
2319   if (theKey.IsEmpty() || theResource.IsNull())
2320   {
2321     return Standard_False;
2322   }
2323   return mySharedResources->Bind (theKey, theResource);
2324 }
2325
2326 // =======================================================================
2327 // function : ReleaseResource
2328 // purpose  :
2329 // =======================================================================
2330 void OpenGl_Context::ReleaseResource (const TCollection_AsciiString& theKey,
2331                                       const Standard_Boolean         theToDelay)
2332 {
2333   if (!mySharedResources->IsBound (theKey))
2334   {
2335     return;
2336   }
2337   const Handle(OpenGl_Resource)& aRes = mySharedResources->Find (theKey);
2338   if (aRes->GetRefCount() > 1)
2339   {
2340     return;
2341   }
2342
2343   if (theToDelay)
2344   {
2345     myDelayed->Bind (theKey, 1);
2346   }
2347   else
2348   {
2349     aRes->Release (this);
2350     mySharedResources->UnBind (theKey);
2351   }
2352 }
2353
2354 // =======================================================================
2355 // function : DelayedRelease
2356 // purpose  :
2357 // =======================================================================
2358 void OpenGl_Context::DelayedRelease (Handle(OpenGl_Resource)& theResource)
2359 {
2360   myUnusedResources->Prepend (theResource);
2361   theResource.Nullify();
2362 }
2363
2364 // =======================================================================
2365 // function : ReleaseDelayed
2366 // purpose  :
2367 // =======================================================================
2368 void OpenGl_Context::ReleaseDelayed()
2369 {
2370   // release queued elements
2371   while (!myUnusedResources->IsEmpty())
2372   {
2373     myUnusedResources->First()->Release (this);
2374     myUnusedResources->RemoveFirst();
2375   }
2376
2377   // release delayed shared resources
2378   NCollection_Vector<TCollection_AsciiString> aDeadList;
2379   for (NCollection_DataMap<TCollection_AsciiString, Standard_Integer>::Iterator anIter (*myDelayed);
2380        anIter.More(); anIter.Next())
2381   {
2382     if (++anIter.ChangeValue() <= 2)
2383     {
2384       continue; // postpone release one more frame to ensure noone use it periodically
2385     }
2386
2387     const TCollection_AsciiString& aKey = anIter.Key();
2388     if (!mySharedResources->IsBound (aKey))
2389     {
2390       // mixed unshared strategy delayed/undelayed was used!
2391       aDeadList.Append (aKey);
2392       continue;
2393     }
2394
2395     Handle(OpenGl_Resource)& aRes = mySharedResources->ChangeFind (aKey);
2396     if (aRes->GetRefCount() > 1)
2397     {
2398       // should be only 1 instance in mySharedResources
2399       // if not - resource was reused again
2400       aDeadList.Append (aKey);
2401       continue;
2402     }
2403
2404     // release resource if no one requiested it more than 2 redraw calls
2405     aRes->Release (this);
2406     mySharedResources->UnBind (aKey);
2407     aDeadList.Append (aKey);
2408   }
2409
2410   for (Standard_Integer anIter = 0; anIter < aDeadList.Length(); ++anIter)
2411   {
2412     myDelayed->UnBind (aDeadList.Value (anIter));
2413   }
2414 }
2415
2416 // =======================================================================
2417 // function : BindProgram
2418 // purpose  :
2419 // =======================================================================
2420 Standard_Boolean OpenGl_Context::BindProgram (const Handle(OpenGl_ShaderProgram)& theProgram)
2421 {
2422   if (core20fwd == NULL)
2423   {
2424     return Standard_False;
2425   }
2426
2427   if (theProgram.IsNull()
2428   || !theProgram->IsValid())
2429   {
2430     if (!myActiveProgram.IsNull())
2431     {
2432       core20fwd->glUseProgram (OpenGl_ShaderProgram::NO_PROGRAM);
2433       myActiveProgram.Nullify();
2434     }
2435     return Standard_False;
2436   }
2437
2438   myActiveProgram = theProgram;
2439   core20fwd->glUseProgram (theProgram->ProgramId());
2440   return Standard_True;
2441 }
2442
2443 // =======================================================================
2444 // function : BindDefaultVao
2445 // purpose  :
2446 // =======================================================================
2447 void OpenGl_Context::BindDefaultVao()
2448 {
2449 #if !defined(GL_ES_VERSION_2_0)
2450   if (myDefaultVao == 0
2451    || core32 == NULL)
2452   {
2453     return;
2454   }
2455
2456   core32->glBindVertexArray (myDefaultVao);
2457 #endif
2458 }
2459
2460 // =======================================================================
2461 // function : SetDefaultFrameBuffer
2462 // purpose  :
2463 // =======================================================================
2464 Handle(OpenGl_FrameBuffer) OpenGl_Context::SetDefaultFrameBuffer (const Handle(OpenGl_FrameBuffer)& theFbo)
2465 {
2466   Handle(OpenGl_FrameBuffer) aFbo = myDefaultFbo;
2467   myDefaultFbo = theFbo;
2468   return aFbo;
2469 }
2470
2471 // =======================================================================
2472 // function : SetColor4fv
2473 // purpose  :
2474 // =======================================================================
2475 void OpenGl_Context::SetColor4fv (const OpenGl_Vec4& theColor)
2476 {
2477   if (!myActiveProgram.IsNull())
2478   {
2479     myActiveProgram->SetUniform (this, myActiveProgram->GetStateLocation (OpenGl_OCCT_COLOR), theColor);
2480   }
2481 #if !defined(GL_ES_VERSION_2_0)
2482   else if (core11 != NULL)
2483   {
2484     core11->glColor4fv (theColor.GetData());
2485   }
2486 #endif
2487 }
2488
2489 // =======================================================================
2490 // function : SetTypeOfLine
2491 // purpose  :
2492 // =======================================================================
2493 void OpenGl_Context::SetTypeOfLine (const Aspect_TypeOfLine  theType,
2494                                     const Standard_ShortReal theFactor)
2495 {
2496   Standard_Integer aPattern = 0xFFFF;
2497   switch (theType)
2498   {
2499     case Aspect_TOL_DASH:
2500     {
2501       aPattern = 0xFFC0;
2502       break;
2503     }
2504     case Aspect_TOL_DOT:
2505     {
2506       aPattern = 0xCCCC;
2507       break;
2508     }
2509     case Aspect_TOL_DOTDASH:
2510     {
2511       aPattern = 0xFF18;
2512       break;
2513     }
2514     case Aspect_TOL_SOLID:
2515     {
2516       aPattern = 0xFFFF;
2517       break;
2518     }
2519     case Aspect_TOL_USERDEFINED:
2520     {
2521       aPattern = 0xFF24;
2522       break;
2523     }
2524   }
2525
2526   if (!myActiveProgram.IsNull())
2527   {
2528     myActiveProgram->SetUniform (this, "uPattern", aPattern);
2529     myActiveProgram->SetUniform (this, "uFactor",  theFactor);
2530     return;
2531   }
2532
2533 #if !defined(GL_ES_VERSION_2_0)
2534   if (theType != Aspect_TOL_SOLID)
2535   {
2536   #ifdef HAVE_GL2PS
2537     if (IsFeedback())
2538     {
2539       gl2psEnable (GL2PS_LINE_STIPPLE);
2540     }
2541   #endif
2542
2543     if (core11 != NULL)
2544     {
2545       core11fwd->glEnable (GL_LINE_STIPPLE);
2546
2547       core11->glLineStipple (static_cast<GLint>    (theFactor),
2548                              static_cast<GLushort> (aPattern));
2549     }
2550   }
2551   else
2552   {
2553     if (core11 != NULL)
2554     {
2555       core11fwd->glDisable (GL_LINE_STIPPLE);
2556     }
2557
2558   #ifdef HAVE_GL2PS
2559     if (IsFeedback())
2560     {
2561       gl2psDisable (GL2PS_LINE_STIPPLE);
2562     }
2563   #endif
2564   }
2565 #endif
2566 }
2567
2568 // =======================================================================
2569 // function : SetLineWidth
2570 // purpose  :
2571 // =======================================================================
2572 void OpenGl_Context::SetLineWidth (const Standard_ShortReal theWidth)
2573 {
2574   if (core11 != NULL)
2575   {
2576     // glLineWidth() is still defined within Core Profile, but has no effect with values != 1.0f
2577     core11fwd->glLineWidth (theWidth);
2578   }
2579 #ifdef HAVE_GL2PS
2580   if (IsFeedback())
2581   {
2582     gl2psLineWidth (theWidth);
2583   }
2584 #endif
2585 }
2586
2587 // =======================================================================
2588 // function : SetPointSize
2589 // purpose  :
2590 // =======================================================================
2591 void OpenGl_Context::SetPointSize (const Standard_ShortReal theSize)
2592 {
2593   if (!myActiveProgram.IsNull())
2594   {
2595     myActiveProgram->SetUniform (this, myActiveProgram->GetStateLocation (OpenGl_OCCT_POINT_SIZE), theSize);
2596   #if !defined(GL_ES_VERSION_2_0)
2597     //myContext->core11fwd->glEnable (GL_VERTEX_PROGRAM_POINT_SIZE);
2598   #endif
2599   }
2600 #if !defined(GL_ES_VERSION_2_0)
2601   //else
2602   {
2603     core11fwd->glPointSize (theSize);
2604     if (core20fwd != NULL)
2605     {
2606       //myContext->core11fwd->glDisable (GL_VERTEX_PROGRAM_POINT_SIZE);
2607     }
2608   }
2609 #endif
2610 }
2611
2612 // =======================================================================
2613 // function : SetGlNormalizeEnabled
2614 // purpose  :
2615 // =======================================================================
2616 Standard_Boolean OpenGl_Context::SetGlNormalizeEnabled (Standard_Boolean isEnabled)
2617 {
2618   if (isEnabled == myIsGlNormalizeEnabled)
2619   {
2620     return myIsGlNormalizeEnabled;
2621   }
2622
2623   Standard_Boolean anOldGlNormalize = myIsGlNormalizeEnabled;
2624
2625   myIsGlNormalizeEnabled = isEnabled;
2626
2627 #if !defined(GL_ES_VERSION_2_0)
2628   if (core11 != NULL)
2629   {
2630     if (isEnabled)
2631     {
2632       ::glEnable  (GL_NORMALIZE);
2633     }
2634     else
2635     {
2636       ::glDisable (GL_NORMALIZE);
2637     }
2638   }
2639 #endif
2640
2641   return anOldGlNormalize;
2642 }
2643
2644 // =======================================================================
2645 // function : ApplyModelWorldMatrix
2646 // purpose  :
2647 // =======================================================================
2648 void OpenGl_Context::ApplyModelWorldMatrix()
2649 {
2650 #if !defined(GL_ES_VERSION_2_0)
2651   if (core11 != NULL)
2652   {
2653     core11->glMatrixMode (GL_MODELVIEW);
2654     core11->glLoadMatrixf (ModelWorldState.Current());
2655   }
2656 #endif
2657
2658   if (!myShaderManager->IsEmpty())
2659   {
2660     myShaderManager->UpdateModelWorldStateTo (ModelWorldState.Current());
2661   }
2662 }
2663
2664 // =======================================================================
2665 // function : ApplyWorldViewMatrix
2666 // purpose  :
2667 // =======================================================================
2668 void OpenGl_Context::ApplyWorldViewMatrix()
2669 {
2670 #if !defined(GL_ES_VERSION_2_0)
2671   if (core11 != NULL)
2672   {
2673     core11->glMatrixMode (GL_MODELVIEW);
2674     core11->glLoadMatrixf (WorldViewState.Current());
2675   }
2676 #endif
2677
2678   if (!myShaderManager->IsEmpty())
2679   {
2680     myShaderManager->UpdateWorldViewStateTo (WorldViewState.Current());
2681   }
2682 }
2683
2684 // =======================================================================
2685 // function : ApplyModelViewMatrix
2686 // purpose  :
2687 // =======================================================================
2688 void OpenGl_Context::ApplyModelViewMatrix()
2689 {
2690 #if !defined(GL_ES_VERSION_2_0)
2691   if (core11 != NULL)
2692   {
2693     OpenGl_Mat4 aModelView = WorldViewState.Current() * ModelWorldState.Current();
2694     core11->glMatrixMode (GL_MODELVIEW);
2695     core11->glLoadMatrixf (aModelView.GetData());
2696   }
2697 #endif
2698
2699   if (!myShaderManager->IsEmpty())
2700   {
2701     myShaderManager->UpdateModelWorldStateTo (ModelWorldState.Current());
2702     myShaderManager->UpdateWorldViewStateTo (WorldViewState.Current());
2703   }
2704 }
2705
2706 // =======================================================================
2707 // function : ApplyProjectionMatrix
2708 // purpose  :
2709 // =======================================================================
2710 void OpenGl_Context::ApplyProjectionMatrix()
2711 {
2712 #if !defined(GL_ES_VERSION_2_0)
2713   if (core11 != NULL)
2714   {
2715     core11->glMatrixMode (GL_PROJECTION);
2716     core11->glLoadMatrixf (ProjectionState.Current().GetData());
2717   }
2718 #endif
2719
2720   if (!myShaderManager->IsEmpty())
2721   {
2722     myShaderManager->UpdateProjectionStateTo (ProjectionState.Current());
2723   }
2724 }