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