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