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