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