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