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