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