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