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