5d854ed3ae8dc5c5e5b049f05fc282a95d52a375
[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_GlCore20.hxx>
29 #include <OpenGl_Sampler.hxx>
30 #include <OpenGl_ShaderManager.hxx>
31
32 #include <Message_Messenger.hxx>
33
34 #include <NCollection_Vector.hxx>
35
36 #include <Standard_ProgramError.hxx>
37
38 #if defined(HAVE_EGL)
39   #include <EGL/egl.h>
40   #ifdef _MSC_VER
41     #pragma comment(lib, "libEGL.lib")
42   #endif
43 #elif defined(_WIN32)
44   //
45 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
46   #include <dlfcn.h>
47 #else
48   #include <GL/glx.h> // glXGetProcAddress()
49 #endif
50
51 // GL_NVX_gpu_memory_info
52 #ifndef GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX
53   enum
54   {
55     GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX         = 0x9047,
56     GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX   = 0x9048,
57     GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX = 0x9049,
58     GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX           = 0x904A,
59     GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX           = 0x904B
60   };
61 #endif
62
63 IMPLEMENT_STANDARD_HANDLE (OpenGl_Context, Standard_Transient)
64 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Context, Standard_Transient)
65
66 namespace
67 {
68   static const Handle(OpenGl_Resource) NULL_GL_RESOURCE;
69 }
70
71 // =======================================================================
72 // function : OpenGl_Context
73 // purpose  :
74 // =======================================================================
75 OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
76 : core11     (NULL),
77   core11fwd  (NULL),
78   core15     (NULL),
79   core15fwd  (NULL),
80   core20     (NULL),
81   core20fwd  (NULL),
82   core32     (NULL),
83   core32back (NULL),
84   core33     (NULL),
85   core33back (NULL),
86   core41     (NULL),
87   core41back (NULL),
88   core42     (NULL),
89   core42back (NULL),
90   core43     (NULL),
91   core43back (NULL),
92   core44     (NULL),
93   core44back (NULL),
94   caps   (!theCaps.IsNull() ? theCaps : new OpenGl_Caps()),
95 #if defined(GL_ES_VERSION_2_0)
96   hasHighp   (Standard_False),
97   hasTexRGBA8(Standard_False),
98 #else
99   hasHighp   (Standard_True),
100   hasTexRGBA8(Standard_True),
101 #endif
102   arbNPTW  (Standard_False),
103   arbTexRG (Standard_False),
104   arbTexBindless (NULL),
105   arbTBO (NULL),
106   arbTboRGB32 (Standard_False),
107   arbIns (NULL),
108   arbDbg (NULL),
109   arbFBO (NULL),
110   extGS  (NULL),
111   extBgra(Standard_False),
112   extAnis(Standard_False),
113   extPDS (Standard_False),
114   atiMem (Standard_False),
115   nvxMem (Standard_False),
116   mySharedResources (new OpenGl_ResourcesMap()),
117   myDelayed         (new OpenGl_DelayReleaseMap()),
118   myUnusedResources (new OpenGl_ResourcesStack()),
119   myClippingState (),
120   myGlLibHandle (NULL),
121   myFuncs (new OpenGl_GlFunctions()),
122   myAnisoMax   (1),
123   myTexClamp   (GL_CLAMP_TO_EDGE),
124   myMaxTexDim  (1024),
125   myMaxClipPlanes (6),
126   myGlVerMajor (0),
127   myGlVerMinor (0),
128   myIsInitialized (Standard_False),
129   myIsStereoBuffers (Standard_False),
130   myIsGlNormalizeEnabled (Standard_False),
131 #if !defined(GL_ES_VERSION_2_0)
132   myRenderMode (GL_RENDER),
133 #else
134   myRenderMode (0),
135 #endif
136   myDrawBuffer (0)
137 {
138 #if defined(__APPLE__) && !defined(MACOSX_USE_GLX)
139   // Vendors can not extend functionality on this system
140   // and developers are limited to OpenGL support provided by Mac OS X SDK.
141   // We retrieve function pointers from system library
142   // to generalize extensions support on all platforms.
143   // In this way we also reach binary compatibility benefit between OS releases
144   // if some newest functionality is optionally used.
145   // Notice that GL version / extension availability checks are required
146   // because function pointers may be available but not functionality itself
147   // (depends on renderer).
148   myGlLibHandle = dlopen ("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
149 #endif
150   memset (myFuncs.operator->(), 0, sizeof(OpenGl_GlFunctions));
151   myShaderManager = new OpenGl_ShaderManager (this);
152 }
153
154 // =======================================================================
155 // function : ~OpenGl_Context
156 // purpose  :
157 // =======================================================================
158 OpenGl_Context::~OpenGl_Context()
159 {
160   // release clean up queue
161   ReleaseDelayed();
162
163   // release shared resources if any
164   if (((const Handle(Standard_Transient)& )mySharedResources)->GetRefCount() <= 1)
165   {
166     myShaderManager.Nullify();
167     for (NCollection_DataMap<TCollection_AsciiString, Handle(OpenGl_Resource)>::Iterator anIter (*mySharedResources);
168          anIter.More(); anIter.Next())
169     {
170       anIter.Value()->Release (this);
171     }
172   }
173   else
174   {
175     myShaderManager->SetContext (NULL);
176   }
177   mySharedResources.Nullify();
178   myDelayed.Nullify();
179
180   // release sampler object
181   if (!myTexSampler.IsNull())
182   {
183     myTexSampler->Release (this);
184   }
185
186 #if !defined(GL_ES_VERSION_2_0)
187   if (arbDbg != NULL
188    && caps->contextDebug
189    && IsValid())
190   {
191     // reset callback
192     void* aPtr = NULL;
193     glGetPointerv (GL_DEBUG_CALLBACK_USER_PARAM_ARB, &aPtr);
194     if (aPtr == this)
195     {
196       arbDbg->glDebugMessageCallbackARB (NULL, NULL);
197     }
198   }
199 #endif
200 }
201
202 // =======================================================================
203 // function : forcedRelease
204 // purpose  :
205 // =======================================================================
206 void OpenGl_Context::forcedRelease()
207 {
208   ReleaseDelayed();
209   for (NCollection_DataMap<TCollection_AsciiString, Handle(OpenGl_Resource)>::Iterator anIter (*mySharedResources);
210        anIter.More(); anIter.Next())
211   {
212     anIter.Value()->Release (this);
213   }
214   mySharedResources->Clear();
215   myShaderManager->clear();
216   myShaderManager->SetContext (NULL);
217 }
218
219 // =======================================================================
220 // function : MaxDegreeOfAnisotropy
221 // purpose  :
222 // =======================================================================
223 Standard_Integer OpenGl_Context::MaxDegreeOfAnisotropy() const
224 {
225   return myAnisoMax;
226 }
227
228 // =======================================================================
229 // function : MaxTextureSize
230 // purpose  :
231 // =======================================================================
232 Standard_Integer OpenGl_Context::MaxTextureSize() const
233 {
234   return myMaxTexDim;
235 }
236
237 // =======================================================================
238 // function : MaxClipPlanes
239 // purpose  :
240 // =======================================================================
241 Standard_Integer OpenGl_Context::MaxClipPlanes() const
242 {
243   return myMaxClipPlanes;
244 }
245
246 // =======================================================================
247 // function : SetDrawBufferLeft
248 // purpose  :
249 // =======================================================================
250 void OpenGl_Context::SetDrawBufferLeft()
251 {
252 #if !defined(GL_ES_VERSION_2_0)
253   switch (myDrawBuffer)
254   {
255     case GL_BACK_RIGHT :
256     case GL_BACK :
257       glDrawBuffer (GL_BACK_LEFT);
258       myDrawBuffer = GL_BACK_LEFT;
259       break;
260
261     case GL_FRONT_RIGHT :
262     case GL_FRONT :
263       glDrawBuffer (GL_FRONT_LEFT);
264       myDrawBuffer = GL_FRONT_LEFT;
265       break;
266
267     case GL_FRONT_AND_BACK :
268     case GL_RIGHT :
269       glDrawBuffer (GL_LEFT);
270       myDrawBuffer = GL_LEFT;
271       break;
272   }
273 #endif
274 }
275
276 // =======================================================================
277 // function : SetDrawBufferRight
278 // purpose  :
279 // =======================================================================
280 void OpenGl_Context::SetDrawBufferRight()
281 {
282 #if !defined(GL_ES_VERSION_2_0)
283   switch (myDrawBuffer)
284   {
285     case GL_BACK_LEFT :
286     case GL_BACK :
287       glDrawBuffer (GL_BACK_RIGHT);
288       myDrawBuffer = GL_BACK_RIGHT;
289       break;
290
291     case GL_FRONT_LEFT :
292     case GL_FRONT :
293       glDrawBuffer (GL_FRONT_RIGHT);
294       myDrawBuffer = GL_FRONT_RIGHT;
295       break;
296
297     case GL_FRONT_AND_BACK :
298     case GL_LEFT :
299       glDrawBuffer (GL_RIGHT);
300       myDrawBuffer = GL_RIGHT;
301       break;
302   }
303 #endif
304 }
305
306 // =======================================================================
307 // function : SetDrawBufferMono
308 // purpose  :
309 // =======================================================================
310 void OpenGl_Context::SetDrawBufferMono()
311 {
312 #if !defined(GL_ES_VERSION_2_0)
313   switch (myDrawBuffer)
314   {
315     case GL_BACK_LEFT :
316     case GL_BACK_RIGHT :
317       glDrawBuffer (GL_BACK);
318       myDrawBuffer = GL_BACK;
319       break;
320
321     case GL_FRONT_LEFT :
322     case GL_FRONT_RIGHT :
323       glDrawBuffer (GL_FRONT);
324       myDrawBuffer = GL_FRONT;
325       break;
326
327     case GL_LEFT :
328     case GL_RIGHT :
329       glDrawBuffer (GL_FRONT_AND_BACK);
330       myDrawBuffer = GL_FRONT_AND_BACK;
331       break;
332   }
333 #endif
334 }
335
336 // =======================================================================
337 // function : FetchState
338 // purpose  :
339 // =======================================================================
340 void OpenGl_Context::FetchState()
341 {
342 #if !defined(GL_ES_VERSION_2_0)
343   // cache feedback mode state
344   glGetIntegerv (GL_RENDER_MODE, &myRenderMode);
345
346   // cache draw buffer state
347   glGetIntegerv (GL_DRAW_BUFFER, &myDrawBuffer);
348 #endif
349 }
350
351 // =======================================================================
352 // function : Share
353 // purpose  :
354 // =======================================================================
355 void OpenGl_Context::Share (const Handle(OpenGl_Context)& theShareCtx)
356 {
357   if (!theShareCtx.IsNull())
358   {
359     mySharedResources = theShareCtx->mySharedResources;
360     myDelayed         = theShareCtx->myDelayed;
361     myUnusedResources = theShareCtx->myUnusedResources;
362     myShaderManager   = theShareCtx->myShaderManager;
363   }
364 }
365
366 #if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
367
368 // =======================================================================
369 // function : IsCurrent
370 // purpose  :
371 // =======================================================================
372 Standard_Boolean OpenGl_Context::IsCurrent() const
373 {
374 #if defined(HAVE_EGL)
375   if ((EGLDisplay )myDisplay  == EGL_NO_DISPLAY
376    || (EGLSurface )myWindow   == EGL_NO_SURFACE
377    || (EGLContext )myGContext == EGL_NO_CONTEXT)
378   {
379     return Standard_False;
380   }
381
382   return (((EGLDisplay )myDisplay  == eglGetCurrentDisplay())
383        && ((EGLContext )myGContext == eglGetCurrentContext())
384        && ((EGLSurface )myWindow   == eglGetCurrentSurface (EGL_DRAW)));
385 #elif defined(_WIN32)
386   if (myWindowDC == NULL || myGContext == NULL)
387   {
388     return Standard_False;
389   }
390   return (( (HDC )myWindowDC == wglGetCurrentDC())
391       && ((HGLRC )myGContext == wglGetCurrentContext()));
392 #else
393   if (myDisplay == NULL || myWindow == 0 || myGContext == 0)
394   {
395     return Standard_False;
396   }
397
398   return (   ((Display* )myDisplay  == glXGetCurrentDisplay())
399        &&  ((GLXContext )myGContext == glXGetCurrentContext())
400        && ((GLXDrawable )myWindow   == glXGetCurrentDrawable()));
401 #endif
402 }
403
404 // =======================================================================
405 // function : MakeCurrent
406 // purpose  :
407 // =======================================================================
408 Standard_Boolean OpenGl_Context::MakeCurrent()
409 {
410 #if defined(HAVE_EGL)
411   if ((EGLDisplay )myDisplay  == EGL_NO_DISPLAY
412    || (EGLSurface )myWindow   == EGL_NO_SURFACE
413    || (EGLContext )myGContext == EGL_NO_CONTEXT)
414   {
415     Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
416     return Standard_False;
417   }
418
419   if (eglMakeCurrent ((EGLDisplay )myDisplay, (EGLSurface )myWindow, (EGLSurface )myWindow, (EGLContext )myGContext) != EGL_TRUE)
420   {
421     // if there is no current context it might be impossible to use glGetError() correctly
422     PushMessage (GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB, GL_DEBUG_TYPE_ERROR_ARB, 0, GL_DEBUG_SEVERITY_HIGH_ARB,
423                  "eglMakeCurrent() has failed!");
424     myIsInitialized = Standard_False;
425     return Standard_False;
426   }
427 #elif defined(_WIN32)
428   if (myWindowDC == NULL || myGContext == NULL)
429   {
430     Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
431     return Standard_False;
432   }
433
434   // technically it should be safe to activate already bound GL context
435   // however some drivers (Intel etc.) may FAIL doing this for unknown reason
436   if (IsCurrent())
437   {
438     myShaderManager->SetContext (this);
439     return Standard_True;
440   }
441   else if (wglMakeCurrent ((HDC )myWindowDC, (HGLRC )myGContext) != TRUE)
442   {
443     // notice that glGetError() couldn't be used here!
444     wchar_t* aMsgBuff = NULL;
445     DWORD anErrorCode = GetLastError();
446     FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
447                     NULL, anErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (wchar_t* )&aMsgBuff, 0, NULL);
448     TCollection_ExtendedString aMsg ("wglMakeCurrent() has failed. ");
449     if (aMsgBuff != NULL)
450     {
451       aMsg += (Standard_ExtString )aMsgBuff;
452       LocalFree (aMsgBuff);
453     }
454     PushMessage (GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB, GL_DEBUG_TYPE_ERROR_ARB, (unsigned int )anErrorCode, GL_DEBUG_SEVERITY_HIGH_ARB, aMsg);
455     myIsInitialized = Standard_False;
456     return Standard_False;
457   }
458 #else
459   if (myDisplay == NULL || myWindow == 0 || myGContext == 0)
460   {
461     Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
462     return Standard_False;
463   }
464
465   if (!glXMakeCurrent ((Display* )myDisplay, (GLXDrawable )myWindow, (GLXContext )myGContext))
466   {
467     // if there is no current context it might be impossible to use glGetError() correctly
468     PushMessage (GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB, GL_DEBUG_TYPE_ERROR_ARB, 0, GL_DEBUG_SEVERITY_HIGH_ARB,
469                  "glXMakeCurrent() has failed!");
470     myIsInitialized = Standard_False;
471     return Standard_False;
472   }
473 #endif
474   myShaderManager->SetContext (this);
475   return Standard_True;
476 }
477
478 // =======================================================================
479 // function : SwapBuffers
480 // purpose  :
481 // =======================================================================
482 void OpenGl_Context::SwapBuffers()
483 {
484 #if defined(HAVE_EGL)
485   if ((EGLSurface )myWindow != EGL_NO_SURFACE)
486   {
487     eglSwapBuffers ((EGLDisplay )myDisplay, (EGLSurface )myWindow);
488   }
489 #elif defined(_WIN32)
490   if ((HDC )myWindowDC != NULL)
491   {
492     ::SwapBuffers ((HDC )myWindowDC);
493     glFlush();
494   }
495 #else
496   if ((Display* )myDisplay != NULL)
497   {
498     glXSwapBuffers ((Display* )myDisplay, (GLXDrawable )myWindow);
499   }
500 #endif
501 }
502
503 #endif // __APPLE__
504
505 // =======================================================================
506 // function : findProc
507 // purpose  :
508 // =======================================================================
509 void* OpenGl_Context::findProc (const char* theFuncName)
510 {
511 #if defined(HAVE_EGL)
512   return (void* )eglGetProcAddress (theFuncName);
513 #elif defined(_WIN32)
514   return wglGetProcAddress (theFuncName);
515 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
516   return (myGlLibHandle != NULL) ? dlsym (myGlLibHandle, theFuncName) : NULL;
517 #else
518   return (void* )glXGetProcAddress ((const GLubyte* )theFuncName);
519 #endif
520 }
521
522 // =======================================================================
523 // function : CheckExtension
524 // purpose  :
525 // =======================================================================
526 Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtName) const
527 {
528   if (theExtName  == NULL)
529   {
530 #ifdef OCCT_DEBUG
531     std::cerr << "CheckExtension called with NULL string!\n";
532 #endif
533     return Standard_False;
534   }
535
536   // available since OpenGL 3.0
537   // and the ONLY way to check extensions with OpenGL 3.1+ core profile
538   /**if (IsGlGreaterEqual (3, 0))
539   {
540     GLint anExtNb = 0;
541     glGetIntegerv (GL_NUM_EXTENSIONS, &anExtNb);
542     for (GLint anIter = 0; anIter < anExtNb; ++anIter)
543     {
544       const char* anExtension = (const char* )core30->glGetStringi (GL_EXTENSIONS, (GLuint )anIter);
545       if (anExtension[anExtNameLen] == '\0' &&
546           strncmp (anExtension, theExtName, anExtNameLen) == 0)
547       {
548         return Standard_True;
549       }
550     }
551     return Standard_False;
552   }*/
553
554   // use old way with huge string for all extensions
555   const char* anExtString = (const char* )glGetString (GL_EXTENSIONS);
556   if (anExtString == NULL)
557   {
558     Messenger()->Send ("TKOpenGL: glGetString (GL_EXTENSIONS) has returned NULL! No GL context?", Message_Warning);
559     return Standard_False;
560   }
561   return CheckExtension (anExtString, theExtName);
562 }
563
564 // =======================================================================
565 // function : CheckExtension
566 // purpose  :
567 // =======================================================================
568 Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtString,
569                                                  const char* theExtName)
570 {
571   if (theExtString == NULL)
572   {
573     return Standard_False;
574   }
575
576   // Search for theExtName in the extensions string.
577   // Use of strstr() is not sufficient because extension names can be prefixes of other extension names.
578   char* aPtrIter = (char* )theExtString;
579   const char*  aPtrEnd      = aPtrIter + strlen (theExtString);
580   const size_t anExtNameLen = strlen (theExtName);
581   while (aPtrIter < aPtrEnd)
582   {
583     const size_t n = strcspn (aPtrIter, " ");
584     if ((n == anExtNameLen) && (strncmp (aPtrIter, theExtName, anExtNameLen) == 0))
585     {
586       return Standard_True;
587     }
588     aPtrIter += (n + 1);
589   }
590   return Standard_False;
591 }
592
593 #if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
594
595 // =======================================================================
596 // function : Init
597 // purpose  :
598 // =======================================================================
599 Standard_Boolean OpenGl_Context::Init()
600 {
601   if (myIsInitialized)
602   {
603     return Standard_True;
604   }
605
606 #if defined(HAVE_EGL)
607   myDisplay  = (Aspect_Display )eglGetCurrentDisplay();
608   myGContext = (Aspect_RenderingContext )eglGetCurrentContext();
609   myWindow   = (Aspect_Drawable )eglGetCurrentSurface(EGL_DRAW);
610 #elif defined(_WIN32)
611   myWindowDC = (Aspect_Handle )wglGetCurrentDC();
612   myGContext = (Aspect_RenderingContext )wglGetCurrentContext();
613 #else
614   myDisplay  = (Aspect_Display )glXGetCurrentDisplay();
615   myGContext = (Aspect_RenderingContext )glXGetCurrentContext();
616   myWindow   = (Aspect_Drawable )glXGetCurrentDrawable();
617 #endif
618   if (myGContext == NULL)
619   {
620     return Standard_False;
621   }
622
623   init();
624   myIsInitialized = Standard_True;
625   return Standard_True;
626 }
627
628 #endif // __APPLE__
629
630 // =======================================================================
631 // function : Init
632 // purpose  :
633 // =======================================================================
634 #if defined(HAVE_EGL)
635 Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable         theEglSurface,
636                                        const Aspect_Display          theEglDisplay,
637                                        const Aspect_RenderingContext theEglContext)
638 #elif defined(_WIN32)
639 Standard_Boolean OpenGl_Context::Init (const Aspect_Handle           theWindow,
640                                        const Aspect_Handle           theWindowDC,
641                                        const Aspect_RenderingContext theGContext)
642 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
643 Standard_Boolean OpenGl_Context::Init (const void*                   theGContext)
644 #else
645 Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable         theWindow,
646                                        const Aspect_Display          theDisplay,
647                                        const Aspect_RenderingContext theGContext)
648 #endif
649 {
650   Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called only once!");
651 #if defined(HAVE_EGL)
652   myWindow   = theEglSurface;
653   myGContext = theEglContext;
654   myDisplay  = theEglDisplay;
655 #elif defined(_WIN32)
656   myWindow   = theWindow;
657   myGContext = theGContext;
658   myWindowDC = theWindowDC;
659 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
660   myGContext = (void* )theGContext;
661 #else
662   myWindow   = theWindow;
663   myGContext = theGContext;
664   myDisplay  = theDisplay;
665 #endif
666   if (myGContext == NULL || !MakeCurrent())
667   {
668     return Standard_False;
669   }
670
671   init();
672   myIsInitialized = Standard_True;
673   return Standard_True;
674 }
675
676 // =======================================================================
677 // function : ResetErrors
678 // purpose  :
679 // =======================================================================
680 void OpenGl_Context::ResetErrors()
681 {
682   while (glGetError() != GL_NO_ERROR)
683   {
684     //
685   }
686 }
687
688 // =======================================================================
689 // function : readGlVersion
690 // purpose  :
691 // =======================================================================
692 void OpenGl_Context::readGlVersion()
693 {
694   // reset values
695   myGlVerMajor = 0;
696   myGlVerMinor = 0;
697
698 #ifdef GL_MAJOR_VERSION
699   // available since OpenGL 3.0 and OpenGL 3.0 ES
700   GLint aMajor = 0, aMinor = 0;
701   glGetIntegerv (GL_MAJOR_VERSION, &aMajor);
702   glGetIntegerv (GL_MINOR_VERSION, &aMinor);
703   // glGetError() sometimes does not report an error here even if
704   // GL does not know GL_MAJOR_VERSION and GL_MINOR_VERSION constants.
705   // This happens on some renderers like e.g. Cygwin MESA.
706   // Thus checking additionally if GL has put anything to
707   // the output variables.
708   if (glGetError() == GL_NO_ERROR && aMajor != 0 && aMinor != 0)
709   {
710     myGlVerMajor = aMajor;
711     myGlVerMinor = aMinor;
712     return;
713   }
714   ResetErrors();
715 #endif
716
717   // Read version string.
718   // Notice that only first two numbers split by point '2.1 XXXXX' are significant.
719   // Following trash (after space) is vendor-specific.
720   // New drivers also returns micro version of GL like '3.3.0' which has no meaning
721   // and should be considered as vendor-specific too.
722   const char* aVerStr = (const char* )glGetString (GL_VERSION);
723   if (aVerStr == NULL || *aVerStr == '\0')
724   {
725     // invalid GL context
726     return;
727   }
728
729 //#if defined(GL_ES_VERSION_2_0)
730   // skip "OpenGL ES-** " section
731   for (; *aVerStr != '\0'; ++aVerStr)
732   {
733     if (*aVerStr >= '0' && *aVerStr <= '9')
734     {
735       break;
736     }
737   }
738 //#endif
739
740   // parse string for major number
741   char aMajorStr[32];
742   char aMinorStr[32];
743   size_t aMajIter = 0;
744   while (aVerStr[aMajIter] >= '0' && aVerStr[aMajIter] <= '9')
745   {
746     ++aMajIter;
747   }
748   if (aMajIter == 0 || aMajIter >= sizeof(aMajorStr))
749   {
750     return;
751   }
752   memcpy (aMajorStr, aVerStr, aMajIter);
753   aMajorStr[aMajIter] = '\0';
754
755   // parse string for minor number
756   aVerStr += aMajIter + 1;
757   size_t aMinIter = 0;
758   while (aVerStr[aMinIter] >= '0' && aVerStr[aMinIter] <= '9')
759   {
760     ++aMinIter;
761   }
762   if (aMinIter == 0 || aMinIter >= sizeof(aMinorStr))
763   {
764     return;
765   }
766   memcpy (aMinorStr, aVerStr, aMinIter);
767   aMinorStr[aMinIter] = '\0';
768
769   // read numbers
770   myGlVerMajor = atoi (aMajorStr);
771   myGlVerMinor = atoi (aMinorStr);
772
773   if (myGlVerMajor <= 0)
774   {
775     myGlVerMajor = 0;
776     myGlVerMinor = 0;
777   }
778 }
779
780 static Standard_CString THE_DBGMSG_UNKNOWN = "UNKNOWN";
781 static Standard_CString THE_DBGMSG_SOURCES[] =
782 {
783   ".OpenGL",    // GL_DEBUG_SOURCE_API_ARB
784   ".WinSystem", // GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB
785   ".GLSL",      // GL_DEBUG_SOURCE_SHADER_COMPILER_ARB
786   ".3rdParty",  // GL_DEBUG_SOURCE_THIRD_PARTY_ARB
787   "",           // GL_DEBUG_SOURCE_APPLICATION_ARB
788   ".Other"      // GL_DEBUG_SOURCE_OTHER_ARB
789 };
790
791 static Standard_CString THE_DBGMSG_TYPES[] =
792 {
793   "Error",           // GL_DEBUG_TYPE_ERROR_ARB
794   "Deprecated",      // GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB
795   "Undef. behavior", // GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB
796   "Portability",     // GL_DEBUG_TYPE_PORTABILITY_ARB
797   "Performance",     // GL_DEBUG_TYPE_PERFORMANCE_ARB
798   "Other"            // GL_DEBUG_TYPE_OTHER_ARB
799 };
800
801 static Standard_CString THE_DBGMSG_SEV_HIGH   = "High";   // GL_DEBUG_SEVERITY_HIGH_ARB
802 static Standard_CString THE_DBGMSG_SEV_MEDIUM = "Medium"; // GL_DEBUG_SEVERITY_MEDIUM_ARB
803 static Standard_CString THE_DBGMSG_SEV_LOW    = "Low";    // GL_DEBUG_SEVERITY_LOW_ARB
804
805 #if !defined(GL_ES_VERSION_2_0)
806 //! Callback for GL_ARB_debug_output extension
807 static void APIENTRY debugCallbackWrap(unsigned int theSource,
808                                        unsigned int theType,
809                                        unsigned int theId,
810                                        unsigned int theSeverity,
811                                        int          /*theLength*/,
812                                        const char*  theMessage,
813                                        const void*  theUserParam)
814 {
815   OpenGl_Context* aCtx = (OpenGl_Context* )theUserParam;
816   aCtx->PushMessage (theSource, theType, theId, theSeverity, theMessage);
817 }
818 #endif
819
820 // =======================================================================
821 // function : PushMessage
822 // purpose  :
823 // =======================================================================
824 void OpenGl_Context::PushMessage (const unsigned int theSource,
825                                   const unsigned int theType,
826                                   const unsigned int theId,
827                                   const unsigned int theSeverity,
828                                   const TCollection_ExtendedString& theMessage)
829 {
830   //OpenGl_Context* aCtx = (OpenGl_Context* )theUserParam;
831   Standard_CString& aSrc = (theSource >= GL_DEBUG_SOURCE_API_ARB
832                         && theSource <= GL_DEBUG_SOURCE_OTHER_ARB)
833                          ? THE_DBGMSG_SOURCES[theSource - GL_DEBUG_SOURCE_API_ARB]
834                          : THE_DBGMSG_UNKNOWN;
835   Standard_CString& aType = (theType >= GL_DEBUG_TYPE_ERROR_ARB
836                          && theType <= GL_DEBUG_TYPE_OTHER_ARB)
837                           ? THE_DBGMSG_TYPES[theType - GL_DEBUG_TYPE_ERROR_ARB]
838                           : THE_DBGMSG_UNKNOWN;
839   Standard_CString& aSev = theSeverity == GL_DEBUG_SEVERITY_HIGH_ARB
840                          ? THE_DBGMSG_SEV_HIGH
841                          : (theSeverity == GL_DEBUG_SEVERITY_MEDIUM_ARB
842                           ? THE_DBGMSG_SEV_MEDIUM
843                           : THE_DBGMSG_SEV_LOW);
844   Message_Gravity aGrav = theSeverity == GL_DEBUG_SEVERITY_HIGH_ARB
845                         ? Message_Alarm
846                         : (theSeverity == GL_DEBUG_SEVERITY_MEDIUM_ARB
847                          ? Message_Warning
848                          : Message_Info);
849
850   TCollection_ExtendedString aMsg;
851   aMsg += "TKOpenGl"; aMsg += aSrc;
852   aMsg += " | Type: ";        aMsg += aType;
853   aMsg += " | ID: ";          aMsg += (Standard_Integer )theId;
854   aMsg += " | Severity: ";    aMsg += aSev;
855   aMsg += " | Message:\n  ";
856   aMsg += theMessage;
857   Messenger()->Send (aMsg, aGrav);
858 }
859
860 // =======================================================================
861 // function : init
862 // purpose  :
863 // =======================================================================
864 void OpenGl_Context::init()
865 {
866   // read version
867   readGlVersion();
868
869   core11     = (OpenGl_GlCore11*    )(&(*myFuncs));
870   core11fwd  = (OpenGl_GlCore11Fwd* )(&(*myFuncs));
871   core15     = NULL;
872   core15fwd  = NULL;
873   core20     = NULL;
874   core20fwd  = NULL;
875   core32     = NULL;
876   core32back = NULL;
877   core33     = NULL;
878   core33back = NULL;
879   core41     = NULL;
880   core41back = NULL;
881   core42     = NULL;
882   core42back = NULL;
883   core43     = NULL;
884   core43back = NULL;
885   core44     = NULL;
886   core44back = NULL;
887   arbTBO     = NULL;
888   arbTboRGB32 = Standard_False;
889   arbIns     = NULL;
890   arbDbg     = NULL;
891   arbFBO     = NULL;
892   extGS      = NULL;
893
894 #if defined(GL_ES_VERSION_2_0)
895
896   hasTexRGBA8 = IsGlGreaterEqual (3, 0)
897              || CheckExtension ("GL_OES_rgb8_rgba8");
898   // NPOT textures has limited support within OpenGL ES 2.0
899   // which are relaxed by OpenGL ES 3.0 or some extensions
900   //arbNPTW     = IsGlGreaterEqual (3, 0)
901   //           || CheckExtension ("GL_OES_texture_npot")
902   //           || CheckExtension ("GL_NV_texture_npot_2D_mipmap");
903   arbNPTW     = Standard_True;
904   arbTexRG    = IsGlGreaterEqual (3, 0)
905              || CheckExtension ("GL_EXT_texture_rg");
906   extBgra     = CheckExtension ("GL_EXT_texture_format_BGRA8888");
907   extAnis = CheckExtension ("GL_EXT_texture_filter_anisotropic");
908   extPDS  = CheckExtension ("GL_OES_packed_depth_stencil");
909
910   core11fwd = (OpenGl_GlCore11Fwd* )(&(*myFuncs));
911   if (IsGlGreaterEqual (2, 0))
912   {
913     // enable compatible functions
914     core20    = (OpenGl_GlCore20*    )(&(*myFuncs));
915     core20fwd = (OpenGl_GlCore20Fwd* )(&(*myFuncs));
916     core15fwd = (OpenGl_GlCore15Fwd* )(&(*myFuncs));
917     arbFBO    = (OpenGl_ArbFBO* )(&(*myFuncs));
918   }
919
920   hasHighp = CheckExtension ("OES_fragment_precision_high");
921   GLint aRange[2] = {0, 0};
922   GLint aPrec [2] = {0, 0};
923   ::glGetShaderPrecisionFormat (GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, aRange, aPrec);
924   if (aPrec[1] != 0)
925   {
926     hasHighp = Standard_True;
927   }
928 #else
929
930   myTexClamp = IsGlGreaterEqual (1, 2) ? GL_CLAMP_TO_EDGE : GL_CLAMP;
931
932   hasTexRGBA8 = Standard_True;
933   arbNPTW = CheckExtension ("GL_ARB_texture_non_power_of_two");
934   extBgra = CheckExtension ("GL_EXT_bgra");
935   extAnis = CheckExtension ("GL_EXT_texture_filter_anisotropic");
936   extPDS  = CheckExtension ("GL_EXT_packed_depth_stencil");
937   atiMem  = CheckExtension ("GL_ATI_meminfo");
938   nvxMem  = CheckExtension ("GL_NVX_gpu_memory_info");
939
940   GLint aStereo = GL_FALSE;
941   glGetIntegerv (GL_STEREO, &aStereo);
942   myIsStereoBuffers = aStereo == 1;
943
944   // get number of maximum clipping planes
945   glGetIntegerv (GL_MAX_CLIP_PLANES,  &myMaxClipPlanes);
946 #endif
947
948   glGetIntegerv (GL_MAX_TEXTURE_SIZE, &myMaxTexDim);
949
950   if (extAnis)
951   {
952     glGetIntegerv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &myAnisoMax);
953   }
954
955   myClippingState.Init (myMaxClipPlanes);
956
957 #if !defined(GL_ES_VERSION_2_0)
958
959   bool has12 = false;
960   bool has13 = false;
961   bool has14 = false;
962   bool has15 = false;
963   bool has20 = false;
964   bool has21 = false;
965   bool has30 = false;
966   bool has31 = false;
967   bool has32 = false;
968   bool has33 = false;
969   bool has40 = false;
970   bool has41 = false;
971   bool has42 = false;
972   bool has43 = false;
973   bool has44 = false;
974
975   //! Make record shorter to retrieve function pointer using variable with same name
976   #define FindProcShort(theFunc) FindProc(#theFunc, myFuncs->theFunc)
977
978     // retrieve platform-dependent extensions
979 #if defined(_WIN32) && !defined(HAVE_EGL)
980   if (FindProcShort (wglGetExtensionsStringARB))
981   {
982     const char* aWglExts = myFuncs->wglGetExtensionsStringARB (wglGetCurrentDC());
983     if (CheckExtension (aWglExts, "WGL_EXT_swap_control"))
984     {
985       FindProcShort (wglSwapIntervalEXT);
986     }
987     if (CheckExtension (aWglExts, "WGL_ARB_pixel_format"))
988     {
989       FindProcShort (wglChoosePixelFormatARB);
990     }
991     if (CheckExtension (aWglExts, "WGL_ARB_create_context_profile"))
992     {
993       FindProcShort (wglCreateContextAttribsARB);
994     }
995     if (CheckExtension (aWglExts, "WGL_NV_DX_interop"))
996     {
997       FindProcShort (wglDXSetResourceShareHandleNV);
998       FindProcShort (wglDXOpenDeviceNV);
999       FindProcShort (wglDXCloseDeviceNV);
1000       FindProcShort (wglDXRegisterObjectNV);
1001       FindProcShort (wglDXUnregisterObjectNV);
1002       FindProcShort (wglDXObjectAccessNV);
1003       FindProcShort (wglDXLockObjectsNV);
1004       FindProcShort (wglDXUnlockObjectsNV);
1005     }
1006   }
1007 #endif
1008
1009   // initialize debug context extension
1010   if (CheckExtension ("GL_ARB_debug_output"))
1011   {
1012     arbDbg = NULL;
1013     if (FindProcShort (glDebugMessageControlARB)
1014      && FindProcShort (glDebugMessageInsertARB)
1015      && FindProcShort (glDebugMessageCallbackARB)
1016      && FindProcShort (glGetDebugMessageLogARB))
1017     {
1018       arbDbg = (OpenGl_ArbDbg* )(&(*myFuncs));
1019     }
1020     if (arbDbg != NULL
1021      && caps->contextDebug)
1022     {
1023       // setup default callback
1024       arbDbg->glDebugMessageCallbackARB (debugCallbackWrap, this);
1025     #ifdef OCCT_DEBUG
1026       glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
1027     #endif
1028     }
1029   }
1030
1031   // load OpenGL 1.2 new functions
1032   has12 = IsGlGreaterEqual (1, 2)
1033        && FindProcShort (glBlendColor)
1034        && FindProcShort (glBlendEquation)
1035        && FindProcShort (glDrawRangeElements)
1036        && FindProcShort (glTexImage3D)
1037        && FindProcShort (glTexSubImage3D)
1038        && FindProcShort (glCopyTexSubImage3D);
1039
1040   // load OpenGL 1.3 new functions
1041   has13 = IsGlGreaterEqual (1, 3)
1042        && FindProcShort (glActiveTexture)
1043        && FindProcShort (glSampleCoverage)
1044        && FindProcShort (glCompressedTexImage3D)
1045        && FindProcShort (glCompressedTexImage2D)
1046        && FindProcShort (glCompressedTexImage1D)
1047        && FindProcShort (glCompressedTexSubImage3D)
1048        && FindProcShort (glCompressedTexSubImage2D)
1049        && FindProcShort (glCompressedTexSubImage1D)
1050        && FindProcShort (glGetCompressedTexImage)
1051        && FindProcShort (glClientActiveTexture)
1052        && FindProcShort (glMultiTexCoord1d)
1053        && FindProcShort (glMultiTexCoord1dv)
1054        && FindProcShort (glMultiTexCoord1f)
1055        && FindProcShort (glMultiTexCoord1fv)
1056        && FindProcShort (glMultiTexCoord1i)
1057        && FindProcShort (glMultiTexCoord1iv)
1058        && FindProcShort (glMultiTexCoord1s)
1059        && FindProcShort (glMultiTexCoord1sv)
1060        && FindProcShort (glMultiTexCoord2d)
1061        && FindProcShort (glMultiTexCoord2dv)
1062        && FindProcShort (glMultiTexCoord2f)
1063        && FindProcShort (glMultiTexCoord2fv)
1064        && FindProcShort (glMultiTexCoord2i)
1065        && FindProcShort (glMultiTexCoord2iv)
1066        && FindProcShort (glMultiTexCoord2s)
1067        && FindProcShort (glMultiTexCoord2sv)
1068        && FindProcShort (glMultiTexCoord3d)
1069        && FindProcShort (glMultiTexCoord3dv)
1070        && FindProcShort (glMultiTexCoord3f)
1071        && FindProcShort (glMultiTexCoord3fv)
1072        && FindProcShort (glMultiTexCoord3i)
1073        && FindProcShort (glMultiTexCoord3iv)
1074        && FindProcShort (glMultiTexCoord3s)
1075        && FindProcShort (glMultiTexCoord3sv)
1076        && FindProcShort (glMultiTexCoord4d)
1077        && FindProcShort (glMultiTexCoord4dv)
1078        && FindProcShort (glMultiTexCoord4f)
1079        && FindProcShort (glMultiTexCoord4fv)
1080        && FindProcShort (glMultiTexCoord4i)
1081        && FindProcShort (glMultiTexCoord4iv)
1082        && FindProcShort (glMultiTexCoord4s)
1083        && FindProcShort (glMultiTexCoord4sv)
1084        && FindProcShort (glLoadTransposeMatrixf)
1085        && FindProcShort (glLoadTransposeMatrixd)
1086        && FindProcShort (glMultTransposeMatrixf)
1087        && FindProcShort (glMultTransposeMatrixd);
1088
1089   // load OpenGL 1.4 new functions
1090   has14 = IsGlGreaterEqual (1, 4)
1091        && FindProcShort (glBlendFuncSeparate)
1092        && FindProcShort (glMultiDrawArrays)
1093        && FindProcShort (glMultiDrawElements)
1094        && FindProcShort (glPointParameterf)
1095        && FindProcShort (glPointParameterfv)
1096        && FindProcShort (glPointParameteri)
1097        && FindProcShort (glPointParameteriv);
1098
1099   // load OpenGL 1.5 new functions
1100   has15 = IsGlGreaterEqual (1, 5)
1101        && FindProcShort (glGenQueries)
1102        && FindProcShort (glDeleteQueries)
1103        && FindProcShort (glIsQuery)
1104        && FindProcShort (glBeginQuery)
1105        && FindProcShort (glEndQuery)
1106        && FindProcShort (glGetQueryiv)
1107        && FindProcShort (glGetQueryObjectiv)
1108        && FindProcShort (glGetQueryObjectuiv)
1109        && FindProcShort (glBindBuffer)
1110        && FindProcShort (glDeleteBuffers)
1111        && FindProcShort (glGenBuffers)
1112        && FindProcShort (glIsBuffer)
1113        && FindProcShort (glBufferData)
1114        && FindProcShort (glBufferSubData)
1115        && FindProcShort (glGetBufferSubData)
1116        && FindProcShort (glMapBuffer)
1117        && FindProcShort (glUnmapBuffer)
1118        && FindProcShort (glGetBufferParameteriv)
1119        && FindProcShort (glGetBufferPointerv);
1120
1121   // load OpenGL 2.0 new functions
1122   has20 = IsGlGreaterEqual (2, 0)
1123        && FindProcShort (glBlendEquationSeparate)
1124        && FindProcShort (glDrawBuffers)
1125        && FindProcShort (glStencilOpSeparate)
1126        && FindProcShort (glStencilFuncSeparate)
1127        && FindProcShort (glStencilMaskSeparate)
1128        && FindProcShort (glAttachShader)
1129        && FindProcShort (glBindAttribLocation)
1130        && FindProcShort (glCompileShader)
1131        && FindProcShort (glCreateProgram)
1132        && FindProcShort (glCreateShader)
1133        && FindProcShort (glDeleteProgram)
1134        && FindProcShort (glDeleteShader)
1135        && FindProcShort (glDetachShader)
1136        && FindProcShort (glDisableVertexAttribArray)
1137        && FindProcShort (glEnableVertexAttribArray)
1138        && FindProcShort (glGetActiveAttrib)
1139        && FindProcShort (glGetActiveUniform)
1140        && FindProcShort (glGetAttachedShaders)
1141        && FindProcShort (glGetAttribLocation)
1142        && FindProcShort (glGetProgramiv)
1143        && FindProcShort (glGetProgramInfoLog)
1144        && FindProcShort (glGetShaderiv)
1145        && FindProcShort (glGetShaderInfoLog)
1146        && FindProcShort (glGetShaderSource)
1147        && FindProcShort (glGetUniformLocation)
1148        && FindProcShort (glGetUniformfv)
1149        && FindProcShort (glGetUniformiv)
1150        && FindProcShort (glGetVertexAttribdv)
1151        && FindProcShort (glGetVertexAttribfv)
1152        && FindProcShort (glGetVertexAttribiv)
1153        && FindProcShort (glGetVertexAttribPointerv)
1154        && FindProcShort (glIsProgram)
1155        && FindProcShort (glIsShader)
1156        && FindProcShort (glLinkProgram)
1157        && FindProcShort (glShaderSource)
1158        && FindProcShort (glUseProgram)
1159        && FindProcShort (glUniform1f)
1160        && FindProcShort (glUniform2f)
1161        && FindProcShort (glUniform3f)
1162        && FindProcShort (glUniform4f)
1163        && FindProcShort (glUniform1i)
1164        && FindProcShort (glUniform2i)
1165        && FindProcShort (glUniform3i)
1166        && FindProcShort (glUniform4i)
1167        && FindProcShort (glUniform1fv)
1168        && FindProcShort (glUniform2fv)
1169        && FindProcShort (glUniform3fv)
1170        && FindProcShort (glUniform4fv)
1171        && FindProcShort (glUniform1iv)
1172        && FindProcShort (glUniform2iv)
1173        && FindProcShort (glUniform3iv)
1174        && FindProcShort (glUniform4iv)
1175        && FindProcShort (glUniformMatrix2fv)
1176        && FindProcShort (glUniformMatrix3fv)
1177        && FindProcShort (glUniformMatrix4fv)
1178        && FindProcShort (glValidateProgram)
1179        && FindProcShort (glVertexAttrib1d)
1180        && FindProcShort (glVertexAttrib1dv)
1181        && FindProcShort (glVertexAttrib1f)
1182        && FindProcShort (glVertexAttrib1fv)
1183        && FindProcShort (glVertexAttrib1s)
1184        && FindProcShort (glVertexAttrib1sv)
1185        && FindProcShort (glVertexAttrib2d)
1186        && FindProcShort (glVertexAttrib2dv)
1187        && FindProcShort (glVertexAttrib2f)
1188        && FindProcShort (glVertexAttrib2fv)
1189        && FindProcShort (glVertexAttrib2s)
1190        && FindProcShort (glVertexAttrib2sv)
1191        && FindProcShort (glVertexAttrib3d)
1192        && FindProcShort (glVertexAttrib3dv)
1193        && FindProcShort (glVertexAttrib3f)
1194        && FindProcShort (glVertexAttrib3fv)
1195        && FindProcShort (glVertexAttrib3s)
1196        && FindProcShort (glVertexAttrib3sv)
1197        && FindProcShort (glVertexAttrib4Nbv)
1198        && FindProcShort (glVertexAttrib4Niv)
1199        && FindProcShort (glVertexAttrib4Nsv)
1200        && FindProcShort (glVertexAttrib4Nub)
1201        && FindProcShort (glVertexAttrib4Nubv)
1202        && FindProcShort (glVertexAttrib4Nuiv)
1203        && FindProcShort (glVertexAttrib4Nusv)
1204        && FindProcShort (glVertexAttrib4bv)
1205        && FindProcShort (glVertexAttrib4d)
1206        && FindProcShort (glVertexAttrib4dv)
1207        && FindProcShort (glVertexAttrib4f)
1208        && FindProcShort (glVertexAttrib4fv)
1209        && FindProcShort (glVertexAttrib4iv)
1210        && FindProcShort (glVertexAttrib4s)
1211        && FindProcShort (glVertexAttrib4sv)
1212        && FindProcShort (glVertexAttrib4ubv)
1213        && FindProcShort (glVertexAttrib4uiv)
1214        && FindProcShort (glVertexAttrib4usv)
1215        && FindProcShort (glVertexAttribPointer);
1216
1217   // load OpenGL 2.1 new functions
1218   has21 = IsGlGreaterEqual (2, 1)
1219        && FindProcShort (glUniformMatrix2x3fv)
1220        && FindProcShort (glUniformMatrix3x2fv)
1221        && FindProcShort (glUniformMatrix2x4fv)
1222        && FindProcShort (glUniformMatrix4x2fv)
1223        && FindProcShort (glUniformMatrix3x4fv)
1224        && FindProcShort (glUniformMatrix4x3fv);
1225
1226   // load GL_ARB_framebuffer_object (added to OpenGL 3.0 core)
1227   const bool hasFBO = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_framebuffer_object"))
1228        && FindProcShort (glIsRenderbuffer)
1229        && FindProcShort (glBindRenderbuffer)
1230        && FindProcShort (glDeleteRenderbuffers)
1231        && FindProcShort (glGenRenderbuffers)
1232        && FindProcShort (glRenderbufferStorage)
1233        && FindProcShort (glGetRenderbufferParameteriv)
1234        && FindProcShort (glIsFramebuffer)
1235        && FindProcShort (glBindFramebuffer)
1236        && FindProcShort (glDeleteFramebuffers)
1237        && FindProcShort (glGenFramebuffers)
1238        && FindProcShort (glCheckFramebufferStatus)
1239        && FindProcShort (glFramebufferTexture1D)
1240        && FindProcShort (glFramebufferTexture2D)
1241        && FindProcShort (glFramebufferTexture3D)
1242        && FindProcShort (glFramebufferRenderbuffer)
1243        && FindProcShort (glGetFramebufferAttachmentParameteriv)
1244        && FindProcShort (glGenerateMipmap)
1245        && FindProcShort (glBlitFramebuffer)
1246        && FindProcShort (glRenderbufferStorageMultisample)
1247        && FindProcShort (glFramebufferTextureLayer);
1248
1249   // load GL_ARB_vertex_array_object (added to OpenGL 3.0 core)
1250   const bool hasVAO = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_vertex_array_object"))
1251        && FindProcShort (glBindVertexArray)
1252        && FindProcShort (glDeleteVertexArrays)
1253        && FindProcShort (glGenVertexArrays)
1254        && FindProcShort (glIsVertexArray);
1255
1256   // load GL_ARB_map_buffer_range (added to OpenGL 3.0 core)
1257   const bool hasMapBufferRange = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_map_buffer_range"))
1258        && FindProcShort (glMapBufferRange)
1259        && FindProcShort (glFlushMappedBufferRange);
1260
1261   // load OpenGL 3.0 new functions
1262   has30 = IsGlGreaterEqual (3, 0)
1263        && hasFBO
1264        && hasVAO
1265        && hasMapBufferRange
1266        && FindProcShort (glColorMaski)
1267        && FindProcShort (glGetBooleani_v)
1268        && FindProcShort (glGetIntegeri_v)
1269        && FindProcShort (glEnablei)
1270        && FindProcShort (glDisablei)
1271        && FindProcShort (glIsEnabledi)
1272        && FindProcShort (glBeginTransformFeedback)
1273        && FindProcShort (glEndTransformFeedback)
1274        && FindProcShort (glBindBufferRange)
1275        && FindProcShort (glBindBufferBase)
1276        && FindProcShort (glTransformFeedbackVaryings)
1277        && FindProcShort (glGetTransformFeedbackVarying)
1278        && FindProcShort (glClampColor)
1279        && FindProcShort (glBeginConditionalRender)
1280        && FindProcShort (glEndConditionalRender)
1281        && FindProcShort (glVertexAttribIPointer)
1282        && FindProcShort (glGetVertexAttribIiv)
1283        && FindProcShort (glGetVertexAttribIuiv)
1284        && FindProcShort (glVertexAttribI1i)
1285        && FindProcShort (glVertexAttribI2i)
1286        && FindProcShort (glVertexAttribI3i)
1287        && FindProcShort (glVertexAttribI4i)
1288        && FindProcShort (glVertexAttribI1ui)
1289        && FindProcShort (glVertexAttribI2ui)
1290        && FindProcShort (glVertexAttribI3ui)
1291        && FindProcShort (glVertexAttribI4ui)
1292        && FindProcShort (glVertexAttribI1iv)
1293        && FindProcShort (glVertexAttribI2iv)
1294        && FindProcShort (glVertexAttribI3iv)
1295        && FindProcShort (glVertexAttribI4iv)
1296        && FindProcShort (glVertexAttribI1uiv)
1297        && FindProcShort (glVertexAttribI2uiv)
1298        && FindProcShort (glVertexAttribI3uiv)
1299        && FindProcShort (glVertexAttribI4uiv)
1300        && FindProcShort (glVertexAttribI4bv)
1301        && FindProcShort (glVertexAttribI4sv)
1302        && FindProcShort (glVertexAttribI4ubv)
1303        && FindProcShort (glVertexAttribI4usv)
1304        && FindProcShort (glGetUniformuiv)
1305        && FindProcShort (glBindFragDataLocation)
1306        && FindProcShort (glGetFragDataLocation)
1307        && FindProcShort (glUniform1ui)
1308        && FindProcShort (glUniform2ui)
1309        && FindProcShort (glUniform3ui)
1310        && FindProcShort (glUniform4ui)
1311        && FindProcShort (glUniform1uiv)
1312        && FindProcShort (glUniform2uiv)
1313        && FindProcShort (glUniform3uiv)
1314        && FindProcShort (glUniform4uiv)
1315        && FindProcShort (glTexParameterIiv)
1316        && FindProcShort (glTexParameterIuiv)
1317        && FindProcShort (glGetTexParameterIiv)
1318        && FindProcShort (glGetTexParameterIuiv)
1319        && FindProcShort (glClearBufferiv)
1320        && FindProcShort (glClearBufferuiv)
1321        && FindProcShort (glClearBufferfv)
1322        && FindProcShort (glClearBufferfi)
1323        && FindProcShort (glGetStringi);
1324
1325   // load GL_ARB_uniform_buffer_object (added to OpenGL 3.1 core)
1326   const bool hasUBO = (IsGlGreaterEqual (3, 1) || CheckExtension ("GL_ARB_uniform_buffer_object"))
1327        && FindProcShort (glGetUniformIndices)
1328        && FindProcShort (glGetActiveUniformsiv)
1329        && FindProcShort (glGetActiveUniformName)
1330        && FindProcShort (glGetUniformBlockIndex)
1331        && FindProcShort (glGetActiveUniformBlockiv)
1332        && FindProcShort (glGetActiveUniformBlockName)
1333        && FindProcShort (glUniformBlockBinding);
1334
1335   // load GL_ARB_copy_buffer (added to OpenGL 3.1 core)
1336   const bool hasCopyBufSubData = (IsGlGreaterEqual (3, 1) || CheckExtension ("GL_ARB_copy_buffer"))
1337        && FindProcShort (glCopyBufferSubData);
1338
1339   if (has30)
1340   {
1341     // NPOT textures are required by OpenGL 2.0 specifications
1342     // but doesn't hardware accelerated by some ancient OpenGL 2.1 hardware (GeForce FX, RadeOn 9700 etc.)
1343     arbNPTW  = Standard_True;
1344     arbTexRG = Standard_True;
1345   }
1346
1347   // load OpenGL 3.1 new functions
1348   has31 = IsGlGreaterEqual (3, 1)
1349        && hasUBO
1350        && hasCopyBufSubData
1351        && FindProcShort (glDrawArraysInstanced)
1352        && FindProcShort (glDrawElementsInstanced)
1353        && FindProcShort (glTexBuffer)
1354        && FindProcShort (glPrimitiveRestartIndex);
1355
1356   // load GL_ARB_draw_elements_base_vertex (added to OpenGL 3.2 core)
1357   const bool hasDrawElemsBaseVert = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_draw_elements_base_vertex"))
1358        && FindProcShort (glDrawElementsBaseVertex)
1359        && FindProcShort (glDrawRangeElementsBaseVertex)
1360        && FindProcShort (glDrawElementsInstancedBaseVertex)
1361        && FindProcShort (glMultiDrawElementsBaseVertex);
1362
1363   // load GL_ARB_provoking_vertex (added to OpenGL 3.2 core)
1364   const bool hasProvokingVert = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_provoking_vertex"))
1365        && FindProcShort (glProvokingVertex);
1366
1367   // load GL_ARB_sync (added to OpenGL 3.2 core)
1368   const bool hasSync = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_sync"))
1369        && FindProcShort (glFenceSync)
1370        && FindProcShort (glIsSync)
1371        && FindProcShort (glDeleteSync)
1372        && FindProcShort (glClientWaitSync)
1373        && FindProcShort (glWaitSync)
1374        && FindProcShort (glGetInteger64v)
1375        && FindProcShort (glGetSynciv);
1376
1377   // load GL_ARB_texture_multisample (added to OpenGL 3.2 core)
1378   const bool hasTextureMultisample = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_texture_multisample"))
1379        && FindProcShort (glTexImage2DMultisample)
1380        && FindProcShort (glTexImage3DMultisample)
1381        && FindProcShort (glGetMultisamplefv)
1382        && FindProcShort (glSampleMaski);
1383
1384   // load OpenGL 3.2 new functions
1385   has32 = IsGlGreaterEqual (3, 2)
1386        && hasDrawElemsBaseVert
1387        && hasProvokingVert
1388        && hasSync
1389        && hasTextureMultisample
1390        && FindProcShort (glGetInteger64i_v)
1391        && FindProcShort (glGetBufferParameteri64v)
1392        && FindProcShort (glFramebufferTexture);
1393
1394   // load GL_ARB_blend_func_extended (added to OpenGL 3.3 core)
1395   const bool hasBlendFuncExtended = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_blend_func_extended"))
1396        && FindProcShort (glBindFragDataLocationIndexed)
1397        && FindProcShort (glGetFragDataIndex);
1398
1399   // load GL_ARB_sampler_objects (added to OpenGL 3.3 core)
1400   const bool hasSamplerObjects = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_sampler_objects"))
1401        && FindProcShort (glGenSamplers)
1402        && FindProcShort (glDeleteSamplers)
1403        && FindProcShort (glIsSampler)
1404        && FindProcShort (glBindSampler)
1405        && FindProcShort (glSamplerParameteri)
1406        && FindProcShort (glSamplerParameteriv)
1407        && FindProcShort (glSamplerParameterf)
1408        && FindProcShort (glSamplerParameterfv)
1409        && FindProcShort (glSamplerParameterIiv)
1410        && FindProcShort (glSamplerParameterIuiv)
1411        && FindProcShort (glGetSamplerParameteriv)
1412        && FindProcShort (glGetSamplerParameterIiv)
1413        && FindProcShort (glGetSamplerParameterfv)
1414        && FindProcShort (glGetSamplerParameterIuiv);
1415
1416   // load GL_ARB_timer_query (added to OpenGL 3.3 core)
1417   const bool hasTimerQuery = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_timer_query"))
1418        && FindProcShort (glQueryCounter)
1419        && FindProcShort (glGetQueryObjecti64v)
1420        && FindProcShort (glGetQueryObjectui64v);
1421
1422   // load GL_ARB_vertex_type_2_10_10_10_rev (added to OpenGL 3.3 core)
1423   const bool hasVertType21010101rev = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_vertex_type_2_10_10_10_rev"))
1424        && FindProcShort (glVertexP2ui)
1425        && FindProcShort (glVertexP2uiv)
1426        && FindProcShort (glVertexP3ui)
1427        && FindProcShort (glVertexP3uiv)
1428        && FindProcShort (glVertexP4ui)
1429        && FindProcShort (glVertexP4uiv)
1430        && FindProcShort (glTexCoordP1ui)
1431        && FindProcShort (glTexCoordP1uiv)
1432        && FindProcShort (glTexCoordP2ui)
1433        && FindProcShort (glTexCoordP2uiv)
1434        && FindProcShort (glTexCoordP3ui)
1435        && FindProcShort (glTexCoordP3uiv)
1436        && FindProcShort (glTexCoordP4ui)
1437        && FindProcShort (glTexCoordP4uiv)
1438        && FindProcShort (glMultiTexCoordP1ui)
1439        && FindProcShort (glMultiTexCoordP1uiv)
1440        && FindProcShort (glMultiTexCoordP2ui)
1441        && FindProcShort (glMultiTexCoordP2uiv)
1442        && FindProcShort (glMultiTexCoordP3ui)
1443        && FindProcShort (glMultiTexCoordP3uiv)
1444        && FindProcShort (glMultiTexCoordP4ui)
1445        && FindProcShort (glMultiTexCoordP4uiv)
1446        && FindProcShort (glNormalP3ui)
1447        && FindProcShort (glNormalP3uiv)
1448        && FindProcShort (glColorP3ui)
1449        && FindProcShort (glColorP3uiv)
1450        && FindProcShort (glColorP4ui)
1451        && FindProcShort (glColorP4uiv)
1452        && FindProcShort (glSecondaryColorP3ui)
1453        && FindProcShort (glSecondaryColorP3uiv)
1454        && FindProcShort (glVertexAttribP1ui)
1455        && FindProcShort (glVertexAttribP1uiv)
1456        && FindProcShort (glVertexAttribP2ui)
1457        && FindProcShort (glVertexAttribP2uiv)
1458        && FindProcShort (glVertexAttribP3ui)
1459        && FindProcShort (glVertexAttribP3uiv)
1460        && FindProcShort (glVertexAttribP4ui)
1461        && FindProcShort (glVertexAttribP4uiv);
1462
1463   // load OpenGL 3.3 extra functions
1464   has33 = IsGlGreaterEqual (3, 3)
1465        && hasBlendFuncExtended
1466        && hasSamplerObjects
1467        && hasTimerQuery
1468        && hasVertType21010101rev
1469        && FindProcShort (glVertexAttribDivisor);
1470
1471   // load GL_ARB_draw_indirect (added to OpenGL 4.0 core)
1472   const bool hasDrawIndirect = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_draw_indirect"))
1473        && FindProcShort (glDrawArraysIndirect)
1474        && FindProcShort (glDrawElementsIndirect);
1475
1476   // load GL_ARB_gpu_shader_fp64 (added to OpenGL 4.0 core)
1477   const bool hasShaderFP64 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_gpu_shader_fp64"))
1478        && FindProcShort (glUniform1d)
1479        && FindProcShort (glUniform2d)
1480        && FindProcShort (glUniform3d)
1481        && FindProcShort (glUniform4d)
1482        && FindProcShort (glUniform1dv)
1483        && FindProcShort (glUniform2dv)
1484        && FindProcShort (glUniform3dv)
1485        && FindProcShort (glUniform4dv)
1486        && FindProcShort (glUniformMatrix2dv)
1487        && FindProcShort (glUniformMatrix3dv)
1488        && FindProcShort (glUniformMatrix4dv)
1489        && FindProcShort (glUniformMatrix2x3dv)
1490        && FindProcShort (glUniformMatrix2x4dv)
1491        && FindProcShort (glUniformMatrix3x2dv)
1492        && FindProcShort (glUniformMatrix3x4dv)
1493        && FindProcShort (glUniformMatrix4x2dv)
1494        && FindProcShort (glUniformMatrix4x3dv)
1495        && FindProcShort (glGetUniformdv);
1496
1497   // load GL_ARB_shader_subroutine (added to OpenGL 4.0 core)
1498   const bool hasShaderSubroutine = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_shader_subroutine"))
1499        && FindProcShort (glGetSubroutineUniformLocation)
1500        && FindProcShort (glGetSubroutineIndex)
1501        && FindProcShort (glGetActiveSubroutineUniformiv)
1502        && FindProcShort (glGetActiveSubroutineUniformName)
1503        && FindProcShort (glGetActiveSubroutineName)
1504        && FindProcShort (glUniformSubroutinesuiv)
1505        && FindProcShort (glGetUniformSubroutineuiv)
1506        && FindProcShort (glGetProgramStageiv);
1507
1508   // load GL_ARB_tessellation_shader (added to OpenGL 4.0 core)
1509   const bool hasTessellationShader = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_tessellation_shader"))
1510        && FindProcShort (glPatchParameteri)
1511        && FindProcShort (glPatchParameterfv);
1512
1513   // load GL_ARB_transform_feedback2 (added to OpenGL 4.0 core)
1514   const bool hasTrsfFeedback2 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_transform_feedback2"))
1515        && FindProcShort (glBindTransformFeedback)
1516        && FindProcShort (glDeleteTransformFeedbacks)
1517        && FindProcShort (glGenTransformFeedbacks)
1518        && FindProcShort (glIsTransformFeedback)
1519        && FindProcShort (glPauseTransformFeedback)
1520        && FindProcShort (glResumeTransformFeedback)
1521        && FindProcShort (glDrawTransformFeedback);
1522
1523   // load GL_ARB_transform_feedback3 (added to OpenGL 4.0 core)
1524   const bool hasTrsfFeedback3 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_transform_feedback3"))
1525        && FindProcShort (glDrawTransformFeedbackStream)
1526        && FindProcShort (glBeginQueryIndexed)
1527        && FindProcShort (glEndQueryIndexed)
1528        && FindProcShort (glGetQueryIndexediv);
1529
1530   // load OpenGL 4.0 new functions
1531   has40 = IsGlGreaterEqual (4, 0)
1532       && hasDrawIndirect
1533       && hasShaderFP64
1534       && hasShaderSubroutine
1535       && hasTessellationShader
1536       && hasTrsfFeedback2
1537       && hasTrsfFeedback3
1538       && FindProcShort (glMinSampleShading)
1539       && FindProcShort (glBlendEquationi)
1540       && FindProcShort (glBlendEquationSeparatei)
1541       && FindProcShort (glBlendFunci)
1542       && FindProcShort (glBlendFuncSeparatei);
1543
1544   // load GL_ARB_ES2_compatibility (added to OpenGL 4.1 core)
1545   const bool hasES2Compatibility = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_ES2_compatibility"))
1546        && FindProcShort (glReleaseShaderCompiler)
1547        && FindProcShort (glShaderBinary)
1548        && FindProcShort (glGetShaderPrecisionFormat)
1549        && FindProcShort (glDepthRangef)
1550        && FindProcShort (glClearDepthf);
1551
1552   // load GL_ARB_get_program_binary (added to OpenGL 4.1 core)
1553   const bool hasGetProgramBinary = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_get_program_binary"))
1554        && FindProcShort (glGetProgramBinary)
1555        && FindProcShort (glProgramBinary)
1556        && FindProcShort (glProgramParameteri);
1557
1558
1559   // load GL_ARB_separate_shader_objects (added to OpenGL 4.1 core)
1560   const bool hasSeparateShaderObjects = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_separate_shader_objects"))
1561        && FindProcShort (glUseProgramStages)
1562        && FindProcShort (glActiveShaderProgram)
1563        && FindProcShort (glCreateShaderProgramv)
1564        && FindProcShort (glBindProgramPipeline)
1565        && FindProcShort (glDeleteProgramPipelines)
1566        && FindProcShort (glGenProgramPipelines)
1567        && FindProcShort (glIsProgramPipeline)
1568        && FindProcShort (glGetProgramPipelineiv)
1569        && FindProcShort (glProgramUniform1i)
1570        && FindProcShort (glProgramUniform1iv)
1571        && FindProcShort (glProgramUniform1f)
1572        && FindProcShort (glProgramUniform1fv)
1573        && FindProcShort (glProgramUniform1d)
1574        && FindProcShort (glProgramUniform1dv)
1575        && FindProcShort (glProgramUniform1ui)
1576        && FindProcShort (glProgramUniform1uiv)
1577        && FindProcShort (glProgramUniform2i)
1578        && FindProcShort (glProgramUniform2iv)
1579        && FindProcShort (glProgramUniform2f)
1580        && FindProcShort (glProgramUniform2fv)
1581        && FindProcShort (glProgramUniform2d)
1582        && FindProcShort (glProgramUniform2dv)
1583        && FindProcShort (glProgramUniform2ui)
1584        && FindProcShort (glProgramUniform2uiv)
1585        && FindProcShort (glProgramUniform3i)
1586        && FindProcShort (glProgramUniform3iv)
1587        && FindProcShort (glProgramUniform3f)
1588        && FindProcShort (glProgramUniform3fv)
1589        && FindProcShort (glProgramUniform3d)
1590        && FindProcShort (glProgramUniform3dv)
1591        && FindProcShort (glProgramUniform3ui)
1592        && FindProcShort (glProgramUniform3uiv)
1593        && FindProcShort (glProgramUniform4i)
1594        && FindProcShort (glProgramUniform4iv)
1595        && FindProcShort (glProgramUniform4f)
1596        && FindProcShort (glProgramUniform4fv)
1597        && FindProcShort (glProgramUniform4d)
1598        && FindProcShort (glProgramUniform4dv)
1599        && FindProcShort (glProgramUniform4ui)
1600        && FindProcShort (glProgramUniform4uiv)
1601        && FindProcShort (glProgramUniformMatrix2fv)
1602        && FindProcShort (glProgramUniformMatrix3fv)
1603        && FindProcShort (glProgramUniformMatrix4fv)
1604        && FindProcShort (glProgramUniformMatrix2dv)
1605        && FindProcShort (glProgramUniformMatrix3dv)
1606        && FindProcShort (glProgramUniformMatrix4dv)
1607        && FindProcShort (glProgramUniformMatrix2x3fv)
1608        && FindProcShort (glProgramUniformMatrix3x2fv)
1609        && FindProcShort (glProgramUniformMatrix2x4fv)
1610        && FindProcShort (glProgramUniformMatrix4x2fv)
1611        && FindProcShort (glProgramUniformMatrix3x4fv)
1612        && FindProcShort (glProgramUniformMatrix4x3fv)
1613        && FindProcShort (glProgramUniformMatrix2x3dv)
1614        && FindProcShort (glProgramUniformMatrix3x2dv)
1615        && FindProcShort (glProgramUniformMatrix2x4dv)
1616        && FindProcShort (glProgramUniformMatrix4x2dv)
1617        && FindProcShort (glProgramUniformMatrix3x4dv)
1618        && FindProcShort (glProgramUniformMatrix4x3dv)
1619        && FindProcShort (glValidateProgramPipeline)
1620        && FindProcShort (glGetProgramPipelineInfoLog);
1621
1622   // load GL_ARB_vertex_attrib_64bit (added to OpenGL 4.1 core)
1623   const bool hasVertAttrib64bit = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_vertex_attrib_64bit"))
1624        && FindProcShort (glVertexAttribL1d)
1625        && FindProcShort (glVertexAttribL2d)
1626        && FindProcShort (glVertexAttribL3d)
1627        && FindProcShort (glVertexAttribL4d)
1628        && FindProcShort (glVertexAttribL1dv)
1629        && FindProcShort (glVertexAttribL2dv)
1630        && FindProcShort (glVertexAttribL3dv)
1631        && FindProcShort (glVertexAttribL4dv)
1632        && FindProcShort (glVertexAttribLPointer)
1633        && FindProcShort (glGetVertexAttribLdv);
1634
1635   // load GL_ARB_viewport_array (added to OpenGL 4.1 core)
1636   const bool hasViewportArray = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_viewport_array"))
1637        && FindProcShort (glViewportArrayv)
1638        && FindProcShort (glViewportIndexedf)
1639        && FindProcShort (glViewportIndexedfv)
1640        && FindProcShort (glScissorArrayv)
1641        && FindProcShort (glScissorIndexed)
1642        && FindProcShort (glScissorIndexedv)
1643        && FindProcShort (glDepthRangeArrayv)
1644        && FindProcShort (glDepthRangeIndexed)
1645        && FindProcShort (glGetFloati_v)
1646        && FindProcShort (glGetDoublei_v);
1647
1648   has41 = IsGlGreaterEqual (4, 1)
1649        && hasES2Compatibility
1650        && hasGetProgramBinary
1651        && hasSeparateShaderObjects
1652        && hasVertAttrib64bit
1653        && hasViewportArray;
1654
1655   // load GL_ARB_base_instance (added to OpenGL 4.2 core)
1656   const bool hasBaseInstance = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_base_instance"))
1657        && FindProcShort (glDrawArraysInstancedBaseInstance)
1658        && FindProcShort (glDrawElementsInstancedBaseInstance)
1659        && FindProcShort (glDrawElementsInstancedBaseVertexBaseInstance);
1660
1661   // load GL_ARB_transform_feedback_instanced (added to OpenGL 4.2 core)
1662   const bool hasTrsfFeedbackInstanced = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_transform_feedback_instanced"))
1663        && FindProcShort (glDrawTransformFeedbackInstanced)
1664        && FindProcShort (glDrawTransformFeedbackStreamInstanced);
1665
1666   // load GL_ARB_internalformat_query (added to OpenGL 4.2 core)
1667   const bool hasInternalFormatQuery = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_internalformat_query"))
1668        && FindProcShort (glGetInternalformativ);
1669
1670   // load GL_ARB_shader_atomic_counters (added to OpenGL 4.2 core)
1671   const bool hasShaderAtomicCounters = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_shader_atomic_counters"))
1672        && FindProcShort (glGetActiveAtomicCounterBufferiv);
1673
1674   // load GL_ARB_shader_image_load_store (added to OpenGL 4.2 core)
1675   const bool hasShaderImgLoadStore = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_shader_image_load_store"))
1676        && FindProcShort (glBindImageTexture)
1677        && FindProcShort (glMemoryBarrier);
1678
1679   // load GL_ARB_texture_storage (added to OpenGL 4.2 core)
1680   const bool hasTextureStorage = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_texture_storage"))
1681        && FindProcShort (glTexStorage1D)
1682        && FindProcShort (glTexStorage2D)
1683        && FindProcShort (glTexStorage3D)
1684        && FindProcShort (glTextureStorage1DEXT)
1685        && FindProcShort (glTextureStorage2DEXT)
1686        && FindProcShort (glTextureStorage3DEXT);
1687
1688   has42 = IsGlGreaterEqual (4, 2)
1689        && hasBaseInstance
1690        && hasTrsfFeedbackInstanced
1691        && hasInternalFormatQuery
1692        && hasShaderAtomicCounters
1693        && hasShaderImgLoadStore
1694        && hasTextureStorage;
1695
1696   has43 = IsGlGreaterEqual (4, 3)
1697        && FindProcShort (glClearBufferData)
1698        && FindProcShort (glClearBufferSubData)
1699        && FindProcShort (glDispatchCompute)
1700        && FindProcShort (glDispatchComputeIndirect)
1701        && FindProcShort (glCopyImageSubData)
1702        && FindProcShort (glFramebufferParameteri)
1703        && FindProcShort (glGetFramebufferParameteriv)
1704        && FindProcShort (glGetInternalformati64v)
1705        && FindProcShort (glInvalidateTexSubImage)
1706        && FindProcShort (glInvalidateTexImage)
1707        && FindProcShort (glInvalidateBufferSubData)
1708        && FindProcShort (glInvalidateBufferData)
1709        && FindProcShort (glInvalidateFramebuffer)
1710        && FindProcShort (glInvalidateSubFramebuffer)
1711        && FindProcShort (glMultiDrawArraysIndirect)
1712        && FindProcShort (glMultiDrawElementsIndirect)
1713        && FindProcShort (glGetProgramInterfaceiv)
1714        && FindProcShort (glGetProgramResourceIndex)
1715        && FindProcShort (glGetProgramResourceName)
1716        && FindProcShort (glGetProgramResourceiv)
1717        && FindProcShort (glGetProgramResourceLocation)
1718        && FindProcShort (glGetProgramResourceLocationIndex)
1719        && FindProcShort (glShaderStorageBlockBinding)
1720        && FindProcShort (glTexBufferRange)
1721        && FindProcShort (glTexStorage2DMultisample)
1722        && FindProcShort (glTexStorage3DMultisample)
1723        && FindProcShort (glTextureView)
1724        && FindProcShort (glBindVertexBuffer)
1725        && FindProcShort (glVertexAttribFormat)
1726        && FindProcShort (glVertexAttribIFormat)
1727        && FindProcShort (glVertexAttribLFormat)
1728        && FindProcShort (glVertexAttribBinding)
1729        && FindProcShort (glVertexBindingDivisor)
1730        && FindProcShort (glDebugMessageControl)
1731        && FindProcShort (glDebugMessageInsert)
1732        && FindProcShort (glDebugMessageCallback)
1733        && FindProcShort (glGetDebugMessageLog)
1734        && FindProcShort (glPushDebugGroup)
1735        && FindProcShort (glPopDebugGroup)
1736        && FindProcShort (glObjectLabel)
1737        && FindProcShort (glGetObjectLabel)
1738        && FindProcShort (glObjectPtrLabel)
1739        && FindProcShort (glGetObjectPtrLabel);
1740
1741   // load GL_ARB_clear_texture (added to OpenGL 4.4 core)
1742   bool arbTexClear = (IsGlGreaterEqual (4, 4) || CheckExtension ("GL_ARB_clear_texture"))
1743        && FindProcShort (glClearTexImage)
1744        && FindProcShort (glClearTexSubImage);
1745
1746   has44 = IsGlGreaterEqual (4, 4)
1747        && arbTexClear
1748        && FindProcShort (glBufferStorage)
1749        && FindProcShort (glBindBuffersBase)
1750        && FindProcShort (glBindBuffersRange)
1751        && FindProcShort (glBindTextures)
1752        && FindProcShort (glBindSamplers)
1753        && FindProcShort (glBindImageTextures)
1754        && FindProcShort (glBindVertexBuffers);
1755
1756   // initialize TBO extension (ARB)
1757   if (!has31
1758    && CheckExtension ("GL_ARB_texture_buffer_object")
1759    && FindProc ("glTexBufferARB", myFuncs->glTexBuffer))
1760   {
1761     arbTBO = (OpenGl_ArbTBO* )(&(*myFuncs));
1762   }
1763   arbTboRGB32 = CheckExtension ("GL_ARB_texture_buffer_object_rgb32");
1764
1765   // initialize hardware instancing extension (ARB)
1766   if (!has31
1767    && CheckExtension ("GL_ARB_draw_instanced")
1768    && FindProc ("glDrawArraysInstancedARB",   myFuncs->glDrawArraysInstanced)
1769    && FindProc ("glDrawElementsInstancedARB", myFuncs->glDrawElementsInstanced))
1770   {
1771     arbIns = (OpenGl_ArbIns* )(&(*myFuncs));
1772   }
1773
1774   // initialize FBO extension (ARB)
1775   if (hasFBO)
1776   {
1777     arbFBO = (OpenGl_ArbFBO* )(&(*myFuncs));
1778     extPDS = Standard_True; // extension for EXT, but part of ARB
1779   }
1780
1781   // initialize GS extension (EXT)
1782   if (CheckExtension ("GL_EXT_geometry_shader4")
1783    && FindProcShort (glProgramParameteriEXT))
1784   {
1785     extGS = (OpenGl_ExtGS* )(&(*myFuncs));
1786   }
1787
1788   // initialize bindless texture extension (ARB)
1789   if (CheckExtension ("GL_ARB_bindless_texture")
1790    && FindProcShort (glGetTextureHandleARB)
1791    && FindProcShort (glGetTextureSamplerHandleARB)
1792    && FindProcShort (glMakeTextureHandleResidentARB)
1793    && FindProcShort (glMakeTextureHandleNonResidentARB)
1794    && FindProcShort (glGetImageHandleARB)
1795    && FindProcShort (glMakeImageHandleResidentARB)
1796    && FindProcShort (glMakeImageHandleNonResidentARB)
1797    && FindProcShort (glUniformHandleui64ARB)
1798    && FindProcShort (glUniformHandleui64vARB)
1799    && FindProcShort (glProgramUniformHandleui64ARB)
1800    && FindProcShort (glProgramUniformHandleui64vARB)
1801    && FindProcShort (glIsTextureHandleResidentARB)
1802    && FindProcShort (glIsImageHandleResidentARB)
1803    && FindProcShort (glVertexAttribL1ui64ARB)
1804    && FindProcShort (glVertexAttribL1ui64vARB)
1805    && FindProcShort (glGetVertexAttribLui64vARB))
1806   {
1807     arbTexBindless = (OpenGl_ArbTexBindless* )(&(*myFuncs));
1808   }
1809
1810   if (!has12)
1811   {
1812     myGlVerMajor = 1;
1813     myGlVerMinor = 1;
1814     return;
1815   }
1816   else if (!has13)
1817   {
1818     myGlVerMajor = 1;
1819     myGlVerMinor = 2;
1820     return;
1821   }
1822   else if (!has14)
1823   {
1824     myGlVerMajor = 1;
1825     myGlVerMinor = 3;
1826     return;
1827   }
1828   else if (!has15)
1829   {
1830     myGlVerMajor = 1;
1831     myGlVerMinor = 4;
1832     return;
1833   }
1834   core15    = (OpenGl_GlCore15*    )(&(*myFuncs));
1835   core15fwd = (OpenGl_GlCore15Fwd* )(&(*myFuncs));
1836
1837   if (!has20)
1838   {
1839     myGlVerMajor = 1;
1840     myGlVerMinor = 5;
1841     return;
1842   }
1843
1844   core20    = (OpenGl_GlCore20*    )(&(*myFuncs));
1845   core20fwd = (OpenGl_GlCore20Fwd* )(&(*myFuncs));
1846
1847   if (!has21)
1848   {
1849     myGlVerMajor = 2;
1850     myGlVerMinor = 0;
1851     return;
1852   }
1853
1854   if (!has30)
1855   {
1856     myGlVerMajor = 2;
1857     myGlVerMinor = 1;
1858     return;
1859   }
1860
1861   if (!has31)
1862   {
1863     myGlVerMajor = 3;
1864     myGlVerMinor = 0;
1865     return;
1866   }
1867   arbTBO = (OpenGl_ArbTBO* )(&(*myFuncs));
1868   arbIns = (OpenGl_ArbIns* )(&(*myFuncs));
1869
1870   if (!has32)
1871   {
1872     myGlVerMajor = 3;
1873     myGlVerMinor = 1;
1874     return;
1875   }
1876   core32     = (OpenGl_GlCore32*     )(&(*myFuncs));
1877   core32back = (OpenGl_GlCore32Back* )(&(*myFuncs));
1878
1879   if (!has33)
1880   {
1881     myGlVerMajor = 3;
1882     myGlVerMinor = 2;
1883     return;
1884   }
1885   core33     = (OpenGl_GlCore33*     )(&(*myFuncs));
1886   core33back = (OpenGl_GlCore33Back* )(&(*myFuncs));
1887
1888   // initialize sampler object
1889   myTexSampler = new OpenGl_Sampler();
1890   myTexSampler->Init (*this);
1891
1892   if (!has40)
1893   {
1894     myGlVerMajor = 3;
1895     myGlVerMinor = 3;
1896     return;
1897   }
1898   arbTboRGB32 = Standard_True; // in core since OpenGL 4.0
1899
1900   if (!has41)
1901   {
1902     myGlVerMajor = 4;
1903     myGlVerMinor = 0;
1904     return;
1905   }
1906   core41     = (OpenGl_GlCore41*     )(&(*myFuncs));
1907   core41back = (OpenGl_GlCore41Back* )(&(*myFuncs));
1908
1909   if(!has42)
1910   {
1911     myGlVerMajor = 4;
1912     myGlVerMinor = 1;
1913     return;
1914   }
1915   core42     = (OpenGl_GlCore42*     )(&(*myFuncs));
1916   core42back = (OpenGl_GlCore42Back* )(&(*myFuncs));
1917
1918   if(!has43)
1919   {
1920     myGlVerMajor = 4;
1921     myGlVerMinor = 2;
1922     return;
1923   }
1924   core43     = (OpenGl_GlCore43*     )(&(*myFuncs));
1925   core43back = (OpenGl_GlCore43Back* )(&(*myFuncs));
1926
1927   if (!has44)
1928   {
1929     myGlVerMajor = 4;
1930     myGlVerMinor = 3;
1931     return;
1932   }
1933   core44     = (OpenGl_GlCore44*     )(&(*myFuncs));
1934   core44back = (OpenGl_GlCore44Back* )(&(*myFuncs));
1935 #endif
1936 }
1937
1938 // =======================================================================
1939 // function : MemoryInfo
1940 // purpose  :
1941 // =======================================================================
1942 Standard_Size OpenGl_Context::AvailableMemory() const
1943 {
1944 #if !defined(GL_ES_VERSION_2_0)
1945   if (atiMem)
1946   {
1947     // this is actually information for VBO pool
1948     // however because pools are mostly shared
1949     // it can be used for total GPU memory estimations
1950     GLint aMemInfo[4];
1951     aMemInfo[0] = 0;
1952     glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aMemInfo);
1953     // returned value is in KiB, however this maybe changed in future
1954     return Standard_Size(aMemInfo[0]) * 1024;
1955   }
1956   else if (nvxMem)
1957   {
1958     // current available dedicated video memory (in KiB), currently unused GPU memory
1959     GLint aMemInfo = 0;
1960     glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aMemInfo);
1961     return Standard_Size(aMemInfo) * 1024;
1962   }
1963 #endif
1964   return 0;
1965 }
1966
1967 // =======================================================================
1968 // function : MemoryInfo
1969 // purpose  :
1970 // =======================================================================
1971 TCollection_AsciiString OpenGl_Context::MemoryInfo() const
1972 {
1973   TCollection_AsciiString anInfo;
1974 #if !defined(GL_ES_VERSION_2_0)
1975   if (atiMem)
1976   {
1977     GLint aValues[4];
1978     memset (aValues, 0, sizeof(aValues));
1979     glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aValues);
1980
1981     // total memory free in the pool
1982     anInfo += TCollection_AsciiString ("  GPU free memory:    ") + (aValues[0] / 1024) + " MiB\n";
1983
1984     // largest available free block in the pool
1985     anInfo += TCollection_AsciiString ("  Largest free block: ") + (aValues[1] / 1024) + " MiB\n";
1986     if (aValues[2] != aValues[0])
1987     {
1988       // total auxiliary memory free
1989       anInfo += TCollection_AsciiString ("  Free memory:        ") + (aValues[2] / 1024) + " MiB\n";
1990     }
1991   }
1992   else if (nvxMem)
1993   {
1994     //current available dedicated video memory (in KiB), currently unused GPU memory
1995     GLint aValue = 0;
1996     glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aValue);
1997     anInfo += TCollection_AsciiString ("  GPU free memory:    ") + (aValue / 1024) + " MiB\n";
1998
1999     // dedicated video memory, total size (in KiB) of the GPU memory
2000     GLint aDedicated = 0;
2001     glGetIntegerv (GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &aDedicated);
2002     anInfo += TCollection_AsciiString ("  GPU memory:         ") + (aDedicated / 1024) + " MiB\n";
2003
2004     // total available memory, total size (in KiB) of the memory available for allocations
2005     glGetIntegerv (GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &aValue);
2006     if (aValue != aDedicated)
2007     {
2008       // different only for special configurations
2009       anInfo += TCollection_AsciiString ("  Total memory:       ") + (aValue / 1024) + " MiB\n";
2010     }
2011   }
2012 #endif
2013   return anInfo;
2014 }
2015
2016
2017 // =======================================================================
2018 // function : GetResource
2019 // purpose  :
2020 // =======================================================================
2021 const Handle(OpenGl_Resource)& OpenGl_Context::GetResource (const TCollection_AsciiString& theKey) const
2022 {
2023   return mySharedResources->IsBound (theKey) ? mySharedResources->Find (theKey) : NULL_GL_RESOURCE;
2024 }
2025
2026 // =======================================================================
2027 // function : ShareResource
2028 // purpose  :
2029 // =======================================================================
2030 Standard_Boolean OpenGl_Context::ShareResource (const TCollection_AsciiString& theKey,
2031                                                 const Handle(OpenGl_Resource)& theResource)
2032 {
2033   if (theKey.IsEmpty() || theResource.IsNull())
2034   {
2035     return Standard_False;
2036   }
2037   return mySharedResources->Bind (theKey, theResource);
2038 }
2039
2040 // =======================================================================
2041 // function : ReleaseResource
2042 // purpose  :
2043 // =======================================================================
2044 void OpenGl_Context::ReleaseResource (const TCollection_AsciiString& theKey,
2045                                       const Standard_Boolean         theToDelay)
2046 {
2047   if (!mySharedResources->IsBound (theKey))
2048   {
2049     return;
2050   }
2051   const Handle(OpenGl_Resource)& aRes = mySharedResources->Find (theKey);
2052   if (aRes->GetRefCount() > 1)
2053   {
2054     return;
2055   }
2056
2057   if (theToDelay)
2058   {
2059     myDelayed->Bind (theKey, 1);
2060   }
2061   else
2062   {
2063     aRes->Release (this);
2064     mySharedResources->UnBind (theKey);
2065   }
2066 }
2067
2068 // =======================================================================
2069 // function : DelayedRelease
2070 // purpose  :
2071 // =======================================================================
2072 void OpenGl_Context::DelayedRelease (Handle(OpenGl_Resource)& theResource)
2073 {
2074   myUnusedResources->Prepend (theResource);
2075   theResource.Nullify();
2076 }
2077
2078 // =======================================================================
2079 // function : ReleaseDelayed
2080 // purpose  :
2081 // =======================================================================
2082 void OpenGl_Context::ReleaseDelayed()
2083 {
2084   // release queued elements
2085   while (!myUnusedResources->IsEmpty())
2086   {
2087     myUnusedResources->First()->Release (this);
2088     myUnusedResources->RemoveFirst();
2089   }
2090
2091   // release delayed shared resources
2092   NCollection_Vector<TCollection_AsciiString> aDeadList;
2093   for (NCollection_DataMap<TCollection_AsciiString, Standard_Integer>::Iterator anIter (*myDelayed);
2094        anIter.More(); anIter.Next())
2095   {
2096     if (++anIter.ChangeValue() <= 2)
2097     {
2098       continue; // postpone release one more frame to ensure noone use it periodically
2099     }
2100
2101     const TCollection_AsciiString& aKey = anIter.Key();
2102     if (!mySharedResources->IsBound (aKey))
2103     {
2104       // mixed unshared strategy delayed/undelayed was used!
2105       aDeadList.Append (aKey);
2106       continue;
2107     }
2108
2109     Handle(OpenGl_Resource)& aRes = mySharedResources->ChangeFind (aKey);
2110     if (aRes->GetRefCount() > 1)
2111     {
2112       // should be only 1 instance in mySharedResources
2113       // if not - resource was reused again
2114       aDeadList.Append (aKey);
2115       continue;
2116     }
2117
2118     // release resource if no one requiested it more than 2 redraw calls
2119     aRes->Release (this);
2120     mySharedResources->UnBind (aKey);
2121     aDeadList.Append (aKey);
2122   }
2123
2124   for (Standard_Integer anIter = 0; anIter < aDeadList.Length(); ++anIter)
2125   {
2126     myDelayed->UnBind (aDeadList.Value (anIter));
2127   }
2128 }
2129
2130 // =======================================================================
2131 // function : BindProgram
2132 // purpose  :
2133 // =======================================================================
2134 Standard_Boolean OpenGl_Context::BindProgram (const Handle(OpenGl_ShaderProgram)& theProgram)
2135 {
2136   if (core20fwd == NULL)
2137   {
2138     return Standard_False;
2139   }
2140
2141   if (theProgram.IsNull()
2142   || !theProgram->IsValid())
2143   {
2144     if (!myActiveProgram.IsNull())
2145     {
2146       core20fwd->glUseProgram (OpenGl_ShaderProgram::NO_PROGRAM);
2147       myActiveProgram.Nullify();
2148     }
2149     return Standard_False;
2150   }
2151
2152   myActiveProgram = theProgram;
2153   core20fwd->glUseProgram (theProgram->ProgramId());
2154   return Standard_True;
2155 }
2156
2157 // =======================================================================
2158 // function : SetColor4fv
2159 // purpose  :
2160 // =======================================================================
2161 void OpenGl_Context::SetColor4fv (const OpenGl_Vec4& theColor)
2162 {
2163   if (!myActiveProgram.IsNull())
2164   {
2165     myActiveProgram->SetUniform (this, myActiveProgram->GetStateLocation (OpenGl_OCCT_COLOR), theColor);
2166   }
2167 #if !defined(GL_ES_VERSION_2_0)
2168   else if (core11 != NULL)
2169   {
2170     core11->glColor4fv (theColor.GetData());
2171   }
2172 #endif
2173 }
2174
2175 // =======================================================================
2176 // function : SetPointSize
2177 // purpose  :
2178 // =======================================================================
2179 void OpenGl_Context::SetPointSize (const Standard_ShortReal theSize)
2180 {
2181   if (!myActiveProgram.IsNull())
2182   {
2183     myActiveProgram->SetUniform (this, myActiveProgram->GetStateLocation (OpenGl_OCCT_POINT_SIZE), theSize);
2184   #if !defined(GL_ES_VERSION_2_0)
2185     //myContext->core11fwd->glEnable (GL_VERTEX_PROGRAM_POINT_SIZE);
2186   #endif
2187   }
2188 #if !defined(GL_ES_VERSION_2_0)
2189   //else
2190   {
2191     core11fwd->glPointSize (theSize);
2192     if (core20fwd != NULL)
2193     {
2194       //myContext->core11fwd->glDisable (GL_VERTEX_PROGRAM_POINT_SIZE);
2195     }
2196   }
2197 #endif
2198 }
2199
2200 // =======================================================================
2201 // function : SetGlNormalizeEnabled
2202 // purpose  :
2203 // =======================================================================
2204 Standard_Boolean OpenGl_Context::SetGlNormalizeEnabled (Standard_Boolean isEnabled)
2205 {
2206   if (isEnabled == myIsGlNormalizeEnabled)
2207   {
2208     return myIsGlNormalizeEnabled;
2209   }
2210
2211   Standard_Boolean anOldGlNormalize = myIsGlNormalizeEnabled;
2212
2213   myIsGlNormalizeEnabled = isEnabled;
2214
2215 #if !defined(GL_ES_VERSION_2_0)
2216   if (isEnabled)
2217   {
2218     glEnable (GL_NORMALIZE);
2219   }
2220   else
2221   {
2222     glDisable (GL_NORMALIZE);
2223   }
2224 #endif
2225
2226   return anOldGlNormalize;
2227 }