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