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