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