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