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