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