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