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