0030729: Visualization - TKOpenGl reports OpenGL 4.5 loading functions error on Intel...
[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 (Standard_Integer theGlVerMajor, Standard_Integer theGlVerMinor,
1168                                         const char* theLastFailedProc)
1169 {
1170   if (!IsGlGreaterEqual (theGlVerMajor, theGlVerMinor))
1171   {
1172     return;
1173   }
1174
1175   PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
1176                TCollection_AsciiString()
1177                + "Error! OpenGL context reports version "
1178                + myGlVerMajor  + "." + myGlVerMinor
1179                + " but does not export required functions for " + theGlVerMajor + "." + theGlVerMinor
1180                + " (" + (theLastFailedProc != NULL ? theLastFailedProc : "") + ")\n"
1181                + "Please report this issue to OpenGL driver vendor '" + myVendor + "'");
1182
1183   // lower internal version
1184   if (theGlVerMinor > 0)
1185   {
1186     myGlVerMajor = theGlVerMajor;
1187     myGlVerMinor = theGlVerMinor - 1;
1188     return;
1189   }
1190 #if defined(GL_ES_VERSION_2_0)
1191   switch (theGlVerMajor)
1192   {
1193     case 3: myGlVerMajor = 2; myGlVerMinor = 0; return;
1194   }
1195 #else
1196   switch (theGlVerMajor)
1197   {
1198     case 2: myGlVerMajor = 1; myGlVerMinor = 5; return;
1199     case 3: myGlVerMajor = 2; myGlVerMinor = 1; return;
1200     case 4: myGlVerMajor = 3; myGlVerMinor = 3; return;
1201   }
1202 #endif
1203 }
1204
1205 // =======================================================================
1206 // function : init
1207 // purpose  :
1208 // =======================================================================
1209 void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
1210 {
1211   // read version
1212   myGlVerMajor = 0;
1213   myGlVerMinor = 0;
1214   myMaxMsaaSamples = 0;
1215   myMaxDrawBuffers = 1;
1216   myMaxColorAttachments = 1;
1217   ReadGlVersion (myGlVerMajor, myGlVerMinor);
1218   myVendor = (const char* )::glGetString (GL_VENDOR);
1219   myVendor.LowerCase();
1220   if (!caps->ffpEnable
1221    && !IsGlGreaterEqual (2, 0))
1222   {
1223     caps->ffpEnable = true;
1224     TCollection_ExtendedString aMsg =
1225       TCollection_ExtendedString("OpenGL driver is too old! Context info:\n")
1226                                + "    Vendor:   " + (const char* )::glGetString (GL_VENDOR)   + "\n"
1227                                + "    Renderer: " + (const char* )::glGetString (GL_RENDERER) + "\n"
1228                                + "    Version:  " + (const char* )::glGetString (GL_VERSION)  + "\n"
1229                                + "  Fallback using deprecated fixed-function pipeline.\n"
1230                                + "  Visualization might work incorrectly.\n"
1231                                  "  Consider upgrading the graphics driver.";
1232     PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
1233   }
1234
1235 #if defined(GL_ES_VERSION_2_0)
1236   (void )theIsCoreProfile;
1237   const bool isCoreProfile = false;
1238 #else
1239
1240   if (myVendor.Search ("nvidia") != -1)
1241   {
1242     // Buffer detailed info: Buffer object 1 (bound to GL_ARRAY_BUFFER_ARB, usage hint is GL_STATIC_DRAW)
1243     // will use VIDEO memory as the source for buffer object operations.
1244     ExcludeMessage (GL_DEBUG_SOURCE_API, 131185);
1245   }
1246   if (IsGlGreaterEqual (3, 0))
1247   {
1248     // retrieve auxiliary function in advance
1249     FindProc ("glGetStringi", myFuncs->glGetStringi);
1250   }
1251
1252   bool isCoreProfile = false;
1253   if (IsGlGreaterEqual (3, 2))
1254   {
1255     isCoreProfile = (theIsCoreProfile == Standard_True);
1256
1257     // detect Core profile
1258     if (!isCoreProfile)
1259     {
1260       GLint aProfile = 0;
1261       ::glGetIntegerv (GL_CONTEXT_PROFILE_MASK, &aProfile);
1262       isCoreProfile = (aProfile & GL_CONTEXT_CORE_PROFILE_BIT) != 0;
1263     }
1264   }
1265 #endif
1266
1267   core11     = NULL;
1268   if (!isCoreProfile)
1269   {
1270     core11 = (OpenGl_GlCore11* )(&(*myFuncs));
1271   }
1272   core11fwd  = (OpenGl_GlCore11Fwd* )(&(*myFuncs));
1273   core15     = NULL;
1274   core15fwd  = NULL;
1275   core20     = NULL;
1276   core20fwd  = NULL;
1277   core32     = NULL;
1278   core32back = NULL;
1279   core33     = NULL;
1280   core33back = NULL;
1281   core41     = NULL;
1282   core41back = NULL;
1283   core42     = NULL;
1284   core42back = NULL;
1285   core43     = NULL;
1286   core43back = NULL;
1287   core44     = NULL;
1288   core44back = NULL;
1289   core45     = NULL;
1290   core45back = NULL;
1291   arbTBO     = NULL;
1292   arbTboRGB32 = Standard_False;
1293   arbIns     = NULL;
1294   arbDbg     = NULL;
1295   arbFBO     = NULL;
1296   arbFBOBlit = NULL;
1297   extGS      = NULL;
1298   myDefaultVao = 0;
1299
1300   //! Make record shorter to retrieve function pointer using variable with same name
1301   const char* aLastFailedProc = NULL;
1302   #define FindProcShort(theFunc) FindProcVerbose(aLastFailedProc, #theFunc, myFuncs->theFunc)
1303
1304 #if defined(GL_ES_VERSION_2_0)
1305
1306   hasTexRGBA8 = IsGlGreaterEqual (3, 0)
1307              || CheckExtension ("GL_OES_rgb8_rgba8");
1308   // NPOT textures has limited support within OpenGL ES 2.0
1309   // which are relaxed by OpenGL ES 3.0 or some extensions
1310   //arbNPTW     = IsGlGreaterEqual (3, 0)
1311   //           || CheckExtension ("GL_OES_texture_npot")
1312   //           || CheckExtension ("GL_NV_texture_npot_2D_mipmap");
1313   arbNPTW     = Standard_True;
1314   arbTexRG    = IsGlGreaterEqual (3, 0)
1315              || CheckExtension ("GL_EXT_texture_rg");
1316   extBgra     = CheckExtension ("GL_EXT_texture_format_BGRA8888");
1317   extAnis = CheckExtension ("GL_EXT_texture_filter_anisotropic");
1318   extPDS  = IsGlGreaterEqual (3, 0)
1319          || CheckExtension ("GL_OES_packed_depth_stencil");
1320
1321   core11fwd = (OpenGl_GlCore11Fwd* )(&(*myFuncs));
1322   if (IsGlGreaterEqual (2, 0))
1323   {
1324     // enable compatible functions
1325     core20    = (OpenGl_GlCore20*    )(&(*myFuncs));
1326     core20fwd = (OpenGl_GlCore20Fwd* )(&(*myFuncs));
1327     core15fwd = (OpenGl_GlCore15Fwd* )(&(*myFuncs));
1328     arbFBO    = (OpenGl_ArbFBO*      )(&(*myFuncs));
1329   }
1330   if (IsGlGreaterEqual (3, 0)
1331    && FindProcShort (glBlitFramebuffer))
1332   {
1333     arbFBOBlit = (OpenGl_ArbFBOBlit* )(&(*myFuncs));
1334   }
1335   if (IsGlGreaterEqual (3, 0)
1336    && FindProcShort (glGenSamplers)
1337    && FindProcShort (glDeleteSamplers)
1338    && FindProcShort (glIsSampler)
1339    && FindProcShort (glBindSampler)
1340    && FindProcShort (glSamplerParameteri)
1341    && FindProcShort (glSamplerParameteriv)
1342    && FindProcShort (glSamplerParameterf)
1343    && FindProcShort (glSamplerParameterfv)
1344    && FindProcShort (glGetSamplerParameteriv)
1345    && FindProcShort (glGetSamplerParameterfv))
1346    //&& FindProcShort (glSamplerParameterIiv) // only on Desktop or with extensions GL_OES_texture_border_clamp/GL_EXT_texture_border_clamp
1347    //&& FindProcShort (glSamplerParameterIuiv)
1348    //&& FindProcShort (glGetSamplerParameterIiv)
1349    //&& FindProcShort (glGetSamplerParameterIuiv))
1350   {
1351     arbSamplerObject = (OpenGl_ArbSamplerObject* )(&(*myFuncs));
1352   }
1353   extFragDepth = !IsGlGreaterEqual(3, 0)
1354                && CheckExtension ("GL_EXT_frag_depth");
1355   if (IsGlGreaterEqual (3, 1)
1356    && FindProcShort (glTexStorage2DMultisample))
1357   {
1358     // MSAA RenderBuffers have been defined in OpenGL ES 3.0,
1359     // but MSAA Textures - only in OpenGL ES 3.1+
1360     ::glGetIntegerv (GL_MAX_SAMPLES, &myMaxMsaaSamples);
1361   }
1362
1363   hasUintIndex = IsGlGreaterEqual (3, 0)
1364               || CheckExtension ("GL_OES_element_index_uint");
1365   hasHighp     = CheckExtension ("GL_OES_fragment_precision_high");
1366   GLint aRange[2] = {0, 0};
1367   GLint aPrec     = 0;
1368   ::glGetShaderPrecisionFormat (GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, aRange, &aPrec);
1369   if (aPrec != 0)
1370   {
1371     hasHighp = Standard_True;
1372   }
1373
1374   arbTexFloat = IsGlGreaterEqual (3, 0)
1375              && FindProcShort (glTexImage3D);
1376
1377   const Standard_Boolean hasTexBuffer32  = IsGlGreaterEqual (3, 2) && FindProcShort (glTexBuffer);
1378   const Standard_Boolean hasExtTexBuffer = CheckExtension ("GL_EXT_texture_buffer") && FindProc ("glTexBufferEXT", myFuncs->glTexBuffer);
1379
1380   if (hasTexBuffer32 || hasExtTexBuffer)
1381   {
1382     arbTBO = reinterpret_cast<OpenGl_ArbTBO*> (myFuncs.get());
1383   }
1384
1385   // initialize debug context extension
1386   if (CheckExtension ("GL_KHR_debug"))
1387   {
1388     // this functionality become a part of OpenGL ES 3.2
1389     arbDbg = NULL;
1390     // According to GL_KHR_debug spec, all functions should have KHR suffix.
1391     // However, some implementations can export these functions without suffix.
1392     if (FindProc ("glDebugMessageControlKHR",  myFuncs->glDebugMessageControl)
1393      && FindProc ("glDebugMessageInsertKHR",   myFuncs->glDebugMessageInsert)
1394      && FindProc ("glDebugMessageCallbackKHR", myFuncs->glDebugMessageCallback)
1395      && FindProc ("glGetDebugMessageLogKHR",   myFuncs->glGetDebugMessageLog))
1396     {
1397       arbDbg = (OpenGl_ArbDbg* )(&(*myFuncs));
1398     }
1399
1400     if (arbDbg != NULL
1401      && caps->contextDebug)
1402     {
1403       // setup default callback
1404       myIsGlDebugCtx = Standard_True;
1405       arbDbg->glDebugMessageCallback (debugCallbackWrap, this);
1406       ::glEnable (GL_DEBUG_OUTPUT);
1407       if (caps->contextSyncDebug)
1408       {
1409         // note that some broken implementations (e.g. simulators) might generate error message on this call
1410         ::glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS);
1411       }
1412     }
1413   }
1414
1415   extDrawBuffers = CheckExtension ("GL_EXT_draw_buffers") && FindProc ("glDrawBuffersEXT", myFuncs->glDrawBuffers);
1416   arbDrawBuffers = CheckExtension ("GL_ARB_draw_buffers") && FindProc ("glDrawBuffersARB", myFuncs->glDrawBuffers);
1417
1418   if (IsGlGreaterEqual (3, 0) && FindProcShort (glDrawBuffers))
1419   {
1420     hasDrawBuffers = OpenGl_FeatureInCore;
1421   }
1422   else if (extDrawBuffers || arbDrawBuffers)
1423   {
1424     hasDrawBuffers = OpenGl_FeatureInExtensions;
1425   }
1426
1427   hasFloatBuffer     = IsGlGreaterEqual (3, 2) ? OpenGl_FeatureInCore :
1428                        CheckExtension ("GL_EXT_color_buffer_float") ? OpenGl_FeatureInExtensions 
1429                                                                     : OpenGl_FeatureNotAvailable;
1430   hasHalfFloatBuffer = IsGlGreaterEqual (3, 2) ? OpenGl_FeatureInCore :
1431                        CheckExtension ("GL_EXT_color_buffer_half_float") ? OpenGl_FeatureInExtensions 
1432                                                                          : OpenGl_FeatureNotAvailable;
1433
1434   oesSampleVariables = CheckExtension ("GL_OES_sample_variables");
1435   oesStdDerivatives  = CheckExtension ("GL_OES_standard_derivatives");
1436   hasSampleVariables = IsGlGreaterEqual (3, 2) ? OpenGl_FeatureInCore :
1437                        oesSampleVariables ? OpenGl_FeatureInExtensions
1438                                           : OpenGl_FeatureNotAvailable;
1439   // without hasHighp, dFdx/dFdy precision is considered too low for flat shading (visual artifacts)
1440   hasFlatShading = IsGlGreaterEqual (3, 0)
1441                  ? OpenGl_FeatureInCore
1442                   : (oesStdDerivatives && hasHighp
1443                    ? OpenGl_FeatureInExtensions
1444                    : OpenGl_FeatureNotAvailable);
1445   if (!IsGlGreaterEqual (3, 1)
1446     && myVendor.Search("qualcomm") != -1)
1447   {
1448     // dFdx/dFdy are completely broken on tested Adreno devices with versions below OpenGl ES 3.1
1449     hasFlatShading = OpenGl_FeatureNotAvailable;
1450   }
1451
1452   hasGeometryStage = IsGlGreaterEqual (3, 2)
1453                    ? OpenGl_FeatureInCore
1454                    : (CheckExtension ("GL_EXT_geometry_shader") && CheckExtension ("GL_EXT_shader_io_blocks")
1455                      ? OpenGl_FeatureInExtensions
1456                      : OpenGl_FeatureNotAvailable);
1457 #else
1458
1459   myTexClamp = IsGlGreaterEqual (1, 2) ? GL_CLAMP_TO_EDGE : GL_CLAMP;
1460
1461   hasTexRGBA8 = Standard_True;
1462   arbDrawBuffers   = CheckExtension ("GL_ARB_draw_buffers");
1463   arbNPTW          = CheckExtension ("GL_ARB_texture_non_power_of_two");
1464   arbTexFloat      = IsGlGreaterEqual (3, 0)
1465                   || CheckExtension ("GL_ARB_texture_float");
1466   arbSampleShading = CheckExtension ("GL_ARB_sample_shading");
1467   extBgra          = CheckExtension ("GL_EXT_bgra");
1468   extAnis          = CheckExtension ("GL_EXT_texture_filter_anisotropic");
1469   extPDS           = CheckExtension ("GL_EXT_packed_depth_stencil");
1470   atiMem           = CheckExtension ("GL_ATI_meminfo");
1471   nvxMem           = CheckExtension ("GL_NVX_gpu_memory_info");
1472
1473   hasDrawBuffers = IsGlGreaterEqual (2, 0) ? OpenGl_FeatureInCore :
1474                    arbDrawBuffers ? OpenGl_FeatureInExtensions 
1475                                   : OpenGl_FeatureNotAvailable;
1476
1477   hasFloatBuffer = hasHalfFloatBuffer =  IsGlGreaterEqual (3, 0) ? OpenGl_FeatureInCore :
1478                                          CheckExtension ("GL_ARB_color_buffer_float") ? OpenGl_FeatureInExtensions
1479                                                                                       : OpenGl_FeatureNotAvailable;
1480
1481   hasGeometryStage = IsGlGreaterEqual (3, 2)
1482                    ? OpenGl_FeatureInCore
1483                    : OpenGl_FeatureNotAvailable;
1484
1485   hasSampleVariables = IsGlGreaterEqual (4, 0) ? OpenGl_FeatureInCore :
1486                         arbSampleShading ? OpenGl_FeatureInExtensions
1487                                          : OpenGl_FeatureNotAvailable;
1488
1489   GLint aStereo = GL_FALSE;
1490   glGetIntegerv (GL_STEREO, &aStereo);
1491   myIsStereoBuffers = aStereo == 1;
1492
1493   // get number of maximum clipping planes
1494   glGetIntegerv (GL_MAX_CLIP_PLANES,  &myMaxClipPlanes);
1495 #endif
1496
1497   if (hasDrawBuffers)
1498   {
1499     glGetIntegerv (GL_MAX_DRAW_BUFFERS,      &myMaxDrawBuffers);
1500     glGetIntegerv (GL_MAX_COLOR_ATTACHMENTS, &myMaxColorAttachments);
1501     if (myDrawBuffers.Length() < myMaxDrawBuffers)
1502     {
1503       myDrawBuffers.Resize (0, myMaxDrawBuffers - 1, false);
1504     }
1505   }
1506
1507   glGetIntegerv (GL_MAX_TEXTURE_SIZE, &myMaxTexDim);
1508   if (IsGlGreaterEqual (2, 0))
1509   {
1510     glGetIntegerv (GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &myMaxTexCombined);
1511   }
1512 #if !defined(GL_ES_VERSION_2_0)
1513   else if (IsGlGreaterEqual (1, 3))
1514   {
1515     // this is a maximum of texture units for FFP functionality,
1516     // dramatically smaller than combined texture units available for GLSL
1517     glGetIntegerv (GL_MAX_TEXTURE_UNITS, &myMaxTexCombined);
1518   }
1519 #endif
1520   mySpriteTexUnit = myMaxTexCombined >= 2
1521                   ? Graphic3d_TextureUnit_1
1522                   : Graphic3d_TextureUnit_0;
1523
1524   GLint aMaxVPortSize[2] = {0, 0};
1525   glGetIntegerv (GL_MAX_VIEWPORT_DIMS, aMaxVPortSize);
1526   myMaxDumpSizeX = Min (aMaxVPortSize[0], myMaxTexDim);
1527   myMaxDumpSizeY = Min (aMaxVPortSize[1], myMaxTexDim);
1528   if (myVendor == "intel")
1529   {
1530     // Intel drivers have known bug with empty dump for images with width>=5462
1531     myMaxDumpSizeX = Min (myMaxDumpSizeX, 4096);
1532   }
1533
1534   if (extAnis)
1535   {
1536     glGetIntegerv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &myAnisoMax);
1537   }
1538
1539   myClippingState.Init();
1540
1541 #if !defined(GL_ES_VERSION_2_0)
1542
1543   bool has12 = false;
1544   bool has13 = false;
1545   bool has14 = false;
1546   bool has15 = false;
1547   bool has20 = false;
1548   bool has21 = false;
1549   bool has30 = false;
1550   bool has31 = false;
1551   bool has32 = false;
1552   bool has33 = false;
1553   bool has40 = false;
1554   bool has41 = false;
1555   bool has42 = false;
1556   bool has43 = false;
1557   bool has44 = false;
1558   bool has45 = false;
1559
1560   // retrieve platform-dependent extensions
1561 #if defined(HAVE_EGL)
1562   //
1563 #elif defined(_WIN32)
1564   if (FindProcShort (wglGetExtensionsStringARB))
1565   {
1566     const char* aWglExts = myFuncs->wglGetExtensionsStringARB (wglGetCurrentDC());
1567     if (CheckExtension (aWglExts, "WGL_EXT_swap_control"))
1568     {
1569       FindProcShort (wglSwapIntervalEXT);
1570     }
1571     if (CheckExtension (aWglExts, "WGL_ARB_pixel_format"))
1572     {
1573       FindProcShort (wglChoosePixelFormatARB);
1574     }
1575     if (CheckExtension (aWglExts, "WGL_ARB_create_context_profile"))
1576     {
1577       FindProcShort (wglCreateContextAttribsARB);
1578     }
1579     if (CheckExtension (aWglExts, "WGL_NV_DX_interop"))
1580     {
1581       FindProcShort (wglDXSetResourceShareHandleNV);
1582       FindProcShort (wglDXOpenDeviceNV);
1583       FindProcShort (wglDXCloseDeviceNV);
1584       FindProcShort (wglDXRegisterObjectNV);
1585       FindProcShort (wglDXUnregisterObjectNV);
1586       FindProcShort (wglDXObjectAccessNV);
1587       FindProcShort (wglDXLockObjectsNV);
1588       FindProcShort (wglDXUnlockObjectsNV);
1589     }
1590     if (CheckExtension (aWglExts, "WGL_AMD_gpu_association"))
1591     {
1592       FindProcShort (wglGetGPUIDsAMD);
1593       FindProcShort (wglGetGPUInfoAMD);
1594       FindProcShort (wglGetContextGPUIDAMD);
1595     }
1596   }
1597 #elif defined(__APPLE__)
1598     //
1599 #else
1600     const char* aGlxExts = ::glXQueryExtensionsString ((Display* )myDisplay, DefaultScreen ((Display* )myDisplay));
1601     if (CheckExtension (aGlxExts, "GLX_EXT_swap_control"))
1602     {
1603       FindProcShort (glXSwapIntervalEXT);
1604     }
1605     if (CheckExtension (aGlxExts, "GLX_SGI_swap_control"))
1606     {
1607       FindProcShort (glXSwapIntervalSGI);
1608     }
1609     if (CheckExtension (aGlxExts, "GLX_MESA_query_renderer"))
1610     {
1611       FindProcShort (glXQueryRendererIntegerMESA);
1612       FindProcShort (glXQueryCurrentRendererIntegerMESA);
1613       FindProcShort (glXQueryRendererStringMESA);
1614       FindProcShort (glXQueryCurrentRendererStringMESA);
1615     }
1616     //extSwapTear = CheckExtension (aGlxExts, "GLX_EXT_swap_control_tear");
1617 #endif
1618
1619   // load OpenGL 1.2 new functions
1620   has12 = IsGlGreaterEqual (1, 2)
1621        && FindProcShort (glBlendColor)
1622        && FindProcShort (glBlendEquation)
1623        && FindProcShort (glDrawRangeElements)
1624        && FindProcShort (glTexImage3D)
1625        && FindProcShort (glTexSubImage3D)
1626        && FindProcShort (glCopyTexSubImage3D);
1627   if (!has12)
1628   {
1629     checkWrongVersion (1, 2, aLastFailedProc);
1630   }
1631
1632   // load OpenGL 1.3 new functions
1633   has13 = IsGlGreaterEqual (1, 3)
1634        && FindProcShort (glActiveTexture)
1635        && FindProcShort (glSampleCoverage)
1636        && FindProcShort (glCompressedTexImage3D)
1637        && FindProcShort (glCompressedTexImage2D)
1638        && FindProcShort (glCompressedTexImage1D)
1639        && FindProcShort (glCompressedTexSubImage3D)
1640        && FindProcShort (glCompressedTexSubImage2D)
1641        && FindProcShort (glCompressedTexSubImage1D)
1642        && FindProcShort (glGetCompressedTexImage);
1643
1644   if (!isCoreProfile)
1645   {
1646     has13 = has13
1647        && FindProcShort (glClientActiveTexture)
1648        && FindProcShort (glMultiTexCoord1d)
1649        && FindProcShort (glMultiTexCoord1dv)
1650        && FindProcShort (glMultiTexCoord1f)
1651        && FindProcShort (glMultiTexCoord1fv)
1652        && FindProcShort (glMultiTexCoord1i)
1653        && FindProcShort (glMultiTexCoord1iv)
1654        && FindProcShort (glMultiTexCoord1s)
1655        && FindProcShort (glMultiTexCoord1sv)
1656        && FindProcShort (glMultiTexCoord2d)
1657        && FindProcShort (glMultiTexCoord2dv)
1658        && FindProcShort (glMultiTexCoord2f)
1659        && FindProcShort (glMultiTexCoord2fv)
1660        && FindProcShort (glMultiTexCoord2i)
1661        && FindProcShort (glMultiTexCoord2iv)
1662        && FindProcShort (glMultiTexCoord2s)
1663        && FindProcShort (glMultiTexCoord2sv)
1664        && FindProcShort (glMultiTexCoord3d)
1665        && FindProcShort (glMultiTexCoord3dv)
1666        && FindProcShort (glMultiTexCoord3f)
1667        && FindProcShort (glMultiTexCoord3fv)
1668        && FindProcShort (glMultiTexCoord3i)
1669        && FindProcShort (glMultiTexCoord3iv)
1670        && FindProcShort (glMultiTexCoord3s)
1671        && FindProcShort (glMultiTexCoord3sv)
1672        && FindProcShort (glMultiTexCoord4d)
1673        && FindProcShort (glMultiTexCoord4dv)
1674        && FindProcShort (glMultiTexCoord4f)
1675        && FindProcShort (glMultiTexCoord4fv)
1676        && FindProcShort (glMultiTexCoord4i)
1677        && FindProcShort (glMultiTexCoord4iv)
1678        && FindProcShort (glMultiTexCoord4s)
1679        && FindProcShort (glMultiTexCoord4sv)
1680        && FindProcShort (glLoadTransposeMatrixf)
1681        && FindProcShort (glLoadTransposeMatrixd)
1682        && FindProcShort (glMultTransposeMatrixf)
1683        && FindProcShort (glMultTransposeMatrixd);
1684   }
1685   if (!has13)
1686   {
1687     checkWrongVersion (1, 3, aLastFailedProc);
1688   }
1689
1690   // load OpenGL 1.4 new functions
1691   has14 = IsGlGreaterEqual (1, 4)
1692        && FindProcShort (glBlendFuncSeparate)
1693        && FindProcShort (glMultiDrawArrays)
1694        && FindProcShort (glMultiDrawElements)
1695        && FindProcShort (glPointParameterf)
1696        && FindProcShort (glPointParameterfv)
1697        && FindProcShort (glPointParameteri)
1698        && FindProcShort (glPointParameteriv);
1699   if (!has14)
1700   {
1701     checkWrongVersion (1, 4, aLastFailedProc);
1702   }
1703
1704   // load OpenGL 1.5 new functions
1705   has15 = IsGlGreaterEqual (1, 5)
1706        && FindProcShort (glGenQueries)
1707        && FindProcShort (glDeleteQueries)
1708        && FindProcShort (glIsQuery)
1709        && FindProcShort (glBeginQuery)
1710        && FindProcShort (glEndQuery)
1711        && FindProcShort (glGetQueryiv)
1712        && FindProcShort (glGetQueryObjectiv)
1713        && FindProcShort (glGetQueryObjectuiv)
1714        && FindProcShort (glBindBuffer)
1715        && FindProcShort (glDeleteBuffers)
1716        && FindProcShort (glGenBuffers)
1717        && FindProcShort (glIsBuffer)
1718        && FindProcShort (glBufferData)
1719        && FindProcShort (glBufferSubData)
1720        && FindProcShort (glGetBufferSubData)
1721        && FindProcShort (glMapBuffer)
1722        && FindProcShort (glUnmapBuffer)
1723        && FindProcShort (glGetBufferParameteriv)
1724        && FindProcShort (glGetBufferPointerv);
1725   if (has15)
1726   {
1727     if (!isCoreProfile)
1728     {
1729       core15 = (OpenGl_GlCore15* )(&(*myFuncs));
1730     }
1731     core15fwd = (OpenGl_GlCore15Fwd* )(&(*myFuncs));
1732   }
1733   else
1734   {
1735     checkWrongVersion (1, 5, aLastFailedProc);
1736   }
1737
1738   // load OpenGL 2.0 new functions
1739   has20 = IsGlGreaterEqual (2, 0)
1740        && FindProcShort (glBlendEquationSeparate)
1741        && FindProcShort (glDrawBuffers)
1742        && FindProcShort (glStencilOpSeparate)
1743        && FindProcShort (glStencilFuncSeparate)
1744        && FindProcShort (glStencilMaskSeparate)
1745        && FindProcShort (glAttachShader)
1746        && FindProcShort (glBindAttribLocation)
1747        && FindProcShort (glCompileShader)
1748        && FindProcShort (glCreateProgram)
1749        && FindProcShort (glCreateShader)
1750        && FindProcShort (glDeleteProgram)
1751        && FindProcShort (glDeleteShader)
1752        && FindProcShort (glDetachShader)
1753        && FindProcShort (glDisableVertexAttribArray)
1754        && FindProcShort (glEnableVertexAttribArray)
1755        && FindProcShort (glGetActiveAttrib)
1756        && FindProcShort (glGetActiveUniform)
1757        && FindProcShort (glGetAttachedShaders)
1758        && FindProcShort (glGetAttribLocation)
1759        && FindProcShort (glGetProgramiv)
1760        && FindProcShort (glGetProgramInfoLog)
1761        && FindProcShort (glGetShaderiv)
1762        && FindProcShort (glGetShaderInfoLog)
1763        && FindProcShort (glGetShaderSource)
1764        && FindProcShort (glGetUniformLocation)
1765        && FindProcShort (glGetUniformfv)
1766        && FindProcShort (glGetUniformiv)
1767        && FindProcShort (glGetVertexAttribdv)
1768        && FindProcShort (glGetVertexAttribfv)
1769        && FindProcShort (glGetVertexAttribiv)
1770        && FindProcShort (glGetVertexAttribPointerv)
1771        && FindProcShort (glIsProgram)
1772        && FindProcShort (glIsShader)
1773        && FindProcShort (glLinkProgram)
1774        && FindProcShort (glShaderSource)
1775        && FindProcShort (glUseProgram)
1776        && FindProcShort (glUniform1f)
1777        && FindProcShort (glUniform2f)
1778        && FindProcShort (glUniform3f)
1779        && FindProcShort (glUniform4f)
1780        && FindProcShort (glUniform1i)
1781        && FindProcShort (glUniform2i)
1782        && FindProcShort (glUniform3i)
1783        && FindProcShort (glUniform4i)
1784        && FindProcShort (glUniform1fv)
1785        && FindProcShort (glUniform2fv)
1786        && FindProcShort (glUniform3fv)
1787        && FindProcShort (glUniform4fv)
1788        && FindProcShort (glUniform1iv)
1789        && FindProcShort (glUniform2iv)
1790        && FindProcShort (glUniform3iv)
1791        && FindProcShort (glUniform4iv)
1792        && FindProcShort (glUniformMatrix2fv)
1793        && FindProcShort (glUniformMatrix3fv)
1794        && FindProcShort (glUniformMatrix4fv)
1795        && FindProcShort (glValidateProgram)
1796        && FindProcShort (glVertexAttrib1d)
1797        && FindProcShort (glVertexAttrib1dv)
1798        && FindProcShort (glVertexAttrib1f)
1799        && FindProcShort (glVertexAttrib1fv)
1800        && FindProcShort (glVertexAttrib1s)
1801        && FindProcShort (glVertexAttrib1sv)
1802        && FindProcShort (glVertexAttrib2d)
1803        && FindProcShort (glVertexAttrib2dv)
1804        && FindProcShort (glVertexAttrib2f)
1805        && FindProcShort (glVertexAttrib2fv)
1806        && FindProcShort (glVertexAttrib2s)
1807        && FindProcShort (glVertexAttrib2sv)
1808        && FindProcShort (glVertexAttrib3d)
1809        && FindProcShort (glVertexAttrib3dv)
1810        && FindProcShort (glVertexAttrib3f)
1811        && FindProcShort (glVertexAttrib3fv)
1812        && FindProcShort (glVertexAttrib3s)
1813        && FindProcShort (glVertexAttrib3sv)
1814        && FindProcShort (glVertexAttrib4Nbv)
1815        && FindProcShort (glVertexAttrib4Niv)
1816        && FindProcShort (glVertexAttrib4Nsv)
1817        && FindProcShort (glVertexAttrib4Nub)
1818        && FindProcShort (glVertexAttrib4Nubv)
1819        && FindProcShort (glVertexAttrib4Nuiv)
1820        && FindProcShort (glVertexAttrib4Nusv)
1821        && FindProcShort (glVertexAttrib4bv)
1822        && FindProcShort (glVertexAttrib4d)
1823        && FindProcShort (glVertexAttrib4dv)
1824        && FindProcShort (glVertexAttrib4f)
1825        && FindProcShort (glVertexAttrib4fv)
1826        && FindProcShort (glVertexAttrib4iv)
1827        && FindProcShort (glVertexAttrib4s)
1828        && FindProcShort (glVertexAttrib4sv)
1829        && FindProcShort (glVertexAttrib4ubv)
1830        && FindProcShort (glVertexAttrib4uiv)
1831        && FindProcShort (glVertexAttrib4usv)
1832        && FindProcShort (glVertexAttribPointer);
1833   if (has20)
1834   {
1835     const char* aGlslVer = (const char* )::glGetString (GL_SHADING_LANGUAGE_VERSION);
1836     if (aGlslVer == NULL
1837     || *aGlslVer == '\0')
1838     {
1839       // broken context has been detected
1840       PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
1841                    TCollection_AsciiString("Error! OpenGL context reports version ")
1842                    + myGlVerMajor  + "." + myGlVerMinor + " but reports wrong GLSL version");
1843       myGlVerMajor = 1;
1844       myGlVerMinor = 5;
1845     }
1846     else
1847     {
1848       if (!isCoreProfile)
1849       {
1850         core20  = (OpenGl_GlCore20*    )(&(*myFuncs));
1851       }
1852       core20fwd = (OpenGl_GlCore20Fwd* )(&(*myFuncs));
1853     }
1854   }
1855   else
1856   {
1857     checkWrongVersion (2, 0, aLastFailedProc);
1858   }
1859
1860   // load OpenGL 2.1 new functions
1861   has21 = IsGlGreaterEqual (2, 1)
1862        && FindProcShort (glUniformMatrix2x3fv)
1863        && FindProcShort (glUniformMatrix3x2fv)
1864        && FindProcShort (glUniformMatrix2x4fv)
1865        && FindProcShort (glUniformMatrix4x2fv)
1866        && FindProcShort (glUniformMatrix3x4fv)
1867        && FindProcShort (glUniformMatrix4x3fv);
1868   if (!has21)
1869   {
1870     checkWrongVersion (2, 1, aLastFailedProc);
1871   }
1872
1873   // load GL_ARB_framebuffer_object (added to OpenGL 3.0 core)
1874   const bool hasFBO = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_framebuffer_object"))
1875        && FindProcShort (glIsRenderbuffer)
1876        && FindProcShort (glBindRenderbuffer)
1877        && FindProcShort (glDeleteRenderbuffers)
1878        && FindProcShort (glGenRenderbuffers)
1879        && FindProcShort (glRenderbufferStorage)
1880        && FindProcShort (glGetRenderbufferParameteriv)
1881        && FindProcShort (glIsFramebuffer)
1882        && FindProcShort (glBindFramebuffer)
1883        && FindProcShort (glDeleteFramebuffers)
1884        && FindProcShort (glGenFramebuffers)
1885        && FindProcShort (glCheckFramebufferStatus)
1886        && FindProcShort (glFramebufferTexture1D)
1887        && FindProcShort (glFramebufferTexture2D)
1888        && FindProcShort (glFramebufferTexture3D)
1889        && FindProcShort (glFramebufferRenderbuffer)
1890        && FindProcShort (glGetFramebufferAttachmentParameteriv)
1891        && FindProcShort (glGenerateMipmap)
1892        && FindProcShort (glBlitFramebuffer)
1893        && FindProcShort (glRenderbufferStorageMultisample)
1894        && FindProcShort (glFramebufferTextureLayer);
1895
1896   // load GL_ARB_vertex_array_object (added to OpenGL 3.0 core)
1897   const bool hasVAO = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_vertex_array_object"))
1898        && FindProcShort (glBindVertexArray)
1899        && FindProcShort (glDeleteVertexArrays)
1900        && FindProcShort (glGenVertexArrays)
1901        && FindProcShort (glIsVertexArray);
1902
1903   // load GL_ARB_map_buffer_range (added to OpenGL 3.0 core)
1904   const bool hasMapBufferRange = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_map_buffer_range"))
1905        && FindProcShort (glMapBufferRange)
1906        && FindProcShort (glFlushMappedBufferRange);
1907
1908   // load OpenGL 3.0 new functions
1909   has30 = IsGlGreaterEqual (3, 0)
1910        && hasFBO
1911        && hasVAO
1912        && hasMapBufferRange
1913        && FindProcShort (glColorMaski)
1914        && FindProcShort (glGetBooleani_v)
1915        && FindProcShort (glGetIntegeri_v)
1916        && FindProcShort (glEnablei)
1917        && FindProcShort (glDisablei)
1918        && FindProcShort (glIsEnabledi)
1919        && FindProcShort (glBeginTransformFeedback)
1920        && FindProcShort (glEndTransformFeedback)
1921        && FindProcShort (glBindBufferRange)
1922        && FindProcShort (glBindBufferBase)
1923        && FindProcShort (glTransformFeedbackVaryings)
1924        && FindProcShort (glGetTransformFeedbackVarying)
1925        && FindProcShort (glClampColor)
1926        && FindProcShort (glBeginConditionalRender)
1927        && FindProcShort (glEndConditionalRender)
1928        && FindProcShort (glVertexAttribIPointer)
1929        && FindProcShort (glGetVertexAttribIiv)
1930        && FindProcShort (glGetVertexAttribIuiv)
1931        && FindProcShort (glVertexAttribI1i)
1932        && FindProcShort (glVertexAttribI2i)
1933        && FindProcShort (glVertexAttribI3i)
1934        && FindProcShort (glVertexAttribI4i)
1935        && FindProcShort (glVertexAttribI1ui)
1936        && FindProcShort (glVertexAttribI2ui)
1937        && FindProcShort (glVertexAttribI3ui)
1938        && FindProcShort (glVertexAttribI4ui)
1939        && FindProcShort (glVertexAttribI1iv)
1940        && FindProcShort (glVertexAttribI2iv)
1941        && FindProcShort (glVertexAttribI3iv)
1942        && FindProcShort (glVertexAttribI4iv)
1943        && FindProcShort (glVertexAttribI1uiv)
1944        && FindProcShort (glVertexAttribI2uiv)
1945        && FindProcShort (glVertexAttribI3uiv)
1946        && FindProcShort (glVertexAttribI4uiv)
1947        && FindProcShort (glVertexAttribI4bv)
1948        && FindProcShort (glVertexAttribI4sv)
1949        && FindProcShort (glVertexAttribI4ubv)
1950        && FindProcShort (glVertexAttribI4usv)
1951        && FindProcShort (glGetUniformuiv)
1952        && FindProcShort (glBindFragDataLocation)
1953        && FindProcShort (glGetFragDataLocation)
1954        && FindProcShort (glUniform1ui)
1955        && FindProcShort (glUniform2ui)
1956        && FindProcShort (glUniform3ui)
1957        && FindProcShort (glUniform4ui)
1958        && FindProcShort (glUniform1uiv)
1959        && FindProcShort (glUniform2uiv)
1960        && FindProcShort (glUniform3uiv)
1961        && FindProcShort (glUniform4uiv)
1962        && FindProcShort (glTexParameterIiv)
1963        && FindProcShort (glTexParameterIuiv)
1964        && FindProcShort (glGetTexParameterIiv)
1965        && FindProcShort (glGetTexParameterIuiv)
1966        && FindProcShort (glClearBufferiv)
1967        && FindProcShort (glClearBufferuiv)
1968        && FindProcShort (glClearBufferfv)
1969        && FindProcShort (glClearBufferfi)
1970        && FindProcShort (glGetStringi);
1971   if (!has30)
1972   {
1973     checkWrongVersion (3, 0, aLastFailedProc);
1974   }
1975
1976   // load GL_ARB_uniform_buffer_object (added to OpenGL 3.1 core)
1977   const bool hasUBO = (IsGlGreaterEqual (3, 1) || CheckExtension ("GL_ARB_uniform_buffer_object"))
1978        && FindProcShort (glGetUniformIndices)
1979        && FindProcShort (glGetActiveUniformsiv)
1980        && FindProcShort (glGetActiveUniformName)
1981        && FindProcShort (glGetUniformBlockIndex)
1982        && FindProcShort (glGetActiveUniformBlockiv)
1983        && FindProcShort (glGetActiveUniformBlockName)
1984        && FindProcShort (glUniformBlockBinding);
1985
1986   // load GL_ARB_copy_buffer (added to OpenGL 3.1 core)
1987   const bool hasCopyBufSubData = (IsGlGreaterEqual (3, 1) || CheckExtension ("GL_ARB_copy_buffer"))
1988        && FindProcShort (glCopyBufferSubData);
1989
1990   if (has30)
1991   {
1992     // NPOT textures are required by OpenGL 2.0 specifications
1993     // but doesn't hardware accelerated by some ancient OpenGL 2.1 hardware (GeForce FX, RadeOn 9700 etc.)
1994     arbNPTW  = Standard_True;
1995     arbTexRG = Standard_True;
1996   }
1997
1998   // load OpenGL 3.1 new functions
1999   has31 = IsGlGreaterEqual (3, 1)
2000        && hasUBO
2001        && hasCopyBufSubData
2002        && FindProcShort (glDrawArraysInstanced)
2003        && FindProcShort (glDrawElementsInstanced)
2004        && FindProcShort (glTexBuffer)
2005        && FindProcShort (glPrimitiveRestartIndex);
2006   if (has31)
2007   {
2008     arbTBO = (OpenGl_ArbTBO* )(&(*myFuncs));
2009     arbIns = (OpenGl_ArbIns* )(&(*myFuncs));
2010   }
2011   else
2012   {
2013     checkWrongVersion (3, 1, aLastFailedProc);
2014
2015     // initialize TBO extension (ARB)
2016     if (CheckExtension ("GL_ARB_texture_buffer_object")
2017      && FindProc ("glTexBufferARB", myFuncs->glTexBuffer))
2018     {
2019       arbTBO = (OpenGl_ArbTBO* )(&(*myFuncs));
2020     }
2021
2022     // initialize hardware instancing extension (ARB)
2023     if (CheckExtension ("GL_ARB_draw_instanced")
2024      && FindProc ("glDrawArraysInstancedARB",   myFuncs->glDrawArraysInstanced)
2025      && FindProc ("glDrawElementsInstancedARB", myFuncs->glDrawElementsInstanced))
2026     {
2027       arbIns = (OpenGl_ArbIns* )(&(*myFuncs));
2028     }
2029   }
2030
2031   arbTboRGB32 = CheckExtension ("GL_ARB_texture_buffer_object_rgb32");
2032
2033   // load GL_ARB_draw_elements_base_vertex (added to OpenGL 3.2 core)
2034   const bool hasDrawElemsBaseVert = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_draw_elements_base_vertex"))
2035        && FindProcShort (glDrawElementsBaseVertex)
2036        && FindProcShort (glDrawRangeElementsBaseVertex)
2037        && FindProcShort (glDrawElementsInstancedBaseVertex)
2038        && FindProcShort (glMultiDrawElementsBaseVertex);
2039
2040   // load GL_ARB_provoking_vertex (added to OpenGL 3.2 core)
2041   const bool hasProvokingVert = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_provoking_vertex"))
2042        && FindProcShort (glProvokingVertex);
2043
2044   // load GL_ARB_sync (added to OpenGL 3.2 core)
2045   const bool hasSync = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_sync"))
2046        && FindProcShort (glFenceSync)
2047        && FindProcShort (glIsSync)
2048        && FindProcShort (glDeleteSync)
2049        && FindProcShort (glClientWaitSync)
2050        && FindProcShort (glWaitSync)
2051        && FindProcShort (glGetInteger64v)
2052        && FindProcShort (glGetSynciv);
2053
2054   // load GL_ARB_texture_multisample (added to OpenGL 3.2 core)
2055   const bool hasTextureMultisample = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_texture_multisample"))
2056        && FindProcShort (glTexImage2DMultisample)
2057        && FindProcShort (glTexImage3DMultisample)
2058        && FindProcShort (glGetMultisamplefv)
2059        && FindProcShort (glSampleMaski);
2060
2061   // load OpenGL 3.2 new functions
2062   has32 = IsGlGreaterEqual (3, 2)
2063        && hasDrawElemsBaseVert
2064        && hasProvokingVert
2065        && hasSync
2066        && hasTextureMultisample
2067        && FindProcShort (glGetInteger64i_v)
2068        && FindProcShort (glGetBufferParameteri64v)
2069        && FindProcShort (glFramebufferTexture);
2070   if (has32)
2071   {
2072     core32 = (OpenGl_GlCore32* )(&(*myFuncs));
2073     if (isCoreProfile)
2074     {
2075       core32->glGenVertexArrays (1, &myDefaultVao);
2076     }
2077     else
2078     {
2079       core32back = (OpenGl_GlCore32Back* )(&(*myFuncs));
2080     }
2081     ::glGetIntegerv (GL_MAX_SAMPLES, &myMaxMsaaSamples);
2082   }
2083   else
2084   {
2085     checkWrongVersion (3, 2, aLastFailedProc);
2086   }
2087
2088   // load GL_ARB_blend_func_extended (added to OpenGL 3.3 core)
2089   const bool hasBlendFuncExtended = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_blend_func_extended"))
2090        && FindProcShort (glBindFragDataLocationIndexed)
2091        && FindProcShort (glGetFragDataIndex);
2092
2093   // load GL_ARB_sampler_objects (added to OpenGL 3.3 core)
2094   const bool hasSamplerObjects = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_sampler_objects"))
2095        && FindProcShort (glGenSamplers)
2096        && FindProcShort (glDeleteSamplers)
2097        && FindProcShort (glIsSampler)
2098        && FindProcShort (glBindSampler)
2099        && FindProcShort (glSamplerParameteri)
2100        && FindProcShort (glSamplerParameteriv)
2101        && FindProcShort (glSamplerParameterf)
2102        && FindProcShort (glSamplerParameterfv)
2103        && FindProcShort (glSamplerParameterIiv)
2104        && FindProcShort (glSamplerParameterIuiv)
2105        && FindProcShort (glGetSamplerParameteriv)
2106        && FindProcShort (glGetSamplerParameterIiv)
2107        && FindProcShort (glGetSamplerParameterfv)
2108        && FindProcShort (glGetSamplerParameterIuiv);
2109   if (hasSamplerObjects)
2110   {
2111     arbSamplerObject = (OpenGl_ArbSamplerObject* )(&(*myFuncs));
2112   }
2113
2114   // load GL_ARB_timer_query (added to OpenGL 3.3 core)
2115   const bool hasTimerQuery = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_timer_query"))
2116        && FindProcShort (glQueryCounter)
2117        && FindProcShort (glGetQueryObjecti64v)
2118        && FindProcShort (glGetQueryObjectui64v);
2119
2120   // load GL_ARB_vertex_type_2_10_10_10_rev (added to OpenGL 3.3 core)
2121   const bool hasVertType21010101rev = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_vertex_type_2_10_10_10_rev"))
2122        && FindProcShort (glVertexAttribP1ui)
2123        && FindProcShort (glVertexAttribP1uiv)
2124        && FindProcShort (glVertexAttribP2ui)
2125        && FindProcShort (glVertexAttribP2uiv)
2126        && FindProcShort (glVertexAttribP3ui)
2127        && FindProcShort (glVertexAttribP3uiv)
2128        && FindProcShort (glVertexAttribP4ui)
2129        && FindProcShort (glVertexAttribP4uiv);
2130
2131   if ( hasVertType21010101rev
2132    && !isCoreProfile)
2133   {
2134     // load deprecated functions
2135     const bool hasVertType21010101revExt =
2136           FindProcShort (glVertexP2ui)
2137        && FindProcShort (glVertexP2uiv)
2138        && FindProcShort (glVertexP3ui)
2139        && FindProcShort (glVertexP3uiv)
2140        && FindProcShort (glVertexP4ui)
2141        && FindProcShort (glVertexP4uiv)
2142        && FindProcShort (glTexCoordP1ui)
2143        && FindProcShort (glTexCoordP1uiv)
2144        && FindProcShort (glTexCoordP2ui)
2145        && FindProcShort (glTexCoordP2uiv)
2146        && FindProcShort (glTexCoordP3ui)
2147        && FindProcShort (glTexCoordP3uiv)
2148        && FindProcShort (glTexCoordP4ui)
2149        && FindProcShort (glTexCoordP4uiv)
2150        && FindProcShort (glMultiTexCoordP1ui)
2151        && FindProcShort (glMultiTexCoordP1uiv)
2152        && FindProcShort (glMultiTexCoordP2ui)
2153        && FindProcShort (glMultiTexCoordP2uiv)
2154        && FindProcShort (glMultiTexCoordP3ui)
2155        && FindProcShort (glMultiTexCoordP3uiv)
2156        && FindProcShort (glMultiTexCoordP4ui)
2157        && FindProcShort (glMultiTexCoordP4uiv)
2158        && FindProcShort (glNormalP3ui)
2159        && FindProcShort (glNormalP3uiv)
2160        && FindProcShort (glColorP3ui)
2161        && FindProcShort (glColorP3uiv)
2162        && FindProcShort (glColorP4ui)
2163        && FindProcShort (glColorP4uiv)
2164        && FindProcShort (glSecondaryColorP3ui)
2165        && FindProcShort (glSecondaryColorP3uiv);
2166     (void )hasVertType21010101revExt;
2167   }
2168
2169   // load OpenGL 3.3 extra functions
2170   has33 = IsGlGreaterEqual (3, 3)
2171        && hasBlendFuncExtended
2172        && hasSamplerObjects
2173        && hasTimerQuery
2174        && hasVertType21010101rev
2175        && FindProcShort (glVertexAttribDivisor);
2176   if (has33)
2177   {
2178     core33 = (OpenGl_GlCore33* )(&(*myFuncs));
2179     if (!isCoreProfile)
2180     {
2181       core33back = (OpenGl_GlCore33Back* )(&(*myFuncs));
2182     }
2183   }
2184   else
2185   {
2186     checkWrongVersion (3, 3, aLastFailedProc);
2187   }
2188
2189   // load GL_ARB_draw_indirect (added to OpenGL 4.0 core)
2190   const bool hasDrawIndirect = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_draw_indirect"))
2191        && FindProcShort (glDrawArraysIndirect)
2192        && FindProcShort (glDrawElementsIndirect);
2193
2194   // load GL_ARB_gpu_shader_fp64 (added to OpenGL 4.0 core)
2195   const bool hasShaderFP64 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_gpu_shader_fp64"))
2196        && FindProcShort (glUniform1d)
2197        && FindProcShort (glUniform2d)
2198        && FindProcShort (glUniform3d)
2199        && FindProcShort (glUniform4d)
2200        && FindProcShort (glUniform1dv)
2201        && FindProcShort (glUniform2dv)
2202        && FindProcShort (glUniform3dv)
2203        && FindProcShort (glUniform4dv)
2204        && FindProcShort (glUniformMatrix2dv)
2205        && FindProcShort (glUniformMatrix3dv)
2206        && FindProcShort (glUniformMatrix4dv)
2207        && FindProcShort (glUniformMatrix2x3dv)
2208        && FindProcShort (glUniformMatrix2x4dv)
2209        && FindProcShort (glUniformMatrix3x2dv)
2210        && FindProcShort (glUniformMatrix3x4dv)
2211        && FindProcShort (glUniformMatrix4x2dv)
2212        && FindProcShort (glUniformMatrix4x3dv)
2213        && FindProcShort (glGetUniformdv);
2214
2215   // load GL_ARB_shader_subroutine (added to OpenGL 4.0 core)
2216   const bool hasShaderSubroutine = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_shader_subroutine"))
2217        && FindProcShort (glGetSubroutineUniformLocation)
2218        && FindProcShort (glGetSubroutineIndex)
2219        && FindProcShort (glGetActiveSubroutineUniformiv)
2220        && FindProcShort (glGetActiveSubroutineUniformName)
2221        && FindProcShort (glGetActiveSubroutineName)
2222        && FindProcShort (glUniformSubroutinesuiv)
2223        && FindProcShort (glGetUniformSubroutineuiv)
2224        && FindProcShort (glGetProgramStageiv);
2225
2226   // load GL_ARB_tessellation_shader (added to OpenGL 4.0 core)
2227   const bool hasTessellationShader = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_tessellation_shader"))
2228        && FindProcShort (glPatchParameteri)
2229        && FindProcShort (glPatchParameterfv);
2230
2231   // load GL_ARB_transform_feedback2 (added to OpenGL 4.0 core)
2232   const bool hasTrsfFeedback2 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_transform_feedback2"))
2233        && FindProcShort (glBindTransformFeedback)
2234        && FindProcShort (glDeleteTransformFeedbacks)
2235        && FindProcShort (glGenTransformFeedbacks)
2236        && FindProcShort (glIsTransformFeedback)
2237        && FindProcShort (glPauseTransformFeedback)
2238        && FindProcShort (glResumeTransformFeedback)
2239        && FindProcShort (glDrawTransformFeedback);
2240
2241   // load GL_ARB_transform_feedback3 (added to OpenGL 4.0 core)
2242   const bool hasTrsfFeedback3 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_transform_feedback3"))
2243        && FindProcShort (glDrawTransformFeedbackStream)
2244        && FindProcShort (glBeginQueryIndexed)
2245        && FindProcShort (glEndQueryIndexed)
2246        && FindProcShort (glGetQueryIndexediv);
2247
2248   // load OpenGL 4.0 new functions
2249   has40 = IsGlGreaterEqual (4, 0)
2250       && hasDrawIndirect
2251       && hasShaderFP64
2252       && hasShaderSubroutine
2253       && hasTessellationShader
2254       && hasTrsfFeedback2
2255       && hasTrsfFeedback3
2256       && FindProcShort (glMinSampleShading)
2257       && FindProcShort (glBlendEquationi)
2258       && FindProcShort (glBlendEquationSeparatei)
2259       && FindProcShort (glBlendFunci)
2260       && FindProcShort (glBlendFuncSeparatei);
2261   if (has40)
2262   {
2263     arbTboRGB32 = Standard_True; // in core since OpenGL 4.0
2264   }
2265   else
2266   {
2267     checkWrongVersion (4, 0, aLastFailedProc);
2268   }
2269
2270   // load GL_ARB_ES2_compatibility (added to OpenGL 4.1 core)
2271   const bool hasES2Compatibility = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_ES2_compatibility"))
2272        && FindProcShort (glReleaseShaderCompiler)
2273        && FindProcShort (glShaderBinary)
2274        && FindProcShort (glGetShaderPrecisionFormat)
2275        && FindProcShort (glDepthRangef)
2276        && FindProcShort (glClearDepthf);
2277
2278   // load GL_ARB_get_program_binary (added to OpenGL 4.1 core)
2279   const bool hasGetProgramBinary = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_get_program_binary"))
2280        && FindProcShort (glGetProgramBinary)
2281        && FindProcShort (glProgramBinary)
2282        && FindProcShort (glProgramParameteri);
2283
2284
2285   // load GL_ARB_separate_shader_objects (added to OpenGL 4.1 core)
2286   const bool hasSeparateShaderObjects = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_separate_shader_objects"))
2287        && FindProcShort (glUseProgramStages)
2288        && FindProcShort (glActiveShaderProgram)
2289        && FindProcShort (glCreateShaderProgramv)
2290        && FindProcShort (glBindProgramPipeline)
2291        && FindProcShort (glDeleteProgramPipelines)
2292        && FindProcShort (glGenProgramPipelines)
2293        && FindProcShort (glIsProgramPipeline)
2294        && FindProcShort (glGetProgramPipelineiv)
2295        && FindProcShort (glProgramUniform1i)
2296        && FindProcShort (glProgramUniform1iv)
2297        && FindProcShort (glProgramUniform1f)
2298        && FindProcShort (glProgramUniform1fv)
2299        && FindProcShort (glProgramUniform1d)
2300        && FindProcShort (glProgramUniform1dv)
2301        && FindProcShort (glProgramUniform1ui)
2302        && FindProcShort (glProgramUniform1uiv)
2303        && FindProcShort (glProgramUniform2i)
2304        && FindProcShort (glProgramUniform2iv)
2305        && FindProcShort (glProgramUniform2f)
2306        && FindProcShort (glProgramUniform2fv)
2307        && FindProcShort (glProgramUniform2d)
2308        && FindProcShort (glProgramUniform2dv)
2309        && FindProcShort (glProgramUniform2ui)
2310        && FindProcShort (glProgramUniform2uiv)
2311        && FindProcShort (glProgramUniform3i)
2312        && FindProcShort (glProgramUniform3iv)
2313        && FindProcShort (glProgramUniform3f)
2314        && FindProcShort (glProgramUniform3fv)
2315        && FindProcShort (glProgramUniform3d)
2316        && FindProcShort (glProgramUniform3dv)
2317        && FindProcShort (glProgramUniform3ui)
2318        && FindProcShort (glProgramUniform3uiv)
2319        && FindProcShort (glProgramUniform4i)
2320        && FindProcShort (glProgramUniform4iv)
2321        && FindProcShort (glProgramUniform4f)
2322        && FindProcShort (glProgramUniform4fv)
2323        && FindProcShort (glProgramUniform4d)
2324        && FindProcShort (glProgramUniform4dv)
2325        && FindProcShort (glProgramUniform4ui)
2326        && FindProcShort (glProgramUniform4uiv)
2327        && FindProcShort (glProgramUniformMatrix2fv)
2328        && FindProcShort (glProgramUniformMatrix3fv)
2329        && FindProcShort (glProgramUniformMatrix4fv)
2330        && FindProcShort (glProgramUniformMatrix2dv)
2331        && FindProcShort (glProgramUniformMatrix3dv)
2332        && FindProcShort (glProgramUniformMatrix4dv)
2333        && FindProcShort (glProgramUniformMatrix2x3fv)
2334        && FindProcShort (glProgramUniformMatrix3x2fv)
2335        && FindProcShort (glProgramUniformMatrix2x4fv)
2336        && FindProcShort (glProgramUniformMatrix4x2fv)
2337        && FindProcShort (glProgramUniformMatrix3x4fv)
2338        && FindProcShort (glProgramUniformMatrix4x3fv)
2339        && FindProcShort (glProgramUniformMatrix2x3dv)
2340        && FindProcShort (glProgramUniformMatrix3x2dv)
2341        && FindProcShort (glProgramUniformMatrix2x4dv)
2342        && FindProcShort (glProgramUniformMatrix4x2dv)
2343        && FindProcShort (glProgramUniformMatrix3x4dv)
2344        && FindProcShort (glProgramUniformMatrix4x3dv)
2345        && FindProcShort (glValidateProgramPipeline)
2346        && FindProcShort (glGetProgramPipelineInfoLog);
2347
2348   // load GL_ARB_vertex_attrib_64bit (added to OpenGL 4.1 core)
2349   const bool hasVertAttrib64bit = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_vertex_attrib_64bit"))
2350        && FindProcShort (glVertexAttribL1d)
2351        && FindProcShort (glVertexAttribL2d)
2352        && FindProcShort (glVertexAttribL3d)
2353        && FindProcShort (glVertexAttribL4d)
2354        && FindProcShort (glVertexAttribL1dv)
2355        && FindProcShort (glVertexAttribL2dv)
2356        && FindProcShort (glVertexAttribL3dv)
2357        && FindProcShort (glVertexAttribL4dv)
2358        && FindProcShort (glVertexAttribLPointer)
2359        && FindProcShort (glGetVertexAttribLdv);
2360
2361   // load GL_ARB_viewport_array (added to OpenGL 4.1 core)
2362   const bool hasViewportArray = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_viewport_array"))
2363        && FindProcShort (glViewportArrayv)
2364        && FindProcShort (glViewportIndexedf)
2365        && FindProcShort (glViewportIndexedfv)
2366        && FindProcShort (glScissorArrayv)
2367        && FindProcShort (glScissorIndexed)
2368        && FindProcShort (glScissorIndexedv)
2369        && FindProcShort (glDepthRangeArrayv)
2370        && FindProcShort (glDepthRangeIndexed)
2371        && FindProcShort (glGetFloati_v)
2372        && FindProcShort (glGetDoublei_v);
2373
2374   has41 = IsGlGreaterEqual (4, 1)
2375        && hasES2Compatibility
2376        && hasGetProgramBinary
2377        && hasSeparateShaderObjects
2378        && hasVertAttrib64bit
2379        && hasViewportArray;
2380   if (has41)
2381   {
2382     core41 = (OpenGl_GlCore41* )(&(*myFuncs));
2383     if (!isCoreProfile)
2384     {
2385       core41back = (OpenGl_GlCore41Back* )(&(*myFuncs));
2386     }
2387   }
2388   else
2389   {
2390     checkWrongVersion (4, 1, aLastFailedProc);
2391   }
2392
2393   // load GL_ARB_base_instance (added to OpenGL 4.2 core)
2394   const bool hasBaseInstance = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_base_instance"))
2395        && FindProcShort (glDrawArraysInstancedBaseInstance)
2396        && FindProcShort (glDrawElementsInstancedBaseInstance)
2397        && FindProcShort (glDrawElementsInstancedBaseVertexBaseInstance);
2398
2399   // load GL_ARB_transform_feedback_instanced (added to OpenGL 4.2 core)
2400   const bool hasTrsfFeedbackInstanced = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_transform_feedback_instanced"))
2401        && FindProcShort (glDrawTransformFeedbackInstanced)
2402        && FindProcShort (glDrawTransformFeedbackStreamInstanced);
2403
2404   // load GL_ARB_internalformat_query (added to OpenGL 4.2 core)
2405   const bool hasInternalFormatQuery = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_internalformat_query"))
2406        && FindProcShort (glGetInternalformativ);
2407
2408   // load GL_ARB_shader_atomic_counters (added to OpenGL 4.2 core)
2409   const bool hasShaderAtomicCounters = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_shader_atomic_counters"))
2410        && FindProcShort (glGetActiveAtomicCounterBufferiv);
2411
2412   // load GL_ARB_shader_image_load_store (added to OpenGL 4.2 core)
2413   const bool hasShaderImgLoadStore = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_shader_image_load_store"))
2414        && FindProcShort (glBindImageTexture)
2415        && FindProcShort (glMemoryBarrier);
2416
2417   // load GL_ARB_texture_storage (added to OpenGL 4.2 core)
2418   const bool hasTextureStorage = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_texture_storage"))
2419        && FindProcShort (glTexStorage1D)
2420        && FindProcShort (glTexStorage2D)
2421        && FindProcShort (glTexStorage3D);
2422
2423   has42 = IsGlGreaterEqual (4, 2)
2424        && hasBaseInstance
2425        && hasTrsfFeedbackInstanced
2426        && hasInternalFormatQuery
2427        && hasShaderAtomicCounters
2428        && hasShaderImgLoadStore
2429        && hasTextureStorage;
2430   if (has42)
2431   {
2432     core42 = (OpenGl_GlCore42* )(&(*myFuncs));
2433     if (!isCoreProfile)
2434     {
2435       core42back = (OpenGl_GlCore42Back* )(&(*myFuncs));
2436     }
2437   }
2438   else
2439   {
2440     checkWrongVersion (4, 2, aLastFailedProc);
2441   }
2442
2443   has43 = IsGlGreaterEqual (4, 3)
2444        && FindProcShort (glClearBufferData)
2445        && FindProcShort (glClearBufferSubData)
2446        && FindProcShort (glDispatchCompute)
2447        && FindProcShort (glDispatchComputeIndirect)
2448        && FindProcShort (glCopyImageSubData)
2449        && FindProcShort (glFramebufferParameteri)
2450        && FindProcShort (glGetFramebufferParameteriv)
2451        && FindProcShort (glGetInternalformati64v)
2452        && FindProcShort (glInvalidateTexSubImage)
2453        && FindProcShort (glInvalidateTexImage)
2454        && FindProcShort (glInvalidateBufferSubData)
2455        && FindProcShort (glInvalidateBufferData)
2456        && FindProcShort (glInvalidateFramebuffer)
2457        && FindProcShort (glInvalidateSubFramebuffer)
2458        && FindProcShort (glMultiDrawArraysIndirect)
2459        && FindProcShort (glMultiDrawElementsIndirect)
2460        && FindProcShort (glGetProgramInterfaceiv)
2461        && FindProcShort (glGetProgramResourceIndex)
2462        && FindProcShort (glGetProgramResourceName)
2463        && FindProcShort (glGetProgramResourceiv)
2464        && FindProcShort (glGetProgramResourceLocation)
2465        && FindProcShort (glGetProgramResourceLocationIndex)
2466        && FindProcShort (glShaderStorageBlockBinding)
2467        && FindProcShort (glTexBufferRange)
2468        && FindProcShort (glTexStorage2DMultisample)
2469        && FindProcShort (glTexStorage3DMultisample)
2470        && FindProcShort (glTextureView)
2471        && FindProcShort (glBindVertexBuffer)
2472        && FindProcShort (glVertexAttribFormat)
2473        && FindProcShort (glVertexAttribIFormat)
2474        && FindProcShort (glVertexAttribLFormat)
2475        && FindProcShort (glVertexAttribBinding)
2476        && FindProcShort (glVertexBindingDivisor)
2477        && FindProcShort (glDebugMessageControl)
2478        && FindProcShort (glDebugMessageInsert)
2479        && FindProcShort (glDebugMessageCallback)
2480        && FindProcShort (glGetDebugMessageLog)
2481        && FindProcShort (glPushDebugGroup)
2482        && FindProcShort (glPopDebugGroup)
2483        && FindProcShort (glObjectLabel)
2484        && FindProcShort (glGetObjectLabel)
2485        && FindProcShort (glObjectPtrLabel)
2486        && FindProcShort (glGetObjectPtrLabel);
2487   if (has43)
2488   {
2489     core43 = (OpenGl_GlCore43* )(&(*myFuncs));
2490     if (!isCoreProfile)
2491     {
2492       core43back = (OpenGl_GlCore43Back* )(&(*myFuncs));
2493     }
2494   }
2495   else
2496   {
2497     checkWrongVersion (4, 3, aLastFailedProc);
2498   }
2499
2500   // load GL_ARB_clear_texture (added to OpenGL 4.4 core)
2501   bool arbTexClear = (IsGlGreaterEqual (4, 4) || CheckExtension ("GL_ARB_clear_texture"))
2502        && FindProcShort (glClearTexImage)
2503        && FindProcShort (glClearTexSubImage);
2504
2505   has44 = IsGlGreaterEqual (4, 4)
2506        && arbTexClear
2507        && FindProcShort (glBufferStorage)
2508        && FindProcShort (glBindBuffersBase)
2509        && FindProcShort (glBindBuffersRange)
2510        && FindProcShort (glBindTextures)
2511        && FindProcShort (glBindSamplers)
2512        && FindProcShort (glBindImageTextures)
2513        && FindProcShort (glBindVertexBuffers);
2514   if (has44)
2515   {
2516     core44 = (OpenGl_GlCore44* )(&(*myFuncs));
2517     if (!isCoreProfile)
2518     {
2519       core44back = (OpenGl_GlCore44Back* )(&(*myFuncs));
2520     }
2521   }
2522   else
2523   {
2524     checkWrongVersion (4, 4, aLastFailedProc);
2525   }
2526
2527   has45 = IsGlGreaterEqual (4, 5)
2528        && FindProcShort (glBindVertexBuffers)
2529        && FindProcShort (glClipControl)
2530        && FindProcShort (glCreateTransformFeedbacks)
2531        && FindProcShort (glTransformFeedbackBufferBase)
2532        && FindProcShort (glTransformFeedbackBufferRange)
2533        && FindProcShort (glGetTransformFeedbackiv)
2534        && FindProcShort (glGetTransformFeedbacki_v)
2535        && FindProcShort (glGetTransformFeedbacki64_v)
2536        && FindProcShort (glCreateBuffers)
2537        && FindProcShort (glNamedBufferStorage)
2538        && FindProcShort (glNamedBufferData)
2539        && FindProcShort (glNamedBufferSubData)
2540        && FindProcShort (glCopyNamedBufferSubData)
2541        && FindProcShort (glClearNamedBufferData)
2542        && FindProcShort (glClearNamedBufferSubData)
2543        && FindProcShort (glMapNamedBuffer)
2544        && FindProcShort (glMapNamedBufferRange)
2545        && FindProcShort (glUnmapNamedBuffer)
2546        && FindProcShort (glFlushMappedNamedBufferRange)
2547        && FindProcShort (glGetNamedBufferParameteriv)
2548        && FindProcShort (glGetNamedBufferParameteri64v)
2549        && FindProcShort (glGetNamedBufferPointerv)
2550        && FindProcShort (glGetNamedBufferSubData)
2551        && FindProcShort (glCreateFramebuffers)
2552        && FindProcShort (glNamedFramebufferRenderbuffer)
2553        && FindProcShort (glNamedFramebufferParameteri)
2554        && FindProcShort (glNamedFramebufferTexture)
2555        && FindProcShort (glNamedFramebufferTextureLayer)
2556        && FindProcShort (glNamedFramebufferDrawBuffer)
2557        && FindProcShort (glNamedFramebufferDrawBuffers)
2558        && FindProcShort (glNamedFramebufferReadBuffer)
2559        && FindProcShort (glInvalidateNamedFramebufferData)
2560        && FindProcShort (glInvalidateNamedFramebufferSubData)
2561        && FindProcShort (glClearNamedFramebufferiv)
2562        && FindProcShort (glClearNamedFramebufferuiv)
2563        && FindProcShort (glClearNamedFramebufferfv)
2564        && FindProcShort (glClearNamedFramebufferfi)
2565        && FindProcShort (glBlitNamedFramebuffer)
2566        && FindProcShort (glCheckNamedFramebufferStatus)
2567        && FindProcShort (glGetNamedFramebufferParameteriv)
2568        && FindProcShort (glGetNamedFramebufferAttachmentParameteriv)
2569        && FindProcShort (glCreateRenderbuffers)
2570        && FindProcShort (glNamedRenderbufferStorage)
2571        && FindProcShort (glNamedRenderbufferStorageMultisample)
2572        && FindProcShort (glGetNamedRenderbufferParameteriv)
2573        && FindProcShort (glCreateTextures)
2574        && FindProcShort (glTextureBuffer)
2575        && FindProcShort (glTextureBufferRange)
2576        && FindProcShort (glTextureStorage1D)
2577        && FindProcShort (glTextureStorage2D)
2578        && FindProcShort (glTextureStorage3D)
2579        && FindProcShort (glTextureStorage2DMultisample)
2580        && FindProcShort (glTextureStorage3DMultisample)
2581        && FindProcShort (glTextureSubImage1D)
2582        && FindProcShort (glTextureSubImage2D)
2583        && FindProcShort (glTextureSubImage3D)
2584        && FindProcShort (glCompressedTextureSubImage1D)
2585        && FindProcShort (glCompressedTextureSubImage2D)
2586        && FindProcShort (glCompressedTextureSubImage3D)
2587        && FindProcShort (glCopyTextureSubImage1D)
2588        && FindProcShort (glCopyTextureSubImage2D)
2589        && FindProcShort (glCopyTextureSubImage3D)
2590        && FindProcShort (glTextureParameterf)
2591        && FindProcShort (glTextureParameterfv)
2592        && FindProcShort (glTextureParameteri)
2593        && FindProcShort (glTextureParameterIiv)
2594        && FindProcShort (glTextureParameterIuiv)
2595        && FindProcShort (glTextureParameteriv)
2596        && FindProcShort (glGenerateTextureMipmap)
2597        && FindProcShort (glBindTextureUnit)
2598        && FindProcShort (glGetTextureImage)
2599        && FindProcShort (glGetCompressedTextureImage)
2600        && FindProcShort (glGetTextureLevelParameterfv)
2601        && FindProcShort (glGetTextureLevelParameteriv)
2602        && FindProcShort (glGetTextureParameterfv)
2603        && FindProcShort (glGetTextureParameterIiv)
2604        && FindProcShort (glGetTextureParameterIuiv)
2605        && FindProcShort (glGetTextureParameteriv)
2606        && FindProcShort (glCreateVertexArrays)
2607        && FindProcShort (glDisableVertexArrayAttrib)
2608        && FindProcShort (glEnableVertexArrayAttrib)
2609        && FindProcShort (glVertexArrayElementBuffer)
2610        && FindProcShort (glVertexArrayVertexBuffer)
2611        && FindProcShort (glVertexArrayVertexBuffers)
2612        && FindProcShort (glVertexArrayAttribBinding)
2613        && FindProcShort (glVertexArrayAttribFormat)
2614        && FindProcShort (glVertexArrayAttribIFormat)
2615        && FindProcShort (glVertexArrayAttribLFormat)
2616        && FindProcShort (glVertexArrayBindingDivisor)
2617        && FindProcShort (glGetVertexArrayiv)
2618        && FindProcShort (glGetVertexArrayIndexediv)
2619        && FindProcShort (glGetVertexArrayIndexed64iv)
2620        && FindProcShort (glCreateSamplers)
2621        && FindProcShort (glCreateProgramPipelines)
2622        && FindProcShort (glCreateQueries)
2623        && FindProcShort (glGetQueryBufferObjecti64v)
2624        && FindProcShort (glGetQueryBufferObjectiv)
2625        && FindProcShort (glGetQueryBufferObjectui64v)
2626        && FindProcShort (glGetQueryBufferObjectuiv)
2627        && FindProcShort (glMemoryBarrierByRegion)
2628        && FindProcShort (glGetTextureSubImage)
2629        && FindProcShort (glGetCompressedTextureSubImage)
2630        && FindProcShort (glGetGraphicsResetStatus)
2631        && FindProcShort (glGetnCompressedTexImage)
2632        && FindProcShort (glGetnTexImage)
2633        && FindProcShort (glGetnUniformdv)
2634        && FindProcShort (glGetnUniformfv)
2635        && FindProcShort (glGetnUniformiv)
2636        && FindProcShort (glGetnUniformuiv)
2637        && FindProcShort (glReadnPixels)
2638        && FindProcShort (glGetnMapdv)
2639        && FindProcShort (glGetnMapfv)
2640        && FindProcShort (glGetnMapiv)
2641        && FindProcShort (glGetnPixelMapfv)
2642        && FindProcShort (glGetnPixelMapuiv)
2643        && FindProcShort (glGetnPixelMapusv)
2644        && FindProcShort (glGetnPolygonStipple)
2645        && FindProcShort (glGetnColorTable)
2646        && FindProcShort (glGetnConvolutionFilter)
2647        && FindProcShort (glGetnSeparableFilter)
2648        && FindProcShort (glGetnHistogram)
2649        && FindProcShort (glGetnMinmax)
2650        && FindProcShort (glTextureBarrier);
2651   if (has45)
2652   {
2653     core45 = (OpenGl_GlCore45* )(&(*myFuncs));
2654     if (!isCoreProfile)
2655     {
2656       core45back = (OpenGl_GlCore45Back* )(&(*myFuncs));
2657     }
2658   }
2659   else
2660   {
2661     checkWrongVersion (4, 5, aLastFailedProc);
2662   }
2663
2664   // initialize debug context extension
2665   if (CheckExtension ("GL_ARB_debug_output"))
2666   {
2667     arbDbg = NULL;
2668     if (has43)
2669     {
2670       arbDbg = (OpenGl_ArbDbg* )(&(*myFuncs));
2671     }
2672     else if (FindProc ("glDebugMessageControlARB",  myFuncs->glDebugMessageControl)
2673           && FindProc ("glDebugMessageInsertARB",   myFuncs->glDebugMessageInsert)
2674           && FindProc ("glDebugMessageCallbackARB", myFuncs->glDebugMessageCallback)
2675           && FindProc ("glGetDebugMessageLogARB",   myFuncs->glGetDebugMessageLog))
2676     {
2677       arbDbg = (OpenGl_ArbDbg* )(&(*myFuncs));
2678     }
2679
2680     if (arbDbg != NULL
2681      && caps->contextDebug)
2682     {
2683       // setup default callback
2684       myIsGlDebugCtx = Standard_True;
2685       arbDbg->glDebugMessageCallback (debugCallbackWrap, this);
2686       if (has43)
2687       {
2688         ::glEnable (GL_DEBUG_OUTPUT);
2689       }
2690       if (caps->contextSyncDebug)
2691       {
2692         ::glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS);
2693       }
2694     }
2695   }
2696
2697   // initialize FBO extension (ARB)
2698   if (hasFBO)
2699   {
2700     arbFBO     = (OpenGl_ArbFBO*     )(&(*myFuncs));
2701     arbFBOBlit = (OpenGl_ArbFBOBlit* )(&(*myFuncs));
2702     extPDS = Standard_True; // extension for EXT, but part of ARB
2703   }
2704
2705   // initialize GS extension (EXT)
2706   if (CheckExtension ("GL_EXT_geometry_shader4")
2707    && FindProcShort (glProgramParameteriEXT))
2708   {
2709     extGS = (OpenGl_ExtGS* )(&(*myFuncs));
2710   }
2711
2712   // initialize bindless texture extension (ARB)
2713   if (CheckExtension ("GL_ARB_bindless_texture")
2714    && FindProcShort (glGetTextureHandleARB)
2715    && FindProcShort (glGetTextureSamplerHandleARB)
2716    && FindProcShort (glMakeTextureHandleResidentARB)
2717    && FindProcShort (glMakeTextureHandleNonResidentARB)
2718    && FindProcShort (glGetImageHandleARB)
2719    && FindProcShort (glMakeImageHandleResidentARB)
2720    && FindProcShort (glMakeImageHandleNonResidentARB)
2721    && FindProcShort (glUniformHandleui64ARB)
2722    && FindProcShort (glUniformHandleui64vARB)
2723    && FindProcShort (glProgramUniformHandleui64ARB)
2724    && FindProcShort (glProgramUniformHandleui64vARB)
2725    && FindProcShort (glIsTextureHandleResidentARB)
2726    && FindProcShort (glIsImageHandleResidentARB)
2727    && FindProcShort (glVertexAttribL1ui64ARB)
2728    && FindProcShort (glVertexAttribL1ui64vARB)
2729    && FindProcShort (glGetVertexAttribLui64vARB))
2730   {
2731     arbTexBindless = (OpenGl_ArbTexBindless* )(&(*myFuncs));
2732   }
2733
2734   if (has30)
2735   {
2736     // MSAA RenderBuffers have been defined in OpenGL 3.0,
2737     // but MSAA Textures - only in OpenGL 3.2+
2738     if (!has32
2739      && CheckExtension ("GL_ARB_texture_multisample")
2740      && FindProcShort (glTexImage2DMultisample))
2741     {
2742       GLint aNbColorSamples = 0, aNbDepthSamples = 0;
2743       ::glGetIntegerv (GL_MAX_COLOR_TEXTURE_SAMPLES, &aNbColorSamples);
2744       ::glGetIntegerv (GL_MAX_DEPTH_TEXTURE_SAMPLES, &aNbDepthSamples);
2745       myMaxMsaaSamples = Min (aNbColorSamples, aNbDepthSamples);
2746     }
2747     if (!has43
2748      && CheckExtension ("GL_ARB_texture_storage_multisample")
2749      && FindProcShort (glTexStorage2DMultisample))
2750     {
2751       //
2752     }
2753   }
2754
2755   // check whether ray tracing mode is supported
2756   myHasRayTracing = has31
2757                  && arbTboRGB32
2758                  && arbFBOBlit  != NULL;
2759
2760   // check whether textures in ray tracing mode are supported
2761   myHasRayTracingTextures = myHasRayTracing
2762                          && arbTexBindless != NULL;
2763
2764   // check whether adaptive screen sampling in ray tracing mode is supported
2765   myHasRayTracingAdaptiveSampling = myHasRayTracing
2766                                  && has44;
2767   myHasRayTracingAdaptiveSamplingAtomic = myHasRayTracingAdaptiveSampling
2768                                        && CheckExtension ("GL_NV_shader_atomic_float");
2769 #endif
2770 }
2771
2772 // =======================================================================
2773 // function : MemoryInfo
2774 // purpose  :
2775 // =======================================================================
2776 Standard_Size OpenGl_Context::AvailableMemory() const
2777 {
2778 #if !defined(GL_ES_VERSION_2_0)
2779   if (atiMem)
2780   {
2781     // this is actually information for VBO pool
2782     // however because pools are mostly shared
2783     // it can be used for total GPU memory estimations
2784     GLint aMemInfo[4];
2785     aMemInfo[0] = 0;
2786     glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aMemInfo);
2787     // returned value is in KiB, however this maybe changed in future
2788     return Standard_Size(aMemInfo[0]) * 1024;
2789   }
2790   else if (nvxMem)
2791   {
2792     // current available dedicated video memory (in KiB), currently unused GPU memory
2793     GLint aMemInfo = 0;
2794     glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aMemInfo);
2795     return Standard_Size(aMemInfo) * 1024;
2796   }
2797 #endif
2798   return 0;
2799 }
2800
2801 // =======================================================================
2802 // function : MemoryInfo
2803 // purpose  :
2804 // =======================================================================
2805 TCollection_AsciiString OpenGl_Context::MemoryInfo() const
2806 {
2807   TColStd_IndexedDataMapOfStringString aDict;
2808   MemoryInfo (aDict);
2809
2810   TCollection_AsciiString aText;
2811   for (TColStd_IndexedDataMapOfStringString::Iterator anIter (aDict); anIter.More(); anIter.Next())
2812   {
2813     if (!aText.IsEmpty())
2814     {
2815       aText += "\n";
2816     }
2817     aText += TCollection_AsciiString("  ") + anIter.Key() + ": " + anIter.Value();
2818   }
2819   return aText;
2820 }
2821
2822 // =======================================================================
2823 // function : MemoryInfo
2824 // purpose  :
2825 // =======================================================================
2826 void OpenGl_Context::MemoryInfo (TColStd_IndexedDataMapOfStringString& theDict) const
2827 {
2828 #if defined(GL_ES_VERSION_2_0)
2829   (void )theDict;
2830 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
2831   GLint aGlRendId = 0;
2832   CGLGetParameter (CGLGetCurrentContext(), kCGLCPCurrentRendererID, &aGlRendId);
2833
2834   CGLRendererInfoObj  aRendObj = NULL;
2835   CGOpenGLDisplayMask aDispMask = CGDisplayIDToOpenGLDisplayMask (kCGDirectMainDisplay);
2836   GLint aRendNb = 0;
2837   CGLQueryRendererInfo (aDispMask, &aRendObj, &aRendNb);
2838   for (GLint aRendIter = 0; aRendIter < aRendNb; ++aRendIter)
2839   {
2840     GLint aRendId = 0;
2841     if (CGLDescribeRenderer (aRendObj, aRendIter, kCGLRPRendererID, &aRendId) != kCGLNoError
2842      || aRendId != aGlRendId)
2843     {
2844       continue;
2845     }
2846
2847     //kCGLRPVideoMemoryMegabytes   = 131;
2848     //kCGLRPTextureMemoryMegabytes = 132;
2849     GLint aVMem = 0;
2850   #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
2851     if (CGLDescribeRenderer(aRendObj, aRendIter, kCGLRPVideoMemoryMegabytes, &aVMem) == kCGLNoError)
2852     {
2853       addInfo (theDict, "GPU memory",         TCollection_AsciiString() + aVMem + " MiB");
2854     }
2855     if (CGLDescribeRenderer(aRendObj, aRendIter, kCGLRPTextureMemoryMegabytes, &aVMem) == kCGLNoError)
2856     {
2857       addInfo (theDict, "GPU Texture memory", TCollection_AsciiString() + aVMem + " MiB");
2858     }
2859   #else
2860     if (CGLDescribeRenderer(aRendObj, aRendIter, kCGLRPVideoMemory, &aVMem) == kCGLNoError)
2861     {
2862       addInfo (theDict, "GPU memory",         TCollection_AsciiString() + (aVMem / (1024 * 1024)) + " MiB");
2863     }
2864     if (CGLDescribeRenderer(aRendObj, aRendIter, kCGLRPTextureMemory, &aVMem) == kCGLNoError)
2865     {
2866       addInfo (theDict, "GPU Texture memory", TCollection_AsciiString() + (aVMem / (1024 * 1024)) + " MiB");
2867     }
2868   #endif
2869   }
2870 #endif
2871
2872 #if !defined(GL_ES_VERSION_2_0)
2873   if (atiMem)
2874   {
2875     GLint aValues[4];
2876     memset (aValues, 0, sizeof(aValues));
2877     glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aValues);
2878
2879     // total memory free in the pool
2880     addInfo (theDict, "GPU free memory",    TCollection_AsciiString() + (aValues[0] / 1024) + " MiB");
2881
2882     if (aValues[1] != aValues[0])
2883     {
2884       // largest available free block in the pool
2885       addInfo (theDict, "Largest free block", TCollection_AsciiString() + (aValues[1] / 1024) + " MiB");
2886     }
2887     if (aValues[2] != aValues[0])
2888     {
2889       // total auxiliary memory free
2890       addInfo (theDict, "Free auxiliary memory", TCollection_AsciiString() + (aValues[2] / 1024) + " MiB");
2891     }
2892   }
2893   else if (nvxMem)
2894   {
2895     //current available dedicated video memory (in KiB), currently unused GPU memory
2896     GLint aValue = 0;
2897     glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aValue);
2898     addInfo (theDict, "GPU free memory", TCollection_AsciiString() + (aValue / 1024) + " MiB");
2899
2900     // dedicated video memory, total size (in KiB) of the GPU memory
2901     GLint aDedicated = 0;
2902     glGetIntegerv (GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &aDedicated);
2903     addInfo (theDict, "GPU memory", TCollection_AsciiString() + (aDedicated / 1024) + " MiB");
2904
2905     // total available memory, total size (in KiB) of the memory available for allocations
2906     glGetIntegerv (GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &aValue);
2907     if (aValue != aDedicated)
2908     {
2909       // different only for special configurations
2910       addInfo (theDict, "Total memory", TCollection_AsciiString() + (aValue / 1024) + " MiB");
2911     }
2912   }
2913 #if defined(_WIN32)
2914   else if (myFuncs->wglGetGPUInfoAMD != NULL
2915         && myFuncs->wglGetContextGPUIDAMD != NULL)
2916   {
2917     GLuint aTotalMemMiB = 0;
2918     UINT anAmdId = myFuncs->wglGetContextGPUIDAMD ((HGLRC )myGContext);
2919     if (anAmdId != 0)
2920     {
2921       if (myFuncs->wglGetGPUInfoAMD (anAmdId, WGL_GPU_RAM_AMD, GL_UNSIGNED_INT, sizeof(aTotalMemMiB), &aTotalMemMiB) > 0)
2922       {
2923         addInfo (theDict, "GPU memory", TCollection_AsciiString() + (int )aTotalMemMiB + " MiB");
2924       }
2925     }
2926   }
2927 #endif
2928 #endif
2929
2930 #if !defined(GL_ES_VERSION_2_0) && !defined(__APPLE__) && !defined(_WIN32)
2931   // GLX_RENDERER_VENDOR_ID_MESA
2932   if (myFuncs->glXQueryCurrentRendererIntegerMESA != NULL)
2933   {
2934     unsigned int aVMemMiB = 0;
2935     if (myFuncs->glXQueryCurrentRendererIntegerMESA (GLX_RENDERER_VIDEO_MEMORY_MESA, &aVMemMiB) != False)
2936     {
2937       addInfo (theDict, "GPU memory", TCollection_AsciiString() + int(aVMemMiB) + " MiB");
2938     }
2939   }
2940 #endif
2941 }
2942
2943 // =======================================================================
2944 // function : DiagnosticInfo
2945 // purpose  :
2946 // =======================================================================
2947 void OpenGl_Context::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
2948                                             Graphic3d_DiagnosticInfo theFlags) const
2949 {
2950   if ((theFlags & Graphic3d_DiagnosticInfo_NativePlatform) != 0)
2951   {
2952   #if defined(HAVE_EGL)
2953     addInfo (theDict, "EGLVersion",    ::eglQueryString ((EGLDisplay )myDisplay, EGL_VERSION));
2954     addInfo (theDict, "EGLVendor",     ::eglQueryString ((EGLDisplay )myDisplay, EGL_VENDOR));
2955     addInfo (theDict, "EGLClientAPIs", ::eglQueryString ((EGLDisplay )myDisplay, EGL_CLIENT_APIS));
2956     if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
2957     {
2958       addInfo (theDict, "EGLExtensions", ::eglQueryString ((EGLDisplay )myDisplay, EGL_EXTENSIONS));
2959     }
2960   #elif defined(_WIN32)
2961     if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0
2962      && myFuncs->wglGetExtensionsStringARB != NULL)
2963     {
2964       const char* aWglExts = myFuncs->wglGetExtensionsStringARB ((HDC )myWindowDC);
2965       addInfo (theDict, "WGLExtensions", aWglExts);
2966     }
2967   #elif defined(__APPLE__)
2968     //
2969   #else
2970     Display* aDisplay = (Display*)myDisplay;
2971     const int aScreen = DefaultScreen(aDisplay);
2972     addInfo (theDict, "GLXDirectRendering", ::glXIsDirect (aDisplay, (GLXContext )myGContext) ? "Yes" : "No");
2973     addInfo (theDict, "GLXVendor",  ::glXQueryServerString (aDisplay, aScreen, GLX_VENDOR));
2974     addInfo (theDict, "GLXVersion", ::glXQueryServerString (aDisplay, aScreen, GLX_VERSION));
2975     if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
2976     {
2977       const char* aGlxExts = ::glXQueryExtensionsString (aDisplay, aScreen);
2978       addInfo(theDict, "GLXExtensions", aGlxExts);
2979     }
2980
2981     addInfo (theDict, "GLXClientVendor",  ::glXGetClientString (aDisplay, GLX_VENDOR));
2982     addInfo (theDict, "GLXClientVersion", ::glXGetClientString (aDisplay, GLX_VERSION));
2983     if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
2984     {
2985       addInfo (theDict, "GLXClientExtensions", ::glXGetClientString (aDisplay, GLX_EXTENSIONS));
2986     }
2987   #endif
2988   }
2989
2990   if ((theFlags & Graphic3d_DiagnosticInfo_Device) != 0)
2991   {
2992     addInfo (theDict, "GLvendor",    (const char*)::glGetString (GL_VENDOR));
2993     addInfo (theDict, "GLdevice",    (const char*)::glGetString (GL_RENDERER));
2994     addInfo (theDict, "GLversion",   (const char*)::glGetString (GL_VERSION));
2995     if (IsGlGreaterEqual (2, 0))
2996     {
2997       addInfo (theDict, "GLSLversion", (const char*)::glGetString (GL_SHADING_LANGUAGE_VERSION));
2998     }
2999     if (myIsGlDebugCtx)
3000     {
3001       addInfo (theDict, "GLdebug", "ON");
3002     }
3003   }
3004
3005   if ((theFlags & Graphic3d_DiagnosticInfo_Limits) != 0)
3006   {
3007     addInfo (theDict, "Max texture size", TCollection_AsciiString(myMaxTexDim));
3008     addInfo (theDict, "Max FBO dump size", TCollection_AsciiString() + myMaxDumpSizeX + "x" + myMaxDumpSizeY);
3009     addInfo (theDict, "Max combined texture units", TCollection_AsciiString(myMaxTexCombined));
3010     addInfo (theDict, "Max MSAA samples", TCollection_AsciiString(myMaxMsaaSamples));
3011   }
3012
3013   if ((theFlags & Graphic3d_DiagnosticInfo_FrameBuffer) != 0)
3014   {
3015     GLint aViewport[4] = {};
3016     ::glGetIntegerv (GL_VIEWPORT, aViewport);
3017     addInfo (theDict, "Viewport", TCollection_AsciiString() + aViewport[2] + "x" + aViewport[3]);
3018   }
3019
3020   if ((theFlags & Graphic3d_DiagnosticInfo_Memory) != 0)
3021   {
3022     MemoryInfo (theDict);
3023   }
3024
3025   if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
3026   {
3027   #if !defined(GL_ES_VERSION_2_0)
3028     if (IsGlGreaterEqual (3, 0)
3029      && myFuncs->glGetStringi != NULL)
3030     {
3031       TCollection_AsciiString anExtList;
3032       GLint anExtNb = 0;
3033       ::glGetIntegerv (GL_NUM_EXTENSIONS, &anExtNb);
3034       for (GLint anIter = 0; anIter < anExtNb; ++anIter)
3035       {
3036         const char* anExtension = (const char*)myFuncs->glGetStringi (GL_EXTENSIONS, (GLuint)anIter);
3037         if (!anExtList.IsEmpty())
3038         {
3039           anExtList += " ";
3040         }
3041         anExtList += anExtension;
3042       }
3043       addInfo(theDict, "GLextensions", anExtList);
3044     }
3045     else
3046   #endif
3047     {
3048       addInfo (theDict, "GLextensions", (const char*)::glGetString (GL_EXTENSIONS));
3049     }
3050   }
3051 }
3052
3053 // =======================================================================
3054 // function : GetResource
3055 // purpose  :
3056 // =======================================================================
3057 const Handle(OpenGl_Resource)& OpenGl_Context::GetResource (const TCollection_AsciiString& theKey) const
3058 {
3059   return mySharedResources->IsBound (theKey) ? mySharedResources->Find (theKey) : NULL_GL_RESOURCE;
3060 }
3061
3062 // =======================================================================
3063 // function : ShareResource
3064 // purpose  :
3065 // =======================================================================
3066 Standard_Boolean OpenGl_Context::ShareResource (const TCollection_AsciiString& theKey,
3067                                                 const Handle(OpenGl_Resource)& theResource)
3068 {
3069   if (theKey.IsEmpty() || theResource.IsNull())
3070   {
3071     return Standard_False;
3072   }
3073   return mySharedResources->Bind (theKey, theResource);
3074 }
3075
3076 // =======================================================================
3077 // function : ReleaseResource
3078 // purpose  :
3079 // =======================================================================
3080 void OpenGl_Context::ReleaseResource (const TCollection_AsciiString& theKey,
3081                                       const Standard_Boolean         theToDelay)
3082 {
3083   if (!mySharedResources->IsBound (theKey))
3084   {
3085     return;
3086   }
3087   const Handle(OpenGl_Resource)& aRes = mySharedResources->Find (theKey);
3088   if (aRes->GetRefCount() > 1)
3089   {
3090     return;
3091   }
3092
3093   if (theToDelay)
3094   {
3095     myDelayed->Bind (theKey, 1);
3096   }
3097   else
3098   {
3099     aRes->Release (this);
3100     mySharedResources->UnBind (theKey);
3101   }
3102 }
3103
3104 // =======================================================================
3105 // function : ReleaseDelayed
3106 // purpose  :
3107 // =======================================================================
3108 void OpenGl_Context::ReleaseDelayed()
3109 {
3110   // release queued elements
3111   while (!myUnusedResources->IsEmpty())
3112   {
3113     myUnusedResources->First()->Release (this);
3114     myUnusedResources->RemoveFirst();
3115   }
3116
3117   // release delayed shared resources
3118   NCollection_Vector<TCollection_AsciiString> aDeadList;
3119   for (NCollection_DataMap<TCollection_AsciiString, Standard_Integer>::Iterator anIter (*myDelayed);
3120        anIter.More(); anIter.Next())
3121   {
3122     if (++anIter.ChangeValue() <= 2)
3123     {
3124       continue; // postpone release one more frame to ensure noone use it periodically
3125     }
3126
3127     const TCollection_AsciiString& aKey = anIter.Key();
3128     if (!mySharedResources->IsBound (aKey))
3129     {
3130       // mixed unshared strategy delayed/undelayed was used!
3131       aDeadList.Append (aKey);
3132       continue;
3133     }
3134
3135     const Handle(OpenGl_Resource)& aRes = mySharedResources->ChangeFind (aKey);
3136     if (aRes->GetRefCount() > 1)
3137     {
3138       // should be only 1 instance in mySharedResources
3139       // if not - resource was reused again
3140       aDeadList.Append (aKey);
3141       continue;
3142     }
3143
3144     // release resource if no one requiested it more than 2 redraw calls
3145     aRes->Release (this);
3146     mySharedResources->UnBind (aKey);
3147     aDeadList.Append (aKey);
3148   }
3149
3150   for (Standard_Integer anIter = 0; anIter < aDeadList.Length(); ++anIter)
3151   {
3152     myDelayed->UnBind (aDeadList.Value (anIter));
3153   }
3154 }
3155
3156 // =======================================================================
3157 // function : BindTextures
3158 // purpose  :
3159 // =======================================================================
3160 Handle(OpenGl_TextureSet) OpenGl_Context::BindTextures (const Handle(OpenGl_TextureSet)& theTextures)
3161 {
3162   if (myActiveTextures == theTextures)
3163   {
3164     return myActiveTextures;
3165   }
3166
3167   Handle(OpenGl_Context) aThisCtx (this);
3168   OpenGl_TextureSet::Iterator aTextureIterOld (myActiveTextures), aTextureIterNew (theTextures);
3169   for (;;)
3170   {
3171     if (!aTextureIterNew.More())
3172     {
3173       for (; aTextureIterOld.More(); aTextureIterOld.Next())
3174       {
3175         if (const Handle(OpenGl_Texture)& aTextureOld = aTextureIterOld.Value())
3176         {
3177         #if !defined(GL_ES_VERSION_2_0)
3178           if (core11 != NULL)
3179           {
3180             OpenGl_Sampler::resetGlobalTextureParams (aThisCtx, *aTextureOld, aTextureOld->Sampler()->Parameters());
3181           }
3182         #endif
3183           aTextureOld->Unbind (aThisCtx);
3184         }
3185       }
3186       break;
3187     }
3188
3189     const Handle(OpenGl_Texture)& aTextureNew = aTextureIterNew.Value();
3190     if (aTextureIterOld.More())
3191     {
3192       const Handle(OpenGl_Texture)& aTextureOld = aTextureIterOld.Value();
3193       if (aTextureNew == aTextureOld)
3194       {
3195         aTextureIterNew.Next();
3196         aTextureIterOld.Next();
3197         continue;
3198       }
3199       else if (aTextureNew.IsNull()
3200            || !aTextureNew->IsValid())
3201       {
3202         if (!aTextureOld.IsNull())
3203         {
3204         #if !defined(GL_ES_VERSION_2_0)
3205           if (core11 != NULL)
3206           {
3207             OpenGl_Sampler::resetGlobalTextureParams (aThisCtx, *aTextureOld, aTextureOld->Sampler()->Parameters());
3208           }
3209         #endif
3210           aTextureOld->Unbind (aThisCtx);
3211         }
3212
3213         aTextureIterNew.Next();
3214         aTextureIterOld.Next();
3215         continue;
3216       }
3217
3218       aTextureIterOld.Next();
3219     }
3220     if (aTextureNew.IsNull())
3221     {
3222       aTextureIterNew.Next();
3223       continue;
3224     }
3225
3226     const Graphic3d_TextureUnit aTexUnit = aTextureNew->Sampler()->Parameters()->TextureUnit();
3227     if (aTexUnit >= myMaxTexCombined)
3228     {
3229       PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
3230                    TCollection_AsciiString("Texture unit ") + aTexUnit + " for " + aTextureNew->ResourceId() + " exceeds hardware limit " + myMaxTexCombined);
3231       aTextureIterNew.Next();
3232       continue;
3233     }
3234
3235     aTextureNew->Bind (aThisCtx);
3236     if (aTextureNew->Sampler()->ToUpdateParameters())
3237     {
3238       if (aTextureNew->Sampler()->IsImmutable())
3239       {
3240         aTextureNew->Sampler()->Init (aThisCtx, *aTextureNew);
3241       }
3242       else
3243       {
3244         OpenGl_Sampler::applySamplerParams (aThisCtx, aTextureNew->Sampler()->Parameters(), aTextureNew->Sampler().get(), aTextureNew->GetTarget(), aTextureNew->HasMipmaps());
3245       }
3246     }
3247   #if !defined(GL_ES_VERSION_2_0)
3248     if (core11 != NULL)
3249     {
3250       OpenGl_Sampler::applyGlobalTextureParams (aThisCtx, *aTextureNew, aTextureNew->Sampler()->Parameters());
3251     }
3252   #endif
3253     aTextureIterNew.Next();
3254   }
3255
3256   Handle(OpenGl_TextureSet) anOldTextures = myActiveTextures;
3257   myActiveTextures = theTextures;
3258   return anOldTextures;
3259 }
3260
3261 // =======================================================================
3262 // function : BindProgram
3263 // purpose  :
3264 // =======================================================================
3265 Standard_Boolean OpenGl_Context::BindProgram (const Handle(OpenGl_ShaderProgram)& theProgram)
3266 {
3267   if (core20fwd == NULL)
3268   {
3269     return Standard_False;
3270   }
3271   else if (myActiveProgram == theProgram)
3272   {
3273     return Standard_True;
3274   }
3275
3276   if (theProgram.IsNull()
3277   || !theProgram->IsValid())
3278   {
3279     if (!myActiveProgram.IsNull())
3280     {
3281       core20fwd->glUseProgram (OpenGl_ShaderProgram::NO_PROGRAM);
3282       myActiveProgram.Nullify();
3283     }
3284     return Standard_False;
3285   }
3286
3287   myActiveProgram = theProgram;
3288   core20fwd->glUseProgram (theProgram->ProgramId());
3289   return Standard_True;
3290 }
3291
3292 // =======================================================================
3293 // function : BindDefaultVao
3294 // purpose  :
3295 // =======================================================================
3296 void OpenGl_Context::BindDefaultVao()
3297 {
3298 #if !defined(GL_ES_VERSION_2_0)
3299   if (myDefaultVao == 0
3300    || core32 == NULL)
3301   {
3302     return;
3303   }
3304
3305   core32->glBindVertexArray (myDefaultVao);
3306 #endif
3307 }
3308
3309 // =======================================================================
3310 // function : SetDefaultFrameBuffer
3311 // purpose  :
3312 // =======================================================================
3313 Handle(OpenGl_FrameBuffer) OpenGl_Context::SetDefaultFrameBuffer (const Handle(OpenGl_FrameBuffer)& theFbo)
3314 {
3315   Handle(OpenGl_FrameBuffer) aFbo = myDefaultFbo;
3316   myDefaultFbo = theFbo;
3317   return aFbo;
3318 }
3319
3320 // =======================================================================
3321 // function : SetShadingMaterial
3322 // purpose  :
3323 // =======================================================================
3324 void OpenGl_Context::SetShadingMaterial (const OpenGl_Aspects* theAspect,
3325                                          const Handle(Graphic3d_PresentationAttributes)& theHighlight)
3326 {
3327   const Handle(Graphic3d_Aspects)& anAspect = (!theHighlight.IsNull() && !theHighlight->BasicFillAreaAspect().IsNull())
3328                                             ?  (const Handle(Graphic3d_Aspects)& )theHighlight->BasicFillAreaAspect()
3329                                             :  theAspect->Aspect();
3330
3331   const bool toDistinguish = anAspect->Distinguish();
3332   const bool toMapTexture  = anAspect->ToMapTexture();
3333   const Graphic3d_MaterialAspect& aMatFrontSrc = anAspect->FrontMaterial();
3334   const Graphic3d_MaterialAspect& aMatBackSrc  = toDistinguish
3335                                                ? anAspect->BackMaterial()
3336                                                : aMatFrontSrc;
3337   const Quantity_Color& aFrontIntColor = anAspect->InteriorColor();
3338   const Quantity_Color& aBackIntColor  = toDistinguish
3339                                        ? anAspect->BackInteriorColor()
3340                                        : aFrontIntColor;
3341
3342   myMatFront.Init (aMatFrontSrc, aFrontIntColor);
3343   if (toDistinguish)
3344   {
3345     myMatBack.Init (aMatBackSrc, aBackIntColor);
3346   }
3347   else
3348   {
3349     myMatBack = myMatFront;
3350   }
3351
3352   if (!theHighlight.IsNull()
3353     && theHighlight->BasicFillAreaAspect().IsNull())
3354   {
3355     myMatFront.SetColor (theHighlight->ColorRGBA());
3356     myMatBack .SetColor (theHighlight->ColorRGBA());
3357   }
3358
3359   Standard_ShortReal anAlphaFront = 1.0f;
3360   Standard_ShortReal anAlphaBack  = 1.0f;
3361   if (CheckIsTransparent (theAspect, theHighlight, anAlphaFront, anAlphaBack))
3362   {
3363     myMatFront.Diffuse.a() = anAlphaFront;
3364     myMatBack .Diffuse.a() = anAlphaBack;
3365   }
3366
3367   // do not update material properties in case of zero reflection mode,
3368   // because GL lighting will be disabled by OpenGl_PrimitiveArray::DrawArray() anyway.
3369   const OpenGl_MaterialState& aMatState = myShaderManager->MaterialState();
3370   float anAlphaCutoff = anAspect->AlphaMode() == Graphic3d_AlphaMode_Mask
3371                       ? anAspect->AlphaCutoff()
3372                       : ShortRealLast();
3373   if (anAspect->ToDrawEdges())
3374   {
3375     if (anAspect->InteriorStyle() == Aspect_IS_EMPTY
3376      || (anAspect->InteriorStyle() == Aspect_IS_SOLID
3377       && anAspect->EdgeColorRGBA().Alpha() < 1.0f))
3378     {
3379       anAlphaCutoff = 0.285f;
3380     }
3381   }
3382   if (theAspect->ShadingModel() == Graphic3d_TOSM_UNLIT)
3383   {
3384     if (anAlphaCutoff == aMatState.AlphaCutoff())
3385     {
3386       return;
3387     }
3388   }
3389   else if (myMatFront    == aMatState.FrontMaterial()
3390         && myMatBack     == aMatState.BackMaterial()
3391         && toDistinguish == aMatState.ToDistinguish()
3392         && toMapTexture  == aMatState.ToMapTexture()
3393         && anAlphaCutoff == aMatState.AlphaCutoff())
3394   {
3395     return;
3396   }
3397
3398   myShaderManager->UpdateMaterialStateTo (myMatFront, myMatBack, anAlphaCutoff, toDistinguish, toMapTexture);
3399 }
3400
3401 // =======================================================================
3402 // function : CheckIsTransparent
3403 // purpose  :
3404 // =======================================================================
3405 Standard_Boolean OpenGl_Context::CheckIsTransparent (const OpenGl_Aspects* theAspect,
3406                                                      const Handle(Graphic3d_PresentationAttributes)& theHighlight,
3407                                                      Standard_ShortReal& theAlphaFront,
3408                                                      Standard_ShortReal& theAlphaBack)
3409 {
3410   const Handle(Graphic3d_Aspects)& anAspect = (!theHighlight.IsNull() && !theHighlight->BasicFillAreaAspect().IsNull())
3411                                             ?  (const Handle(Graphic3d_Aspects)& )theHighlight->BasicFillAreaAspect()
3412                                             :  theAspect->Aspect();
3413
3414   const bool toDistinguish = anAspect->Distinguish();
3415   const Graphic3d_MaterialAspect& aMatFrontSrc = anAspect->FrontMaterial();
3416   const Graphic3d_MaterialAspect& aMatBackSrc  = toDistinguish
3417                                                ? anAspect->BackMaterial()
3418                                                : aMatFrontSrc;
3419
3420   // handling transparency
3421   if (!theHighlight.IsNull()
3422     && theHighlight->BasicFillAreaAspect().IsNull())
3423   {
3424     theAlphaFront = theHighlight->ColorRGBA().Alpha();
3425     theAlphaBack  = theHighlight->ColorRGBA().Alpha();
3426   }
3427   else
3428   {
3429     theAlphaFront = aMatFrontSrc.Alpha();
3430     theAlphaBack  = aMatBackSrc .Alpha();
3431   }
3432
3433   if (anAspect->AlphaMode() == Graphic3d_AlphaMode_BlendAuto)
3434   {
3435     return theAlphaFront < 1.0f
3436         || theAlphaBack  < 1.0f;
3437   }
3438   return anAspect->AlphaMode() == Graphic3d_AlphaMode_Blend;
3439 }
3440
3441 // =======================================================================
3442 // function : SetColor4fv
3443 // purpose  :
3444 // =======================================================================
3445 void OpenGl_Context::SetColor4fv (const OpenGl_Vec4& theColor)
3446 {
3447   if (!myActiveProgram.IsNull())
3448   {
3449     myActiveProgram->SetUniform (this, myActiveProgram->GetStateLocation (OpenGl_OCCT_COLOR), theColor);
3450   }
3451 #if !defined(GL_ES_VERSION_2_0)
3452   else if (core11 != NULL)
3453   {
3454     core11->glColor4fv (theColor.GetData());
3455   }
3456 #endif
3457 }
3458
3459 // =======================================================================
3460 // function : SetTypeOfLine
3461 // purpose  :
3462 // =======================================================================
3463 void OpenGl_Context::SetTypeOfLine (const Aspect_TypeOfLine  theType,
3464                                     const Standard_ShortReal theFactor)
3465 {
3466   Standard_Integer aPattern = 0xFFFF;
3467   switch (theType)
3468   {
3469     case Aspect_TOL_DASH:
3470     {
3471       aPattern = 0xFFC0;
3472       break;
3473     }
3474     case Aspect_TOL_DOT:
3475     {
3476       aPattern = 0xCCCC;
3477       break;
3478     }
3479     case Aspect_TOL_DOTDASH:
3480     {
3481       aPattern = 0xFF18;
3482       break;
3483     }
3484     case Aspect_TOL_EMPTY:
3485     case Aspect_TOL_SOLID:
3486     {
3487       aPattern = 0xFFFF;
3488       break;
3489     }
3490     case Aspect_TOL_USERDEFINED:
3491     {
3492       aPattern = 0xFF24;
3493       break;
3494     }
3495   }
3496
3497   if (!myActiveProgram.IsNull())
3498   {
3499     myActiveProgram->SetUniform (this, "uPattern", aPattern);
3500     myActiveProgram->SetUniform (this, "uFactor",  theFactor);
3501     return;
3502   }
3503
3504 #if !defined(GL_ES_VERSION_2_0)
3505   if (aPattern != 0xFFFF)
3506   {
3507     if (core11 != NULL)
3508     {
3509       core11fwd->glEnable (GL_LINE_STIPPLE);
3510
3511       core11->glLineStipple (static_cast<GLint>    (theFactor),
3512                              static_cast<GLushort> (aPattern));
3513     }
3514   }
3515   else
3516   {
3517     if (core11 != NULL)
3518     {
3519       core11fwd->glDisable (GL_LINE_STIPPLE);
3520     }
3521   }
3522 #endif
3523 }
3524
3525 // =======================================================================
3526 // function : SetLineWidth
3527 // purpose  :
3528 // =======================================================================
3529 void OpenGl_Context::SetLineWidth (const Standard_ShortReal theWidth)
3530 {
3531   if (core11 != NULL)
3532   {
3533     // glLineWidth() is still defined within Core Profile, but has no effect with values != 1.0f
3534     core11fwd->glLineWidth (theWidth * myLineWidthScale);
3535   }
3536 }
3537
3538 // =======================================================================
3539 // function : SetTextureMatrix
3540 // purpose  :
3541 // =======================================================================
3542 void OpenGl_Context::SetTextureMatrix (const Handle(Graphic3d_TextureParams)& theParams)
3543 {
3544   if (theParams.IsNull())
3545   {
3546     return;
3547   }
3548   else if (!myActiveProgram.IsNull())
3549   {
3550     const GLint aUniLoc = myActiveProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_TRSF2D);
3551     if (aUniLoc == OpenGl_ShaderProgram::INVALID_LOCATION)
3552     {
3553       return;
3554     }
3555
3556     // pack transformation parameters
3557     OpenGl_Vec4 aTrsf[2] =
3558     {
3559       OpenGl_Vec4 (-theParams->Translation().x(),
3560                    -theParams->Translation().y(),
3561                     theParams->Scale().x(),
3562                     theParams->Scale().y()),
3563       OpenGl_Vec4 (static_cast<float> (std::sin (-theParams->Rotation() * M_PI / 180.0)),
3564                    static_cast<float> (std::cos (-theParams->Rotation() * M_PI / 180.0)),
3565                    0.0f, 0.0f)
3566     };
3567     myActiveProgram->SetUniform (this, aUniLoc, 2, aTrsf);
3568     return;
3569   }
3570
3571 #if !defined(GL_ES_VERSION_2_0)
3572   if (core11 != NULL)
3573   {
3574     GLint aMatrixMode = GL_TEXTURE;
3575     ::glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
3576
3577     core11->glMatrixMode (GL_TEXTURE);
3578     OpenGl_Mat4 aTextureMat;
3579     const Graphic3d_Vec2& aScale = theParams->Scale();
3580     const Graphic3d_Vec2& aTrans = theParams->Translation();
3581     Graphic3d_TransformUtils::Scale     (aTextureMat,  aScale.x(),  aScale.y(), 1.0f);
3582     Graphic3d_TransformUtils::Translate (aTextureMat, -aTrans.x(), -aTrans.y(), 0.0f);
3583     Graphic3d_TransformUtils::Rotate    (aTextureMat, -theParams->Rotation(), 0.0f, 0.0f, 1.0f);
3584     core11->glLoadMatrixf (aTextureMat);
3585     core11->glMatrixMode (aMatrixMode);
3586   }
3587 #endif
3588 }
3589
3590 // =======================================================================
3591 // function : SetPointSize
3592 // purpose  :
3593 // =======================================================================
3594 void OpenGl_Context::SetPointSize (const Standard_ShortReal theSize)