10e7a42836478db2ba11bc1fe1739256e5919891
[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   if (caps->suppressExtraMsg
903    && theSource >= GL_DEBUG_SOURCE_API_ARB
904    && theSource <= GL_DEBUG_SOURCE_OTHER_ARB
905    && myFilters[theSource - GL_DEBUG_SOURCE_API_ARB].Contains (theId))
906   {
907     return;
908   }
909
910   Standard_CString& aSrc = (theSource >= GL_DEBUG_SOURCE_API_ARB
911                         && theSource <= GL_DEBUG_SOURCE_OTHER_ARB)
912                          ? THE_DBGMSG_SOURCES[theSource - GL_DEBUG_SOURCE_API_ARB]
913                          : THE_DBGMSG_UNKNOWN;
914   Standard_CString& aType = (theType >= GL_DEBUG_TYPE_ERROR_ARB
915                          && theType <= GL_DEBUG_TYPE_OTHER_ARB)
916                           ? THE_DBGMSG_TYPES[theType - GL_DEBUG_TYPE_ERROR_ARB]
917                           : THE_DBGMSG_UNKNOWN;
918   Standard_CString& aSev = theSeverity == GL_DEBUG_SEVERITY_HIGH_ARB
919                          ? THE_DBGMSG_SEV_HIGH
920                          : (theSeverity == GL_DEBUG_SEVERITY_MEDIUM_ARB
921                           ? THE_DBGMSG_SEV_MEDIUM
922                           : THE_DBGMSG_SEV_LOW);
923   Message_Gravity aGrav = theSeverity == GL_DEBUG_SEVERITY_HIGH_ARB
924                         ? Message_Alarm
925                         : (theSeverity == GL_DEBUG_SEVERITY_MEDIUM_ARB
926                          ? Message_Warning
927                          : Message_Info);
928
929   TCollection_ExtendedString aMsg;
930   aMsg += "TKOpenGl"; aMsg += aSrc;
931   aMsg += " | Type: ";        aMsg += aType;
932   aMsg += " | ID: ";          aMsg += (Standard_Integer )theId;
933   aMsg += " | Severity: ";    aMsg += aSev;
934   aMsg += " | Message:\n  ";
935   aMsg += theMessage;
936   Messenger()->Send (aMsg, aGrav);
937 }
938
939 // =======================================================================
940 // function : ExcludeMessage
941 // purpose  :
942 // ======================================================================
943 Standard_Boolean OpenGl_Context::ExcludeMessage (const unsigned int theSource,
944                                                  const unsigned int theId)
945 {
946   return theSource >= GL_DEBUG_SOURCE_API_ARB
947       && theSource <= GL_DEBUG_SOURCE_OTHER_ARB
948       && myFilters[theSource - GL_DEBUG_SOURCE_API_ARB].Add (theId);
949 }
950
951 // =======================================================================
952 // function : IncludeMessage
953 // purpose  :
954 // ======================================================================
955 Standard_Boolean OpenGl_Context::IncludeMessage (const unsigned int theSource,
956                                                  const unsigned int theId)
957 {
958   return theSource >= GL_DEBUG_SOURCE_API_ARB
959       && theSource <= GL_DEBUG_SOURCE_OTHER_ARB
960       && myFilters[theSource - GL_DEBUG_SOURCE_API_ARB].Remove (theId);
961 }
962
963 // =======================================================================
964 // function : checkWrongVersion
965 // purpose  :
966 // ======================================================================
967 void OpenGl_Context::checkWrongVersion (const Standard_Integer theGlVerMajor,
968                                         const Standard_Integer theGlVerMinor)
969 {
970   if (!IsGlGreaterEqual (theGlVerMajor, theGlVerMinor))
971   {
972     return;
973   }
974
975   TCollection_ExtendedString aMsg = TCollection_ExtendedString()
976     + "Error! OpenGL context reports version "
977     + myGlVerMajor  + "." + myGlVerMinor
978     + " but does not export required functions for "
979     + theGlVerMajor + "." + theGlVerMinor;
980   PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
981                GL_DEBUG_TYPE_ERROR_ARB,
982                0,
983                GL_DEBUG_SEVERITY_HIGH_ARB,
984                aMsg);
985 }
986
987 // =======================================================================
988 // function : init
989 // purpose  :
990 // =======================================================================
991 void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
992 {
993   // read version
994   myGlVerMajor = 0;
995   myGlVerMinor = 0;
996   ReadGlVersion (myGlVerMajor, myGlVerMinor);
997   myVendor = (const char* )::glGetString (GL_VENDOR);
998
999 #if defined(GL_ES_VERSION_2_0)
1000   (void )theIsCoreProfile;
1001   const bool isCoreProfile = false;
1002 #else
1003
1004   if (myVendor.Search ("NVIDIA") != -1)
1005   {
1006     // Buffer detailed info: Buffer object 1 (bound to GL_ARRAY_BUFFER_ARB, usage hint is GL_STATIC_DRAW)
1007     // will use VIDEO memory as the source for buffer object operations.
1008     ExcludeMessage (GL_DEBUG_SOURCE_API_ARB, 131185);
1009   }
1010   if (IsGlGreaterEqual (3, 0))
1011   {
1012     // retrieve auxiliary function in advance
1013     FindProc ("glGetStringi", myFuncs->glGetStringi);
1014   }
1015
1016   bool isCoreProfile = false;
1017   if (IsGlGreaterEqual (3, 2))
1018   {
1019     isCoreProfile = (theIsCoreProfile == Standard_True);
1020
1021     // detect Core profile
1022     if (isCoreProfile)
1023     {
1024       GLint aProfile = 0;
1025       ::glGetIntegerv (GL_CONTEXT_PROFILE_MASK, &aProfile);
1026       isCoreProfile = (aProfile & GL_CONTEXT_CORE_PROFILE_BIT) != 0;
1027     }
1028   }
1029 #endif
1030
1031   core11     = NULL;
1032   if (!isCoreProfile)
1033   {
1034     core11 = (OpenGl_GlCore11* )(&(*myFuncs));
1035   }
1036   core11fwd  = (OpenGl_GlCore11Fwd* )(&(*myFuncs));
1037   core15     = NULL;
1038   core15fwd  = NULL;
1039   core20     = NULL;
1040   core20fwd  = NULL;
1041   core32     = NULL;
1042   core32back = NULL;
1043   core33     = NULL;
1044   core33back = NULL;
1045   core41     = NULL;
1046   core41back = NULL;
1047   core42     = NULL;
1048   core42back = NULL;
1049   core43     = NULL;
1050   core43back = NULL;
1051   core44     = NULL;
1052   core44back = NULL;
1053   arbTBO     = NULL;
1054   arbTboRGB32 = Standard_False;
1055   arbIns     = NULL;
1056   arbDbg     = NULL;
1057   arbFBO     = NULL;
1058   arbFBOBlit = NULL;
1059   extGS      = NULL;
1060   myDefaultVao = 0;
1061
1062 #if defined(GL_ES_VERSION_2_0)
1063
1064   hasTexRGBA8 = IsGlGreaterEqual (3, 0)
1065              || CheckExtension ("GL_OES_rgb8_rgba8");
1066   // NPOT textures has limited support within OpenGL ES 2.0
1067   // which are relaxed by OpenGL ES 3.0 or some extensions
1068   //arbNPTW     = IsGlGreaterEqual (3, 0)
1069   //           || CheckExtension ("GL_OES_texture_npot")
1070   //           || CheckExtension ("GL_NV_texture_npot_2D_mipmap");
1071   arbNPTW     = Standard_True;
1072   arbTexRG    = IsGlGreaterEqual (3, 0)
1073              || CheckExtension ("GL_EXT_texture_rg");
1074   extBgra     = CheckExtension ("GL_EXT_texture_format_BGRA8888");
1075   extAnis = CheckExtension ("GL_EXT_texture_filter_anisotropic");
1076   extPDS  = CheckExtension ("GL_OES_packed_depth_stencil");
1077
1078   core11fwd = (OpenGl_GlCore11Fwd* )(&(*myFuncs));
1079   if (IsGlGreaterEqual (2, 0))
1080   {
1081     // enable compatible functions
1082     core20    = (OpenGl_GlCore20*    )(&(*myFuncs));
1083     core20fwd = (OpenGl_GlCore20Fwd* )(&(*myFuncs));
1084     core15fwd = (OpenGl_GlCore15Fwd* )(&(*myFuncs));
1085     arbFBO    = (OpenGl_ArbFBO*      )(&(*myFuncs));
1086   }
1087   if (IsGlGreaterEqual (3, 0)
1088    && FindProc ("glBlitFramebuffer", myFuncs->glBlitFramebuffer))
1089   {
1090     arbFBOBlit = (OpenGl_ArbFBOBlit* )(&(*myFuncs));
1091   }
1092
1093   hasHighp = CheckExtension ("GL_OES_fragment_precision_high");
1094   GLint aRange[2] = {0, 0};
1095   GLint aPrec     = 0;
1096   ::glGetShaderPrecisionFormat (GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, aRange, &aPrec);
1097   if (aPrec != 0)
1098   {
1099     hasHighp = Standard_True;
1100   }
1101 #else
1102
1103   myTexClamp = IsGlGreaterEqual (1, 2) ? GL_CLAMP_TO_EDGE : GL_CLAMP;
1104
1105   hasTexRGBA8 = Standard_True;
1106   arbNPTW = CheckExtension ("GL_ARB_texture_non_power_of_two");
1107   extBgra = CheckExtension ("GL_EXT_bgra");
1108   extAnis = CheckExtension ("GL_EXT_texture_filter_anisotropic");
1109   extPDS  = CheckExtension ("GL_EXT_packed_depth_stencil");
1110   atiMem  = CheckExtension ("GL_ATI_meminfo");
1111   nvxMem  = CheckExtension ("GL_NVX_gpu_memory_info");
1112
1113   GLint aStereo = GL_FALSE;
1114   glGetIntegerv (GL_STEREO, &aStereo);
1115   myIsStereoBuffers = aStereo == 1;
1116
1117   // get number of maximum clipping planes
1118   glGetIntegerv (GL_MAX_CLIP_PLANES,  &myMaxClipPlanes);
1119 #endif
1120
1121   glGetIntegerv (GL_MAX_TEXTURE_SIZE, &myMaxTexDim);
1122
1123   if (extAnis)
1124   {
1125     glGetIntegerv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &myAnisoMax);
1126   }
1127
1128   myClippingState.Init (myMaxClipPlanes);
1129
1130 #if !defined(GL_ES_VERSION_2_0)
1131
1132   bool has12 = false;
1133   bool has13 = false;
1134   bool has14 = false;
1135   bool has15 = false;
1136   bool has20 = false;
1137   bool has21 = false;
1138   bool has30 = false;
1139   bool has31 = false;
1140   bool has32 = false;
1141   bool has33 = false;
1142   bool has40 = false;
1143   bool has41 = false;
1144   bool has42 = false;
1145   bool has43 = false;
1146   bool has44 = false;
1147
1148   //! Make record shorter to retrieve function pointer using variable with same name
1149   #define FindProcShort(theFunc) FindProc(#theFunc, myFuncs->theFunc)
1150
1151   // retrieve platform-dependent extensions
1152 #if defined(_WIN32) && !defined(HAVE_EGL)
1153   if (FindProcShort (wglGetExtensionsStringARB))
1154   {
1155     const char* aWglExts = myFuncs->wglGetExtensionsStringARB (wglGetCurrentDC());
1156     if (CheckExtension (aWglExts, "WGL_EXT_swap_control"))
1157     {
1158       FindProcShort (wglSwapIntervalEXT);
1159     }
1160     if (CheckExtension (aWglExts, "WGL_ARB_pixel_format"))
1161     {
1162       FindProcShort (wglChoosePixelFormatARB);
1163     }
1164     if (CheckExtension (aWglExts, "WGL_ARB_create_context_profile"))
1165     {
1166       FindProcShort (wglCreateContextAttribsARB);
1167     }
1168     if (CheckExtension (aWglExts, "WGL_NV_DX_interop"))
1169     {
1170       FindProcShort (wglDXSetResourceShareHandleNV);
1171       FindProcShort (wglDXOpenDeviceNV);
1172       FindProcShort (wglDXCloseDeviceNV);
1173       FindProcShort (wglDXRegisterObjectNV);
1174       FindProcShort (wglDXUnregisterObjectNV);
1175       FindProcShort (wglDXObjectAccessNV);
1176       FindProcShort (wglDXLockObjectsNV);
1177       FindProcShort (wglDXUnlockObjectsNV);
1178     }
1179   }
1180 #endif
1181
1182   // initialize debug context extension
1183   if (CheckExtension ("GL_ARB_debug_output"))
1184   {
1185     arbDbg = NULL;
1186     if (FindProcShort (glDebugMessageControlARB)
1187      && FindProcShort (glDebugMessageInsertARB)
1188      && FindProcShort (glDebugMessageCallbackARB)
1189      && FindProcShort (glGetDebugMessageLogARB))
1190     {
1191       arbDbg = (OpenGl_ArbDbg* )(&(*myFuncs));
1192     }
1193     if (arbDbg != NULL
1194      && caps->contextDebug)
1195     {
1196       // setup default callback
1197       myIsGlDebugCtx = Standard_True;
1198       arbDbg->glDebugMessageCallbackARB (debugCallbackWrap, this);
1199       if (caps->contextSyncDebug)
1200       {
1201         ::glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
1202       }
1203     }
1204   }
1205
1206   // load OpenGL 1.2 new functions
1207   has12 = IsGlGreaterEqual (1, 2)
1208        && FindProcShort (glBlendColor)
1209        && FindProcShort (glBlendEquation)
1210        && FindProcShort (glDrawRangeElements)
1211        && FindProcShort (glTexImage3D)
1212        && FindProcShort (glTexSubImage3D)
1213        && FindProcShort (glCopyTexSubImage3D);
1214
1215   // load OpenGL 1.3 new functions
1216   has13 = IsGlGreaterEqual (1, 3)
1217        && FindProcShort (glActiveTexture)
1218        && FindProcShort (glSampleCoverage)
1219        && FindProcShort (glCompressedTexImage3D)
1220        && FindProcShort (glCompressedTexImage2D)
1221        && FindProcShort (glCompressedTexImage1D)
1222        && FindProcShort (glCompressedTexSubImage3D)
1223        && FindProcShort (glCompressedTexSubImage2D)
1224        && FindProcShort (glCompressedTexSubImage1D)
1225        && FindProcShort (glGetCompressedTexImage);
1226
1227   if (!isCoreProfile)
1228   {
1229     has13 = has13
1230        && FindProcShort (glClientActiveTexture)
1231        && FindProcShort (glMultiTexCoord1d)
1232        && FindProcShort (glMultiTexCoord1dv)
1233        && FindProcShort (glMultiTexCoord1f)
1234        && FindProcShort (glMultiTexCoord1fv)
1235        && FindProcShort (glMultiTexCoord1i)
1236        && FindProcShort (glMultiTexCoord1iv)
1237        && FindProcShort (glMultiTexCoord1s)
1238        && FindProcShort (glMultiTexCoord1sv)
1239        && FindProcShort (glMultiTexCoord2d)
1240        && FindProcShort (glMultiTexCoord2dv)
1241        && FindProcShort (glMultiTexCoord2f)
1242        && FindProcShort (glMultiTexCoord2fv)
1243        && FindProcShort (glMultiTexCoord2i)
1244        && FindProcShort (glMultiTexCoord2iv)
1245        && FindProcShort (glMultiTexCoord2s)
1246        && FindProcShort (glMultiTexCoord2sv)
1247        && FindProcShort (glMultiTexCoord3d)
1248        && FindProcShort (glMultiTexCoord3dv)
1249        && FindProcShort (glMultiTexCoord3f)
1250        && FindProcShort (glMultiTexCoord3fv)
1251        && FindProcShort (glMultiTexCoord3i)
1252        && FindProcShort (glMultiTexCoord3iv)
1253        && FindProcShort (glMultiTexCoord3s)
1254        && FindProcShort (glMultiTexCoord3sv)
1255        && FindProcShort (glMultiTexCoord4d)
1256        && FindProcShort (glMultiTexCoord4dv)
1257        && FindProcShort (glMultiTexCoord4f)
1258        && FindProcShort (glMultiTexCoord4fv)
1259        && FindProcShort (glMultiTexCoord4i)
1260        && FindProcShort (glMultiTexCoord4iv)
1261        && FindProcShort (glMultiTexCoord4s)
1262        && FindProcShort (glMultiTexCoord4sv)
1263        && FindProcShort (glLoadTransposeMatrixf)
1264        && FindProcShort (glLoadTransposeMatrixd)
1265        && FindProcShort (glMultTransposeMatrixf)
1266        && FindProcShort (glMultTransposeMatrixd);
1267   }
1268
1269   // load OpenGL 1.4 new functions
1270   has14 = IsGlGreaterEqual (1, 4)
1271        && FindProcShort (glBlendFuncSeparate)
1272        && FindProcShort (glMultiDrawArrays)
1273        && FindProcShort (glMultiDrawElements)
1274        && FindProcShort (glPointParameterf)
1275        && FindProcShort (glPointParameterfv)
1276        && FindProcShort (glPointParameteri)
1277        && FindProcShort (glPointParameteriv);
1278
1279   // load OpenGL 1.5 new functions
1280   has15 = IsGlGreaterEqual (1, 5)
1281        && FindProcShort (glGenQueries)
1282        && FindProcShort (glDeleteQueries)
1283        && FindProcShort (glIsQuery)
1284        && FindProcShort (glBeginQuery)
1285        && FindProcShort (glEndQuery)
1286        && FindProcShort (glGetQueryiv)
1287        && FindProcShort (glGetQueryObjectiv)
1288        && FindProcShort (glGetQueryObjectuiv)
1289        && FindProcShort (glBindBuffer)
1290        && FindProcShort (glDeleteBuffers)
1291        && FindProcShort (glGenBuffers)
1292        && FindProcShort (glIsBuffer)
1293        && FindProcShort (glBufferData)
1294        && FindProcShort (glBufferSubData)
1295        && FindProcShort (glGetBufferSubData)
1296        && FindProcShort (glMapBuffer)
1297        && FindProcShort (glUnmapBuffer)
1298        && FindProcShort (glGetBufferParameteriv)
1299        && FindProcShort (glGetBufferPointerv);
1300
1301   // load OpenGL 2.0 new functions
1302   has20 = IsGlGreaterEqual (2, 0)
1303        && FindProcShort (glBlendEquationSeparate)
1304        && FindProcShort (glDrawBuffers)
1305        && FindProcShort (glStencilOpSeparate)
1306        && FindProcShort (glStencilFuncSeparate)
1307        && FindProcShort (glStencilMaskSeparate)
1308        && FindProcShort (glAttachShader)
1309        && FindProcShort (glBindAttribLocation)
1310        && FindProcShort (glCompileShader)
1311        && FindProcShort (glCreateProgram)
1312        && FindProcShort (glCreateShader)
1313        && FindProcShort (glDeleteProgram)
1314        && FindProcShort (glDeleteShader)
1315        && FindProcShort (glDetachShader)
1316        && FindProcShort (glDisableVertexAttribArray)
1317        && FindProcShort (glEnableVertexAttribArray)
1318        && FindProcShort (glGetActiveAttrib)
1319        && FindProcShort (glGetActiveUniform)
1320        && FindProcShort (glGetAttachedShaders)
1321        && FindProcShort (glGetAttribLocation)
1322        && FindProcShort (glGetProgramiv)
1323        && FindProcShort (glGetProgramInfoLog)
1324        && FindProcShort (glGetShaderiv)
1325        && FindProcShort (glGetShaderInfoLog)
1326        && FindProcShort (glGetShaderSource)
1327        && FindProcShort (glGetUniformLocation)
1328        && FindProcShort (glGetUniformfv)
1329        && FindProcShort (glGetUniformiv)
1330        && FindProcShort (glGetVertexAttribdv)
1331        && FindProcShort (glGetVertexAttribfv)
1332        && FindProcShort (glGetVertexAttribiv)
1333        && FindProcShort (glGetVertexAttribPointerv)
1334        && FindProcShort (glIsProgram)
1335        && FindProcShort (glIsShader)
1336        && FindProcShort (glLinkProgram)
1337        && FindProcShort (glShaderSource)
1338        && FindProcShort (glUseProgram)
1339        && FindProcShort (glUniform1f)
1340        && FindProcShort (glUniform2f)
1341        && FindProcShort (glUniform3f)
1342        && FindProcShort (glUniform4f)
1343        && FindProcShort (glUniform1i)
1344        && FindProcShort (glUniform2i)
1345        && FindProcShort (glUniform3i)
1346        && FindProcShort (glUniform4i)
1347        && FindProcShort (glUniform1fv)
1348        && FindProcShort (glUniform2fv)
1349        && FindProcShort (glUniform3fv)
1350        && FindProcShort (glUniform4fv)
1351        && FindProcShort (glUniform1iv)
1352        && FindProcShort (glUniform2iv)
1353        && FindProcShort (glUniform3iv)
1354        && FindProcShort (glUniform4iv)
1355        && FindProcShort (glUniformMatrix2fv)
1356        && FindProcShort (glUniformMatrix3fv)
1357        && FindProcShort (glUniformMatrix4fv)
1358        && FindProcShort (glValidateProgram)
1359        && FindProcShort (glVertexAttrib1d)
1360        && FindProcShort (glVertexAttrib1dv)
1361        && FindProcShort (glVertexAttrib1f)
1362        && FindProcShort (glVertexAttrib1fv)
1363        && FindProcShort (glVertexAttrib1s)
1364        && FindProcShort (glVertexAttrib1sv)
1365        && FindProcShort (glVertexAttrib2d)
1366        && FindProcShort (glVertexAttrib2dv)
1367        && FindProcShort (glVertexAttrib2f)
1368        && FindProcShort (glVertexAttrib2fv)
1369        && FindProcShort (glVertexAttrib2s)
1370        && FindProcShort (glVertexAttrib2sv)
1371        && FindProcShort (glVertexAttrib3d)
1372        && FindProcShort (glVertexAttrib3dv)
1373        && FindProcShort (glVertexAttrib3f)
1374        && FindProcShort (glVertexAttrib3fv)
1375        && FindProcShort (glVertexAttrib3s)
1376        && FindProcShort (glVertexAttrib3sv)
1377        && FindProcShort (glVertexAttrib4Nbv)
1378        && FindProcShort (glVertexAttrib4Niv)
1379        && FindProcShort (glVertexAttrib4Nsv)
1380        && FindProcShort (glVertexAttrib4Nub)
1381        && FindProcShort (glVertexAttrib4Nubv)
1382        && FindProcShort (glVertexAttrib4Nuiv)
1383        && FindProcShort (glVertexAttrib4Nusv)
1384        && FindProcShort (glVertexAttrib4bv)
1385        && FindProcShort (glVertexAttrib4d)
1386        && FindProcShort (glVertexAttrib4dv)
1387        && FindProcShort (glVertexAttrib4f)
1388        && FindProcShort (glVertexAttrib4fv)
1389        && FindProcShort (glVertexAttrib4iv)
1390        && FindProcShort (glVertexAttrib4s)
1391        && FindProcShort (glVertexAttrib4sv)
1392        && FindProcShort (glVertexAttrib4ubv)
1393        && FindProcShort (glVertexAttrib4uiv)
1394        && FindProcShort (glVertexAttrib4usv)
1395        && FindProcShort (glVertexAttribPointer);
1396
1397   // load OpenGL 2.1 new functions
1398   has21 = IsGlGreaterEqual (2, 1)
1399        && FindProcShort (glUniformMatrix2x3fv)
1400        && FindProcShort (glUniformMatrix3x2fv)
1401        && FindProcShort (glUniformMatrix2x4fv)
1402        && FindProcShort (glUniformMatrix4x2fv)
1403        && FindProcShort (glUniformMatrix3x4fv)
1404        && FindProcShort (glUniformMatrix4x3fv);
1405
1406   // load GL_ARB_framebuffer_object (added to OpenGL 3.0 core)
1407   const bool hasFBO = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_framebuffer_object"))
1408        && FindProcShort (glIsRenderbuffer)
1409        && FindProcShort (glBindRenderbuffer)
1410        && FindProcShort (glDeleteRenderbuffers)
1411        && FindProcShort (glGenRenderbuffers)
1412        && FindProcShort (glRenderbufferStorage)
1413        && FindProcShort (glGetRenderbufferParameteriv)
1414        && FindProcShort (glIsFramebuffer)
1415        && FindProcShort (glBindFramebuffer)
1416        && FindProcShort (glDeleteFramebuffers)
1417        && FindProcShort (glGenFramebuffers)
1418        && FindProcShort (glCheckFramebufferStatus)
1419        && FindProcShort (glFramebufferTexture1D)
1420        && FindProcShort (glFramebufferTexture2D)
1421        && FindProcShort (glFramebufferTexture3D)
1422        && FindProcShort (glFramebufferRenderbuffer)
1423        && FindProcShort (glGetFramebufferAttachmentParameteriv)
1424        && FindProcShort (glGenerateMipmap)
1425        && FindProcShort (glBlitFramebuffer)
1426        && FindProcShort (glRenderbufferStorageMultisample)
1427        && FindProcShort (glFramebufferTextureLayer);
1428
1429   // load GL_ARB_vertex_array_object (added to OpenGL 3.0 core)
1430   const bool hasVAO = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_vertex_array_object"))
1431        && FindProcShort (glBindVertexArray)
1432        && FindProcShort (glDeleteVertexArrays)
1433        && FindProcShort (glGenVertexArrays)
1434        && FindProcShort (glIsVertexArray);
1435
1436   // load GL_ARB_map_buffer_range (added to OpenGL 3.0 core)
1437   const bool hasMapBufferRange = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_map_buffer_range"))
1438        && FindProcShort (glMapBufferRange)
1439        && FindProcShort (glFlushMappedBufferRange);
1440
1441   // load OpenGL 3.0 new functions
1442   has30 = IsGlGreaterEqual (3, 0)
1443        && hasFBO
1444        && hasVAO
1445        && hasMapBufferRange
1446        && FindProcShort (glColorMaski)
1447        && FindProcShort (glGetBooleani_v)
1448        && FindProcShort (glGetIntegeri_v)
1449        && FindProcShort (glEnablei)
1450        && FindProcShort (glDisablei)
1451        && FindProcShort (glIsEnabledi)
1452        && FindProcShort (glBeginTransformFeedback)
1453        && FindProcShort (glEndTransformFeedback)
1454        && FindProcShort (glBindBufferRange)
1455        && FindProcShort (glBindBufferBase)
1456        && FindProcShort (glTransformFeedbackVaryings)
1457        && FindProcShort (glGetTransformFeedbackVarying)
1458        && FindProcShort (glClampColor)
1459        && FindProcShort (glBeginConditionalRender)
1460        && FindProcShort (glEndConditionalRender)
1461        && FindProcShort (glVertexAttribIPointer)
1462        && FindProcShort (glGetVertexAttribIiv)
1463        && FindProcShort (glGetVertexAttribIuiv)
1464        && FindProcShort (glVertexAttribI1i)
1465        && FindProcShort (glVertexAttribI2i)
1466        && FindProcShort (glVertexAttribI3i)
1467        && FindProcShort (glVertexAttribI4i)
1468        && FindProcShort (glVertexAttribI1ui)
1469        && FindProcShort (glVertexAttribI2ui)
1470        && FindProcShort (glVertexAttribI3ui)
1471        && FindProcShort (glVertexAttribI4ui)
1472        && FindProcShort (glVertexAttribI1iv)
1473        && FindProcShort (glVertexAttribI2iv)
1474        && FindProcShort (glVertexAttribI3iv)
1475        && FindProcShort (glVertexAttribI4iv)
1476        && FindProcShort (glVertexAttribI1uiv)
1477        && FindProcShort (glVertexAttribI2uiv)
1478        && FindProcShort (glVertexAttribI3uiv)
1479        && FindProcShort (glVertexAttribI4uiv)
1480        && FindProcShort (glVertexAttribI4bv)
1481        && FindProcShort (glVertexAttribI4sv)
1482        && FindProcShort (glVertexAttribI4ubv)
1483        && FindProcShort (glVertexAttribI4usv)
1484        && FindProcShort (glGetUniformuiv)
1485        && FindProcShort (glBindFragDataLocation)
1486        && FindProcShort (glGetFragDataLocation)
1487        && FindProcShort (glUniform1ui)
1488        && FindProcShort (glUniform2ui)
1489        && FindProcShort (glUniform3ui)
1490        && FindProcShort (glUniform4ui)
1491        && FindProcShort (glUniform1uiv)
1492        && FindProcShort (glUniform2uiv)
1493        && FindProcShort (glUniform3uiv)
1494        && FindProcShort (glUniform4uiv)
1495        && FindProcShort (glTexParameterIiv)
1496        && FindProcShort (glTexParameterIuiv)
1497        && FindProcShort (glGetTexParameterIiv)
1498        && FindProcShort (glGetTexParameterIuiv)
1499        && FindProcShort (glClearBufferiv)
1500        && FindProcShort (glClearBufferuiv)
1501        && FindProcShort (glClearBufferfv)
1502        && FindProcShort (glClearBufferfi)
1503        && FindProcShort (glGetStringi);
1504
1505   // load GL_ARB_uniform_buffer_object (added to OpenGL 3.1 core)
1506   const bool hasUBO = (IsGlGreaterEqual (3, 1) || CheckExtension ("GL_ARB_uniform_buffer_object"))
1507        && FindProcShort (glGetUniformIndices)
1508        && FindProcShort (glGetActiveUniformsiv)
1509        && FindProcShort (glGetActiveUniformName)
1510        && FindProcShort (glGetUniformBlockIndex)
1511        && FindProcShort (glGetActiveUniformBlockiv)
1512        && FindProcShort (glGetActiveUniformBlockName)
1513        && FindProcShort (glUniformBlockBinding);
1514
1515   // load GL_ARB_copy_buffer (added to OpenGL 3.1 core)
1516   const bool hasCopyBufSubData = (IsGlGreaterEqual (3, 1) || CheckExtension ("GL_ARB_copy_buffer"))
1517        && FindProcShort (glCopyBufferSubData);
1518
1519   if (has30)
1520   {
1521     // NPOT textures are required by OpenGL 2.0 specifications
1522     // but doesn't hardware accelerated by some ancient OpenGL 2.1 hardware (GeForce FX, RadeOn 9700 etc.)
1523     arbNPTW  = Standard_True;
1524     arbTexRG = Standard_True;
1525   }
1526
1527   // load OpenGL 3.1 new functions
1528   has31 = IsGlGreaterEqual (3, 1)
1529        && hasUBO
1530        && hasCopyBufSubData
1531        && FindProcShort (glDrawArraysInstanced)
1532        && FindProcShort (glDrawElementsInstanced)
1533        && FindProcShort (glTexBuffer)
1534        && FindProcShort (glPrimitiveRestartIndex);
1535
1536   // load GL_ARB_draw_elements_base_vertex (added to OpenGL 3.2 core)
1537   const bool hasDrawElemsBaseVert = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_draw_elements_base_vertex"))
1538        && FindProcShort (glDrawElementsBaseVertex)
1539        && FindProcShort (glDrawRangeElementsBaseVertex)
1540        && FindProcShort (glDrawElementsInstancedBaseVertex)
1541        && FindProcShort (glMultiDrawElementsBaseVertex);
1542
1543   // load GL_ARB_provoking_vertex (added to OpenGL 3.2 core)
1544   const bool hasProvokingVert = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_provoking_vertex"))
1545        && FindProcShort (glProvokingVertex);
1546
1547   // load GL_ARB_sync (added to OpenGL 3.2 core)
1548   const bool hasSync = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_sync"))
1549        && FindProcShort (glFenceSync)
1550        && FindProcShort (glIsSync)
1551        && FindProcShort (glDeleteSync)
1552        && FindProcShort (glClientWaitSync)
1553        && FindProcShort (glWaitSync)
1554        && FindProcShort (glGetInteger64v)
1555        && FindProcShort (glGetSynciv);
1556
1557   // load GL_ARB_texture_multisample (added to OpenGL 3.2 core)
1558   const bool hasTextureMultisample = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_texture_multisample"))
1559        && FindProcShort (glTexImage2DMultisample)
1560        && FindProcShort (glTexImage3DMultisample)
1561        && FindProcShort (glGetMultisamplefv)
1562        && FindProcShort (glSampleMaski);
1563
1564   // load OpenGL 3.2 new functions
1565   has32 = IsGlGreaterEqual (3, 2)
1566        && hasDrawElemsBaseVert
1567        && hasProvokingVert
1568        && hasSync
1569        && hasTextureMultisample
1570        && FindProcShort (glGetInteger64i_v)
1571        && FindProcShort (glGetBufferParameteri64v)
1572        && FindProcShort (glFramebufferTexture);
1573
1574   // load GL_ARB_blend_func_extended (added to OpenGL 3.3 core)
1575   const bool hasBlendFuncExtended = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_blend_func_extended"))
1576        && FindProcShort (glBindFragDataLocationIndexed)
1577        && FindProcShort (glGetFragDataIndex);
1578
1579   // load GL_ARB_sampler_objects (added to OpenGL 3.3 core)
1580   const bool hasSamplerObjects = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_sampler_objects"))
1581        && FindProcShort (glGenSamplers)
1582        && FindProcShort (glDeleteSamplers)
1583        && FindProcShort (glIsSampler)
1584        && FindProcShort (glBindSampler)
1585        && FindProcShort (glSamplerParameteri)
1586        && FindProcShort (glSamplerParameteriv)
1587        && FindProcShort (glSamplerParameterf)
1588        && FindProcShort (glSamplerParameterfv)
1589        && FindProcShort (glSamplerParameterIiv)
1590        && FindProcShort (glSamplerParameterIuiv)
1591        && FindProcShort (glGetSamplerParameteriv)
1592        && FindProcShort (glGetSamplerParameterIiv)
1593        && FindProcShort (glGetSamplerParameterfv)
1594        && FindProcShort (glGetSamplerParameterIuiv);
1595
1596   // load GL_ARB_timer_query (added to OpenGL 3.3 core)
1597   const bool hasTimerQuery = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_timer_query"))
1598        && FindProcShort (glQueryCounter)
1599        && FindProcShort (glGetQueryObjecti64v)
1600        && FindProcShort (glGetQueryObjectui64v);
1601
1602   // load GL_ARB_vertex_type_2_10_10_10_rev (added to OpenGL 3.3 core)
1603   const bool hasVertType21010101rev = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_vertex_type_2_10_10_10_rev"))
1604        && FindProcShort (glVertexP2ui)
1605        && FindProcShort (glVertexP2uiv)
1606        && FindProcShort (glVertexP3ui)
1607        && FindProcShort (glVertexP3uiv)
1608        && FindProcShort (glVertexP4ui)
1609        && FindProcShort (glVertexP4uiv)
1610        && FindProcShort (glTexCoordP1ui)
1611        && FindProcShort (glTexCoordP1uiv)
1612        && FindProcShort (glTexCoordP2ui)
1613        && FindProcShort (glTexCoordP2uiv)
1614        && FindProcShort (glTexCoordP3ui)
1615        && FindProcShort (glTexCoordP3uiv)
1616        && FindProcShort (glTexCoordP4ui)
1617        && FindProcShort (glTexCoordP4uiv)
1618        && FindProcShort (glMultiTexCoordP1ui)
1619        && FindProcShort (glMultiTexCoordP1uiv)
1620        && FindProcShort (glMultiTexCoordP2ui)
1621        && FindProcShort (glMultiTexCoordP2uiv)
1622        && FindProcShort (glMultiTexCoordP3ui)
1623        && FindProcShort (glMultiTexCoordP3uiv)
1624        && FindProcShort (glMultiTexCoordP4ui)
1625        && FindProcShort (glMultiTexCoordP4uiv)
1626        && FindProcShort (glNormalP3ui)
1627        && FindProcShort (glNormalP3uiv)
1628        && FindProcShort (glColorP3ui)
1629        && FindProcShort (glColorP3uiv)
1630        && FindProcShort (glColorP4ui)
1631        && FindProcShort (glColorP4uiv)
1632        && FindProcShort (glSecondaryColorP3ui)
1633        && FindProcShort (glSecondaryColorP3uiv)
1634        && FindProcShort (glVertexAttribP1ui)
1635        && FindProcShort (glVertexAttribP1uiv)
1636        && FindProcShort (glVertexAttribP2ui)
1637        && FindProcShort (glVertexAttribP2uiv)
1638        && FindProcShort (glVertexAttribP3ui)
1639        && FindProcShort (glVertexAttribP3uiv)
1640        && FindProcShort (glVertexAttribP4ui)
1641        && FindProcShort (glVertexAttribP4uiv);
1642
1643   // load OpenGL 3.3 extra functions
1644   has33 = IsGlGreaterEqual (3, 3)
1645        && hasBlendFuncExtended
1646        && hasSamplerObjects
1647        && hasTimerQuery
1648        && hasVertType21010101rev
1649        && FindProcShort (glVertexAttribDivisor);
1650
1651   // load GL_ARB_draw_indirect (added to OpenGL 4.0 core)
1652   const bool hasDrawIndirect = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_draw_indirect"))
1653        && FindProcShort (glDrawArraysIndirect)
1654        && FindProcShort (glDrawElementsIndirect);
1655
1656   // load GL_ARB_gpu_shader_fp64 (added to OpenGL 4.0 core)
1657   const bool hasShaderFP64 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_gpu_shader_fp64"))
1658        && FindProcShort (glUniform1d)
1659        && FindProcShort (glUniform2d)
1660        && FindProcShort (glUniform3d)
1661        && FindProcShort (glUniform4d)
1662        && FindProcShort (glUniform1dv)
1663        && FindProcShort (glUniform2dv)
1664        && FindProcShort (glUniform3dv)
1665        && FindProcShort (glUniform4dv)
1666        && FindProcShort (glUniformMatrix2dv)
1667        && FindProcShort (glUniformMatrix3dv)
1668        && FindProcShort (glUniformMatrix4dv)
1669        && FindProcShort (glUniformMatrix2x3dv)
1670        && FindProcShort (glUniformMatrix2x4dv)
1671        && FindProcShort (glUniformMatrix3x2dv)
1672        && FindProcShort (glUniformMatrix3x4dv)
1673        && FindProcShort (glUniformMatrix4x2dv)
1674        && FindProcShort (glUniformMatrix4x3dv)
1675        && FindProcShort (glGetUniformdv);
1676
1677   // load GL_ARB_shader_subroutine (added to OpenGL 4.0 core)
1678   const bool hasShaderSubroutine = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_shader_subroutine"))
1679        && FindProcShort (glGetSubroutineUniformLocation)
1680        && FindProcShort (glGetSubroutineIndex)
1681        && FindProcShort (glGetActiveSubroutineUniformiv)
1682        && FindProcShort (glGetActiveSubroutineUniformName)
1683        && FindProcShort (glGetActiveSubroutineName)
1684        && FindProcShort (glUniformSubroutinesuiv)
1685        && FindProcShort (glGetUniformSubroutineuiv)
1686        && FindProcShort (glGetProgramStageiv);
1687
1688   // load GL_ARB_tessellation_shader (added to OpenGL 4.0 core)
1689   const bool hasTessellationShader = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_tessellation_shader"))
1690        && FindProcShort (glPatchParameteri)
1691        && FindProcShort (glPatchParameterfv);
1692
1693   // load GL_ARB_transform_feedback2 (added to OpenGL 4.0 core)
1694   const bool hasTrsfFeedback2 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_transform_feedback2"))
1695        && FindProcShort (glBindTransformFeedback)
1696        && FindProcShort (glDeleteTransformFeedbacks)
1697        && FindProcShort (glGenTransformFeedbacks)
1698        && FindProcShort (glIsTransformFeedback)
1699        && FindProcShort (glPauseTransformFeedback)
1700        && FindProcShort (glResumeTransformFeedback)
1701        && FindProcShort (glDrawTransformFeedback);
1702
1703   // load GL_ARB_transform_feedback3 (added to OpenGL 4.0 core)
1704   const bool hasTrsfFeedback3 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_transform_feedback3"))
1705        && FindProcShort (glDrawTransformFeedbackStream)
1706        && FindProcShort (glBeginQueryIndexed)
1707        && FindProcShort (glEndQueryIndexed)
1708        && FindProcShort (glGetQueryIndexediv);
1709
1710   // load OpenGL 4.0 new functions
1711   has40 = IsGlGreaterEqual (4, 0)
1712       && hasDrawIndirect
1713       && hasShaderFP64
1714       && hasShaderSubroutine
1715       && hasTessellationShader
1716       && hasTrsfFeedback2
1717       && hasTrsfFeedback3
1718       && FindProcShort (glMinSampleShading)
1719       && FindProcShort (glBlendEquationi)
1720       && FindProcShort (glBlendEquationSeparatei)
1721       && FindProcShort (glBlendFunci)
1722       && FindProcShort (glBlendFuncSeparatei);
1723
1724   // load GL_ARB_ES2_compatibility (added to OpenGL 4.1 core)
1725   const bool hasES2Compatibility = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_ES2_compatibility"))
1726        && FindProcShort (glReleaseShaderCompiler)
1727        && FindProcShort (glShaderBinary)
1728        && FindProcShort (glGetShaderPrecisionFormat)
1729        && FindProcShort (glDepthRangef)
1730        && FindProcShort (glClearDepthf);
1731
1732   // load GL_ARB_get_program_binary (added to OpenGL 4.1 core)
1733   const bool hasGetProgramBinary = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_get_program_binary"))
1734        && FindProcShort (glGetProgramBinary)
1735        && FindProcShort (glProgramBinary)
1736        && FindProcShort (glProgramParameteri);
1737
1738
1739   // load GL_ARB_separate_shader_objects (added to OpenGL 4.1 core)
1740   const bool hasSeparateShaderObjects = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_separate_shader_objects"))
1741        && FindProcShort (glUseProgramStages)
1742        && FindProcShort (glActiveShaderProgram)
1743        && FindProcShort (glCreateShaderProgramv)
1744        && FindProcShort (glBindProgramPipeline)
1745        && FindProcShort (glDeleteProgramPipelines)
1746        && FindProcShort (glGenProgramPipelines)
1747        && FindProcShort (glIsProgramPipeline)
1748        && FindProcShort (glGetProgramPipelineiv)
1749        && FindProcShort (glProgramUniform1i)
1750        && FindProcShort (glProgramUniform1iv)
1751        && FindProcShort (glProgramUniform1f)
1752        && FindProcShort (glProgramUniform1fv)
1753        && FindProcShort (glProgramUniform1d)
1754        && FindProcShort (glProgramUniform1dv)
1755        && FindProcShort (glProgramUniform1ui)
1756        && FindProcShort (glProgramUniform1uiv)
1757        && FindProcShort (glProgramUniform2i)
1758        && FindProcShort (glProgramUniform2iv)
1759        && FindProcShort (glProgramUniform2f)
1760        && FindProcShort (glProgramUniform2fv)
1761        && FindProcShort (glProgramUniform2d)
1762        && FindProcShort (glProgramUniform2dv)
1763        && FindProcShort (glProgramUniform2ui)
1764        && FindProcShort (glProgramUniform2uiv)
1765        && FindProcShort (glProgramUniform3i)
1766        && FindProcShort (glProgramUniform3iv)
1767        && FindProcShort (glProgramUniform3f)
1768        && FindProcShort (glProgramUniform3fv)
1769        && FindProcShort (glProgramUniform3d)
1770        && FindProcShort (glProgramUniform3dv)
1771        && FindProcShort (glProgramUniform3ui)
1772        && FindProcShort (glProgramUniform3uiv)
1773        && FindProcShort (glProgramUniform4i)
1774        && FindProcShort (glProgramUniform4iv)
1775        && FindProcShort (glProgramUniform4f)
1776        && FindProcShort (glProgramUniform4fv)
1777        && FindProcShort (glProgramUniform4d)
1778        && FindProcShort (glProgramUniform4dv)
1779        && FindProcShort (glProgramUniform4ui)
1780        && FindProcShort (glProgramUniform4uiv)
1781        && FindProcShort (glProgramUniformMatrix2fv)
1782        && FindProcShort (glProgramUniformMatrix3fv)
1783        && FindProcShort (glProgramUniformMatrix4fv)
1784        && FindProcShort (glProgramUniformMatrix2dv)
1785        && FindProcShort (glProgramUniformMatrix3dv)
1786        && FindProcShort (glProgramUniformMatrix4dv)
1787        && FindProcShort (glProgramUniformMatrix2x3fv)
1788        && FindProcShort (glProgramUniformMatrix3x2fv)
1789        && FindProcShort (glProgramUniformMatrix2x4fv)
1790        && FindProcShort (glProgramUniformMatrix4x2fv)
1791        && FindProcShort (glProgramUniformMatrix3x4fv)
1792        && FindProcShort (glProgramUniformMatrix4x3fv)
1793        && FindProcShort (glProgramUniformMatrix2x3dv)
1794        && FindProcShort (glProgramUniformMatrix3x2dv)
1795        && FindProcShort (glProgramUniformMatrix2x4dv)
1796        && FindProcShort (glProgramUniformMatrix4x2dv)
1797        && FindProcShort (glProgramUniformMatrix3x4dv)
1798        && FindProcShort (glProgramUniformMatrix4x3dv)
1799        && FindProcShort (glValidateProgramPipeline)
1800        && FindProcShort (glGetProgramPipelineInfoLog);
1801
1802   // load GL_ARB_vertex_attrib_64bit (added to OpenGL 4.1 core)
1803   const bool hasVertAttrib64bit = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_vertex_attrib_64bit"))
1804        && FindProcShort (glVertexAttribL1d)
1805        && FindProcShort (glVertexAttribL2d)
1806        && FindProcShort (glVertexAttribL3d)
1807        && FindProcShort (glVertexAttribL4d)
1808        && FindProcShort (glVertexAttribL1dv)
1809        && FindProcShort (glVertexAttribL2dv)
1810        && FindProcShort (glVertexAttribL3dv)
1811        && FindProcShort (glVertexAttribL4dv)
1812        && FindProcShort (glVertexAttribLPointer)
1813        && FindProcShort (glGetVertexAttribLdv);
1814
1815   // load GL_ARB_viewport_array (added to OpenGL 4.1 core)
1816   const bool hasViewportArray = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_viewport_array"))
1817        && FindProcShort (glViewportArrayv)
1818        && FindProcShort (glViewportIndexedf)
1819        && FindProcShort (glViewportIndexedfv)
1820        && FindProcShort (glScissorArrayv)
1821        && FindProcShort (glScissorIndexed)
1822        && FindProcShort (glScissorIndexedv)
1823        && FindProcShort (glDepthRangeArrayv)
1824        && FindProcShort (glDepthRangeIndexed)
1825        && FindProcShort (glGetFloati_v)
1826        && FindProcShort (glGetDoublei_v);
1827
1828   has41 = IsGlGreaterEqual (4, 1)
1829        && hasES2Compatibility
1830        && hasGetProgramBinary
1831        && hasSeparateShaderObjects
1832        && hasVertAttrib64bit
1833        && hasViewportArray;
1834
1835   // load GL_ARB_base_instance (added to OpenGL 4.2 core)
1836   const bool hasBaseInstance = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_base_instance"))
1837        && FindProcShort (glDrawArraysInstancedBaseInstance)
1838        && FindProcShort (glDrawElementsInstancedBaseInstance)
1839        && FindProcShort (glDrawElementsInstancedBaseVertexBaseInstance);
1840
1841   // load GL_ARB_transform_feedback_instanced (added to OpenGL 4.2 core)
1842   const bool hasTrsfFeedbackInstanced = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_transform_feedback_instanced"))
1843        && FindProcShort (glDrawTransformFeedbackInstanced)
1844        && FindProcShort (glDrawTransformFeedbackStreamInstanced);
1845
1846   // load GL_ARB_internalformat_query (added to OpenGL 4.2 core)
1847   const bool hasInternalFormatQuery = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_internalformat_query"))
1848        && FindProcShort (glGetInternalformativ);
1849
1850   // load GL_ARB_shader_atomic_counters (added to OpenGL 4.2 core)
1851   const bool hasShaderAtomicCounters = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_shader_atomic_counters"))
1852        && FindProcShort (glGetActiveAtomicCounterBufferiv);
1853
1854   // load GL_ARB_shader_image_load_store (added to OpenGL 4.2 core)
1855   const bool hasShaderImgLoadStore = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_shader_image_load_store"))
1856        && FindProcShort (glBindImageTexture)
1857        && FindProcShort (glMemoryBarrier);
1858
1859   // load GL_ARB_texture_storage (added to OpenGL 4.2 core)
1860   const bool hasTextureStorage = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_texture_storage"))
1861        && FindProcShort (glTexStorage1D)
1862        && FindProcShort (glTexStorage2D)
1863        && FindProcShort (glTexStorage3D);
1864
1865   has42 = IsGlGreaterEqual (4, 2)
1866        && hasBaseInstance
1867        && hasTrsfFeedbackInstanced
1868        && hasInternalFormatQuery
1869        && hasShaderAtomicCounters
1870        && hasShaderImgLoadStore
1871        && hasTextureStorage;
1872
1873   has43 = IsGlGreaterEqual (4, 3)
1874        && FindProcShort (glClearBufferData)
1875        && FindProcShort (glClearBufferSubData)
1876        && FindProcShort (glDispatchCompute)
1877        && FindProcShort (glDispatchComputeIndirect)
1878        && FindProcShort (glCopyImageSubData)
1879        && FindProcShort (glFramebufferParameteri)
1880        && FindProcShort (glGetFramebufferParameteriv)
1881        && FindProcShort (glGetInternalformati64v)
1882        && FindProcShort (glInvalidateTexSubImage)
1883        && FindProcShort (glInvalidateTexImage)
1884        && FindProcShort (glInvalidateBufferSubData)
1885        && FindProcShort (glInvalidateBufferData)
1886        && FindProcShort (glInvalidateFramebuffer)
1887        && FindProcShort (glInvalidateSubFramebuffer)
1888        && FindProcShort (glMultiDrawArraysIndirect)
1889        && FindProcShort (glMultiDrawElementsIndirect)
1890        && FindProcShort (glGetProgramInterfaceiv)
1891        && FindProcShort (glGetProgramResourceIndex)
1892        && FindProcShort (glGetProgramResourceName)
1893        && FindProcShort (glGetProgramResourceiv)
1894        && FindProcShort (glGetProgramResourceLocation)
1895        && FindProcShort (glGetProgramResourceLocationIndex)
1896        && FindProcShort (glShaderStorageBlockBinding)
1897        && FindProcShort (glTexBufferRange)
1898        && FindProcShort (glTexStorage2DMultisample)
1899        && FindProcShort (glTexStorage3DMultisample)
1900        && FindProcShort (glTextureView)
1901        && FindProcShort (glBindVertexBuffer)
1902        && FindProcShort (glVertexAttribFormat)
1903        && FindProcShort (glVertexAttribIFormat)
1904        && FindProcShort (glVertexAttribLFormat)
1905        && FindProcShort (glVertexAttribBinding)
1906        && FindProcShort (glVertexBindingDivisor)
1907        && FindProcShort (glDebugMessageControl)
1908        && FindProcShort (glDebugMessageInsert)
1909        && FindProcShort (glDebugMessageCallback)
1910        && FindProcShort (glGetDebugMessageLog)
1911        && FindProcShort (glPushDebugGroup)
1912        && FindProcShort (glPopDebugGroup)
1913        && FindProcShort (glObjectLabel)
1914        && FindProcShort (glGetObjectLabel)
1915        && FindProcShort (glObjectPtrLabel)
1916        && FindProcShort (glGetObjectPtrLabel);
1917
1918   // load GL_ARB_clear_texture (added to OpenGL 4.4 core)
1919   bool arbTexClear = (IsGlGreaterEqual (4, 4) || CheckExtension ("GL_ARB_clear_texture"))
1920        && FindProcShort (glClearTexImage)
1921        && FindProcShort (glClearTexSubImage);
1922
1923   has44 = IsGlGreaterEqual (4, 4)
1924        && arbTexClear
1925        && FindProcShort (glBufferStorage)
1926        && FindProcShort (glBindBuffersBase)
1927        && FindProcShort (glBindBuffersRange)
1928        && FindProcShort (glBindTextures)
1929        && FindProcShort (glBindSamplers)
1930        && FindProcShort (glBindImageTextures)
1931        && FindProcShort (glBindVertexBuffers);
1932
1933   // initialize TBO extension (ARB)
1934   if (!has31
1935    && CheckExtension ("GL_ARB_texture_buffer_object")
1936    && FindProc ("glTexBufferARB", myFuncs->glTexBuffer))
1937   {
1938     arbTBO = (OpenGl_ArbTBO* )(&(*myFuncs));
1939   }
1940   arbTboRGB32 = CheckExtension ("GL_ARB_texture_buffer_object_rgb32");
1941
1942   // initialize hardware instancing extension (ARB)
1943   if (!has31
1944    && CheckExtension ("GL_ARB_draw_instanced")
1945    && FindProc ("glDrawArraysInstancedARB",   myFuncs->glDrawArraysInstanced)
1946    && FindProc ("glDrawElementsInstancedARB", myFuncs->glDrawElementsInstanced))
1947   {
1948     arbIns = (OpenGl_ArbIns* )(&(*myFuncs));
1949   }
1950
1951   // initialize FBO extension (ARB)
1952   if (hasFBO)
1953   {
1954     arbFBO     = (OpenGl_ArbFBO*     )(&(*myFuncs));
1955     arbFBOBlit = (OpenGl_ArbFBOBlit* )(&(*myFuncs));
1956     extPDS = Standard_True; // extension for EXT, but part of ARB
1957   }
1958
1959   // initialize GS extension (EXT)
1960   if (CheckExtension ("GL_EXT_geometry_shader4")
1961    && FindProcShort (glProgramParameteriEXT))
1962   {
1963     extGS = (OpenGl_ExtGS* )(&(*myFuncs));
1964   }
1965
1966   // initialize bindless texture extension (ARB)
1967   if (CheckExtension ("GL_ARB_bindless_texture")
1968    && FindProcShort (glGetTextureHandleARB)
1969    && FindProcShort (glGetTextureSamplerHandleARB)
1970    && FindProcShort (glMakeTextureHandleResidentARB)
1971    && FindProcShort (glMakeTextureHandleNonResidentARB)
1972    && FindProcShort (glGetImageHandleARB)
1973    && FindProcShort (glMakeImageHandleResidentARB)
1974    && FindProcShort (glMakeImageHandleNonResidentARB)
1975    && FindProcShort (glUniformHandleui64ARB)
1976    && FindProcShort (glUniformHandleui64vARB)
1977    && FindProcShort (glProgramUniformHandleui64ARB)
1978    && FindProcShort (glProgramUniformHandleui64vARB)
1979    && FindProcShort (glIsTextureHandleResidentARB)
1980    && FindProcShort (glIsImageHandleResidentARB)
1981    && FindProcShort (glVertexAttribL1ui64ARB)
1982    && FindProcShort (glVertexAttribL1ui64vARB)
1983    && FindProcShort (glGetVertexAttribLui64vARB))
1984   {
1985     arbTexBindless = (OpenGl_ArbTexBindless* )(&(*myFuncs));
1986   }
1987
1988   if (!has12)
1989   {
1990     checkWrongVersion (1, 2);
1991     myGlVerMajor = 1;
1992     myGlVerMinor = 1;
1993     return;
1994   }
1995   else if (!has13)
1996   {
1997     checkWrongVersion (1, 3);
1998     myGlVerMajor = 1;
1999     myGlVerMinor = 2;
2000     return;
2001   }
2002   else if (!has14)
2003   {
2004     checkWrongVersion (1, 4);
2005     myGlVerMajor = 1;
2006     myGlVerMinor = 3;
2007     return;
2008   }
2009   else if (!has15)
2010   {
2011     checkWrongVersion (1, 5);
2012     myGlVerMajor = 1;
2013     myGlVerMinor = 4;
2014     return;
2015   }
2016   if (!isCoreProfile)
2017   {
2018     core15 = (OpenGl_GlCore15* )(&(*myFuncs));
2019   }
2020   core15fwd = (OpenGl_GlCore15Fwd* )(&(*myFuncs));
2021
2022   if (!has20)
2023   {
2024     checkWrongVersion (2, 0);
2025     myGlVerMajor = 1;
2026     myGlVerMinor = 5;
2027     return;
2028   }
2029
2030   const char* aGlslVer = (const char* )::glGetString (GL_SHADING_LANGUAGE_VERSION);
2031   if (aGlslVer == NULL
2032   || *aGlslVer == '\0')
2033   {
2034     // broken context has been detected
2035     TCollection_ExtendedString aMsg = TCollection_ExtendedString()
2036       + "Error! OpenGL context reports version "
2037       + myGlVerMajor  + "." + myGlVerMinor
2038       + " but reports wrong GLSL version";
2039     PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
2040                  GL_DEBUG_TYPE_ERROR_ARB,
2041                  0,
2042                  GL_DEBUG_SEVERITY_HIGH_ARB,
2043                  aMsg);
2044     myGlVerMajor = 1;
2045     myGlVerMinor = 5;
2046     return;
2047   }
2048
2049   if (!isCoreProfile)
2050   {
2051     core20  = (OpenGl_GlCore20*    )(&(*myFuncs));
2052   }
2053   core20fwd = (OpenGl_GlCore20Fwd* )(&(*myFuncs));
2054
2055   if (!has21)
2056   {
2057     checkWrongVersion (2, 1);
2058     myGlVerMajor = 2;
2059     myGlVerMinor = 0;
2060     return;
2061   }
2062
2063   if (!has30)
2064   {
2065     checkWrongVersion (3, 0);
2066     myGlVerMajor = 2;
2067     myGlVerMinor = 1;
2068     return;
2069   }
2070
2071   if (!has31)
2072   {
2073     checkWrongVersion (3, 1);
2074     myGlVerMajor = 3;
2075     myGlVerMinor = 0;
2076     return;
2077   }
2078   arbTBO = (OpenGl_ArbTBO* )(&(*myFuncs));
2079   arbIns = (OpenGl_ArbIns* )(&(*myFuncs));
2080
2081   if (!has32)
2082   {
2083     checkWrongVersion (3, 2);
2084     myGlVerMajor = 3;
2085     myGlVerMinor = 1;
2086     return;
2087   }
2088   core32 = (OpenGl_GlCore32* )(&(*myFuncs));
2089   if (isCoreProfile)
2090   {
2091     core32->glGenVertexArrays (1, &myDefaultVao);
2092   }
2093   else
2094   {
2095     core32back = (OpenGl_GlCore32Back* )(&(*myFuncs));
2096   }
2097
2098   if (!has33)
2099   {
2100     checkWrongVersion (3, 3);
2101     myGlVerMajor = 3;
2102     myGlVerMinor = 2;
2103     return;
2104   }
2105   core33 = (OpenGl_GlCore33* )(&(*myFuncs));
2106   if (!isCoreProfile)
2107   {
2108     core33back = (OpenGl_GlCore33Back* )(&(*myFuncs));
2109   }
2110
2111   // initialize sampler object
2112   myTexSampler = new OpenGl_Sampler();
2113   myTexSampler->Init (*this);
2114
2115   if (!has40)
2116   {
2117     checkWrongVersion (4, 0);
2118     myGlVerMajor = 3;
2119     myGlVerMinor = 3;
2120     return;
2121   }
2122   arbTboRGB32 = Standard_True; // in core since OpenGL 4.0
2123
2124   if (!has41)
2125   {
2126     checkWrongVersion (4, 1);
2127     myGlVerMajor = 4;
2128     myGlVerMinor = 0;
2129     return;
2130   }
2131   core41 = (OpenGl_GlCore41* )(&(*myFuncs));
2132   if (!isCoreProfile)
2133   {
2134     core41back = (OpenGl_GlCore41Back* )(&(*myFuncs));
2135   }
2136
2137   if(!has42)
2138   {
2139     checkWrongVersion (4, 2);
2140     myGlVerMajor = 4;
2141     myGlVerMinor = 1;
2142     return;
2143   }
2144   core42 = (OpenGl_GlCore42* )(&(*myFuncs));
2145   if (!isCoreProfile)
2146   {
2147     core42back = (OpenGl_GlCore42Back* )(&(*myFuncs));
2148   }
2149
2150   if (!has43)
2151   {
2152     checkWrongVersion (4, 3);
2153     myGlVerMajor = 4;
2154     myGlVerMinor = 2;
2155     return;
2156   }
2157   core43 = (OpenGl_GlCore43* )(&(*myFuncs));
2158   if (!isCoreProfile)
2159   {
2160     core43back = (OpenGl_GlCore43Back* )(&(*myFuncs));
2161   }
2162
2163   if (!has44)
2164   {
2165     checkWrongVersion (4, 4);
2166     myGlVerMajor = 4;
2167     myGlVerMinor = 3;
2168     return;
2169   }
2170   core44 = (OpenGl_GlCore44* )(&(*myFuncs));
2171   if (!isCoreProfile)
2172   {
2173     core44back = (OpenGl_GlCore44Back* )(&(*myFuncs));
2174   }
2175 #endif
2176 }
2177
2178 // =======================================================================
2179 // function : MemoryInfo
2180 // purpose  :
2181 // =======================================================================
2182 Standard_Size OpenGl_Context::AvailableMemory() const
2183 {
2184 #if !defined(GL_ES_VERSION_2_0)
2185   if (atiMem)
2186   {
2187     // this is actually information for VBO pool
2188     // however because pools are mostly shared
2189     // it can be used for total GPU memory estimations
2190     GLint aMemInfo[4];
2191     aMemInfo[0] = 0;
2192     glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aMemInfo);
2193     // returned value is in KiB, however this maybe changed in future
2194     return Standard_Size(aMemInfo[0]) * 1024;
2195   }
2196   else if (nvxMem)
2197   {
2198     // current available dedicated video memory (in KiB), currently unused GPU memory
2199     GLint aMemInfo = 0;
2200     glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aMemInfo);
2201     return Standard_Size(aMemInfo) * 1024;
2202   }
2203 #endif
2204   return 0;
2205 }
2206
2207 // =======================================================================
2208 // function : MemoryInfo
2209 // purpose  :
2210 // =======================================================================
2211 TCollection_AsciiString OpenGl_Context::MemoryInfo() const
2212 {
2213   TCollection_AsciiString anInfo;
2214 #if !defined(GL_ES_VERSION_2_0)
2215   if (atiMem)
2216   {
2217     GLint aValues[4];
2218     memset (aValues, 0, sizeof(aValues));
2219     glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aValues);
2220
2221     // total memory free in the pool
2222     anInfo += TCollection_AsciiString ("  GPU free memory:    ") + (aValues[0] / 1024) + " MiB\n";
2223
2224     // largest available free block in the pool
2225     anInfo += TCollection_AsciiString ("  Largest free block: ") + (aValues[1] / 1024) + " MiB\n";
2226     if (aValues[2] != aValues[0])
2227     {
2228       // total auxiliary memory free
2229       anInfo += TCollection_AsciiString ("  Free memory:        ") + (aValues[2] / 1024) + " MiB\n";
2230     }
2231   }
2232   else if (nvxMem)
2233   {
2234     //current available dedicated video memory (in KiB), currently unused GPU memory
2235     GLint aValue = 0;
2236     glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aValue);
2237     anInfo += TCollection_AsciiString ("  GPU free memory:    ") + (aValue / 1024) + " MiB\n";
2238
2239     // dedicated video memory, total size (in KiB) of the GPU memory
2240     GLint aDedicated = 0;
2241     glGetIntegerv (GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &aDedicated);
2242     anInfo += TCollection_AsciiString ("  GPU memory:         ") + (aDedicated / 1024) + " MiB\n";
2243
2244     // total available memory, total size (in KiB) of the memory available for allocations
2245     glGetIntegerv (GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &aValue);
2246     if (aValue != aDedicated)
2247     {
2248       // different only for special configurations
2249       anInfo += TCollection_AsciiString ("  Total memory:       ") + (aValue / 1024) + " MiB\n";
2250     }
2251   }
2252 #endif
2253   return anInfo;
2254 }
2255
2256
2257 // =======================================================================
2258 // function : GetResource
2259 // purpose  :
2260 // =======================================================================
2261 const Handle(OpenGl_Resource)& OpenGl_Context::GetResource (const TCollection_AsciiString& theKey) const
2262 {
2263   return mySharedResources->IsBound (theKey) ? mySharedResources->Find (theKey) : NULL_GL_RESOURCE;
2264 }
2265
2266 // =======================================================================
2267 // function : ShareResource
2268 // purpose  :
2269 // =======================================================================
2270 Standard_Boolean OpenGl_Context::ShareResource (const TCollection_AsciiString& theKey,
2271                                                 const Handle(OpenGl_Resource)& theResource)
2272 {
2273   if (theKey.IsEmpty() || theResource.IsNull())
2274   {
2275     return Standard_False;
2276   }
2277   return mySharedResources->Bind (theKey, theResource);
2278 }
2279
2280 // =======================================================================
2281 // function : ReleaseResource
2282 // purpose  :
2283 // =======================================================================
2284 void OpenGl_Context::ReleaseResource (const TCollection_AsciiString& theKey,
2285                                       const Standard_Boolean         theToDelay)
2286 {
2287   if (!mySharedResources->IsBound (theKey))
2288   {
2289     return;
2290   }
2291   const Handle(OpenGl_Resource)& aRes = mySharedResources->Find (theKey);
2292   if (aRes->GetRefCount() > 1)
2293   {
2294     return;
2295   }
2296
2297   if (theToDelay)
2298   {
2299     myDelayed->Bind (theKey, 1);
2300   }
2301   else
2302   {
2303     aRes->Release (this);
2304     mySharedResources->UnBind (theKey);
2305   }
2306 }
2307
2308 // =======================================================================
2309 // function : DelayedRelease
2310 // purpose  :
2311 // =======================================================================
2312 void OpenGl_Context::DelayedRelease (Handle(OpenGl_Resource)& theResource)
2313 {
2314   myUnusedResources->Prepend (theResource);
2315   theResource.Nullify();
2316 }
2317
2318 // =======================================================================
2319 // function : ReleaseDelayed
2320 // purpose  :
2321 // =======================================================================
2322 void OpenGl_Context::ReleaseDelayed()
2323 {
2324   // release queued elements
2325   while (!myUnusedResources->IsEmpty())
2326   {
2327     myUnusedResources->First()->Release (this);
2328     myUnusedResources->RemoveFirst();
2329   }
2330
2331   // release delayed shared resources
2332   NCollection_Vector<TCollection_AsciiString> aDeadList;
2333   for (NCollection_DataMap<TCollection_AsciiString, Standard_Integer>::Iterator anIter (*myDelayed);
2334        anIter.More(); anIter.Next())
2335   {
2336     if (++anIter.ChangeValue() <= 2)
2337     {
2338       continue; // postpone release one more frame to ensure noone use it periodically
2339     }
2340
2341     const TCollection_AsciiString& aKey = anIter.Key();
2342     if (!mySharedResources->IsBound (aKey))
2343     {
2344       // mixed unshared strategy delayed/undelayed was used!
2345       aDeadList.Append (aKey);
2346       continue;
2347     }
2348
2349     Handle(OpenGl_Resource)& aRes = mySharedResources->ChangeFind (aKey);
2350     if (aRes->GetRefCount() > 1)
2351     {
2352       // should be only 1 instance in mySharedResources
2353       // if not - resource was reused again
2354       aDeadList.Append (aKey);
2355       continue;
2356     }
2357
2358     // release resource if no one requiested it more than 2 redraw calls
2359     aRes->Release (this);
2360     mySharedResources->UnBind (aKey);
2361     aDeadList.Append (aKey);
2362   }
2363
2364   for (Standard_Integer anIter = 0; anIter < aDeadList.Length(); ++anIter)
2365   {
2366     myDelayed->UnBind (aDeadList.Value (anIter));
2367   }
2368 }
2369
2370 // =======================================================================
2371 // function : BindProgram
2372 // purpose  :
2373 // =======================================================================
2374 Standard_Boolean OpenGl_Context::BindProgram (const Handle(OpenGl_ShaderProgram)& theProgram)
2375 {
2376   if (core20fwd == NULL)
2377   {
2378     return Standard_False;
2379   }
2380
2381   if (theProgram.IsNull()
2382   || !theProgram->IsValid())
2383   {
2384     if (!myActiveProgram.IsNull())
2385     {
2386       core20fwd->glUseProgram (OpenGl_ShaderProgram::NO_PROGRAM);
2387       myActiveProgram.Nullify();
2388     }
2389     return Standard_False;
2390   }
2391
2392   myActiveProgram = theProgram;
2393   core20fwd->glUseProgram (theProgram->ProgramId());
2394   return Standard_True;
2395 }
2396
2397 // =======================================================================
2398 // function : BindDefaultVao
2399 // purpose  :
2400 // =======================================================================
2401 void OpenGl_Context::BindDefaultVao()
2402 {
2403 #if !defined(GL_ES_VERSION_2_0)
2404   if (myDefaultVao == 0
2405    || core32 == NULL)
2406   {
2407     return;
2408   }
2409
2410   core32->glBindVertexArray (myDefaultVao);
2411 #endif
2412 }
2413
2414 // =======================================================================
2415 // function : SetDefaultFrameBuffer
2416 // purpose  :
2417 // =======================================================================
2418 Handle(OpenGl_FrameBuffer) OpenGl_Context::SetDefaultFrameBuffer (const Handle(OpenGl_FrameBuffer)& theFbo)
2419 {
2420   Handle(OpenGl_FrameBuffer) aFbo = myDefaultFbo;
2421   myDefaultFbo = theFbo;
2422   return aFbo;
2423 }
2424
2425 // =======================================================================
2426 // function : SetColor4fv
2427 // purpose  :
2428 // =======================================================================
2429 void OpenGl_Context::SetColor4fv (const OpenGl_Vec4& theColor)
2430 {
2431   if (!myActiveProgram.IsNull())
2432   {
2433     myActiveProgram->SetUniform (this, myActiveProgram->GetStateLocation (OpenGl_OCCT_COLOR), theColor);
2434   }
2435 #if !defined(GL_ES_VERSION_2_0)
2436   else if (core11 != NULL)
2437   {
2438     core11->glColor4fv (theColor.GetData());
2439   }
2440 #endif
2441 }
2442
2443 // =======================================================================
2444 // function : SetPointSize
2445 // purpose  :
2446 // =======================================================================
2447 void OpenGl_Context::SetPointSize (const Standard_ShortReal theSize)
2448 {
2449   if (!myActiveProgram.IsNull())
2450   {
2451     myActiveProgram->SetUniform (this, myActiveProgram->GetStateLocation (OpenGl_OCCT_POINT_SIZE), theSize);
2452   #if !defined(GL_ES_VERSION_2_0)
2453     //myContext->core11fwd->glEnable (GL_VERTEX_PROGRAM_POINT_SIZE);
2454   #endif
2455   }
2456 #if !defined(GL_ES_VERSION_2_0)
2457   //else
2458   {
2459     core11fwd->glPointSize (theSize);
2460     if (core20fwd != NULL)
2461     {
2462       //myContext->core11fwd->glDisable (GL_VERTEX_PROGRAM_POINT_SIZE);
2463     }
2464   }
2465 #endif
2466 }
2467
2468 // =======================================================================
2469 // function : SetGlNormalizeEnabled
2470 // purpose  :
2471 // =======================================================================
2472 Standard_Boolean OpenGl_Context::SetGlNormalizeEnabled (Standard_Boolean isEnabled)
2473 {
2474   if (isEnabled == myIsGlNormalizeEnabled)
2475   {
2476     return myIsGlNormalizeEnabled;
2477   }
2478
2479   Standard_Boolean anOldGlNormalize = myIsGlNormalizeEnabled;
2480
2481   myIsGlNormalizeEnabled = isEnabled;
2482
2483 #if !defined(GL_ES_VERSION_2_0)
2484   if (isEnabled)
2485   {
2486     glEnable (GL_NORMALIZE);
2487   }
2488   else
2489   {
2490     glDisable (GL_NORMALIZE);
2491   }
2492 #endif
2493
2494   return anOldGlNormalize;
2495 }
2496
2497 // =======================================================================
2498 // function : ApplyModelWorldMatrix
2499 // purpose  :
2500 // =======================================================================
2501 void OpenGl_Context::ApplyModelWorldMatrix()
2502 {
2503 #if !defined(GL_ES_VERSION_2_0)
2504   if (core11 != NULL)
2505   {
2506     core11->glMatrixMode (GL_MODELVIEW);
2507     core11->glLoadMatrixf (ModelWorldState.Current());
2508   }
2509 #endif
2510
2511   if (!myShaderManager->IsEmpty())
2512   {
2513     myShaderManager->UpdateModelWorldStateTo (ModelWorldState.Current());
2514   }
2515 }
2516
2517 // =======================================================================
2518 // function : ApplyWorldViewMatrix
2519 // purpose  :
2520 // =======================================================================
2521 void OpenGl_Context::ApplyWorldViewMatrix()
2522 {
2523 #if !defined(GL_ES_VERSION_2_0)
2524   if (core11 != NULL)
2525   {
2526     core11->glMatrixMode (GL_MODELVIEW);
2527     core11->glLoadMatrixf (WorldViewState.Current());
2528   }
2529 #endif
2530
2531   if (!myShaderManager->IsEmpty())
2532   {
2533     myShaderManager->UpdateWorldViewStateTo (WorldViewState.Current());
2534   }
2535 }
2536
2537 // =======================================================================
2538 // function : ApplyModelViewMatrix
2539 // purpose  :
2540 // =======================================================================
2541 void OpenGl_Context::ApplyModelViewMatrix()
2542 {
2543 #if !defined(GL_ES_VERSION_2_0)
2544   if (core11 != NULL)
2545   {
2546     OpenGl_Mat4 aModelView = WorldViewState.Current() * ModelWorldState.Current();
2547     core11->glMatrixMode (GL_MODELVIEW);
2548     core11->glLoadMatrixf (aModelView.GetData());
2549   }
2550 #endif
2551
2552   if (!myShaderManager->IsEmpty())
2553   {
2554     myShaderManager->UpdateModelWorldStateTo (ModelWorldState.Current());
2555     myShaderManager->UpdateWorldViewStateTo (WorldViewState.Current());
2556   }
2557 }
2558
2559 // =======================================================================
2560 // function : ApplyProjectionMatrix
2561 // purpose  :
2562 // =======================================================================
2563 void OpenGl_Context::ApplyProjectionMatrix()
2564 {
2565 #if !defined(GL_ES_VERSION_2_0)
2566   if (core11 != NULL)
2567   {
2568     core11->glMatrixMode (GL_PROJECTION);
2569     core11->glLoadMatrixf (ProjectionState.Current().GetData());
2570   }
2571 #endif
2572
2573   if (!myShaderManager->IsEmpty())
2574   {
2575     myShaderManager->UpdateProjectionStateTo (ProjectionState.Current());
2576   }
2577 }