0030638: Visualization, TKOpenGl - load OpenGL 4.5 functions within OpenGl_Context
[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_ArbSamplerObject.hxx>
28 #include <OpenGl_ArbTexBindless.hxx>
29 #include <OpenGl_GlCore45.hxx>
30 #include <OpenGl_FrameBuffer.hxx>
31 #include <OpenGl_FrameStats.hxx>
32 #include <OpenGl_Sampler.hxx>
33 #include <OpenGl_ShaderManager.hxx>
34 #include <OpenGl_Workspace.hxx>
35 #include <OpenGl_Aspects.hxx>
36 #include <Graphic3d_TransformUtils.hxx>
37 #include <Graphic3d_RenderingParams.hxx>
38
39 #include <Message_Messenger.hxx>
40
41 #include <NCollection_Vector.hxx>
42
43 #include <Standard_ProgramError.hxx>
44
45 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Context,Standard_Transient)
46
47 #if defined(HAVE_EGL)
48   #include <EGL/egl.h>
49   #ifdef _MSC_VER
50     #pragma comment(lib, "libEGL.lib")
51   #endif
52 #elif defined(_WIN32)
53   //
54 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
55   #include <dlfcn.h>
56   #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
57     //
58   #else
59     #include <OpenGL/OpenGL.h>
60     #include <CoreGraphics/CoreGraphics.h>
61   #endif
62 #else
63   #include <GL/glx.h> // glXGetProcAddress()
64 #endif
65
66 namespace
67 {
68   static const Handle(OpenGl_Resource) NULL_GL_RESOURCE;
69   static const OpenGl_Mat4 THE_IDENTITY_MATRIX;
70
71   //! Add key-value pair to the dictionary.
72   static void addInfo (TColStd_IndexedDataMapOfStringString& theDict,
73                        const TCollection_AsciiString& theKey,
74                        const TCollection_AsciiString& theValue)
75   {
76     theDict.ChangeFromIndex (theDict.Add (theKey, theValue)) = theValue;
77   }
78
79   //! Add key-value pair to the dictionary.
80   static void addInfo (TColStd_IndexedDataMapOfStringString& theDict,
81                        const TCollection_AsciiString& theKey,
82                        const char* theValue)
83   {
84     TCollection_AsciiString aValue (theValue != NULL ? theValue : "");
85     theDict.ChangeFromIndex (theDict.Add (theKey, aValue)) = aValue;
86   }
87 }
88
89 // =======================================================================
90 // function : OpenGl_Context
91 // purpose  :
92 // =======================================================================
93 OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
94 : core11     (NULL),
95   core11fwd  (NULL),
96   core15     (NULL),
97   core15fwd  (NULL),
98   core20     (NULL),
99   core20fwd  (NULL),
100   core32     (NULL),
101   core32back (NULL),
102   core33     (NULL),
103   core33back (NULL),
104   core41     (NULL),
105   core41back (NULL),
106   core42     (NULL),
107   core42back (NULL),
108   core43     (NULL),
109   core43back (NULL),
110   core44     (NULL),
111   core44back (NULL),
112   core45     (NULL),
113   core45back (NULL),
114   caps   (!theCaps.IsNull() ? theCaps : new OpenGl_Caps()),
115 #if defined(GL_ES_VERSION_2_0)
116   hasHighp   (Standard_False),
117   hasUintIndex(Standard_False),
118   hasTexRGBA8(Standard_False),
119   hasFlatShading (OpenGl_FeatureNotAvailable),
120 #else
121   hasHighp   (Standard_True),
122   hasUintIndex(Standard_True),
123   hasTexRGBA8(Standard_True),
124   hasFlatShading (OpenGl_FeatureInCore),
125 #endif
126   hasDrawBuffers     (OpenGl_FeatureNotAvailable),
127   hasFloatBuffer     (OpenGl_FeatureNotAvailable),
128   hasHalfFloatBuffer (OpenGl_FeatureNotAvailable),
129   hasSampleVariables (OpenGl_FeatureNotAvailable),
130   hasGeometryStage   (OpenGl_FeatureNotAvailable),
131   arbDrawBuffers (Standard_False),
132   arbNPTW  (Standard_False),
133   arbTexRG (Standard_False),
134   arbTexFloat (Standard_False),
135   arbSamplerObject (NULL),
136   arbTexBindless (NULL),
137   arbTBO (NULL),
138   arbTboRGB32 (Standard_False),
139   arbIns (NULL),
140   arbDbg (NULL),
141   arbFBO (NULL),
142   arbFBOBlit (NULL),
143   arbSampleShading (Standard_False),
144   extFragDepth (Standard_False),
145   extDrawBuffers (Standard_False),
146   extGS  (NULL),
147   extBgra(Standard_False),
148   extAnis(Standard_False),
149   extPDS (Standard_False),
150   atiMem (Standard_False),
151   nvxMem (Standard_False),
152   oesSampleVariables (Standard_False),
153   oesStdDerivatives (Standard_False),
154   mySharedResources (new OpenGl_ResourcesMap()),
155   myDelayed         (new OpenGl_DelayReleaseMap()),
156   myUnusedResources (new OpenGl_ResourcesStack()),
157   myClippingState (),
158   myGlLibHandle (NULL),
159   myFuncs (new OpenGl_GlFunctions()),
160   myAnisoMax   (1),
161   myTexClamp   (GL_CLAMP_TO_EDGE),
162   myMaxTexDim  (1024),
163   myMaxTexCombined (1),
164   myMaxDumpSizeX (1024),
165   myMaxDumpSizeY (1024),
166   myMaxClipPlanes (6),
167   myMaxMsaaSamples(0),
168   myMaxDrawBuffers (1),
169   myMaxColorAttachments (1),
170   myGlVerMajor (0),
171   myGlVerMinor (0),
172   myIsInitialized (Standard_False),
173   myIsStereoBuffers (Standard_False),
174   myIsGlNormalizeEnabled (Standard_False),
175   mySpriteTexUnit (Graphic3d_TextureUnit_0),
176   myHasRayTracing (Standard_False),
177   myHasRayTracingTextures (Standard_False),
178   myHasRayTracingAdaptiveSampling (Standard_False),
179   myHasRayTracingAdaptiveSamplingAtomic (Standard_False),
180   myFrameStats (new OpenGl_FrameStats()),
181 #if !defined(GL_ES_VERSION_2_0)
182   myPointSpriteOrig (GL_UPPER_LEFT),
183   myRenderMode (GL_RENDER),
184   myPolygonMode (GL_FILL),
185 #else
186   myPointSpriteOrig (0),
187   myRenderMode (0),
188   myPolygonMode (0),
189 #endif
190   myToCullBackFaces (false),
191   myReadBuffer (0),
192   myDrawBuffers (0, 7),
193   myDefaultVao (0),
194   myColorMask (true),
195   myAlphaToCoverage (false),
196   myIsGlDebugCtx (Standard_False),
197   myResolution (Graphic3d_RenderingParams::THE_DEFAULT_RESOLUTION),
198   myResolutionRatio (1.0f),
199   myLineWidthScale (1.0f),
200   myLineFeather (1.0f),
201   myRenderScale (1.0f),
202   myRenderScaleInv (1.0f)
203 {
204   myViewport[0] = 0;
205   myViewport[1] = 0;
206   myViewport[2] = 0;
207   myViewport[3] = 0;
208   myViewportVirt[0] = 0;
209   myViewportVirt[1] = 0;
210   myViewportVirt[2] = 0;
211   myViewportVirt[3] = 0;
212
213   myPolygonOffset.Mode   = Aspect_POM_Off;
214   myPolygonOffset.Factor = 0.0f;
215   myPolygonOffset.Units  = 0.0f;
216
217   // system-dependent fields
218 #if defined(HAVE_EGL)
219   myDisplay  = (Aspect_Display          )EGL_NO_DISPLAY;
220   myWindow   = (Aspect_Drawable         )EGL_NO_SURFACE;
221   myGContext = (Aspect_RenderingContext )EGL_NO_CONTEXT;
222 #elif defined(_WIN32)
223   myWindow   = NULL;
224   myWindowDC = NULL;
225   myGContext = NULL;
226 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
227   // Vendors can not extend functionality on this system
228   // and developers are limited to OpenGL support provided by Mac OS X SDK.
229   // We retrieve function pointers from system library
230   // to generalize extensions support on all platforms.
231   // In this way we also reach binary compatibility benefit between OS releases
232   // if some newest functionality is optionally used.
233   // Notice that GL version / extension availability checks are required
234   // because function pointers may be available but not functionality itself
235   // (depends on renderer).
236 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
237   myGContext    = NULL;
238   myGlLibHandle = dlopen ("/System/Library/Frameworks/OpenGLES.framework/OpenGLES", RTLD_LAZY);
239 #else
240   myGContext    = NULL;
241   myGlLibHandle = dlopen ("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
242 #endif
243 #else
244   myDisplay =  NULL;
245   myWindow   = 0;
246   myGContext = 0;
247 #endif
248
249   memset (myFuncs.operator->(), 0, sizeof(OpenGl_GlFunctions));
250   myShaderManager = new OpenGl_ShaderManager (this);
251 }
252
253 // =======================================================================
254 // function : ~OpenGl_Context
255 // purpose  :
256 // =======================================================================
257 OpenGl_Context::~OpenGl_Context()
258 {
259   // release clean up queue
260   ReleaseDelayed();
261
262 #if !defined(GL_ES_VERSION_2_0)
263   // release default VAO
264   if (myDefaultVao != 0
265    && IsValid()
266    && core32 != NULL)
267   {
268     core32->glDeleteVertexArrays (1, &myDefaultVao);
269   }
270   myDefaultVao = 0;
271 #endif
272
273   // release default FBO
274   if (!myDefaultFbo.IsNull())
275   {
276     myDefaultFbo->Release (this);
277     myDefaultFbo.Nullify();
278   }
279
280   // release shared resources if any
281   if (mySharedResources->GetRefCount() <= 1)
282   {
283     myShaderManager.Nullify();
284     for (NCollection_DataMap<TCollection_AsciiString, Handle(OpenGl_Resource)>::Iterator anIter (*mySharedResources);
285          anIter.More(); anIter.Next())
286     {
287       anIter.Value()->Release (this);
288     }
289
290     // release delayed resources added during deletion of shared resources
291     while (!myUnusedResources->IsEmpty())
292     {
293       myUnusedResources->First()->Release (this);
294       myUnusedResources->RemoveFirst();
295     }
296   }
297   else if (myShaderManager->IsSameContext (this))
298   {
299     myShaderManager->SetContext (NULL);
300   }
301   mySharedResources.Nullify();
302   myDelayed.Nullify();
303
304   if (arbDbg != NULL
305    && myIsGlDebugCtx
306    && IsValid())
307   {
308     // reset callback
309   #if !defined(GL_ES_VERSION_2_0)
310     void* aPtr = NULL;
311     glGetPointerv (GL_DEBUG_CALLBACK_USER_PARAM, &aPtr);
312     if (aPtr == this)
313   #endif
314     {
315       arbDbg->glDebugMessageCallback (NULL, NULL);
316     }
317     myIsGlDebugCtx = Standard_False;
318   }
319 }
320
321 // =======================================================================
322 // function : forcedRelease
323 // purpose  :
324 // =======================================================================
325 void OpenGl_Context::forcedRelease()
326 {
327   ReleaseDelayed();
328   for (NCollection_DataMap<TCollection_AsciiString, Handle(OpenGl_Resource)>::Iterator anIter (*mySharedResources);
329        anIter.More(); anIter.Next())
330   {
331     anIter.Value()->Release (this);
332   }
333   mySharedResources->Clear();
334   myShaderManager->clear();
335   myShaderManager->SetContext (NULL);
336
337   // release delayed resources added during deletion of shared resources
338   while (!myUnusedResources->IsEmpty())
339   {
340     myUnusedResources->First()->Release (this);
341     myUnusedResources->RemoveFirst();
342   }
343 }
344
345 // =======================================================================
346 // function : ResizeViewport
347 // purpose  :
348 // =======================================================================
349 void OpenGl_Context::ResizeViewport (const Standard_Integer* theRect)
350 {
351   core11fwd->glViewport (theRect[0], theRect[1], theRect[2], theRect[3]);
352   myViewport[0] = theRect[0];
353   myViewport[1] = theRect[1];
354   myViewport[2] = theRect[2];
355   myViewport[3] = theRect[3];
356   if (HasRenderScale())
357   {
358     myViewportVirt[0] = Standard_Integer(theRect[0] * myRenderScaleInv);
359     myViewportVirt[1] = Standard_Integer(theRect[1] * myRenderScaleInv);
360     myViewportVirt[2] = Standard_Integer(theRect[2] * myRenderScaleInv);
361     myViewportVirt[3] = Standard_Integer(theRect[3] * myRenderScaleInv);
362   }
363   else
364   {
365     myViewportVirt[0] = theRect[0];
366     myViewportVirt[1] = theRect[1];
367     myViewportVirt[2] = theRect[2];
368     myViewportVirt[3] = theRect[3];
369   }
370 }
371
372 #if !defined(GL_ES_VERSION_2_0)
373 inline Standard_Integer stereoToMonoBuffer (const Standard_Integer theBuffer)
374 {
375   switch (theBuffer)
376   {
377     case GL_BACK_LEFT:
378     case GL_BACK_RIGHT:
379       return GL_BACK;
380     case GL_FRONT_LEFT:
381     case GL_FRONT_RIGHT:
382       return GL_FRONT;
383     default:
384       return theBuffer;
385   }
386 }
387 #endif
388
389 // =======================================================================
390 // function : SetReadBuffer
391 // purpose  :
392 // =======================================================================
393 void OpenGl_Context::SetReadBuffer (const Standard_Integer theReadBuffer)
394 {
395 #if !defined(GL_ES_VERSION_2_0)
396   myReadBuffer = !myIsStereoBuffers ? stereoToMonoBuffer (theReadBuffer) : theReadBuffer;
397   if (myReadBuffer < GL_COLOR_ATTACHMENT0
398    && arbFBO != NULL)
399   {
400     arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
401   }
402   ::glReadBuffer (myReadBuffer);
403 #else
404   (void )theReadBuffer;
405 #endif
406 }
407
408 // =======================================================================
409 // function : SetDrawBuffer
410 // purpose  :
411 // =======================================================================
412 void OpenGl_Context::SetDrawBuffer (const Standard_Integer theDrawBuffer)
413 {
414 #if !defined(GL_ES_VERSION_2_0)
415   const Standard_Integer aDrawBuffer = !myIsStereoBuffers ? stereoToMonoBuffer (theDrawBuffer) : theDrawBuffer;
416   if (aDrawBuffer < GL_COLOR_ATTACHMENT0
417    && arbFBO != NULL)
418   {
419     arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
420   }
421   ::glDrawBuffer (aDrawBuffer);
422
423   myDrawBuffers.Init (GL_NONE);
424   myDrawBuffers.SetValue (0, aDrawBuffer);
425 #else
426   (void )theDrawBuffer;
427 #endif
428 }
429
430 // =======================================================================
431 // function : SetDrawBuffers
432 // purpose  :
433 // =======================================================================
434 void OpenGl_Context::SetDrawBuffers (const Standard_Integer theNb, const Standard_Integer* theDrawBuffers)
435 {
436   Standard_ASSERT_RETURN (hasDrawBuffers, "Multiple draw buffers feature is not supported by the context", Standard_ASSERT_DO_NOTHING());
437
438   if (myDrawBuffers.Length() < theNb)
439   {
440     // should actually never happen here
441     myDrawBuffers.Resize (0, theNb - 1, false);
442   }
443   myDrawBuffers.Init (GL_NONE);
444
445   Standard_Boolean useDefaultFbo = Standard_False;
446   for (Standard_Integer anI = 0; anI < theNb; ++anI)
447   {
448     if (theDrawBuffers[anI] < GL_COLOR_ATTACHMENT0 && theDrawBuffers[anI] != GL_NONE)
449     {
450       useDefaultFbo = Standard_True;
451     }
452     else
453     {
454       myDrawBuffers.SetValue (anI, theDrawBuffers[anI]);
455     }
456   }
457   if (arbFBO != NULL && useDefaultFbo)
458   {
459     arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
460   }
461
462   myFuncs->glDrawBuffers (theNb, (const GLenum*)theDrawBuffers);
463 }
464
465 // =======================================================================
466 // function : SetCullBackFaces
467 // purpose  :
468 // =======================================================================
469 void OpenGl_Context::SetCullBackFaces (bool theToEnable)
470 {
471   if (myToCullBackFaces == theToEnable)
472   {
473     return;
474   }
475
476   myToCullBackFaces = theToEnable;
477   if (theToEnable)
478   {
479     //glCullFace (GL_BACK); GL_BACK by default
480     core11fwd->glEnable (GL_CULL_FACE);
481   }
482   else
483   {
484     core11fwd->glDisable (GL_CULL_FACE);
485   }
486 }
487
488 // =======================================================================
489 // function : FetchState
490 // purpose  :
491 // =======================================================================
492 void OpenGl_Context::FetchState()
493 {
494 #if !defined(GL_ES_VERSION_2_0)
495   // cache feedback mode state
496   if (core11 != NULL)
497   {
498     ::glGetIntegerv (GL_RENDER_MODE, &myRenderMode);
499   }
500
501   // cache read buffers state
502   ::glGetIntegerv (GL_READ_BUFFER, &myReadBuffer);
503
504   // cache draw buffers state
505   if (myDrawBuffers.Length() < myMaxDrawBuffers)
506   {
507     myDrawBuffers.Resize (0, myMaxDrawBuffers - 1, false);
508   }
509   myDrawBuffers.Init (GL_NONE);
510
511   Standard_Integer aDrawBuffer = GL_NONE;
512   if (myMaxDrawBuffers == 1)
513   {
514     ::glGetIntegerv (GL_DRAW_BUFFER, &aDrawBuffer);
515     myDrawBuffers.SetValue (0, aDrawBuffer);
516   }
517   else
518   {
519     for (Standard_Integer anI = 0; anI < myMaxDrawBuffers; ++anI)
520     {
521       ::glGetIntegerv (GL_DRAW_BUFFER0 + anI, &aDrawBuffer);
522       myDrawBuffers.SetValue (anI, aDrawBuffer);
523     }
524   }
525 #endif
526 }
527
528 // =======================================================================
529 // function : Share
530 // purpose  :
531 // =======================================================================
532 void OpenGl_Context::Share (const Handle(OpenGl_Context)& theShareCtx)
533 {
534   if (!theShareCtx.IsNull())
535   {
536     mySharedResources = theShareCtx->mySharedResources;
537     myDelayed         = theShareCtx->myDelayed;
538     myUnusedResources = theShareCtx->myUnusedResources;
539     myShaderManager   = theShareCtx->myShaderManager;
540   }
541 }
542
543 #if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
544
545 // =======================================================================
546 // function : IsCurrent
547 // purpose  :
548 // =======================================================================
549 Standard_Boolean OpenGl_Context::IsCurrent() const
550 {
551 #if defined(HAVE_EGL)
552   if ((EGLDisplay )myDisplay  == EGL_NO_DISPLAY
553    || (EGLContext )myGContext == EGL_NO_CONTEXT)
554   {
555     return Standard_False;
556   }
557
558   return (((EGLDisplay )myDisplay  == eglGetCurrentDisplay())
559        && ((EGLContext )myGContext == eglGetCurrentContext())
560        && ((EGLSurface )myWindow   == eglGetCurrentSurface (EGL_DRAW)));
561 #elif defined(_WIN32)
562   if (myWindowDC == NULL || myGContext == NULL)
563   {
564     return Standard_False;
565   }
566   return (( (HDC )myWindowDC == wglGetCurrentDC())
567       && ((HGLRC )myGContext == wglGetCurrentContext()));
568 #else
569   if (myDisplay == NULL || myWindow == 0 || myGContext == 0)
570   {
571     return Standard_False;
572   }
573
574   return (   ((Display* )myDisplay  == glXGetCurrentDisplay())
575        &&  ((GLXContext )myGContext == glXGetCurrentContext())
576        && ((GLXDrawable )myWindow   == glXGetCurrentDrawable()));
577 #endif
578 }
579
580 // =======================================================================
581 // function : MakeCurrent
582 // purpose  :
583 // =======================================================================
584 Standard_Boolean OpenGl_Context::MakeCurrent()
585 {
586 #if defined(HAVE_EGL)
587   if ((EGLDisplay )myDisplay  == EGL_NO_DISPLAY
588    || (EGLContext )myGContext == EGL_NO_CONTEXT)
589   {
590     Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
591     return Standard_False;
592   }
593
594   if (eglMakeCurrent ((EGLDisplay )myDisplay, (EGLSurface )myWindow, (EGLSurface )myWindow, (EGLContext )myGContext) != EGL_TRUE)
595   {
596     // if there is no current context it might be impossible to use glGetError() correctly
597     PushMessage (GL_DEBUG_SOURCE_WINDOW_SYSTEM, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
598                  "eglMakeCurrent() has failed!");
599     myIsInitialized = Standard_False;
600     return Standard_False;
601   }
602 #elif defined(_WIN32)
603   if (myWindowDC == NULL || myGContext == NULL)
604   {
605     Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
606     return Standard_False;
607   }
608
609   // technically it should be safe to activate already bound GL context
610   // however some drivers (Intel etc.) may FAIL doing this for unknown reason
611   if (IsCurrent())
612   {
613     myShaderManager->SetContext (this);
614     return Standard_True;
615   }
616   else if (wglMakeCurrent ((HDC )myWindowDC, (HGLRC )myGContext) != TRUE)
617   {
618     // notice that glGetError() couldn't be used here!
619     wchar_t* aMsgBuff = NULL;
620     DWORD anErrorCode = GetLastError();
621     FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
622                     NULL, anErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (wchar_t* )&aMsgBuff, 0, NULL);
623     TCollection_ExtendedString aMsg ("wglMakeCurrent() has failed. ");
624     if (aMsgBuff != NULL)
625     {
626       aMsg += (Standard_ExtString )aMsgBuff;
627       LocalFree (aMsgBuff);
628     }
629     PushMessage (GL_DEBUG_SOURCE_WINDOW_SYSTEM, GL_DEBUG_TYPE_ERROR, (unsigned int )anErrorCode, GL_DEBUG_SEVERITY_HIGH, aMsg);
630     myIsInitialized = Standard_False;
631     return Standard_False;
632   }
633 #else
634   if (myDisplay == NULL || myWindow == 0 || myGContext == 0)
635   {
636     Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
637     return Standard_False;
638   }
639
640   if (!glXMakeCurrent ((Display* )myDisplay, (GLXDrawable )myWindow, (GLXContext )myGContext))
641   {
642     // if there is no current context it might be impossible to use glGetError() correctly
643     PushMessage (GL_DEBUG_SOURCE_WINDOW_SYSTEM, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
644                  "glXMakeCurrent() has failed!");
645     myIsInitialized = Standard_False;
646     return Standard_False;
647   }
648 #endif
649   myShaderManager->SetContext (this);
650   return Standard_True;
651 }
652
653 // =======================================================================
654 // function : SwapBuffers
655 // purpose  :
656 // =======================================================================
657 void OpenGl_Context::SwapBuffers()
658 {
659 #if defined(HAVE_EGL)
660   if ((EGLSurface )myWindow != EGL_NO_SURFACE)
661   {
662     eglSwapBuffers ((EGLDisplay )myDisplay, (EGLSurface )myWindow);
663   }
664 #elif defined(_WIN32)
665   if ((HDC )myWindowDC != NULL)
666   {
667     ::SwapBuffers ((HDC )myWindowDC);
668     glFlush();
669   }
670 #else
671   if ((Display* )myDisplay != NULL)
672   {
673     glXSwapBuffers ((Display* )myDisplay, (GLXDrawable )myWindow);
674   }
675 #endif
676 }
677
678 #endif // __APPLE__
679
680 // =======================================================================
681 // function : SetSwapInterval
682 // purpose  :
683 // =======================================================================
684 Standard_Boolean OpenGl_Context::SetSwapInterval (const Standard_Integer theInterval)
685 {
686 #if defined(HAVE_EGL)
687   if (::eglSwapInterval ((EGLDisplay )myDisplay, theInterval) == EGL_TRUE)
688   {
689     return Standard_True;
690   }
691 #elif defined(_WIN32)
692   if (myFuncs->wglSwapIntervalEXT != NULL)
693   {
694     myFuncs->wglSwapIntervalEXT (theInterval);
695     return Standard_True;
696   }
697 #elif defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
698   //
699 #elif defined(__APPLE__)
700   if (::CGLSetParameter (CGLGetCurrentContext(), kCGLCPSwapInterval, &theInterval) == kCGLNoError)
701   {
702     return Standard_True;
703   }
704 #else
705   if (theInterval == -1
706    && myFuncs->glXSwapIntervalEXT != NULL)
707   {
708     typedef int (*glXSwapIntervalEXT_t_x)(Display* theDisplay, GLXDrawable theDrawable, int theInterval);
709     glXSwapIntervalEXT_t_x aFuncPtr = (glXSwapIntervalEXT_t_x )myFuncs->glXSwapIntervalEXT;
710     aFuncPtr ((Display* )myDisplay, (GLXDrawable )myWindow, theInterval);
711     return Standard_True;
712   }
713   else if (myFuncs->glXSwapIntervalSGI != NULL)
714   {
715     myFuncs->glXSwapIntervalSGI (theInterval);
716     return Standard_True;
717   }
718 #endif
719   return Standard_False;
720 }
721
722 // =======================================================================
723 // function : findProc
724 // purpose  :
725 // =======================================================================
726 void* OpenGl_Context::findProc (const char* theFuncName)
727 {
728 #if defined(HAVE_EGL)
729   return (void* )eglGetProcAddress (theFuncName);
730 #elif defined(_WIN32)
731   return (void* )wglGetProcAddress (theFuncName);
732 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
733   return (myGlLibHandle != NULL) ? dlsym (myGlLibHandle, theFuncName) : NULL;
734 #else
735   return (void* )glXGetProcAddress ((const GLubyte* )theFuncName);
736 #endif
737 }
738
739 // =======================================================================
740 // function : CheckExtension
741 // purpose  :
742 // =======================================================================
743 Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtName) const
744 {
745   if (theExtName  == NULL)
746   {
747 #ifdef OCCT_DEBUG
748     std::cerr << "CheckExtension called with NULL string!\n";
749 #endif
750     return Standard_False;
751   }
752
753 #if !defined(GL_ES_VERSION_2_0)
754   // available since OpenGL 3.0
755   // and the ONLY way to check extensions with OpenGL 3.1+ core profile
756   if (IsGlGreaterEqual (3, 0)
757    && myFuncs->glGetStringi != NULL)
758   {
759     GLint anExtNb = 0;
760     ::glGetIntegerv (GL_NUM_EXTENSIONS, &anExtNb);
761     const size_t anExtNameLen = strlen (theExtName);
762     for (GLint anIter = 0; anIter < anExtNb; ++anIter)
763     {
764       const char* anExtension = (const char* )myFuncs->glGetStringi (GL_EXTENSIONS, (GLuint )anIter);
765       const size_t aTestExtNameLen = strlen (anExtension);
766       if (aTestExtNameLen == anExtNameLen
767        && strncmp (anExtension, theExtName, anExtNameLen) == 0)
768       {
769         return Standard_True;
770       }
771     }
772     return Standard_False;
773   }
774 #endif
775
776   // use old way with huge string for all extensions
777   const char* anExtString = (const char* )glGetString (GL_EXTENSIONS);
778   if (anExtString == NULL)
779   {
780     Messenger()->Send ("TKOpenGL: glGetString (GL_EXTENSIONS) has returned NULL! No GL context?", Message_Warning);
781     return Standard_False;
782   }
783   return CheckExtension (anExtString, theExtName);
784 }
785
786 // =======================================================================
787 // function : CheckExtension
788 // purpose  :
789 // =======================================================================
790 Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtString,
791                                                  const char* theExtName)
792 {
793   if (theExtString == NULL)
794   {
795     return Standard_False;
796   }
797
798   // Search for theExtName in the extensions string.
799   // Use of strstr() is not sufficient because extension names can be prefixes of other extension names.
800   char* aPtrIter = (char* )theExtString;
801   const char*  aPtrEnd      = aPtrIter + strlen (theExtString);
802   const size_t anExtNameLen = strlen (theExtName);
803   while (aPtrIter < aPtrEnd)
804   {
805     const size_t n = strcspn (aPtrIter, " ");
806     if ((n == anExtNameLen) && (strncmp (aPtrIter, theExtName, anExtNameLen) == 0))
807     {
808       return Standard_True;
809     }
810     aPtrIter += (n + 1);
811   }
812   return Standard_False;
813 }
814
815 #if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
816
817 // =======================================================================
818 // function : Init
819 // purpose  :
820 // =======================================================================
821 Standard_Boolean OpenGl_Context::Init (const Standard_Boolean theIsCoreProfile)
822 {
823   if (myIsInitialized)
824   {
825     return Standard_True;
826   }
827
828 #if defined(HAVE_EGL)
829   myDisplay  = (Aspect_Display )eglGetCurrentDisplay();
830   myGContext = (Aspect_RenderingContext )eglGetCurrentContext();
831   myWindow   = (Aspect_Drawable )eglGetCurrentSurface(EGL_DRAW);
832 #elif defined(_WIN32)
833   myWindowDC = (Aspect_Handle )wglGetCurrentDC();
834   myGContext = (Aspect_RenderingContext )wglGetCurrentContext();
835 #else
836   myDisplay  = (Aspect_Display )glXGetCurrentDisplay();
837   myGContext = (Aspect_RenderingContext )glXGetCurrentContext();
838   myWindow   = (Aspect_Drawable )glXGetCurrentDrawable();
839 #endif
840   if (myGContext == NULL)
841   {
842     return Standard_False;
843   }
844
845   init (theIsCoreProfile);
846   myIsInitialized = Standard_True;
847   return Standard_True;
848 }
849
850 #endif // __APPLE__
851
852 // =======================================================================
853 // function : Init
854 // purpose  :
855 // =======================================================================
856 #if defined(HAVE_EGL)
857 Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable         theEglSurface,
858                                        const Aspect_Display          theEglDisplay,
859                                        const Aspect_RenderingContext theEglContext,
860                                        const Standard_Boolean        theIsCoreProfile)
861 #elif defined(_WIN32)
862 Standard_Boolean OpenGl_Context::Init (const Aspect_Handle           theWindow,
863                                        const Aspect_Handle           theWindowDC,
864                                        const Aspect_RenderingContext theGContext,
865                                        const Standard_Boolean        theIsCoreProfile)
866 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
867
868 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
869 Standard_Boolean OpenGl_Context::Init (EAGLContext*                  theGContext,
870                                        const Standard_Boolean        theIsCoreProfile)
871 #else
872 Standard_Boolean OpenGl_Context::Init (NSOpenGLContext*              theGContext,
873                                        const Standard_Boolean        theIsCoreProfile)
874 #endif
875
876 #else
877 Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable         theWindow,
878                                        const Aspect_Display          theDisplay,
879                                        const Aspect_RenderingContext theGContext,
880                                        const Standard_Boolean        theIsCoreProfile)
881 #endif
882 {
883   Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called only once!");
884 #if defined(HAVE_EGL)
885   myWindow   = theEglSurface;
886   myGContext = theEglContext;
887   myDisplay  = theEglDisplay;
888 #elif defined(_WIN32)
889   myWindow   = theWindow;
890   myGContext = theGContext;
891   myWindowDC = theWindowDC;
892 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
893   myGContext = theGContext;
894 #else
895   myWindow   = theWindow;
896   myGContext = theGContext;
897   myDisplay  = theDisplay;
898 #endif
899   if (myGContext == NULL || !MakeCurrent())
900   {
901     return Standard_False;
902   }
903
904   init (theIsCoreProfile);
905   myIsInitialized = Standard_True;
906   return Standard_True;
907 }
908
909 // =======================================================================
910 // function : ResetErrors
911 // purpose  :
912 // =======================================================================
913 bool OpenGl_Context::ResetErrors (const bool theToPrintErrors)
914 {
915   int aPrevErr = 0;
916   int anErr    = ::glGetError();
917   const bool hasError = anErr != GL_NO_ERROR;
918   if (!theToPrintErrors)
919   {
920     for (; anErr != GL_NO_ERROR && aPrevErr != anErr; aPrevErr = anErr, anErr = ::glGetError())
921     {
922       //
923     }
924     return hasError;
925   }
926
927   for (; anErr != GL_NO_ERROR && aPrevErr != anErr; aPrevErr = anErr, anErr = ::glGetError())
928   {
929     TCollection_ExtendedString anErrId;
930     switch (anErr)
931     {
932       case GL_INVALID_ENUM:      anErrId = "GL_INVALID_ENUM";      break;
933       case GL_INVALID_VALUE:     anErrId = "GL_INVALID_VALUE";     break;
934       case GL_INVALID_OPERATION: anErrId = "GL_INVALID_OPERATION"; break;
935     #ifdef GL_STACK_OVERFLOW
936       case GL_STACK_OVERFLOW:    anErrId = "GL_STACK_OVERFLOW";    break;
937       case GL_STACK_UNDERFLOW:   anErrId = "GL_STACK_UNDERFLOW";   break;
938     #endif
939       case GL_OUT_OF_MEMORY:     anErrId = "GL_OUT_OF_MEMORY";     break;
940       case GL_INVALID_FRAMEBUFFER_OPERATION:
941         anErrId = "GL_INVALID_FRAMEBUFFER_OPERATION";
942         break;
943       default:
944         anErrId = TCollection_ExtendedString("#") + anErr;
945         break;
946     }
947
948     const TCollection_ExtendedString aMsg = TCollection_ExtendedString ("Unhandled GL error: ") + anErrId;
949     PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, 0, GL_DEBUG_SEVERITY_LOW, aMsg);
950   }
951   return hasError;
952 }
953
954 // =======================================================================
955 // function : ReadGlVersion
956 // purpose  :
957 // =======================================================================
958 void OpenGl_Context::ReadGlVersion (Standard_Integer& theGlVerMajor,
959                                     Standard_Integer& theGlVerMinor)
960 {
961   // reset values
962   theGlVerMajor = 0;
963   theGlVerMinor = 0;
964
965 #ifdef GL_MAJOR_VERSION
966   // available since OpenGL 3.0 and OpenGL 3.0 ES
967   GLint aMajor = 0, aMinor = 0;
968   glGetIntegerv (GL_MAJOR_VERSION, &aMajor);
969   glGetIntegerv (GL_MINOR_VERSION, &aMinor);
970   // glGetError() sometimes does not report an error here even if
971   // GL does not know GL_MAJOR_VERSION and GL_MINOR_VERSION constants.
972   // This happens on some renderers like e.g. Cygwin MESA.
973   // Thus checking additionally if GL has put anything to
974   // the output variables.
975   if (::glGetError() == GL_NO_ERROR && aMajor != 0 && aMinor != 0)
976   {
977     theGlVerMajor = aMajor;
978     theGlVerMinor = aMinor;
979     return;
980   }
981   for (GLenum anErr = ::glGetError(), aPrevErr = GL_NO_ERROR;; aPrevErr = anErr, anErr = ::glGetError())
982   {
983     if (anErr == GL_NO_ERROR
984      || anErr == aPrevErr)
985     {
986       break;
987     }
988   }
989 #endif
990
991   // Read version string.
992   // Notice that only first two numbers split by point '2.1 XXXXX' are significant.
993   // Following trash (after space) is vendor-specific.
994   // New drivers also returns micro version of GL like '3.3.0' which has no meaning
995   // and should be considered as vendor-specific too.
996   const char* aVerStr = (const char* )glGetString (GL_VERSION);
997   if (aVerStr == NULL || *aVerStr == '\0')
998   {
999     // invalid GL context
1000     return;
1001   }
1002
1003 //#if defined(GL_ES_VERSION_2_0)
1004   // skip "OpenGL ES-** " section
1005   for (; *aVerStr != '\0'; ++aVerStr)
1006   {
1007     if (*aVerStr >= '0' && *aVerStr <= '9')
1008     {
1009       break;
1010     }
1011   }
1012 //#endif
1013
1014   // parse string for major number
1015   char aMajorStr[32];
1016   char aMinorStr[32];
1017   size_t aMajIter = 0;
1018   while (aVerStr[aMajIter] >= '0' && aVerStr[aMajIter] <= '9')
1019   {
1020     ++aMajIter;
1021   }
1022   if (aMajIter == 0 || aMajIter >= sizeof(aMajorStr))
1023   {
1024     return;
1025   }
1026   memcpy (aMajorStr, aVerStr, aMajIter);
1027   aMajorStr[aMajIter] = '\0';
1028
1029   // parse string for minor number
1030   aVerStr += aMajIter + 1;
1031   size_t aMinIter = 0;
1032   while (aVerStr[aMinIter] >= '0' && aVerStr[aMinIter] <= '9')
1033   {
1034     ++aMinIter;
1035   }
1036   if (aMinIter == 0 || aMinIter >= sizeof(aMinorStr))
1037   {
1038     return;
1039   }
1040   memcpy (aMinorStr, aVerStr, aMinIter);
1041   aMinorStr[aMinIter] = '\0';
1042
1043   // read numbers
1044   theGlVerMajor = atoi (aMajorStr);
1045   theGlVerMinor = atoi (aMinorStr);
1046
1047   if (theGlVerMajor <= 0)
1048   {
1049     theGlVerMajor = 0;
1050     theGlVerMinor = 0;
1051   }
1052 }
1053
1054 static Standard_CString THE_DBGMSG_UNKNOWN = "UNKNOWN";
1055 static Standard_CString THE_DBGMSG_SOURCES[] =
1056 {
1057   ".OpenGL",    // GL_DEBUG_SOURCE_API
1058   ".WinSystem", // GL_DEBUG_SOURCE_WINDOW_SYSTEM
1059   ".GLSL",      // GL_DEBUG_SOURCE_SHADER_COMPILER
1060   ".3rdParty",  // GL_DEBUG_SOURCE_THIRD_PARTY
1061   "",           // GL_DEBUG_SOURCE_APPLICATION
1062   ".Other"      // GL_DEBUG_SOURCE_OTHER
1063 };
1064
1065 static Standard_CString THE_DBGMSG_TYPES[] =
1066 {
1067   "Error",           // GL_DEBUG_TYPE_ERROR
1068   "Deprecated",      // GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR
1069   "Undef. behavior", // GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR
1070   "Portability",     // GL_DEBUG_TYPE_PORTABILITY
1071   "Performance",     // GL_DEBUG_TYPE_PERFORMANCE
1072   "Other"            // GL_DEBUG_TYPE_OTHER
1073 };
1074
1075 static Standard_CString THE_DBGMSG_SEV_HIGH   = "High";   // GL_DEBUG_SEVERITY_HIGH
1076 static Standard_CString THE_DBGMSG_SEV_MEDIUM = "Medium"; // GL_DEBUG_SEVERITY_MEDIUM
1077 static Standard_CString THE_DBGMSG_SEV_LOW    = "Low";    // GL_DEBUG_SEVERITY_LOW
1078
1079 //! Callback for GL_ARB_debug_output extension
1080 static void APIENTRY debugCallbackWrap(unsigned int theSource,
1081                                        unsigned int theType,
1082                                        unsigned int theId,
1083                                        unsigned int theSeverity,
1084                                        int          /*theLength*/,
1085                                        const char*  theMessage,
1086                                        const void*  theUserParam)
1087 {
1088   OpenGl_Context* aCtx = (OpenGl_Context* )theUserParam;
1089   aCtx->PushMessage (theSource, theType, theId, theSeverity, theMessage);
1090 }
1091
1092 // =======================================================================
1093 // function : PushMessage
1094 // purpose  :
1095 // =======================================================================
1096 void OpenGl_Context::PushMessage (const unsigned int theSource,
1097                                   const unsigned int theType,
1098                                   const unsigned int theId,
1099                                   const unsigned int theSeverity,
1100                                   const TCollection_ExtendedString& theMessage)
1101 {
1102   if (caps->suppressExtraMsg
1103    && theSource >= GL_DEBUG_SOURCE_API
1104    && theSource <= GL_DEBUG_SOURCE_OTHER
1105    && myFilters[theSource - GL_DEBUG_SOURCE_API].Contains (theId))
1106   {
1107     return;
1108   }
1109
1110   Standard_CString& aSrc = (theSource >= GL_DEBUG_SOURCE_API
1111                         && theSource <= GL_DEBUG_SOURCE_OTHER)
1112                          ? THE_DBGMSG_SOURCES[theSource - GL_DEBUG_SOURCE_API]
1113                          : THE_DBGMSG_UNKNOWN;
1114   Standard_CString& aType = (theType >= GL_DEBUG_TYPE_ERROR
1115                          && theType <= GL_DEBUG_TYPE_OTHER)
1116                           ? THE_DBGMSG_TYPES[theType - GL_DEBUG_TYPE_ERROR]
1117                           : THE_DBGMSG_UNKNOWN;
1118   Standard_CString& aSev = theSeverity == GL_DEBUG_SEVERITY_HIGH
1119                          ? THE_DBGMSG_SEV_HIGH
1120                          : (theSeverity == GL_DEBUG_SEVERITY_MEDIUM
1121                           ? THE_DBGMSG_SEV_MEDIUM
1122                           : THE_DBGMSG_SEV_LOW);
1123   Message_Gravity aGrav = theSeverity == GL_DEBUG_SEVERITY_HIGH
1124                         ? Message_Alarm
1125                         : (theSeverity == GL_DEBUG_SEVERITY_MEDIUM
1126                          ? Message_Warning
1127                          : Message_Info);
1128
1129   TCollection_ExtendedString aMsg;
1130   aMsg += "TKOpenGl"; aMsg += aSrc;
1131   aMsg += " | Type: ";        aMsg += aType;
1132   aMsg += " | ID: ";          aMsg += (Standard_Integer )theId;
1133   aMsg += " | Severity: ";    aMsg += aSev;
1134   aMsg += " | Message:\n  ";
1135   aMsg += theMessage;
1136   Messenger()->Send (aMsg, aGrav);
1137 }
1138
1139 // =======================================================================
1140 // function : ExcludeMessage
1141 // purpose  :
1142 // ======================================================================
1143 Standard_Boolean OpenGl_Context::ExcludeMessage (const unsigned int theSource,
1144                                                  const unsigned int theId)
1145 {
1146   return theSource >= GL_DEBUG_SOURCE_API
1147       && theSource <= GL_DEBUG_SOURCE_OTHER
1148       && myFilters[theSource - GL_DEBUG_SOURCE_API].Add (theId);
1149 }
1150
1151 // =======================================================================
1152 // function : IncludeMessage
1153 // purpose  :
1154 // ======================================================================
1155 Standard_Boolean OpenGl_Context::IncludeMessage (const unsigned int theSource,
1156                                                  const unsigned int theId)
1157 {
1158   return theSource >= GL_DEBUG_SOURCE_API
1159       && theSource <= GL_DEBUG_SOURCE_OTHER
1160       && myFilters[theSource - GL_DEBUG_SOURCE_API].Remove (theId);
1161 }
1162
1163 // =======================================================================
1164 // function : checkWrongVersion
1165 // purpose  :
1166 // ======================================================================
1167 void OpenGl_Context::checkWrongVersion (const Standard_Integer theGlVerMajor,
1168                                         const Standard_Integer theGlVerMinor)
1169 {
1170   if (!IsGlGreaterEqual (theGlVerMajor, theGlVerMinor))
1171   {
1172     return;
1173   }
1174
1175   TCollection_ExtendedString aMsg = TCollection_ExtendedString()
1176     + "Error! OpenGL context reports version "
1177     + myGlVerMajor  + "." + myGlVerMinor
1178     + " but does not export required functions for "
1179     + theGlVerMajor + "." + theGlVerMinor;
1180   PushMessage (GL_DEBUG_SOURCE_APPLICATION,
1181                GL_DEBUG_TYPE_ERROR,
1182                0,
1183                GL_DEBUG_SEVERITY_HIGH,
1184                aMsg);
1185 }
1186
1187 // =======================================================================
1188 // function : init
1189 // purpose  :
1190 // =======================================================================
1191 void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
1192 {
1193   // read version
1194   myGlVerMajor = 0;
1195   myGlVerMinor = 0;
1196   myMaxMsaaSamples = 0;
1197   myMaxDrawBuffers = 1;
1198   myMaxColorAttachments = 1;
1199   ReadGlVersion (myGlVerMajor, myGlVerMinor);
1200   myVendor = (const char* )::glGetString (GL_VENDOR);
1201   myVendor.LowerCase();
1202   if (!caps->ffpEnable
1203    && !IsGlGreaterEqual (2, 0))
1204   {
1205     caps->ffpEnable = true;
1206     TCollection_ExtendedString aMsg =
1207       TCollection_ExtendedString("OpenGL driver is too old! Context info:\n")
1208                                + "    Vendor:   " + (const char* )::glGetString (GL_VENDOR)   + "\n"
1209                                + "    Renderer: " + (const char* )::glGetString (GL_RENDERER) + "\n"
1210                                + "    Version:  " + (const char* )::glGetString (GL_VERSION)  + "\n"
1211                                + "  Fallback using deprecated fixed-function pipeline.\n"
1212                                + "  Visualization might work incorrectly.\n"
1213                                  "  Consider upgrading the graphics driver.";
1214     PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
1215   }
1216
1217 #if defined(GL_ES_VERSION_2_0)
1218   (void )theIsCoreProfile;
1219   const bool isCoreProfile = false;
1220 #else
1221
1222   if (myVendor.Search ("nvidia") != -1)
1223   {
1224     // Buffer detailed info: Buffer object 1 (bound to GL_ARRAY_BUFFER_ARB, usage hint is GL_STATIC_DRAW)
1225     // will use VIDEO memory as the source for buffer object operations.
1226     ExcludeMessage (GL_DEBUG_SOURCE_API, 131185);
1227   }
1228   if (IsGlGreaterEqual (3, 0))
1229   {
1230     // retrieve auxiliary function in advance
1231     FindProc ("glGetStringi", myFuncs->glGetStringi);
1232   }
1233
1234   bool isCoreProfile = false;
1235   if (IsGlGreaterEqual (3, 2))
1236   {
1237     isCoreProfile = (theIsCoreProfile == Standard_True);
1238
1239     // detect Core profile
1240     if (!isCoreProfile)
1241     {
1242       GLint aProfile = 0;
1243       ::glGetIntegerv (GL_CONTEXT_PROFILE_MASK, &aProfile);
1244       isCoreProfile = (aProfile & GL_CONTEXT_CORE_PROFILE_BIT) != 0;
1245     }
1246   }
1247 #endif
1248
1249   core11     = NULL;
1250   if (!isCoreProfile)
1251   {
1252     core11 = (OpenGl_GlCore11* )(&(*myFuncs));
1253   }
1254   core11fwd  = (OpenGl_GlCore11Fwd* )(&(*myFuncs));
1255   core15     = NULL;
1256   core15fwd  = NULL;
1257   core20     = NULL;
1258   core20fwd  = NULL;
1259   core32     = NULL;
1260   core32back = NULL;
1261   core33     = NULL;
1262   core33back = NULL;
1263   core41     = NULL;
1264   core41back = NULL;
1265   core42     = NULL;
1266   core42back = NULL;
1267   core43     = NULL;
1268   core43back = NULL;
1269   core44     = NULL;
1270   core44back = NULL;
1271   core45     = NULL;
1272   core45back = NULL;
1273   arbTBO     = NULL;
1274   arbTboRGB32 = Standard_False;
1275   arbIns     = NULL;
1276   arbDbg     = NULL;
1277   arbFBO     = NULL;
1278   arbFBOBlit = NULL;
1279   extGS      = NULL;
1280   myDefaultVao = 0;
1281
1282   //! Make record shorter to retrieve function pointer using variable with same name
1283   #define FindProcShort(theFunc) FindProc(#theFunc, myFuncs->theFunc)
1284
1285 #if defined(GL_ES_VERSION_2_0)
1286
1287   hasTexRGBA8 = IsGlGreaterEqual (3, 0)
1288              || CheckExtension ("GL_OES_rgb8_rgba8");
1289   // NPOT textures has limited support within OpenGL ES 2.0
1290   // which are relaxed by OpenGL ES 3.0 or some extensions
1291   //arbNPTW     = IsGlGreaterEqual (3, 0)
1292   //           || CheckExtension ("GL_OES_texture_npot")
1293   //           || CheckExtension ("GL_NV_texture_npot_2D_mipmap");
1294   arbNPTW     = Standard_True;
1295   arbTexRG    = IsGlGreaterEqual (3, 0)
1296              || CheckExtension ("GL_EXT_texture_rg");
1297   extBgra     = CheckExtension ("GL_EXT_texture_format_BGRA8888");
1298   extAnis = CheckExtension ("GL_EXT_texture_filter_anisotropic");
1299   extPDS  = IsGlGreaterEqual (3, 0)
1300          || CheckExtension ("GL_OES_packed_depth_stencil");
1301
1302   core11fwd = (OpenGl_GlCore11Fwd* )(&(*myFuncs));
1303   if (IsGlGreaterEqual (2, 0))
1304   {
1305     // enable compatible functions
1306     core20    = (OpenGl_GlCore20*    )(&(*myFuncs));
1307     core20fwd = (OpenGl_GlCore20Fwd* )(&(*myFuncs));
1308     core15fwd = (OpenGl_GlCore15Fwd* )(&(*myFuncs));
1309     arbFBO    = (OpenGl_ArbFBO*      )(&(*myFuncs));
1310   }
1311   if (IsGlGreaterEqual (3, 0)
1312    && FindProcShort (glBlitFramebuffer))
1313   {
1314     arbFBOBlit = (OpenGl_ArbFBOBlit* )(&(*myFuncs));
1315   }
1316   if (IsGlGreaterEqual (3, 0)
1317    && FindProcShort (glGenSamplers)
1318    && FindProcShort (glDeleteSamplers)
1319    && FindProcShort (glIsSampler)
1320    && FindProcShort (glBindSampler)
1321    && FindProcShort (glSamplerParameteri)
1322    && FindProcShort (glSamplerParameteriv)
1323    && FindProcShort (glSamplerParameterf)
1324    && FindProcShort (glSamplerParameterfv)
1325    && FindProcShort (glGetSamplerParameteriv)
1326    && FindProcShort (glGetSamplerParameterfv))
1327    //&& FindProcShort (glSamplerParameterIiv) // only on Desktop or with extensions GL_OES_texture_border_clamp/GL_EXT_texture_border_clamp
1328    //&& FindProcShort (glSamplerParameterIuiv)
1329    //&& FindProcShort (glGetSamplerParameterIiv)
1330    //&& FindProcShort (glGetSamplerParameterIuiv))
1331   {
1332     arbSamplerObject = (OpenGl_ArbSamplerObject* )(&(*myFuncs));
1333   }
1334   extFragDepth = !IsGlGreaterEqual(3, 0)
1335                && CheckExtension ("GL_EXT_frag_depth");
1336   if (IsGlGreaterEqual (3, 1)
1337    && FindProc ("glTexStorage2DMultisample", myFuncs->glTexStorage2DMultisample))
1338   {
1339     // MSAA RenderBuffers have been defined in OpenGL ES 3.0,
1340     // but MSAA Textures - only in OpenGL ES 3.1+
1341     ::glGetIntegerv (GL_MAX_SAMPLES, &myMaxMsaaSamples);
1342   }
1343
1344   hasUintIndex = IsGlGreaterEqual (3, 0)
1345               || CheckExtension ("GL_OES_element_index_uint");
1346   hasHighp     = CheckExtension ("GL_OES_fragment_precision_high");
1347   GLint aRange[2] = {0, 0};
1348   GLint aPrec     = 0;
1349   ::glGetShaderPrecisionFormat (GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, aRange, &aPrec);
1350   if (aPrec != 0)
1351   {
1352     hasHighp = Standard_True;
1353   }
1354
1355   arbTexFloat = IsGlGreaterEqual (3, 0)
1356              && FindProc ("glTexImage3D", myFuncs->glTexImage3D);
1357
1358   const Standard_Boolean hasTexBuffer32  = IsGlGreaterEqual (3, 2) && FindProc ("glTexBuffer", myFuncs->glTexBuffer);
1359   const Standard_Boolean hasExtTexBuffer = CheckExtension ("GL_EXT_texture_buffer") && FindProc ("glTexBufferEXT", myFuncs->glTexBuffer);
1360
1361   if (hasTexBuffer32 || hasExtTexBuffer)
1362   {
1363     arbTBO = reinterpret_cast<OpenGl_ArbTBO*> (myFuncs.get());
1364   }
1365
1366   // initialize debug context extension
1367   if (CheckExtension ("GL_KHR_debug"))
1368   {
1369     // this functionality become a part of OpenGL ES 3.2
1370     arbDbg = NULL;
1371     // According to GL_KHR_debug spec, all functions should have KHR suffix.
1372     // However, some implementations can export these functions without suffix.
1373     if (FindProc ("glDebugMessageControlKHR",  myFuncs->glDebugMessageControl)
1374      && FindProc ("glDebugMessageInsertKHR",   myFuncs->glDebugMessageInsert)
1375      && FindProc ("glDebugMessageCallbackKHR", myFuncs->glDebugMessageCallback)
1376      && FindProc ("glGetDebugMessageLogKHR",   myFuncs->glGetDebugMessageLog))
1377     {
1378       arbDbg = (OpenGl_ArbDbg* )(&(*myFuncs));
1379     }
1380
1381     if (arbDbg != NULL
1382      && caps->contextDebug)
1383     {
1384       // setup default callback
1385       myIsGlDebugCtx = Standard_True;
1386       arbDbg->glDebugMessageCallback (debugCallbackWrap, this);
1387       ::glEnable (GL_DEBUG_OUTPUT);
1388       if (caps->contextSyncDebug)
1389       {
1390         // note that some broken implementations (e.g. simulators) might generate error message on this call
1391         ::glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS);
1392       }
1393     }
1394   }
1395
1396   extDrawBuffers = CheckExtension ("GL_EXT_draw_buffers") && FindProc ("glDrawBuffersEXT", myFuncs->glDrawBuffers);
1397   arbDrawBuffers = CheckExtension ("GL_ARB_draw_buffers") && FindProc ("glDrawBuffersARB", myFuncs->glDrawBuffers);
1398
1399   if (IsGlGreaterEqual (3, 0) && FindProc ("glDrawBuffers", myFuncs->glDrawBuffers))
1400   {
1401     hasDrawBuffers = OpenGl_FeatureInCore;
1402   }
1403   else if (extDrawBuffers || arbDrawBuffers)
1404   {
1405     hasDrawBuffers = OpenGl_FeatureInExtensions;
1406   }
1407
1408   hasFloatBuffer     = IsGlGreaterEqual (3, 2) ? OpenGl_FeatureInCore :
1409                        CheckExtension ("GL_EXT_color_buffer_float") ? OpenGl_FeatureInExtensions 
1410                                                                     : OpenGl_FeatureNotAvailable;
1411   hasHalfFloatBuffer = IsGlGreaterEqual (3, 2) ? OpenGl_FeatureInCore :
1412                        CheckExtension ("GL_EXT_color_buffer_half_float") ? OpenGl_FeatureInExtensions 
1413                                                                          : OpenGl_FeatureNotAvailable;
1414
1415   oesSampleVariables = CheckExtension ("GL_OES_sample_variables");
1416   oesStdDerivatives  = CheckExtension ("GL_OES_standard_derivatives");
1417   hasSampleVariables = IsGlGreaterEqual (3, 2) ? OpenGl_FeatureInCore :
1418                        oesSampleVariables ? OpenGl_FeatureInExtensions
1419                                           : OpenGl_FeatureNotAvailable;
1420   // without hasHighp, dFdx/dFdy precision is considered too low for flat shading (visual artifacts)
1421   hasFlatShading = IsGlGreaterEqual (3, 0)
1422                  ? OpenGl_FeatureInCore
1423                   : (oesStdDerivatives && hasHighp
1424                    ? OpenGl_FeatureInExtensions
1425                    : OpenGl_FeatureNotAvailable);
1426   if (!IsGlGreaterEqual (3, 1)
1427     && myVendor.Search("qualcomm") != -1)
1428   {
1429     // dFdx/dFdy are completely broken on tested Adreno devices with versions below OpenGl ES 3.1
1430     hasFlatShading = OpenGl_FeatureNotAvailable;
1431   }
1432
1433   hasGeometryStage = IsGlGreaterEqual (3, 2)
1434                    ? OpenGl_FeatureInCore
1435                    : (CheckExtension ("GL_EXT_geometry_shader") && CheckExtension ("GL_EXT_shader_io_blocks")
1436                      ? OpenGl_FeatureInExtensions
1437                      : OpenGl_FeatureNotAvailable);
1438 #else
1439
1440   myTexClamp = IsGlGreaterEqual (1, 2) ? GL_CLAMP_TO_EDGE : GL_CLAMP;
1441
1442   hasTexRGBA8 = Standard_True;
1443   arbDrawBuffers   = CheckExtension ("GL_ARB_draw_buffers");
1444   arbNPTW          = CheckExtension ("GL_ARB_texture_non_power_of_two");
1445   arbTexFloat      = IsGlGreaterEqual (3, 0)
1446                   || CheckExtension ("GL_ARB_texture_float");
1447   arbSampleShading = CheckExtension ("GL_ARB_sample_shading");
1448   extBgra          = CheckExtension ("GL_EXT_bgra");
1449   extAnis          = CheckExtension ("GL_EXT_texture_filter_anisotropic");
1450   extPDS           = CheckExtension ("GL_EXT_packed_depth_stencil");
1451   atiMem           = CheckExtension ("GL_ATI_meminfo");
1452   nvxMem           = CheckExtension ("GL_NVX_gpu_memory_info");
1453
1454   hasDrawBuffers = IsGlGreaterEqual (2, 0) ? OpenGl_FeatureInCore :
1455                    arbDrawBuffers ? OpenGl_FeatureInExtensions 
1456                                   : OpenGl_FeatureNotAvailable;
1457
1458   hasFloatBuffer = hasHalfFloatBuffer =  IsGlGreaterEqual (3, 0) ? OpenGl_FeatureInCore :
1459                                          CheckExtension ("GL_ARB_color_buffer_float") ? OpenGl_FeatureInExtensions
1460                                                                                       : OpenGl_FeatureNotAvailable;
1461
1462   hasGeometryStage = IsGlGreaterEqual (3, 2)
1463                    ? OpenGl_FeatureInCore
1464                    : OpenGl_FeatureNotAvailable;
1465
1466   hasSampleVariables = IsGlGreaterEqual (4, 0) ? OpenGl_FeatureInCore :
1467                         arbSampleShading ? OpenGl_FeatureInExtensions
1468                                          : OpenGl_FeatureNotAvailable;
1469
1470   GLint aStereo = GL_FALSE;
1471   glGetIntegerv (GL_STEREO, &aStereo);
1472   myIsStereoBuffers = aStereo == 1;
1473
1474   // get number of maximum clipping planes
1475   glGetIntegerv (GL_MAX_CLIP_PLANES,  &myMaxClipPlanes);
1476 #endif
1477
1478   if (hasDrawBuffers)
1479   {
1480     glGetIntegerv (GL_MAX_DRAW_BUFFERS,      &myMaxDrawBuffers);
1481     glGetIntegerv (GL_MAX_COLOR_ATTACHMENTS, &myMaxColorAttachments);
1482     if (myDrawBuffers.Length() < myMaxDrawBuffers)
1483     {
1484       myDrawBuffers.Resize (0, myMaxDrawBuffers - 1, false);
1485     }
1486   }
1487
1488   glGetIntegerv (GL_MAX_TEXTURE_SIZE, &myMaxTexDim);
1489   if (IsGlGreaterEqual (2, 0))
1490   {
1491     glGetIntegerv (GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &myMaxTexCombined);
1492   }
1493 #if !defined(GL_ES_VERSION_2_0)
1494   else if (IsGlGreaterEqual (1, 3))
1495   {
1496     // this is a maximum of texture units for FFP functionality,
1497     // dramatically smaller than combined texture units available for GLSL
1498     glGetIntegerv (GL_MAX_TEXTURE_UNITS, &myMaxTexCombined);
1499   }
1500 #endif
1501   mySpriteTexUnit = myMaxTexCombined >= 2
1502                   ? Graphic3d_TextureUnit_1
1503                   : Graphic3d_TextureUnit_0;
1504
1505   GLint aMaxVPortSize[2] = {0, 0};
1506   glGetIntegerv (GL_MAX_VIEWPORT_DIMS, aMaxVPortSize);
1507   myMaxDumpSizeX = Min (aMaxVPortSize[0], myMaxTexDim);
1508   myMaxDumpSizeY = Min (aMaxVPortSize[1], myMaxTexDim);
1509   if (myVendor == "intel")
1510   {
1511     // Intel drivers have known bug with empty dump for images with width>=5462
1512     myMaxDumpSizeX = Min (myMaxDumpSizeX, 4096);
1513   }
1514
1515   if (extAnis)
1516   {
1517     glGetIntegerv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &myAnisoMax);
1518   }
1519
1520   myClippingState.Init();
1521
1522 #if !defined(GL_ES_VERSION_2_0)
1523
1524   bool has12 = false;
1525   bool has13 = false;
1526   bool has14 = false;
1527   bool has15 = false;
1528   bool has20 = false;
1529   bool has21 = false;
1530   bool has30 = false;
1531   bool has31 = false;
1532   bool has32 = false;
1533   bool has33 = false;
1534   bool has40 = false;
1535   bool has41 = false;
1536   bool has42 = false;
1537   bool has43 = false;
1538   bool has44 = false;
1539   bool has45 = false;
1540
1541   // retrieve platform-dependent extensions
1542 #if defined(HAVE_EGL)
1543   //
1544 #elif defined(_WIN32)
1545   if (FindProcShort (wglGetExtensionsStringARB))
1546   {
1547     const char* aWglExts = myFuncs->wglGetExtensionsStringARB (wglGetCurrentDC());
1548     if (CheckExtension (aWglExts, "WGL_EXT_swap_control"))
1549     {
1550       FindProcShort (wglSwapIntervalEXT);
1551     }
1552     if (CheckExtension (aWglExts, "WGL_ARB_pixel_format"))
1553     {
1554       FindProcShort (wglChoosePixelFormatARB);
1555     }
1556     if (CheckExtension (aWglExts, "WGL_ARB_create_context_profile"))
1557     {
1558       FindProcShort (wglCreateContextAttribsARB);
1559     }
1560     if (CheckExtension (aWglExts, "WGL_NV_DX_interop"))
1561     {
1562       FindProcShort (wglDXSetResourceShareHandleNV);
1563       FindProcShort (wglDXOpenDeviceNV);
1564       FindProcShort (wglDXCloseDeviceNV);
1565       FindProcShort (wglDXRegisterObjectNV);
1566       FindProcShort (wglDXUnregisterObjectNV);
1567       FindProcShort (wglDXObjectAccessNV);
1568       FindProcShort (wglDXLockObjectsNV);
1569       FindProcShort (wglDXUnlockObjectsNV);
1570     }
1571     if (CheckExtension (aWglExts, "WGL_AMD_gpu_association"))
1572     {
1573       FindProcShort (wglGetGPUIDsAMD);
1574       FindProcShort (wglGetGPUInfoAMD);
1575       FindProcShort (wglGetContextGPUIDAMD);
1576     }
1577   }
1578 #elif defined(__APPLE__)
1579     //
1580 #else
1581     const char* aGlxExts = ::glXQueryExtensionsString ((Display* )myDisplay, DefaultScreen ((Display* )myDisplay));
1582     if (CheckExtension (aGlxExts, "GLX_EXT_swap_control"))
1583     {
1584       FindProcShort (glXSwapIntervalEXT);
1585     }
1586     if (CheckExtension (aGlxExts, "GLX_SGI_swap_control"))
1587     {
1588       FindProcShort (glXSwapIntervalSGI);
1589     }
1590     if (CheckExtension (aGlxExts, "GLX_MESA_query_renderer"))
1591     {
1592       FindProcShort (glXQueryRendererIntegerMESA);
1593       FindProcShort (glXQueryCurrentRendererIntegerMESA);
1594       FindProcShort (glXQueryRendererStringMESA);
1595       FindProcShort (glXQueryCurrentRendererStringMESA);
1596     }
1597     //extSwapTear = CheckExtension (aGlxExts, "GLX_EXT_swap_control_tear");
1598 #endif
1599
1600   // load OpenGL 1.2 new functions
1601   has12 = IsGlGreaterEqual (1, 2)
1602        && FindProcShort (glBlendColor)
1603        && FindProcShort (glBlendEquation)
1604        && FindProcShort (glDrawRangeElements)
1605        && FindProcShort (glTexImage3D)
1606        && FindProcShort (glTexSubImage3D)
1607        && FindProcShort (glCopyTexSubImage3D);
1608
1609   // load OpenGL 1.3 new functions
1610   has13 = IsGlGreaterEqual (1, 3)
1611        && FindProcShort (glActiveTexture)
1612        && FindProcShort (glSampleCoverage)
1613        && FindProcShort (glCompressedTexImage3D)
1614        && FindProcShort (glCompressedTexImage2D)
1615        && FindProcShort (glCompressedTexImage1D)
1616        && FindProcShort (glCompressedTexSubImage3D)
1617        && FindProcShort (glCompressedTexSubImage2D)
1618        && FindProcShort (glCompressedTexSubImage1D)
1619        && FindProcShort (glGetCompressedTexImage);
1620
1621   if (!isCoreProfile)
1622   {
1623     has13 = has13
1624        && FindProcShort (glClientActiveTexture)
1625        && FindProcShort (glMultiTexCoord1d)
1626        && FindProcShort (glMultiTexCoord1dv)
1627        && FindProcShort (glMultiTexCoord1f)
1628        && FindProcShort (glMultiTexCoord1fv)
1629        && FindProcShort (glMultiTexCoord1i)
1630        && FindProcShort (glMultiTexCoord1iv)
1631        && FindProcShort (glMultiTexCoord1s)
1632        && FindProcShort (glMultiTexCoord1sv)
1633        && FindProcShort (glMultiTexCoord2d)
1634        && FindProcShort (glMultiTexCoord2dv)
1635        && FindProcShort (glMultiTexCoord2f)
1636        && FindProcShort (glMultiTexCoord2fv)
1637        && FindProcShort (glMultiTexCoord2i)
1638        && FindProcShort (glMultiTexCoord2iv)
1639        && FindProcShort (glMultiTexCoord2s)
1640        && FindProcShort (glMultiTexCoord2sv)
1641        && FindProcShort (glMultiTexCoord3d)
1642        && FindProcShort (glMultiTexCoord3dv)
1643        && FindProcShort (glMultiTexCoord3f)
1644        && FindProcShort (glMultiTexCoord3fv)
1645        && FindProcShort (glMultiTexCoord3i)
1646        && FindProcShort (glMultiTexCoord3iv)
1647        && FindProcShort (glMultiTexCoord3s)
1648        && FindProcShort (glMultiTexCoord3sv)
1649        && FindProcShort (glMultiTexCoord4d)
1650        && FindProcShort (glMultiTexCoord4dv)
1651        && FindProcShort (glMultiTexCoord4f)
1652        && FindProcShort (glMultiTexCoord4fv)
1653        && FindProcShort (glMultiTexCoord4i)
1654        && FindProcShort (glMultiTexCoord4iv)
1655        && FindProcShort (glMultiTexCoord4s)
1656        && FindProcShort (glMultiTexCoord4sv)
1657        && FindProcShort (glLoadTransposeMatrixf)
1658        && FindProcShort (glLoadTransposeMatrixd)
1659        && FindProcShort (glMultTransposeMatrixf)
1660        && FindProcShort (glMultTransposeMatrixd);
1661   }
1662
1663   // load OpenGL 1.4 new functions
1664   has14 = IsGlGreaterEqual (1, 4)
1665        && FindProcShort (glBlendFuncSeparate)
1666        && FindProcShort (glMultiDrawArrays)
1667        && FindProcShort (glMultiDrawElements)
1668        && FindProcShort (glPointParameterf)
1669        && FindProcShort (glPointParameterfv)
1670        && FindProcShort (glPointParameteri)
1671        && FindProcShort (glPointParameteriv);
1672
1673   // load OpenGL 1.5 new functions
1674   has15 = IsGlGreaterEqual (1, 5)
1675        && FindProcShort (glGenQueries)
1676        && FindProcShort (glDeleteQueries)
1677        && FindProcShort (glIsQuery)
1678        && FindProcShort (glBeginQuery)
1679        && FindProcShort (glEndQuery)
1680        && FindProcShort (glGetQueryiv)
1681        && FindProcShort (glGetQueryObjectiv)
1682        && FindProcShort (glGetQueryObjectuiv)
1683        && FindProcShort (glBindBuffer)
1684        && FindProcShort (glDeleteBuffers)
1685        && FindProcShort (glGenBuffers)
1686        && FindProcShort (glIsBuffer)
1687        && FindProcShort (glBufferData)
1688        && FindProcShort (glBufferSubData)
1689        && FindProcShort (glGetBufferSubData)
1690        && FindProcShort (glMapBuffer)
1691        && FindProcShort (glUnmapBuffer)
1692        && FindProcShort (glGetBufferParameteriv)
1693        && FindProcShort (glGetBufferPointerv);
1694
1695   // load OpenGL 2.0 new functions
1696   has20 = IsGlGreaterEqual (2, 0)
1697        && FindProcShort (glBlendEquationSeparate)
1698        && FindProcShort (glDrawBuffers)
1699        && FindProcShort (glStencilOpSeparate)
1700        && FindProcShort (glStencilFuncSeparate)
1701        && FindProcShort (glStencilMaskSeparate)
1702        && FindProcShort (glAttachShader)
1703        && FindProcShort (glBindAttribLocation)
1704        && FindProcShort (glCompileShader)
1705        && FindProcShort (glCreateProgram)
1706        && FindProcShort (glCreateShader)
1707        && FindProcShort (glDeleteProgram)
1708        && FindProcShort (glDeleteShader)
1709        && FindProcShort (glDetachShader)
1710        && FindProcShort (glDisableVertexAttribArray)
1711        && FindProcShort (glEnableVertexAttribArray)
1712        && FindProcShort (glGetActiveAttrib)
1713        && FindProcShort (glGetActiveUniform)
1714        && FindProcShort (glGetAttachedShaders)
1715        && FindProcShort (glGetAttribLocation)
1716        && FindProcShort (glGetProgramiv)
1717        && FindProcShort (glGetProgramInfoLog)
1718        && FindProcShort (glGetShaderiv)
1719        && FindProcShort (glGetShaderInfoLog)
1720        && FindProcShort (glGetShaderSource)
1721        && FindProcShort (glGetUniformLocation)
1722        && FindProcShort (glGetUniformfv)
1723        && FindProcShort (glGetUniformiv)
1724        && FindProcShort (glGetVertexAttribdv)
1725        && FindProcShort (glGetVertexAttribfv)
1726        && FindProcShort (glGetVertexAttribiv)
1727        && FindProcShort (glGetVertexAttribPointerv)
1728        && FindProcShort (glIsProgram)
1729        && FindProcShort (glIsShader)
1730        && FindProcShort (glLinkProgram)
1731        && FindProcShort (glShaderSource)
1732        && FindProcShort (glUseProgram)
1733        && FindProcShort (glUniform1f)
1734        && FindProcShort (glUniform2f)
1735        && FindProcShort (glUniform3f)
1736        && FindProcShort (glUniform4f)
1737        && FindProcShort (glUniform1i)
1738        && FindProcShort (glUniform2i)
1739        && FindProcShort (glUniform3i)
1740        && FindProcShort (glUniform4i)
1741        && FindProcShort (glUniform1fv)
1742        && FindProcShort (glUniform2fv)
1743        && FindProcShort (glUniform3fv)
1744        && FindProcShort (glUniform4fv)
1745        && FindProcShort (glUniform1iv)
1746        && FindProcShort (glUniform2iv)
1747        && FindProcShort (glUniform3iv)
1748        && FindProcShort (glUniform4iv)
1749        && FindProcShort (glUniformMatrix2fv)
1750        && FindProcShort (glUniformMatrix3fv)
1751        && FindProcShort (glUniformMatrix4fv)
1752        && FindProcShort (glValidateProgram)
1753        && FindProcShort (glVertexAttrib1d)
1754        && FindProcShort (glVertexAttrib1dv)
1755        && FindProcShort (glVertexAttrib1f)
1756        && FindProcShort (glVertexAttrib1fv)
1757        && FindProcShort (glVertexAttrib1s)
1758        && FindProcShort (glVertexAttrib1sv)
1759        && FindProcShort (glVertexAttrib2d)
1760        && FindProcShort (glVertexAttrib2dv)
1761        && FindProcShort (glVertexAttrib2f)
1762        && FindProcShort (glVertexAttrib2fv)
1763        && FindProcShort (glVertexAttrib2s)
1764        && FindProcShort (glVertexAttrib2sv)
1765        && FindProcShort (glVertexAttrib3d)
1766        && FindProcShort (glVertexAttrib3dv)
1767        && FindProcShort (glVertexAttrib3f)
1768        && FindProcShort (glVertexAttrib3fv)
1769        && FindProcShort (glVertexAttrib3s)
1770        && FindProcShort (glVertexAttrib3sv)
1771        && FindProcShort (glVertexAttrib4Nbv)
1772        && FindProcShort (glVertexAttrib4Niv)
1773        && FindProcShort (glVertexAttrib4Nsv)
1774        && FindProcShort (glVertexAttrib4Nub)
1775        && FindProcShort (glVertexAttrib4Nubv)
1776        && FindProcShort (glVertexAttrib4Nuiv)
1777        && FindProcShort (glVertexAttrib4Nusv)
1778        && FindProcShort (glVertexAttrib4bv)
1779        && FindProcShort (glVertexAttrib4d)
1780        && FindProcShort (glVertexAttrib4dv)
1781        && FindProcShort (glVertexAttrib4f)
1782        && FindProcShort (glVertexAttrib4fv)
1783        && FindProcShort (glVertexAttrib4iv)
1784        && FindProcShort (glVertexAttrib4s)
1785        && FindProcShort (glVertexAttrib4sv)
1786        && FindProcShort (glVertexAttrib4ubv)
1787        && FindProcShort (glVertexAttrib4uiv)
1788        && FindProcShort (glVertexAttrib4usv)
1789        && FindProcShort (glVertexAttribPointer);
1790
1791   // load OpenGL 2.1 new functions
1792   has21 = IsGlGreaterEqual (2, 1)
1793        && FindProcShort (glUniformMatrix2x3fv)
1794        && FindProcShort (glUniformMatrix3x2fv)
1795        && FindProcShort (glUniformMatrix2x4fv)
1796        && FindProcShort (glUniformMatrix4x2fv)
1797        && FindProcShort (glUniformMatrix3x4fv)
1798        && FindProcShort (glUniformMatrix4x3fv);
1799
1800   // load GL_ARB_framebuffer_object (added to OpenGL 3.0 core)
1801   const bool hasFBO = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_framebuffer_object"))
1802        && FindProcShort (glIsRenderbuffer)
1803        && FindProcShort (glBindRenderbuffer)
1804        && FindProcShort (glDeleteRenderbuffers)
1805        && FindProcShort (glGenRenderbuffers)
1806        && FindProcShort (glRenderbufferStorage)
1807        && FindProcShort (glGetRenderbufferParameteriv)
1808        && FindProcShort (glIsFramebuffer)
1809        && FindProcShort (glBindFramebuffer)
1810        && FindProcShort (glDeleteFramebuffers)
1811        && FindProcShort (glGenFramebuffers)
1812        && FindProcShort (glCheckFramebufferStatus)
1813        && FindProcShort (glFramebufferTexture1D)
1814        && FindProcShort (glFramebufferTexture2D)
1815        && FindProcShort (glFramebufferTexture3D)
1816        && FindProcShort (glFramebufferRenderbuffer)
1817        && FindProcShort (glGetFramebufferAttachmentParameteriv)
1818        && FindProcShort (glGenerateMipmap)
1819        && FindProcShort (glBlitFramebuffer)
1820        && FindProcShort (glRenderbufferStorageMultisample)
1821        && FindProcShort (glFramebufferTextureLayer);
1822
1823   // load GL_ARB_vertex_array_object (added to OpenGL 3.0 core)
1824   const bool hasVAO = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_vertex_array_object"))
1825        && FindProcShort (glBindVertexArray)
1826        && FindProcShort (glDeleteVertexArrays)
1827        && FindProcShort (glGenVertexArrays)
1828        && FindProcShort (glIsVertexArray);
1829
1830   // load GL_ARB_map_buffer_range (added to OpenGL 3.0 core)
1831   const bool hasMapBufferRange = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_map_buffer_range"))
1832        && FindProcShort (glMapBufferRange)
1833        && FindProcShort (glFlushMappedBufferRange);
1834
1835   // load OpenGL 3.0 new functions
1836   has30 = IsGlGreaterEqual (3, 0)
1837        && hasFBO
1838        && hasVAO
1839        && hasMapBufferRange
1840        && FindProcShort (glColorMaski)
1841        && FindProcShort (glGetBooleani_v)
1842        && FindProcShort (glGetIntegeri_v)
1843        && FindProcShort (glEnablei)
1844        && FindProcShort (glDisablei)
1845        && FindProcShort (glIsEnabledi)
1846        && FindProcShort (glBeginTransformFeedback)
1847        && FindProcShort (glEndTransformFeedback)
1848        && FindProcShort (glBindBufferRange)
1849        && FindProcShort (glBindBufferBase)
1850        && FindProcShort (glTransformFeedbackVaryings)
1851        && FindProcShort (glGetTransformFeedbackVarying)
1852        && FindProcShort (glClampColor)
1853        && FindProcShort (glBeginConditionalRender)
1854        && FindProcShort (glEndConditionalRender)
1855        && FindProcShort (glVertexAttribIPointer)
1856        && FindProcShort (glGetVertexAttribIiv)
1857        && FindProcShort (glGetVertexAttribIuiv)
1858        && FindProcShort (glVertexAttribI1i)
1859        && FindProcShort (glVertexAttribI2i)
1860        && FindProcShort (glVertexAttribI3i)
1861        && FindProcShort (glVertexAttribI4i)
1862        && FindProcShort (glVertexAttribI1ui)
1863        && FindProcShort (glVertexAttribI2ui)
1864        && FindProcShort (glVertexAttribI3ui)
1865        && FindProcShort (glVertexAttribI4ui)
1866        && FindProcShort (glVertexAttribI1iv)
1867        && FindProcShort (glVertexAttribI2iv)
1868        && FindProcShort (glVertexAttribI3iv)
1869        && FindProcShort (glVertexAttribI4iv)
1870        && FindProcShort (glVertexAttribI1uiv)
1871        && FindProcShort (glVertexAttribI2uiv)
1872        && FindProcShort (glVertexAttribI3uiv)
1873        && FindProcShort (glVertexAttribI4uiv)
1874        && FindProcShort (glVertexAttribI4bv)
1875        && FindProcShort (glVertexAttribI4sv)
1876        && FindProcShort (glVertexAttribI4ubv)
1877        && FindProcShort (glVertexAttribI4usv)
1878        && FindProcShort (glGetUniformuiv)
1879        && FindProcShort (glBindFragDataLocation)
1880        && FindProcShort (glGetFragDataLocation)
1881        && FindProcShort (glUniform1ui)
1882        && FindProcShort (glUniform2ui)
1883        && FindProcShort (glUniform3ui)
1884        && FindProcShort (glUniform4ui)
1885        && FindProcShort (glUniform1uiv)
1886        && FindProcShort (glUniform2uiv)
1887        && FindProcShort (glUniform3uiv)
1888        && FindProcShort (glUniform4uiv)
1889        && FindProcShort (glTexParameterIiv)
1890        && FindProcShort (glTexParameterIuiv)
1891        && FindProcShort (glGetTexParameterIiv)
1892        && FindProcShort (glGetTexParameterIuiv)
1893        && FindProcShort (glClearBufferiv)
1894        && FindProcShort (glClearBufferuiv)
1895        && FindProcShort (glClearBufferfv)
1896        && FindProcShort (glClearBufferfi)
1897        && FindProcShort (glGetStringi);
1898
1899   // load GL_ARB_uniform_buffer_object (added to OpenGL 3.1 core)
1900   const bool hasUBO = (IsGlGreaterEqual (3, 1) || CheckExtension ("GL_ARB_uniform_buffer_object"))
1901        && FindProcShort (glGetUniformIndices)
1902        && FindProcShort (glGetActiveUniformsiv)
1903        && FindProcShort (glGetActiveUniformName)
1904        && FindProcShort (glGetUniformBlockIndex)
1905        && FindProcShort (glGetActiveUniformBlockiv)
1906        && FindProcShort (glGetActiveUniformBlockName)
1907        && FindProcShort (glUniformBlockBinding);
1908
1909   // load GL_ARB_copy_buffer (added to OpenGL 3.1 core)
1910   const bool hasCopyBufSubData = (IsGlGreaterEqual (3, 1) || CheckExtension ("GL_ARB_copy_buffer"))
1911        && FindProcShort (glCopyBufferSubData);
1912
1913   if (has30)
1914   {
1915     // NPOT textures are required by OpenGL 2.0 specifications
1916     // but doesn't hardware accelerated by some ancient OpenGL 2.1 hardware (GeForce FX, RadeOn 9700 etc.)
1917     arbNPTW  = Standard_True;
1918     arbTexRG = Standard_True;
1919   }
1920
1921   // load OpenGL 3.1 new functions
1922   has31 = IsGlGreaterEqual (3, 1)
1923        && hasUBO
1924        && hasCopyBufSubData
1925        && FindProcShort (glDrawArraysInstanced)
1926        && FindProcShort (glDrawElementsInstanced)
1927        && FindProcShort (glTexBuffer)
1928        && FindProcShort (glPrimitiveRestartIndex);
1929
1930   // load GL_ARB_draw_elements_base_vertex (added to OpenGL 3.2 core)
1931   const bool hasDrawElemsBaseVert = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_draw_elements_base_vertex"))
1932        && FindProcShort (glDrawElementsBaseVertex)
1933        && FindProcShort (glDrawRangeElementsBaseVertex)
1934        && FindProcShort (glDrawElementsInstancedBaseVertex)
1935        && FindProcShort (glMultiDrawElementsBaseVertex);
1936
1937   // load GL_ARB_provoking_vertex (added to OpenGL 3.2 core)
1938   const bool hasProvokingVert = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_provoking_vertex"))
1939        && FindProcShort (glProvokingVertex);
1940
1941   // load GL_ARB_sync (added to OpenGL 3.2 core)
1942   const bool hasSync = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_sync"))
1943        && FindProcShort (glFenceSync)
1944        && FindProcShort (glIsSync)
1945        && FindProcShort (glDeleteSync)
1946        && FindProcShort (glClientWaitSync)
1947        && FindProcShort (glWaitSync)
1948        && FindProcShort (glGetInteger64v)
1949        && FindProcShort (glGetSynciv);
1950
1951   // load GL_ARB_texture_multisample (added to OpenGL 3.2 core)
1952   const bool hasTextureMultisample = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_texture_multisample"))
1953        && FindProcShort (glTexImage2DMultisample)
1954        && FindProcShort (glTexImage3DMultisample)
1955        && FindProcShort (glGetMultisamplefv)
1956        && FindProcShort (glSampleMaski);
1957
1958   // load OpenGL 3.2 new functions
1959   has32 = IsGlGreaterEqual (3, 2)
1960        && hasDrawElemsBaseVert
1961        && hasProvokingVert
1962        && hasSync
1963        && hasTextureMultisample
1964        && FindProcShort (glGetInteger64i_v)
1965        && FindProcShort (glGetBufferParameteri64v)
1966        && FindProcShort (glFramebufferTexture);
1967
1968   // load GL_ARB_blend_func_extended (added to OpenGL 3.3 core)
1969   const bool hasBlendFuncExtended = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_blend_func_extended"))
1970        && FindProcShort (glBindFragDataLocationIndexed)
1971        && FindProcShort (glGetFragDataIndex);
1972
1973   // load GL_ARB_sampler_objects (added to OpenGL 3.3 core)
1974   const bool hasSamplerObjects = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_sampler_objects"))
1975        && FindProcShort (glGenSamplers)
1976        && FindProcShort (glDeleteSamplers)
1977        && FindProcShort (glIsSampler)
1978        && FindProcShort (glBindSampler)
1979        && FindProcShort (glSamplerParameteri)
1980        && FindProcShort (glSamplerParameteriv)
1981        && FindProcShort (glSamplerParameterf)
1982        && FindProcShort (glSamplerParameterfv)
1983        && FindProcShort (glSamplerParameterIiv)
1984        && FindProcShort (glSamplerParameterIuiv)
1985        && FindProcShort (glGetSamplerParameteriv)
1986        && FindProcShort (glGetSamplerParameterIiv)
1987        && FindProcShort (glGetSamplerParameterfv)
1988        && FindProcShort (glGetSamplerParameterIuiv);
1989   if (hasSamplerObjects)
1990   {
1991     arbSamplerObject = (OpenGl_ArbSamplerObject* )(&(*myFuncs));
1992   }
1993
1994   // load GL_ARB_timer_query (added to OpenGL 3.3 core)
1995   const bool hasTimerQuery = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_timer_query"))
1996        && FindProcShort (glQueryCounter)
1997        && FindProcShort (glGetQueryObjecti64v)
1998        && FindProcShort (glGetQueryObjectui64v);
1999
2000   // load GL_ARB_vertex_type_2_10_10_10_rev (added to OpenGL 3.3 core)
2001   const bool hasVertType21010101rev = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_vertex_type_2_10_10_10_rev"))
2002        && FindProcShort (glVertexAttribP1ui)
2003        && FindProcShort (glVertexAttribP1uiv)
2004        && FindProcShort (glVertexAttribP2ui)
2005        && FindProcShort (glVertexAttribP2uiv)
2006        && FindProcShort (glVertexAttribP3ui)
2007        && FindProcShort (glVertexAttribP3uiv)
2008        && FindProcShort (glVertexAttribP4ui)
2009        && FindProcShort (glVertexAttribP4uiv);
2010
2011   if ( hasVertType21010101rev
2012    && !isCoreProfile)
2013   {
2014     // load deprecated functions
2015     const bool hasVertType21010101revExt =
2016           FindProcShort (glVertexP2ui)
2017        && FindProcShort (glVertexP2uiv)
2018        && FindProcShort (glVertexP3ui)
2019        && FindProcShort (glVertexP3uiv)
2020        && FindProcShort (glVertexP4ui)
2021        && FindProcShort (glVertexP4uiv)
2022        && FindProcShort (glTexCoordP1ui)
2023        && FindProcShort (glTexCoordP1uiv)
2024        && FindProcShort (glTexCoordP2ui)
2025        && FindProcShort (glTexCoordP2uiv)
2026        && FindProcShort (glTexCoordP3ui)
2027        && FindProcShort (glTexCoordP3uiv)
2028        && FindProcShort (glTexCoordP4ui)
2029        && FindProcShort (glTexCoordP4uiv)
2030        && FindProcShort (glMultiTexCoordP1ui)
2031        && FindProcShort (glMultiTexCoordP1uiv)
2032        && FindProcShort (glMultiTexCoordP2ui)
2033        && FindProcShort (glMultiTexCoordP2uiv)
2034        && FindProcShort (glMultiTexCoordP3ui)
2035        && FindProcShort (glMultiTexCoordP3uiv)
2036        && FindProcShort (glMultiTexCoordP4ui)
2037        && FindProcShort (glMultiTexCoordP4uiv)
2038        && FindProcShort (glNormalP3ui)
2039        && FindProcShort (glNormalP3uiv)
2040        && FindProcShort (glColorP3ui)
2041        && FindProcShort (glColorP3uiv)
2042        && FindProcShort (glColorP4ui)
2043        && FindProcShort (glColorP4uiv)
2044        && FindProcShort (glSecondaryColorP3ui)
2045        && FindProcShort (glSecondaryColorP3uiv);
2046     (void )hasVertType21010101revExt;
2047   }
2048
2049   // load OpenGL 3.3 extra functions
2050   has33 = IsGlGreaterEqual (3, 3)
2051        && hasBlendFuncExtended
2052        && hasSamplerObjects
2053        && hasTimerQuery
2054        && hasVertType21010101rev
2055        && FindProcShort (glVertexAttribDivisor);
2056
2057   // load GL_ARB_draw_indirect (added to OpenGL 4.0 core)
2058   const bool hasDrawIndirect = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_draw_indirect"))
2059        && FindProcShort (glDrawArraysIndirect)
2060        && FindProcShort (glDrawElementsIndirect);
2061
2062   // load GL_ARB_gpu_shader_fp64 (added to OpenGL 4.0 core)
2063   const bool hasShaderFP64 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_gpu_shader_fp64"))
2064        && FindProcShort (glUniform1d)
2065        && FindProcShort (glUniform2d)
2066        && FindProcShort (glUniform3d)
2067        && FindProcShort (glUniform4d)
2068        && FindProcShort (glUniform1dv)
2069        && FindProcShort (glUniform2dv)
2070        && FindProcShort (glUniform3dv)
2071        && FindProcShort (glUniform4dv)
2072        && FindProcShort (glUniformMatrix2dv)
2073        && FindProcShort (glUniformMatrix3dv)
2074        && FindProcShort (glUniformMatrix4dv)
2075        && FindProcShort (glUniformMatrix2x3dv)
2076        && FindProcShort (glUniformMatrix2x4dv)
2077        && FindProcShort (glUniformMatrix3x2dv)
2078        && FindProcShort (glUniformMatrix3x4dv)
2079        && FindProcShort (glUniformMatrix4x2dv)
2080        && FindProcShort (glUniformMatrix4x3dv)
2081        && FindProcShort (glGetUniformdv);
2082
2083   // load GL_ARB_shader_subroutine (added to OpenGL 4.0 core)
2084   const bool hasShaderSubroutine = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_shader_subroutine"))
2085        && FindProcShort (glGetSubroutineUniformLocation)
2086        && FindProcShort (glGetSubroutineIndex)
2087        && FindProcShort (glGetActiveSubroutineUniformiv)
2088        && FindProcShort (glGetActiveSubroutineUniformName)
2089        && FindProcShort (glGetActiveSubroutineName)
2090        && FindProcShort (glUniformSubroutinesuiv)
2091        && FindProcShort (glGetUniformSubroutineuiv)
2092        && FindProcShort (glGetProgramStageiv);
2093
2094   // load GL_ARB_tessellation_shader (added to OpenGL 4.0 core)
2095   const bool hasTessellationShader = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_tessellation_shader"))
2096        && FindProcShort (glPatchParameteri)
2097        && FindProcShort (glPatchParameterfv);
2098
2099   // load GL_ARB_transform_feedback2 (added to OpenGL 4.0 core)
2100   const bool hasTrsfFeedback2 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_transform_feedback2"))
2101        && FindProcShort (glBindTransformFeedback)
2102        && FindProcShort (glDeleteTransformFeedbacks)
2103        && FindProcShort (glGenTransformFeedbacks)
2104        && FindProcShort (glIsTransformFeedback)
2105        && FindProcShort (glPauseTransformFeedback)
2106        && FindProcShort (glResumeTransformFeedback)
2107        && FindProcShort (glDrawTransformFeedback);
2108
2109   // load GL_ARB_transform_feedback3 (added to OpenGL 4.0 core)
2110   const bool hasTrsfFeedback3 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_transform_feedback3"))
2111        && FindProcShort (glDrawTransformFeedbackStream)
2112        && FindProcShort (glBeginQueryIndexed)
2113        && FindProcShort (glEndQueryIndexed)
2114        && FindProcShort (glGetQueryIndexediv);
2115
2116   // load OpenGL 4.0 new functions
2117   has40 = IsGlGreaterEqual (4, 0)
2118       && hasDrawIndirect
2119       && hasShaderFP64
2120       && hasShaderSubroutine
2121       && hasTessellationShader
2122       && hasTrsfFeedback2
2123       && hasTrsfFeedback3
2124       && FindProcShort (glMinSampleShading)
2125       && FindProcShort (glBlendEquationi)
2126       && FindProcShort (glBlendEquationSeparatei)
2127       && FindProcShort (glBlendFunci)
2128       && FindProcShort (glBlendFuncSeparatei);
2129
2130   // load GL_ARB_ES2_compatibility (added to OpenGL 4.1 core)
2131   const bool hasES2Compatibility = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_ES2_compatibility"))
2132        && FindProcShort (glReleaseShaderCompiler)
2133        && FindProcShort (glShaderBinary)
2134        && FindProcShort (glGetShaderPrecisionFormat)
2135        && FindProcShort (glDepthRangef)
2136        && FindProcShort (glClearDepthf);
2137
2138   // load GL_ARB_get_program_binary (added to OpenGL 4.1 core)
2139   const bool hasGetProgramBinary = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_get_program_binary"))
2140        && FindProcShort (glGetProgramBinary)
2141        && FindProcShort (glProgramBinary)
2142        && FindProcShort (glProgramParameteri);
2143
2144
2145   // load GL_ARB_separate_shader_objects (added to OpenGL 4.1 core)
2146   const bool hasSeparateShaderObjects = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_separate_shader_objects"))
2147        && FindProcShort (glUseProgramStages)
2148        && FindProcShort (glActiveShaderProgram)
2149        && FindProcShort (glCreateShaderProgramv)
2150        && FindProcShort (glBindProgramPipeline)
2151        && FindProcShort (glDeleteProgramPipelines)
2152        && FindProcShort (glGenProgramPipelines)
2153        && FindProcShort (glIsProgramPipeline)
2154        && FindProcShort (glGetProgramPipelineiv)
2155        && FindProcShort (glProgramUniform1i)
2156        && FindProcShort (glProgramUniform1iv)
2157        && FindProcShort (glProgramUniform1f)
2158        && FindProcShort (glProgramUniform1fv)
2159        && FindProcShort (glProgramUniform1d)
2160        && FindProcShort (glProgramUniform1dv)
2161        && FindProcShort (glProgramUniform1ui)
2162        && FindProcShort (glProgramUniform1uiv)
2163        && FindProcShort (glProgramUniform2i)
2164        && FindProcShort (glProgramUniform2iv)
2165        && FindProcShort (glProgramUniform2f)
2166        && FindProcShort (glProgramUniform2fv)
2167        && FindProcShort (glProgramUniform2d)
2168        && FindProcShort (glProgramUniform2dv)
2169        && FindProcShort (glProgramUniform2ui)
2170        && FindProcShort (glProgramUniform2uiv)
2171        && FindProcShort (glProgramUniform3i)
2172        && FindProcShort (glProgramUniform3iv)
2173        && FindProcShort (glProgramUniform3f)
2174        && FindProcShort (glProgramUniform3fv)
2175        && FindProcShort (glProgramUniform3d)
2176        && FindProcShort (glProgramUniform3dv)
2177        && FindProcShort (glProgramUniform3ui)
2178        && FindProcShort (glProgramUniform3uiv)
2179        && FindProcShort (glProgramUniform4i)
2180        && FindProcShort (glProgramUniform4iv)
2181        && FindProcShort (glProgramUniform4f)
2182        && FindProcShort (glProgramUniform4fv)
2183        && FindProcShort (glProgramUniform4d)
2184        && FindProcShort (glProgramUniform4dv)
2185        && FindProcShort (glProgramUniform4ui)
2186        && FindProcShort (glProgramUniform4uiv)
2187        && FindProcShort (glProgramUniformMatrix2fv)
2188        && FindProcShort (glProgramUniformMatrix3fv)
2189        && FindProcShort (glProgramUniformMatrix4fv)
2190        && FindProcShort (glProgramUniformMatrix2dv)
2191        && FindProcShort (glProgramUniformMatrix3dv)
2192        && FindProcShort (glProgramUniformMatrix4dv)
2193        && FindProcShort (glProgramUniformMatrix2x3fv)
2194        && FindProcShort (glProgramUniformMatrix3x2fv)
2195        && FindProcShort (glProgramUniformMatrix2x4fv)
2196        && FindProcShort (glProgramUniformMatrix4x2fv)
2197        && FindProcShort (glProgramUniformMatrix3x4fv)
2198        && FindProcShort (glProgramUniformMatrix4x3fv)
2199        && FindProcShort (glProgramUniformMatrix2x3dv)
2200        && FindProcShort (glProgramUniformMatrix3x2dv)
2201        && FindProcShort (glProgramUniformMatrix2x4dv)
2202        && FindProcShort (glProgramUniformMatrix4x2dv)
2203        && FindProcShort (glProgramUniformMatrix3x4dv)
2204        && FindProcShort (glProgramUniformMatrix4x3dv)
2205        && FindProcShort (glValidateProgramPipeline)
2206        && FindProcShort (glGetProgramPipelineInfoLog);
2207
2208   // load GL_ARB_vertex_attrib_64bit (added to OpenGL 4.1 core)
2209   const bool hasVertAttrib64bit = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_vertex_attrib_64bit"))
2210        && FindProcShort (glVertexAttribL1d)
2211        && FindProcShort (glVertexAttribL2d)
2212        && FindProcShort (glVertexAttribL3d)
2213        && FindProcShort (glVertexAttribL4d)
2214        && FindProcShort (glVertexAttribL1dv)
2215        && FindProcShort (glVertexAttribL2dv)
2216        && FindProcShort (glVertexAttribL3dv)
2217        && FindProcShort (glVertexAttribL4dv)
2218        && FindProcShort (glVertexAttribLPointer)
2219        && FindProcShort (glGetVertexAttribLdv);
2220
2221   // load GL_ARB_viewport_array (added to OpenGL 4.1 core)
2222   const bool hasViewportArray = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_viewport_array"))
2223        && FindProcShort (glViewportArrayv)
2224        && FindProcShort (glViewportIndexedf)
2225        && FindProcShort (glViewportIndexedfv)
2226        && FindProcShort (glScissorArrayv)
2227        && FindProcShort (glScissorIndexed)
2228        && FindProcShort (glScissorIndexedv)
2229        && FindProcShort (glDepthRangeArrayv)
2230        && FindProcShort (glDepthRangeIndexed)
2231        && FindProcShort (glGetFloati_v)
2232        && FindProcShort (glGetDoublei_v);
2233
2234   has41 = IsGlGreaterEqual (4, 1)
2235        && hasES2Compatibility
2236        && hasGetProgramBinary
2237        && hasSeparateShaderObjects
2238        && hasVertAttrib64bit
2239        && hasViewportArray;
2240
2241   // load GL_ARB_base_instance (added to OpenGL 4.2 core)
2242   const bool hasBaseInstance = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_base_instance"))
2243        && FindProcShort (glDrawArraysInstancedBaseInstance)
2244        && FindProcShort (glDrawElementsInstancedBaseInstance)
2245        && FindProcShort (glDrawElementsInstancedBaseVertexBaseInstance);
2246
2247   // load GL_ARB_transform_feedback_instanced (added to OpenGL 4.2 core)
2248   const bool hasTrsfFeedbackInstanced = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_transform_feedback_instanced"))
2249        && FindProcShort (glDrawTransformFeedbackInstanced)
2250        && FindProcShort (glDrawTransformFeedbackStreamInstanced);
2251
2252   // load GL_ARB_internalformat_query (added to OpenGL 4.2 core)
2253   const bool hasInternalFormatQuery = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_internalformat_query"))
2254        && FindProcShort (glGetInternalformativ);
2255
2256   // load GL_ARB_shader_atomic_counters (added to OpenGL 4.2 core)
2257   const bool hasShaderAtomicCounters = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_shader_atomic_counters"))
2258        && FindProcShort (glGetActiveAtomicCounterBufferiv);
2259
2260   // load GL_ARB_shader_image_load_store (added to OpenGL 4.2 core)
2261   const bool hasShaderImgLoadStore = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_shader_image_load_store"))
2262        && FindProcShort (glBindImageTexture)
2263        && FindProcShort (glMemoryBarrier);
2264
2265   // load GL_ARB_texture_storage (added to OpenGL 4.2 core)
2266   const bool hasTextureStorage = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_texture_storage"))
2267        && FindProcShort (glTexStorage1D)
2268        && FindProcShort (glTexStorage2D)
2269        && FindProcShort (glTexStorage3D);
2270
2271   has42 = IsGlGreaterEqual (4, 2)
2272        && hasBaseInstance
2273        && hasTrsfFeedbackInstanced
2274        && hasInternalFormatQuery
2275        && hasShaderAtomicCounters
2276        && hasShaderImgLoadStore
2277        && hasTextureStorage;
2278
2279   has43 = IsGlGreaterEqual (4, 3)
2280        && FindProcShort (glClearBufferData)
2281        && FindProcShort (glClearBufferSubData)
2282        && FindProcShort (glDispatchCompute)
2283        && FindProcShort (glDispatchComputeIndirect)
2284        && FindProcShort (glCopyImageSubData)
2285        && FindProcShort (glFramebufferParameteri)
2286        && FindProcShort (glGetFramebufferParameteriv)
2287        && FindProcShort (glGetInternalformati64v)
2288        && FindProcShort (glInvalidateTexSubImage)
2289        && FindProcShort (glInvalidateTexImage)
2290        && FindProcShort (glInvalidateBufferSubData)
2291        && FindProcShort (glInvalidateBufferData)
2292        && FindProcShort (glInvalidateFramebuffer)
2293        && FindProcShort (glInvalidateSubFramebuffer)
2294        && FindProcShort (glMultiDrawArraysIndirect)
2295        && FindProcShort (glMultiDrawElementsIndirect)
2296        && FindProcShort (glGetProgramInterfaceiv)
2297        && FindProcShort (glGetProgramResourceIndex)
2298        && FindProcShort (glGetProgramResourceName)
2299        && FindProcShort (glGetProgramResourceiv)
2300        && FindProcShort (glGetProgramResourceLocation)
2301        && FindProcShort (glGetProgramResourceLocationIndex)
2302        && FindProcShort (glShaderStorageBlockBinding)
2303        && FindProcShort (glTexBufferRange)
2304        && FindProcShort (glTexStorage2DMultisample)
2305        && FindProcShort (glTexStorage3DMultisample)
2306        && FindProcShort (glTextureView)
2307        && FindProcShort (glBindVertexBuffer)
2308        && FindProcShort (glVertexAttribFormat)
2309        && FindProcShort (glVertexAttribIFormat)
2310        && FindProcShort (glVertexAttribLFormat)
2311        && FindProcShort (glVertexAttribBinding)
2312        && FindProcShort (glVertexBindingDivisor)
2313        && FindProcShort (glDebugMessageControl)
2314        && FindProcShort (glDebugMessageInsert)
2315        && FindProcShort (glDebugMessageCallback)
2316        && FindProcShort (glGetDebugMessageLog)
2317        && FindProcShort (glPushDebugGroup)
2318        && FindProcShort (glPopDebugGroup)
2319        && FindProcShort (glObjectLabel)
2320        && FindProcShort (glGetObjectLabel)
2321        && FindProcShort (glObjectPtrLabel)
2322        && FindProcShort (glGetObjectPtrLabel);
2323
2324   // load GL_ARB_clear_texture (added to OpenGL 4.4 core)
2325   bool arbTexClear = (IsGlGreaterEqual (4, 4) || CheckExtension ("GL_ARB_clear_texture"))
2326        && FindProcShort (glClearTexImage)
2327        && FindProcShort (glClearTexSubImage);
2328
2329   has44 = IsGlGreaterEqual (4, 4)
2330        && arbTexClear
2331        && FindProcShort (glBufferStorage)
2332        && FindProcShort (glBindBuffersBase)
2333        && FindProcShort (glBindBuffersRange)
2334        && FindProcShort (glBindTextures)
2335        && FindProcShort (glBindSamplers)
2336        && FindProcShort (glBindImageTextures)
2337        && FindProcShort (glBindVertexBuffers);
2338
2339   has45 = IsGlGreaterEqual (4, 5)
2340        && FindProcShort (glBindVertexBuffers)
2341        && FindProcShort (glClipControl)
2342        && FindProcShort (glCreateTransformFeedbacks)
2343        && FindProcShort (glTransformFeedbackBufferBase)
2344        && FindProcShort (glTransformFeedbackBufferRange)
2345        && FindProcShort (glGetTransformFeedbackiv)
2346        && FindProcShort (glGetTransformFeedbacki_v)
2347        && FindProcShort (glGetTransformFeedbacki64_v)
2348        && FindProcShort (glCreateBuffers)
2349        && FindProcShort (glNamedBufferStorage)
2350        && FindProcShort (glNamedBufferData)
2351        && FindProcShort (glNamedBufferSubData)
2352        && FindProcShort (glCopyNamedBufferSubData)
2353        && FindProcShort (glClearNamedBufferData)
2354        && FindProcShort (glClearNamedBufferSubData)
2355        && FindProcShort (glMapNamedBuffer)
2356        && FindProcShort (glMapNamedBufferRange)
2357        && FindProcShort (glUnmapNamedBuffer)
2358        && FindProcShort (glFlushMappedNamedBufferRange)
2359        && FindProcShort (glGetNamedBufferParameteriv)
2360        && FindProcShort (glGetNamedBufferParameteri64v)
2361        && FindProcShort (glGetNamedBufferPointerv)
2362        && FindProcShort (glGetNamedBufferSubData)
2363        && FindProcShort (glCreateFramebuffers)
2364        && FindProcShort (glNamedFramebufferRenderbuffer)
2365        && FindProcShort (glNamedFramebufferParameteri)
2366        && FindProcShort (glNamedFramebufferTexture)
2367        && FindProcShort (glNamedFramebufferTextureLayer)
2368        && FindProcShort (glNamedFramebufferDrawBuffer)
2369        && FindProcShort (glNamedFramebufferDrawBuffers)
2370        && FindProcShort (glNamedFramebufferReadBuffer)
2371        && FindProcShort (glInvalidateNamedFramebufferData)
2372        && FindProcShort (glInvalidateNamedFramebufferSubData)
2373        && FindProcShort (glClearNamedFramebufferiv)
2374        && FindProcShort (glClearNamedFramebufferuiv)
2375        && FindProcShort (glClearNamedFramebufferfv)
2376        && FindProcShort (glClearNamedFramebufferfi)
2377        && FindProcShort (glBlitNamedFramebuffer)
2378        && FindProcShort (glCheckNamedFramebufferStatus)
2379        && FindProcShort (glGetNamedFramebufferParameteriv)
2380        && FindProcShort (glGetNamedFramebufferAttachmentParameteriv)
2381        && FindProcShort (glCreateRenderbuffers)
2382        && FindProcShort (glNamedRenderbufferStorage)
2383        && FindProcShort (glNamedRenderbufferStorageMultisample)
2384        && FindProcShort (glGetNamedRenderbufferParameteriv)
2385        && FindProcShort (glCreateTextures)
2386        && FindProcShort (glTextureBuffer)
2387        && FindProcShort (glTextureBufferRange)
2388        && FindProcShort (glTextureStorage1D)
2389        && FindProcShort (glTextureStorage2D)
2390        && FindProcShort (glTextureStorage3D)
2391        && FindProcShort (glTextureStorage2DMultisample)
2392        && FindProcShort (glTextureStorage3DMultisample)
2393        && FindProcShort (glTextureSubImage1D)
2394        && FindProcShort (glTextureSubImage2D)
2395        && FindProcShort (glTextureSubImage3D)
2396        && FindProcShort (glCompressedTextureSubImage1D)
2397        && FindProcShort (glCompressedTextureSubImage2D)
2398        && FindProcShort (glCompressedTextureSubImage3D)
2399        && FindProcShort (glCopyTextureSubImage1D)
2400        && FindProcShort (glCopyTextureSubImage2D)
2401        && FindProcShort (glCopyTextureSubImage3D)
2402        && FindProcShort (glTextureParameterf)
2403        && FindProcShort (glTextureParameterfv)
2404        && FindProcShort (glTextureParameteri)
2405        && FindProcShort (glTextureParameterIiv)
2406        && FindProcShort (glTextureParameterIuiv)
2407        && FindProcShort (glTextureParameteriv)
2408        && FindProcShort (glGenerateTextureMipmap)
2409        && FindProcShort (glBindTextureUnit)
2410        && FindProcShort (glGetTextureImage)
2411        && FindProcShort (glGetCompressedTextureImage)
2412        && FindProcShort (glGetTextureLevelParameterfv)
2413        && FindProcShort (glGetTextureLevelParameteriv)
2414        && FindProcShort (glGetTextureParameterfv)
2415        && FindProcShort (glGetTextureParameterIiv)
2416        && FindProcShort (glGetTextureParameterIuiv)
2417        && FindProcShort (glGetTextureParameteriv)
2418        && FindProcShort (glCreateVertexArrays)
2419        && FindProcShort (glDisableVertexArrayAttrib)
2420        && FindProcShort (glEnableVertexArrayAttrib)
2421        && FindProcShort (glVertexArrayElementBuffer)
2422        && FindProcShort (glVertexArrayVertexBuffer)
2423        && FindProcShort (glVertexArrayVertexBuffers)
2424        && FindProcShort (glVertexArrayAttribBinding)
2425        && FindProcShort (glVertexArrayAttribFormat)
2426        && FindProcShort (glVertexArrayAttribIFormat)
2427        && FindProcShort (glVertexArrayAttribLFormat)
2428        && FindProcShort (glVertexArrayBindingDivisor)
2429        && FindProcShort (glGetVertexArrayiv)
2430        && FindProcShort (glGetVertexArrayIndexediv)
2431        && FindProcShort (glGetVertexArrayIndexed64iv)
2432        && FindProcShort (glCreateSamplers)
2433        && FindProcShort (glCreateProgramPipelines)
2434        && FindProcShort (glCreateQueries)
2435        && FindProcShort (glGetQueryBufferObjecti64v)
2436        && FindProcShort (glGetQueryBufferObjectiv)
2437        && FindProcShort (glGetQueryBufferObjectui64v)
2438        && FindProcShort (glGetQueryBufferObjectuiv)
2439        && FindProcShort (glMemoryBarrierByRegion)
2440        && FindProcShort (glGetTextureSubImage)
2441        && FindProcShort (glGetCompressedTextureSubImage)
2442        && FindProcShort (glGetGraphicsResetStatus)
2443        && FindProcShort (glGetnCompressedTexImage)
2444        && FindProcShort (glGetnTexImage)
2445        && FindProcShort (glGetnUniformdv)
2446        && FindProcShort (glGetnUniformfv)
2447        && FindProcShort (glGetnUniformiv)
2448        && FindProcShort (glGetnUniformuiv)
2449        && FindProcShort (glReadnPixels)
2450        && FindProcShort (glGetnMapdv)
2451        && FindProcShort (glGetnMapfv)
2452        && FindProcShort (glGetnMapiv)
2453        && FindProcShort (glGetnPixelMapfv)
2454        && FindProcShort (glGetnPixelMapuiv)
2455        && FindProcShort (glGetnPixelMapusv)
2456        && FindProcShort (glGetnPolygonStipple)
2457        && FindProcShort (glGetnColorTable)
2458        && FindProcShort (glGetnConvolutionFilter)
2459        && FindProcShort (glGetnSeparableFilter)
2460        && FindProcShort (glGetnHistogram)
2461        && FindProcShort (glGetnMinmax)
2462        && FindProcShort (glTextureBarrier);
2463
2464   // initialize debug context extension
2465   if (CheckExtension ("GL_ARB_debug_output"))
2466   {
2467     arbDbg = NULL;
2468     if (has43)
2469     {
2470       arbDbg = (OpenGl_ArbDbg* )(&(*myFuncs));
2471     }
2472     else if (FindProc ("glDebugMessageControlARB",  myFuncs->glDebugMessageControl)
2473           && FindProc ("glDebugMessageInsertARB",   myFuncs->glDebugMessageInsert)
2474           && FindProc ("glDebugMessageCallbackARB", myFuncs->glDebugMessageCallback)
2475           && FindProc ("glGetDebugMessageLogARB",   myFuncs->glGetDebugMessageLog))
2476     {
2477       arbDbg = (OpenGl_ArbDbg* )(&(*myFuncs));
2478     }
2479
2480     if (arbDbg != NULL
2481      && caps->contextDebug)
2482     {
2483       // setup default callback
2484       myIsGlDebugCtx = Standard_True;
2485       arbDbg->glDebugMessageCallback (debugCallbackWrap, this);
2486       if (has43)
2487       {
2488         ::glEnable (GL_DEBUG_OUTPUT);
2489       }
2490       if (caps->contextSyncDebug)
2491       {
2492         ::glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS);
2493       }
2494     }
2495   }
2496
2497   // initialize TBO extension (ARB)
2498   if (!has31
2499    && CheckExtension ("GL_ARB_texture_buffer_object")
2500    && FindProc ("glTexBufferARB", myFuncs->glTexBuffer))
2501   {
2502     arbTBO = (OpenGl_ArbTBO* )(&(*myFuncs));
2503   }
2504   arbTboRGB32 = CheckExtension ("GL_ARB_texture_buffer_object_rgb32");
2505
2506   // initialize hardware instancing extension (ARB)
2507   if (!has31
2508    && CheckExtension ("GL_ARB_draw_instanced")
2509    && FindProc ("glDrawArraysInstancedARB",   myFuncs->glDrawArraysInstanced)
2510    && FindProc ("glDrawElementsInstancedARB", myFuncs->glDrawElementsInstanced))
2511   {
2512     arbIns = (OpenGl_ArbIns* )(&(*myFuncs));
2513   }
2514
2515   // initialize FBO extension (ARB)
2516   if (hasFBO)
2517   {
2518     arbFBO     = (OpenGl_ArbFBO*     )(&(*myFuncs));
2519     arbFBOBlit = (OpenGl_ArbFBOBlit* )(&(*myFuncs));
2520     extPDS = Standard_True; // extension for EXT, but part of ARB
2521   }
2522
2523   // initialize GS extension (EXT)
2524   if (CheckExtension ("GL_EXT_geometry_shader4")
2525    && FindProcShort (glProgramParameteriEXT))
2526   {
2527     extGS = (OpenGl_ExtGS* )(&(*myFuncs));
2528   }
2529
2530   // initialize bindless texture extension (ARB)
2531   if (CheckExtension ("GL_ARB_bindless_texture")
2532    && FindProcShort (glGetTextureHandleARB)
2533    && FindProcShort (glGetTextureSamplerHandleARB)
2534    && FindProcShort (glMakeTextureHandleResidentARB)
2535    && FindProcShort (glMakeTextureHandleNonResidentARB)
2536    && FindProcShort (glGetImageHandleARB)
2537    && FindProcShort (glMakeImageHandleResidentARB)
2538    && FindProcShort (glMakeImageHandleNonResidentARB)
2539    && FindProcShort (glUniformHandleui64ARB)
2540    && FindProcShort (glUniformHandleui64vARB)
2541    && FindProcShort (glProgramUniformHandleui64ARB)
2542    && FindProcShort (glProgramUniformHandleui64vARB)
2543    && FindProcShort (glIsTextureHandleResidentARB)
2544    && FindProcShort (glIsImageHandleResidentARB)
2545    && FindProcShort (glVertexAttribL1ui64ARB)
2546    && FindProcShort (glVertexAttribL1ui64vARB)
2547    && FindProcShort (glGetVertexAttribLui64vARB))
2548   {
2549     arbTexBindless = (OpenGl_ArbTexBindless* )(&(*myFuncs));
2550   }
2551
2552   if (!has12)
2553   {
2554     checkWrongVersion (1, 2);
2555     myGlVerMajor = 1;
2556     myGlVerMinor = 1;
2557     return;
2558   }
2559   else if (!has13)
2560   {
2561     checkWrongVersion (1, 3);
2562     myGlVerMajor = 1;
2563     myGlVerMinor = 2;
2564     return;
2565   }
2566   else if (!has14)
2567   {
2568     checkWrongVersion (1, 4);
2569     myGlVerMajor = 1;
2570     myGlVerMinor = 3;
2571     return;
2572   }
2573   else if (!has15)
2574   {
2575     checkWrongVersion (1, 5);
2576     myGlVerMajor = 1;
2577     myGlVerMinor = 4;
2578     return;
2579   }
2580   if (!isCoreProfile)
2581   {
2582     core15 = (OpenGl_GlCore15* )(&(*myFuncs));
2583   }
2584   core15fwd = (OpenGl_GlCore15Fwd* )(&(*myFuncs));
2585
2586   if (!has20)
2587   {
2588     checkWrongVersion (2, 0);
2589     myGlVerMajor = 1;
2590     myGlVerMinor = 5;
2591     return;
2592   }
2593
2594   const char* aGlslVer = (const char* )::glGetString (GL_SHADING_LANGUAGE_VERSION);
2595   if (aGlslVer == NULL
2596   || *aGlslVer == '\0')
2597   {
2598     // broken context has been detected
2599     TCollection_ExtendedString aMsg = TCollection_ExtendedString()
2600       + "Error! OpenGL context reports version "
2601       + myGlVerMajor  + "." + myGlVerMinor
2602       + " but reports wrong GLSL version";
2603     PushMessage (GL_DEBUG_SOURCE_APPLICATION,
2604                  GL_DEBUG_TYPE_ERROR,
2605                  0,
2606                  GL_DEBUG_SEVERITY_HIGH,
2607                  aMsg);
2608     myGlVerMajor = 1;
2609     myGlVerMinor = 5;
2610     return;
2611   }
2612
2613   if (!isCoreProfile)
2614   {
2615     core20  = (OpenGl_GlCore20*    )(&(*myFuncs));
2616   }
2617   core20fwd = (OpenGl_GlCore20Fwd* )(&(*myFuncs));
2618
2619   if (!has21)
2620   {
2621     checkWrongVersion (2, 1);
2622     myGlVerMajor = 2;
2623     myGlVerMinor = 0;
2624     return;
2625   }
2626
2627   if (!has30)
2628   {
2629     checkWrongVersion (3, 0);
2630     myGlVerMajor = 2;
2631     myGlVerMinor = 1;
2632     return;
2633   }
2634
2635   // MSAA RenderBuffers have been defined in OpenGL 3.0,
2636   // but MSAA Textures - only in OpenGL 3.2+
2637   if (!has32
2638    && CheckExtension ("GL_ARB_texture_multisample")
2639    && FindProcShort (glTexImage2DMultisample))
2640   {
2641     GLint aNbColorSamples = 0, aNbDepthSamples = 0;
2642     ::glGetIntegerv (GL_MAX_COLOR_TEXTURE_SAMPLES, &aNbColorSamples);
2643     ::glGetIntegerv (GL_MAX_DEPTH_TEXTURE_SAMPLES, &aNbDepthSamples);
2644     myMaxMsaaSamples = Min (aNbColorSamples, aNbDepthSamples);
2645   }
2646   if (!has43
2647    && CheckExtension ("GL_ARB_texture_storage_multisample")
2648    && FindProcShort (glTexStorage2DMultisample))
2649   {
2650     //
2651   }
2652
2653   if (!has31)
2654   {
2655     checkWrongVersion (3, 1);
2656     myGlVerMajor = 3;
2657     myGlVerMinor = 0;
2658     return;
2659   }
2660   arbTBO = (OpenGl_ArbTBO* )(&(*myFuncs));
2661   arbIns = (OpenGl_ArbIns* )(&(*myFuncs));
2662
2663   // check whether ray tracing mode is supported
2664   myHasRayTracing = has31
2665                  && arbTboRGB32
2666                  && arbFBOBlit  != NULL;
2667
2668   // check whether textures in ray tracing mode are supported
2669   myHasRayTracingTextures = myHasRayTracing
2670                          && arbTexBindless != NULL;
2671
2672   // check whether adaptive screen sampling in ray tracing mode is supported
2673   myHasRayTracingAdaptiveSampling = myHasRayTracing
2674                                  && has44;
2675   myHasRayTracingAdaptiveSamplingAtomic = myHasRayTracingAdaptiveSampling
2676                                        && CheckExtension ("GL_NV_shader_atomic_float");
2677
2678   if (!has32)
2679   {
2680     checkWrongVersion (3, 2);
2681     myGlVerMajor = 3;
2682     myGlVerMinor = 1;
2683     return;
2684   }
2685   core32 = (OpenGl_GlCore32* )(&(*myFuncs));
2686   if (isCoreProfile)
2687   {
2688     core32->glGenVertexArrays (1, &myDefaultVao);
2689   }
2690   else
2691   {
2692     core32back = (OpenGl_GlCore32Back* )(&(*myFuncs));
2693   }
2694   ::glGetIntegerv (GL_MAX_SAMPLES, &myMaxMsaaSamples);
2695
2696   if (!has33)
2697   {
2698     checkWrongVersion (3, 3);
2699     myGlVerMajor = 3;
2700     myGlVerMinor = 2;
2701     return;
2702   }
2703   core33 = (OpenGl_GlCore33* )(&(*myFuncs));
2704   if (!isCoreProfile)
2705   {
2706     core33back = (OpenGl_GlCore33Back* )(&(*myFuncs));
2707   }
2708
2709   if (!has40)
2710   {
2711     checkWrongVersion (4, 0);
2712     myGlVerMajor = 3;
2713     myGlVerMinor = 3;
2714     return;
2715   }
2716   arbTboRGB32 = Standard_True; // in core since OpenGL 4.0
2717
2718   if (!has41)
2719   {
2720     checkWrongVersion (4, 1);
2721     myGlVerMajor = 4;
2722     myGlVerMinor = 0;
2723     return;
2724   }
2725   core41 = (OpenGl_GlCore41* )(&(*myFuncs));
2726   if (!isCoreProfile)
2727   {
2728     core41back = (OpenGl_GlCore41Back* )(&(*myFuncs));
2729   }
2730
2731   if(!has42)
2732   {
2733     checkWrongVersion (4, 2);
2734     myGlVerMajor = 4;
2735     myGlVerMinor = 1;
2736     return;
2737   }
2738   core42 = (OpenGl_GlCore42* )(&(*myFuncs));
2739   if (!isCoreProfile)
2740   {
2741     core42back = (OpenGl_GlCore42Back* )(&(*myFuncs));
2742   }
2743
2744   if (!has43)
2745   {
2746     checkWrongVersion (4, 3);
2747     myGlVerMajor = 4;
2748     myGlVerMinor = 2;
2749     return;
2750   }
2751   core43 = (OpenGl_GlCore43* )(&(*myFuncs));
2752   if (!isCoreProfile)
2753   {
2754     core43back = (OpenGl_GlCore43Back* )(&(*myFuncs));
2755   }
2756
2757   if (!has44)
2758   {
2759     checkWrongVersion (4, 4);
2760     myGlVerMajor = 4;
2761     myGlVerMinor = 3;
2762     return;
2763   }
2764   core44 = (OpenGl_GlCore44* )(&(*myFuncs));
2765   if (!isCoreProfile)
2766   {
2767     core44back = (OpenGl_GlCore44Back* )(&(*myFuncs));
2768   }
2769
2770   if (!has45)
2771   {
2772     checkWrongVersion (4, 5);
2773     myGlVerMajor = 4;
2774     myGlVerMinor = 4;
2775     return;
2776   }
2777   core45 = (OpenGl_GlCore45* )(&(*myFuncs));
2778   if (!isCoreProfile)
2779   {
2780     core45back = (OpenGl_GlCore45Back* )(&(*myFuncs));
2781   }
2782 #endif
2783 }
2784
2785 // =======================================================================
2786 // function : MemoryInfo
2787 // purpose  :
2788 // =======================================================================
2789 Standard_Size OpenGl_Context::AvailableMemory() const
2790 {
2791 #if !defined(GL_ES_VERSION_2_0)
2792   if (atiMem)
2793   {
2794     // this is actually information for VBO pool
2795     // however because pools are mostly shared
2796     // it can be used for total GPU memory estimations
2797     GLint aMemInfo[4];
2798     aMemInfo[0] = 0;
2799     glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aMemInfo);
2800     // returned value is in KiB, however this maybe changed in future
2801     return Standard_Size(aMemInfo[0]) * 1024;
2802   }
2803   else if (nvxMem)
2804   {
2805     // current available dedicated video memory (in KiB), currently unused GPU memory
2806     GLint aMemInfo = 0;
2807     glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aMemInfo);
2808     return Standard_Size(aMemInfo) * 1024;
2809   }
2810 #endif
2811   return 0;
2812 }
2813
2814 // =======================================================================
2815 // function : MemoryInfo
2816 // purpose  :
2817 // =======================================================================
2818 TCollection_AsciiString OpenGl_Context::MemoryInfo() const
2819 {
2820   TColStd_IndexedDataMapOfStringString aDict;
2821   MemoryInfo (aDict);
2822
2823   TCollection_AsciiString aText;
2824   for (TColStd_IndexedDataMapOfStringString::Iterator anIter (aDict); anIter.More(); anIter.Next())
2825   {
2826     if (!aText.IsEmpty())
2827     {
2828       aText += "\n";
2829     }
2830     aText += TCollection_AsciiString("  ") + anIter.Key() + ": " + anIter.Value();
2831   }
2832   return aText;
2833 }
2834
2835 // =======================================================================
2836 // function : MemoryInfo
2837 // purpose  :
2838 // =======================================================================
2839 void OpenGl_Context::MemoryInfo (TColStd_IndexedDataMapOfStringString& theDict) const
2840 {
2841 #if defined(GL_ES_VERSION_2_0)
2842   (void )theDict;
2843 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
2844   GLint aGlRendId = 0;
2845   CGLGetParameter (CGLGetCurrentContext(), kCGLCPCurrentRendererID, &aGlRendId);
2846
2847   CGLRendererInfoObj  aRendObj = NULL;
2848   CGOpenGLDisplayMask aDispMask = CGDisplayIDToOpenGLDisplayMask (kCGDirectMainDisplay);
2849   GLint aRendNb = 0;
2850   CGLQueryRendererInfo (aDispMask, &aRendObj, &aRendNb);
2851   for (GLint aRendIter = 0; aRendIter < aRendNb; ++aRendIter)
2852   {
2853     GLint aRendId = 0;
2854     if (CGLDescribeRenderer (aRendObj, aRendIter, kCGLRPRendererID, &aRendId) != kCGLNoError
2855      || aRendId != aGlRendId)
2856     {
2857       continue;
2858     }
2859
2860     //kCGLRPVideoMemoryMegabytes   = 131;
2861     //kCGLRPTextureMemoryMegabytes = 132;
2862     GLint aVMem = 0;
2863   #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
2864     if (CGLDescribeRenderer(aRendObj, aRendIter, kCGLRPVideoMemoryMegabytes, &aVMem) == kCGLNoError)
2865     {
2866       addInfo (theDict, "GPU memory",         TCollection_AsciiString() + aVMem + " MiB");
2867     }
2868     if (CGLDescribeRenderer(aRendObj, aRendIter, kCGLRPTextureMemoryMegabytes, &aVMem) == kCGLNoError)
2869     {
2870       addInfo (theDict, "GPU Texture memory", TCollection_AsciiString() + aVMem + " MiB");
2871     }
2872   #else
2873     if (CGLDescribeRenderer(aRendObj, aRendIter, kCGLRPVideoMemory, &aVMem) == kCGLNoError)
2874     {
2875       addInfo (theDict, "GPU memory",         TCollection_AsciiString() + (aVMem / (1024 * 1024)) + " MiB");
2876     }
2877     if (CGLDescribeRenderer(aRendObj, aRendIter, kCGLRPTextureMemory, &aVMem) == kCGLNoError)
2878     {
2879       addInfo (theDict, "GPU Texture memory", TCollection_AsciiString() + (aVMem / (1024 * 1024)) + " MiB");
2880     }
2881   #endif
2882   }
2883 #endif
2884
2885 #if !defined(GL_ES_VERSION_2_0)
2886   if (atiMem)
2887   {
2888     GLint aValues[4];
2889     memset (aValues, 0, sizeof(aValues));
2890     glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aValues);
2891
2892     // total memory free in the pool
2893     addInfo (theDict, "GPU free memory",    TCollection_AsciiString() + (aValues[0] / 1024) + " MiB");
2894
2895     if (aValues[1] != aValues[0])
2896     {
2897       // largest available free block in the pool
2898       addInfo (theDict, "Largest free block", TCollection_AsciiString() + (aValues[1] / 1024) + " MiB");
2899     }
2900     if (aValues[2] != aValues[0])
2901     {
2902       // total auxiliary memory free
2903       addInfo (theDict, "Free auxiliary memory", TCollection_AsciiString() + (aValues[2] / 1024) + " MiB");
2904     }
2905   }
2906   else if (nvxMem)
2907   {
2908     //current available dedicated video memory (in KiB), currently unused GPU memory
2909     GLint aValue = 0;
2910     glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aValue);
2911     addInfo (theDict, "GPU free memory", TCollection_AsciiString() + (aValue / 1024) + " MiB");
2912
2913     // dedicated video memory, total size (in KiB) of the GPU memory
2914     GLint aDedicated = 0;
2915     glGetIntegerv (GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &aDedicated);
2916     addInfo (theDict, "GPU memory", TCollection_AsciiString() + (aDedicated / 1024) + " MiB");
2917
2918     // total available memory, total size (in KiB) of the memory available for allocations
2919     glGetIntegerv (GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &aValue);
2920     if (aValue != aDedicated)
2921     {
2922       // different only for special configurations
2923       addInfo (theDict, "Total memory", TCollection_AsciiString() + (aValue / 1024) + " MiB");
2924     }
2925   }
2926 #if defined(_WIN32)
2927   else if (myFuncs->wglGetGPUInfoAMD != NULL
2928         && myFuncs->wglGetContextGPUIDAMD != NULL)
2929   {
2930     GLuint aTotalMemMiB = 0;
2931     UINT anAmdId = myFuncs->wglGetContextGPUIDAMD ((HGLRC )myGContext);
2932     if (anAmdId != 0)
2933     {
2934       if (myFuncs->wglGetGPUInfoAMD (anAmdId, WGL_GPU_RAM_AMD, GL_UNSIGNED_INT, sizeof(aTotalMemMiB), &aTotalMemMiB) > 0)
2935       {
2936         addInfo (theDict, "GPU memory", TCollection_AsciiString() + (int )aTotalMemMiB + " MiB");
2937       }
2938     }
2939   }
2940 #endif
2941 #endif
2942
2943 #if !defined(GL_ES_VERSION_2_0) && !defined(__APPLE__) && !defined(_WIN32)
2944   // GLX_RENDERER_VENDOR_ID_MESA
2945   if (myFuncs->glXQueryCurrentRendererIntegerMESA != NULL)
2946   {
2947     unsigned int aVMemMiB = 0;
2948     if (myFuncs->glXQueryCurrentRendererIntegerMESA (GLX_RENDERER_VIDEO_MEMORY_MESA, &aVMemMiB) != False)
2949     {
2950       addInfo (theDict, "GPU memory", TCollection_AsciiString() + int(aVMemMiB) + " MiB");
2951     }
2952   }
2953 #endif
2954 }
2955
2956 // =======================================================================
2957 // function : DiagnosticInfo
2958 // purpose  :
2959 // =======================================================================
2960 void OpenGl_Context::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
2961                                             Graphic3d_DiagnosticInfo theFlags) const
2962 {
2963   if ((theFlags & Graphic3d_DiagnosticInfo_NativePlatform) != 0)
2964   {
2965   #if defined(HAVE_EGL)
2966     addInfo (theDict, "EGLVersion",    ::eglQueryString ((EGLDisplay )myDisplay, EGL_VERSION));
2967     addInfo (theDict, "EGLVendor",     ::eglQueryString ((EGLDisplay )myDisplay, EGL_VENDOR));
2968     addInfo (theDict, "EGLClientAPIs", ::eglQueryString ((EGLDisplay )myDisplay, EGL_CLIENT_APIS));
2969     if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
2970     {
2971       addInfo (theDict, "EGLExtensions", ::eglQueryString ((EGLDisplay )myDisplay, EGL_EXTENSIONS));
2972     }
2973   #elif defined(_WIN32)
2974     if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0
2975      && myFuncs->wglGetExtensionsStringARB != NULL)
2976     {
2977       const char* aWglExts = myFuncs->wglGetExtensionsStringARB ((HDC )myWindowDC);
2978       addInfo (theDict, "WGLExtensions", aWglExts);
2979     }
2980   #elif defined(__APPLE__)
2981     //
2982   #else
2983     Display* aDisplay = (Display*)myDisplay;
2984     const int aScreen = DefaultScreen(aDisplay);
2985     addInfo (theDict, "GLXDirectRendering", ::glXIsDirect (aDisplay, (GLXContext )myGContext) ? "Yes" : "No");
2986     addInfo (theDict, "GLXVendor",  ::glXQueryServerString (aDisplay, aScreen, GLX_VENDOR));
2987     addInfo (theDict, "GLXVersion", ::glXQueryServerString (aDisplay, aScreen, GLX_VERSION));
2988     if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
2989     {
2990       const char* aGlxExts = ::glXQueryExtensionsString (aDisplay, aScreen);
2991       addInfo(theDict, "GLXExtensions", aGlxExts);
2992     }
2993
2994     addInfo (theDict, "GLXClientVendor",  ::glXGetClientString (aDisplay, GLX_VENDOR));
2995     addInfo (theDict, "GLXClientVersion", ::glXGetClientString (aDisplay, GLX_VERSION));
2996     if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
2997     {
2998       addInfo (theDict, "GLXClientExtensions", ::glXGetClientString (aDisplay, GLX_EXTENSIONS));
2999     }
3000   #endif
3001   }
3002
3003   if ((theFlags & Graphic3d_DiagnosticInfo_Device) != 0)
3004   {
3005     addInfo (theDict, "GLvendor",    (const char*)::glGetString (GL_VENDOR));
3006     addInfo (theDict, "GLdevice",    (const char*)::glGetString (GL_RENDERER));
3007     addInfo (theDict, "GLversion",   (const char*)::glGetString (GL_VERSION));
3008     if (IsGlGreaterEqual (2, 0))
3009     {
3010       addInfo (theDict, "GLSLversion", (const char*)::glGetString (GL_SHADING_LANGUAGE_VERSION));
3011     }
3012     if (myIsGlDebugCtx)
3013     {
3014       addInfo (theDict, "GLdebug", "ON");
3015     }
3016   }
3017
3018   if ((theFlags & Graphic3d_DiagnosticInfo_Limits) != 0)
3019   {
3020     addInfo (theDict, "Max texture size", TCollection_AsciiString(myMaxTexDim));
3021     addInfo (theDict, "Max FBO dump size", TCollection_AsciiString() + myMaxDumpSizeX + "x" + myMaxDumpSizeY);
3022     addInfo (theDict, "Max combined texture units", TCollection_AsciiString(myMaxTexCombined));
3023     addInfo (theDict, "Max MSAA samples", TCollection_AsciiString(myMaxMsaaSamples));
3024   }
3025
3026   if ((theFlags & Graphic3d_DiagnosticInfo_FrameBuffer) != 0)
3027   {
3028     GLint aViewport[4] = {};
3029     ::glGetIntegerv (GL_VIEWPORT, aViewport);
3030     addInfo (theDict, "Viewport", TCollection_AsciiString() + aViewport[2] + "x" + aViewport[3]);
3031   }
3032
3033   if ((theFlags & Graphic3d_DiagnosticInfo_Memory) != 0)
3034   {
3035     MemoryInfo (theDict);
3036   }
3037
3038   if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
3039   {
3040   #if !defined(GL_ES_VERSION_2_0)
3041     if (IsGlGreaterEqual (3, 0)
3042      && myFuncs->glGetStringi != NULL)
3043     {
3044       TCollection_AsciiString anExtList;
3045       GLint anExtNb = 0;
3046       ::glGetIntegerv (GL_NUM_EXTENSIONS, &anExtNb);
3047       for (GLint anIter = 0; anIter < anExtNb; ++anIter)
3048       {
3049         const char* anExtension = (const char*)myFuncs->glGetStringi (GL_EXTENSIONS, (GLuint)anIter);
3050         if (!anExtList.IsEmpty())
3051         {
3052           anExtList += " ";
3053         }
3054         anExtList += anExtension;
3055       }
3056       addInfo(theDict, "GLextensions", anExtList);
3057     }
3058     else
3059   #endif
3060     {
3061       addInfo (theDict, "GLextensions", (const char*)::glGetString (GL_EXTENSIONS));
3062     }
3063   }
3064 }
3065
3066 // =======================================================================
3067 // function : GetResource
3068 // purpose  :
3069 // =======================================================================
3070 const Handle(OpenGl_Resource)& OpenGl_Context::GetResource (const TCollection_AsciiString& theKey) const
3071 {
3072   return mySharedResources->IsBound (theKey) ? mySharedResources->Find (theKey) : NULL_GL_RESOURCE;
3073 }
3074
3075 // =======================================================================
3076 // function : ShareResource
3077 // purpose  :
3078 // =======================================================================
3079 Standard_Boolean OpenGl_Context::ShareResource (const TCollection_AsciiString& theKey,
3080                                                 const Handle(OpenGl_Resource)& theResource)
3081 {
3082   if (theKey.IsEmpty() || theResource.IsNull())
3083   {
3084     return Standard_False;
3085   }
3086   return mySharedResources->Bind (theKey, theResource);
3087 }
3088
3089 // =======================================================================
3090 // function : ReleaseResource
3091 // purpose  :
3092 // =======================================================================
3093 void OpenGl_Context::ReleaseResource (const TCollection_AsciiString& theKey,
3094                                       const Standard_Boolean         theToDelay)
3095 {
3096   if (!mySharedResources->IsBound (theKey))
3097   {
3098     return;
3099   }
3100   const Handle(OpenGl_Resource)& aRes = mySharedResources->Find (theKey);
3101   if (aRes->GetRefCount() > 1)
3102   {
3103     return;
3104   }
3105
3106   if (theToDelay)
3107   {
3108     myDelayed->Bind (theKey, 1);
3109   }
3110   else
3111   {
3112     aRes->Release (this);
3113     mySharedResources->UnBind (theKey);
3114   }
3115 }
3116
3117 // =======================================================================
3118 // function : ReleaseDelayed
3119 // purpose  :
3120 // =======================================================================
3121 void OpenGl_Context::ReleaseDelayed()
3122 {
3123   // release queued elements
3124   while (!myUnusedResources->IsEmpty())
3125   {
3126     myUnusedResources->First()->Release (this);
3127     myUnusedResources->RemoveFirst();
3128   }
3129
3130   // release delayed shared resources
3131   NCollection_Vector<TCollection_AsciiString> aDeadList;
3132   for (NCollection_DataMap<TCollection_AsciiString, Standard_Integer>::Iterator anIter (*myDelayed);
3133        anIter.More(); anIter.Next())
3134   {
3135     if (++anIter.ChangeValue() <= 2)
3136     {
3137       continue; // postpone release one more frame to ensure noone use it periodically
3138     }
3139
3140     const TCollection_AsciiString& aKey = anIter.Key();
3141     if (!mySharedResources->IsBound (aKey))
3142     {
3143       // mixed unshared strategy delayed/undelayed was used!
3144       aDeadList.Append (aKey);
3145       continue;
3146     }
3147
3148     const Handle(OpenGl_Resource)& aRes = mySharedResources->ChangeFind (aKey);
3149     if (aRes->GetRefCount() > 1)
3150     {
3151       // should be only 1 instance in mySharedResources
3152       // if not - resource was reused again
3153       aDeadList.Append (aKey);
3154       continue;
3155     }
3156
3157     // release resource if no one requiested it more than 2 redraw calls
3158     aRes->Release (this);
3159     mySharedResources->UnBind (aKey);
3160     aDeadList.Append (aKey);
3161   }
3162
3163   for (Standard_Integer anIter = 0; anIter < aDeadList.Length(); ++anIter)
3164   {
3165     myDelayed->UnBind (aDeadList.Value (anIter));
3166   }
3167 }
3168
3169 // =======================================================================
3170 // function : BindTextures
3171 // purpose  :
3172 // =======================================================================
3173 Handle(OpenGl_TextureSet) OpenGl_Context::BindTextures (const Handle(OpenGl_TextureSet)& theTextures)
3174 {
3175   if (myActiveTextures == theTextures)
3176   {
3177     return myActiveTextures;
3178   }
3179
3180   Handle(OpenGl_Context) aThisCtx (this);
3181   OpenGl_TextureSet::Iterator aTextureIterOld (myActiveTextures), aTextureIterNew (theTextures);
3182   for (;;)
3183   {
3184     if (!aTextureIterNew.More())
3185     {
3186       for (; aTextureIterOld.More(); aTextureIterOld.Next())
3187       {
3188         if (const Handle(OpenGl_Texture)& aTextureOld = aTextureIterOld.Value())
3189         {
3190         #if !defined(GL_ES_VERSION_2_0)
3191           if (core11 != NULL)
3192           {
3193             OpenGl_Sampler::resetGlobalTextureParams (aThisCtx, *aTextureOld, aTextureOld->Sampler()->Parameters());
3194           }
3195         #endif
3196           aTextureOld->Unbind (aThisCtx);
3197         }
3198       }
3199       break;
3200     }
3201
3202     const Handle(OpenGl_Texture)& aTextureNew = aTextureIterNew.Value();
3203     if (aTextureIterOld.More())
3204     {
3205       const Handle(OpenGl_Texture)& aTextureOld = aTextureIterOld.Value();
3206       if (aTextureNew == aTextureOld)
3207       {
3208         aTextureIterNew.Next();
3209         aTextureIterOld.Next();
3210         continue;
3211       }
3212       else if (aTextureNew.IsNull()
3213            || !aTextureNew->IsValid())
3214       {
3215         if (!aTextureOld.IsNull())
3216         {
3217         #if !defined(GL_ES_VERSION_2_0)
3218           if (core11 != NULL)
3219           {
3220             OpenGl_Sampler::resetGlobalTextureParams (aThisCtx, *aTextureOld, aTextureOld->Sampler()->Parameters());
3221           }
3222         #endif
3223           aTextureOld->Unbind (aThisCtx);
3224         }
3225
3226         aTextureIterNew.Next();
3227         aTextureIterOld.Next();
3228         continue;
3229       }
3230
3231       aTextureIterOld.Next();
3232     }
3233     if (aTextureNew.IsNull())
3234     {
3235       aTextureIterNew.Next();
3236       continue;
3237     }
3238
3239     const Graphic3d_TextureUnit aTexUnit = aTextureNew->Sampler()->Parameters()->TextureUnit();
3240     if (aTexUnit >= myMaxTexCombined)
3241     {
3242       PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
3243                    TCollection_AsciiString("Texture unit ") + aTexUnit + " for " + aTextureNew->ResourceId() + " exceeds hardware limit " + myMaxTexCombined);
3244       aTextureIterNew.Next();
3245       continue;
3246     }
3247
3248     aTextureNew->Bind (aThisCtx);
3249     if (aTextureNew->Sampler()->ToUpdateParameters())
3250     {
3251       if (aTextureNew->Sampler()->IsImmutable())
3252       {
3253         aTextureNew->Sampler()->Init (aThisCtx, *aTextureNew);
3254       }
3255       else
3256       {
3257         OpenGl_Sampler::applySamplerParams (aThisCtx, aTextureNew->Sampler()->Parameters(), aTextureNew->Sampler().get(), aTextureNew->GetTarget(), aTextureNew->HasMipmaps());
3258       }
3259     }
3260   #if !defined(GL_ES_VERSION_2_0)
3261     if (core11 != NULL)
3262     {
3263       OpenGl_Sampler::applyGlobalTextureParams (aThisCtx, *aTextureNew, aTextureNew->Sampler()->Parameters());
3264     }
3265   #endif
3266     aTextureIterNew.Next();
3267   }
3268
3269   Handle(OpenGl_TextureSet) anOldTextures = myActiveTextures;
3270   myActiveTextures = theTextures;
3271   return anOldTextures;
3272 }
3273
3274 // =======================================================================
3275 // function : BindProgram
3276 // purpose  :
3277 // =======================================================================
3278 Standard_Boolean OpenGl_Context::BindProgram (const Handle(OpenGl_ShaderProgram)& theProgram)
3279 {
3280   if (core20fwd == NULL)
3281   {
3282     return Standard_False;
3283   }
3284   else if (myActiveProgram == theProgram)
3285   {
3286     return Standard_True;
3287   }
3288
3289   if (theProgram.IsNull()
3290   || !theProgram->IsValid())
3291   {
3292     if (!myActiveProgram.IsNull())
3293     {
3294       core20fwd->glUseProgram (OpenGl_ShaderProgram::NO_PROGRAM);
3295       myActiveProgram.Nullify();
3296     }
3297     return Standard_False;
3298   }
3299
3300   myActiveProgram = theProgram;
3301   core20fwd->glUseProgram (theProgram->ProgramId());
3302   return Standard_True;
3303 }
3304
3305 // =======================================================================
3306 // function : BindDefaultVao
3307 // purpose  :
3308 // =======================================================================
3309 void OpenGl_Context::BindDefaultVao()
3310 {
3311 #if !defined(GL_ES_VERSION_2_0)
3312   if (myDefaultVao == 0
3313    || core32 == NULL)
3314   {
3315     return;
3316   }
3317
3318   core32->glBindVertexArray (myDefaultVao);
3319 #endif
3320 }
3321
3322 // =======================================================================
3323 // function : SetDefaultFrameBuffer
3324 // purpose  :
3325 // =======================================================================
3326 Handle(OpenGl_FrameBuffer) OpenGl_Context::SetDefaultFrameBuffer (const Handle(OpenGl_FrameBuffer)& theFbo)
3327 {
3328   Handle(OpenGl_FrameBuffer) aFbo = myDefaultFbo;
3329   myDefaultFbo = theFbo;
3330   return aFbo;
3331 }
3332
3333 // =======================================================================
3334 // function : SetShadingMaterial
3335 // purpose  :
3336 // =======================================================================
3337 void OpenGl_Context::SetShadingMaterial (const OpenGl_Aspects* theAspect,
3338                                          const Handle(Graphic3d_PresentationAttributes)& theHighlight)
3339 {
3340   const Handle(Graphic3d_Aspects)& anAspect = (!theHighlight.IsNull() && !theHighlight->BasicFillAreaAspect().IsNull())
3341                                             ?  (const Handle(Graphic3d_Aspects)& )theHighlight->BasicFillAreaAspect()
3342                                             :  theAspect->Aspect();
3343
3344   const bool toDistinguish = anAspect->Distinguish();
3345   const bool toMapTexture  = anAspect->ToMapTexture();
3346   const Graphic3d_MaterialAspect& aMatFrontSrc = anAspect->FrontMaterial();
3347   const Graphic3d_MaterialAspect& aMatBackSrc  = toDistinguish
3348                                                ? anAspect->BackMaterial()
3349                                                : aMatFrontSrc;
3350   const Quantity_Color& aFrontIntColor = anAspect->InteriorColor();
3351   const Quantity_Color& aBackIntColor  = toDistinguish
3352                                        ? anAspect->BackInteriorColor()
3353                                        : aFrontIntColor;
3354
3355   myMatFront.Init (aMatFrontSrc, aFrontIntColor);
3356   if (toDistinguish)
3357   {
3358     myMatBack.Init (aMatBackSrc, aBackIntColor);
3359   }
3360   else
3361   {
3362     myMatBack = myMatFront;
3363   }
3364
3365   if (!theHighlight.IsNull()
3366     && theHighlight->BasicFillAreaAspect().IsNull())
3367   {
3368     myMatFront.SetColor (theHighlight->ColorRGBA());
3369     myMatBack .SetColor (theHighlight->ColorRGBA());
3370   }
3371
3372   Standard_ShortReal anAlphaFront = 1.0f;
3373   Standard_ShortReal anAlphaBack  = 1.0f;
3374   if (CheckIsTransparent (theAspect, theHighlight, anAlphaFront, anAlphaBack))
3375   {
3376     myMatFront.Diffuse.a() = anAlphaFront;
3377     myMatBack .Diffuse.a() = anAlphaBack;
3378   }
3379
3380   // do not update material properties in case of zero reflection mode,
3381   // because GL lighting will be disabled by OpenGl_PrimitiveArray::DrawArray() anyway.
3382   const OpenGl_MaterialState& aMatState = myShaderManager->MaterialState();
3383   float anAlphaCutoff = anAspect->AlphaMode() == Graphic3d_AlphaMode_Mask
3384                       ? anAspect->AlphaCutoff()
3385                       : ShortRealLast();
3386   if (anAspect->ToDrawEdges())
3387   {
3388     if (anAspect->InteriorStyle() == Aspect_IS_EMPTY
3389      || (anAspect->InteriorStyle() == Aspect_IS_SOLID
3390       && anAspect->EdgeColorRGBA().Alpha() < 1.0f))
3391     {
3392       anAlphaCutoff = 0.285f;
3393     }
3394   }
3395   if (theAspect->ShadingModel() == Graphic3d_TOSM_UNLIT)
3396   {
3397     if (anAlphaCutoff == aMatState.AlphaCutoff())
3398     {
3399       return;
3400     }
3401   }
3402   else if (myMatFront    == aMatState.FrontMaterial()
3403         && myMatBack     == aMatState.BackMaterial()
3404         && toDistinguish == aMatState.ToDistinguish()
3405         && toMapTexture  == aMatState.ToMapTexture()
3406         && anAlphaCutoff == aMatState.AlphaCutoff())
3407   {
3408     return;
3409   }
3410
3411   myShaderManager->UpdateMaterialStateTo (myMatFront, myMatBack, anAlphaCutoff, toDistinguish, toMapTexture);
3412 }
3413
3414 // =======================================================================
3415 // function : CheckIsTransparent
3416 // purpose  :
3417 // =======================================================================
3418 Standard_Boolean OpenGl_Context::CheckIsTransparent (const OpenGl_Aspects* theAspect,
3419                                                      const Handle(Graphic3d_PresentationAttributes)& theHighlight,
3420                                                      Standard_ShortReal& theAlphaFront,
3421                                                      Standard_ShortReal& theAlphaBack)
3422 {
3423   const Handle(Graphic3d_Aspects)& anAspect = (!theHighlight.IsNull() && !theHighlight->BasicFillAreaAspect().IsNull())
3424                                             ?  (const Handle(Graphic3d_Aspects)& )theHighlight->BasicFillAreaAspect()
3425                                             :  theAspect->Aspect();
3426
3427   const bool toDistinguish = anAspect->Distinguish();
3428   const Graphic3d_MaterialAspect& aMatFrontSrc = anAspect->FrontMaterial();
3429   const Graphic3d_MaterialAspect& aMatBackSrc  = toDistinguish
3430                                                ? anAspect->BackMaterial()
3431                                                : aMatFrontSrc;
3432
3433   // handling transparency
3434   if (!theHighlight.IsNull()
3435     && theHighlight->BasicFillAreaAspect().IsNull())
3436   {
3437     theAlphaFront = theHighlight->ColorRGBA().Alpha();
3438     theAlphaBack  = theHighlight->ColorRGBA().Alpha();
3439   }
3440   else
3441   {
3442     theAlphaFront = aMatFrontSrc.Alpha();
3443     theAlphaBack  = aMatBackSrc .Alpha();
3444   }
3445
3446   if (anAspect->AlphaMode() == Graphic3d_AlphaMode_BlendAuto)
3447   {
3448     return theAlphaFront < 1.0f
3449         || theAlphaBack  < 1.0f;
3450   }
3451   return anAspect->AlphaMode() == Graphic3d_AlphaMode_Blend;
3452 }
3453
3454 // =======================================================================
3455 // function : SetColor4fv
3456 // purpose  :
3457 // =======================================================================
3458 void OpenGl_Context::SetColor4fv (const OpenGl_Vec4& theColor)
3459 {
3460   if (!myActiveProgram.IsNull())
3461   {
3462     myActiveProgram->SetUniform (this, myActiveProgram->GetStateLocation (OpenGl_OCCT_COLOR), theColor);
3463   }
3464 #if !defined(GL_ES_VERSION_2_0)
3465   else if (core11 != NULL)
3466   {
3467     core11->glColor4fv (theColor.GetData());
3468   }
3469 #endif
3470 }
3471
3472 // =======================================================================
3473 // function : SetTypeOfLine
3474 // purpose  :
3475 // =======================================================================
3476 void OpenGl_Context::SetTypeOfLine (const Aspect_TypeOfLine  theType,
3477                                     const Standard_ShortReal theFactor)
3478 {
3479   Standard_Integer aPattern = 0xFFFF;
3480   switch (theType)
3481   {
3482     case Aspect_TOL_DASH:
3483     {
3484       aPattern = 0xFFC0;
3485       break;
3486     }
3487     case Aspect_TOL_DOT:
3488     {
3489       aPattern = 0xCCCC;
3490       break;
3491     }
3492     case Aspect_TOL_DOTDASH:
3493     {
3494       aPattern = 0xFF18;
3495       break;
3496     }
3497     case Aspect_TOL_EMPTY:
3498     case Aspect_TOL_SOLID:
3499     {
3500       aPattern = 0xFFFF;
3501       break;
3502     }
3503     case Aspect_TOL_USERDEFINED:
3504     {
3505       aPattern = 0xFF24;
3506       break;
3507     }
3508   }
3509
3510   if (!myActiveProgram.IsNull())
3511   {
3512     myActiveProgram->SetUniform (this, "uPattern", aPattern);
3513     myActiveProgram->SetUniform (this, "uFactor",  theFactor);
3514     return;
3515   }
3516
3517 #if !defined(GL_ES_VERSION_2_0)
3518   if (aPattern != 0xFFFF)
3519   {
3520     if (core11 != NULL)
3521     {
3522       core11fwd->glEnable (GL_LINE_STIPPLE);
3523
3524       core11->glLineStipple (static_cast<GLint>    (theFactor),
3525                              static_cast<GLushort> (aPattern));
3526     }
3527   }
3528   else
3529   {
3530     if (core11 != NULL)
3531     {
3532       core11fwd->glDisable (GL_LINE_STIPPLE);
3533     }
3534   }
3535 #endif
3536 }
3537
3538 // =======================================================================
3539 // function : SetLineWidth
3540 // purpose  :
3541 // =======================================================================
3542 void OpenGl_Context::SetLineWidth (const Standard_ShortReal theWidth)
3543 {
3544   if (core11 != NULL)
3545   {
3546     // glLineWidth() is still defined within Core Profile, but has no effect with values != 1.0f
3547     core11fwd->glLineWidth (theWidth * myLineWidthScale);
3548   }
3549 }
3550
3551 // =======================================================================
3552 // function : SetTextureMatrix
3553 // purpose  :
3554 // =======================================================================
3555 void OpenGl_Context::SetTextureMatrix (const Handle(Graphic3d_TextureParams)& theParams)
3556 {
3557   if (theParams.IsNull())
3558   {
3559     return;
3560   }
3561   else if (!myActiveProgram.IsNull())
3562   {
3563     const GLint aUniLoc = myActiveProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_TRSF2D);
3564     if (aUniLoc == OpenGl_ShaderProgram::INVALID_LOCATION)
3565     {
3566       return;
3567     }
3568
3569     // pack transformation parameters
3570     OpenGl_Vec4 aTrsf[2] =
3571     {
3572       OpenGl_Vec4 (-theParams->Translation().x(),
3573                    -theParams->Translation().y(),
3574                     theParams->Scale().x(),
3575                     theParams->Scale().y()),
3576       OpenGl_Vec4 (static_cast<float> (std::sin (-theParams->Rotation() * M_PI / 180.0)),
3577                    static_cast<float> (std::cos (-theParams->Rotation() * M_PI / 180.0)),
3578                    0.0f, 0.0f)
3579     };
3580     myActiveProgram->SetUniform (this, aUniLoc, 2, aTrsf);
3581     return;
3582   }
3583
3584 #if !defined(GL_ES_VERSION_2_0)
3585   if (core11 != NULL)
3586   {
3587     GLint aMatrixMode = GL_TEXTURE;
3588     ::glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
3589
3590     core11->glMatrixMode (GL_TEXTURE);
3591     OpenGl_Mat4 aTextureMat;
3592     const Graphic3d_Vec2& aScale = theParams->Scale();
3593     const Graphic3d_Vec2& aTrans = theParams->Translation();
3594     Graphic3d_TransformUtils::Scale     (aTextureMat,  aScale.x(),  aScale.y(), 1.0f);
3595     Graphic3d_TransformUtils::Translate (aTextureMat, -aTrans.x(), -aTrans.y(), 0.0f);
3596     Graphic3d_TransformUtils::Rotate    (aTextureMat, -theParams->Rotation(), 0.0f, 0.0f, 1.0f);
3597     core11->glLoadMatrixf (aTextureMat);
3598     core11->glMatrixMode (aMatrixMode);
3599   }