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