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