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