0027789: Visualization, TKOpenGl - improve compatibility with new OpenGL ES devices
[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 (arbDbg != NULL
251    && myIsGlDebugCtx
252    && IsValid())
253   {
254     // reset callback
255   #if !defined(GL_ES_VERSION_2_0)
256     void* aPtr = NULL;
257     glGetPointerv (GL_DEBUG_CALLBACK_USER_PARAM, &aPtr);
258     if (aPtr == this)
259   #endif
260     {
261       arbDbg->glDebugMessageCallback (NULL, NULL);
262     }
263     myIsGlDebugCtx = Standard_False;
264   }
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 //! Callback for GL_ARB_debug_output extension
940 static void APIENTRY debugCallbackWrap(unsigned int theSource,
941                                        unsigned int theType,
942                                        unsigned int theId,
943                                        unsigned int theSeverity,
944                                        int          /*theLength*/,
945                                        const char*  theMessage,
946                                        const void*  theUserParam)
947 {
948   OpenGl_Context* aCtx = (OpenGl_Context* )theUserParam;
949   aCtx->PushMessage (theSource, theType, theId, theSeverity, theMessage);
950 }
951
952 // =======================================================================
953 // function : PushMessage
954 // purpose  :
955 // =======================================================================
956 void OpenGl_Context::PushMessage (const unsigned int theSource,
957                                   const unsigned int theType,
958                                   const unsigned int theId,
959                                   const unsigned int theSeverity,
960                                   const TCollection_ExtendedString& theMessage)
961 {
962   if (caps->suppressExtraMsg
963    && theSource >= GL_DEBUG_SOURCE_API
964    && theSource <= GL_DEBUG_SOURCE_OTHER
965    && myFilters[theSource - GL_DEBUG_SOURCE_API].Contains (theId))
966   {
967     return;
968   }
969
970   Standard_CString& aSrc = (theSource >= GL_DEBUG_SOURCE_API
971                         && theSource <= GL_DEBUG_SOURCE_OTHER)
972                          ? THE_DBGMSG_SOURCES[theSource - GL_DEBUG_SOURCE_API]
973                          : THE_DBGMSG_UNKNOWN;
974   Standard_CString& aType = (theType >= GL_DEBUG_TYPE_ERROR
975                          && theType <= GL_DEBUG_TYPE_OTHER)
976                           ? THE_DBGMSG_TYPES[theType - GL_DEBUG_TYPE_ERROR]
977                           : THE_DBGMSG_UNKNOWN;
978   Standard_CString& aSev = theSeverity == GL_DEBUG_SEVERITY_HIGH
979                          ? THE_DBGMSG_SEV_HIGH
980                          : (theSeverity == GL_DEBUG_SEVERITY_MEDIUM
981                           ? THE_DBGMSG_SEV_MEDIUM
982                           : THE_DBGMSG_SEV_LOW);
983   Message_Gravity aGrav = theSeverity == GL_DEBUG_SEVERITY_HIGH
984                         ? Message_Alarm
985                         : (theSeverity == GL_DEBUG_SEVERITY_MEDIUM
986                          ? Message_Warning
987                          : Message_Info);
988
989   TCollection_ExtendedString aMsg;
990   aMsg += "TKOpenGl"; aMsg += aSrc;
991   aMsg += " | Type: ";        aMsg += aType;
992   aMsg += " | ID: ";          aMsg += (Standard_Integer )theId;
993   aMsg += " | Severity: ";    aMsg += aSev;
994   aMsg += " | Message:\n  ";
995   aMsg += theMessage;
996   Messenger()->Send (aMsg, aGrav);
997 }
998
999 // =======================================================================
1000 // function : ExcludeMessage
1001 // purpose  :
1002 // ======================================================================
1003 Standard_Boolean OpenGl_Context::ExcludeMessage (const unsigned int theSource,
1004                                                  const unsigned int theId)
1005 {
1006   return theSource >= GL_DEBUG_SOURCE_API
1007       && theSource <= GL_DEBUG_SOURCE_OTHER
1008       && myFilters[theSource - GL_DEBUG_SOURCE_API].Add (theId);
1009 }
1010
1011 // =======================================================================
1012 // function : IncludeMessage
1013 // purpose  :
1014 // ======================================================================
1015 Standard_Boolean OpenGl_Context::IncludeMessage (const unsigned int theSource,
1016                                                  const unsigned int theId)
1017 {
1018   return theSource >= GL_DEBUG_SOURCE_API
1019       && theSource <= GL_DEBUG_SOURCE_OTHER
1020       && myFilters[theSource - GL_DEBUG_SOURCE_API].Remove (theId);
1021 }
1022
1023 // =======================================================================
1024 // function : checkWrongVersion
1025 // purpose  :
1026 // ======================================================================
1027 void OpenGl_Context::checkWrongVersion (const Standard_Integer theGlVerMajor,
1028                                         const Standard_Integer theGlVerMinor)
1029 {
1030   if (!IsGlGreaterEqual (theGlVerMajor, theGlVerMinor))
1031   {
1032     return;
1033   }
1034
1035   TCollection_ExtendedString aMsg = TCollection_ExtendedString()
1036     + "Error! OpenGL context reports version "
1037     + myGlVerMajor  + "." + myGlVerMinor
1038     + " but does not export required functions for "
1039     + theGlVerMajor + "." + theGlVerMinor;
1040   PushMessage (GL_DEBUG_SOURCE_APPLICATION,
1041                GL_DEBUG_TYPE_ERROR,
1042                0,
1043                GL_DEBUG_SEVERITY_HIGH,
1044                aMsg);
1045 }
1046
1047 // =======================================================================
1048 // function : init
1049 // purpose  :
1050 // =======================================================================
1051 void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
1052 {
1053   // read version
1054   myGlVerMajor = 0;
1055   myGlVerMinor = 0;
1056   myMaxMsaaSamples = 0;
1057   ReadGlVersion (myGlVerMajor, myGlVerMinor);
1058   myVendor = (const char* )::glGetString (GL_VENDOR);
1059   if (!caps->ffpEnable
1060    && !IsGlGreaterEqual (2, 0))
1061   {
1062     caps->ffpEnable = true;
1063     TCollection_ExtendedString aMsg =
1064       TCollection_ExtendedString("OpenGL driver is too old! Context info:\n")
1065                                + "    Vendor:   " + (const char* )::glGetString (GL_VENDOR)   + "\n"
1066                                + "    Renderer: " + (const char* )::glGetString (GL_RENDERER) + "\n"
1067                                + "    Version:  " + (const char* )::glGetString (GL_VERSION)  + "\n"
1068                                + "  Fallback using deprecated fixed-function pipeline.\n"
1069                                + "  Visualization might work incorrectly.\n"
1070                                  "  Consider upgrading the graphics driver.";
1071     PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
1072   }
1073
1074 #if defined(GL_ES_VERSION_2_0)
1075   (void )theIsCoreProfile;
1076   const bool isCoreProfile = false;
1077 #else
1078
1079   if (myVendor.Search ("NVIDIA") != -1)
1080   {
1081     // Buffer detailed info: Buffer object 1 (bound to GL_ARRAY_BUFFER_ARB, usage hint is GL_STATIC_DRAW)
1082     // will use VIDEO memory as the source for buffer object operations.
1083     ExcludeMessage (GL_DEBUG_SOURCE_API, 131185);
1084   }
1085   if (IsGlGreaterEqual (3, 0))
1086   {
1087     // retrieve auxiliary function in advance
1088     FindProc ("glGetStringi", myFuncs->glGetStringi);
1089   }
1090
1091   bool isCoreProfile = false;
1092   if (IsGlGreaterEqual (3, 2))
1093   {
1094     isCoreProfile = (theIsCoreProfile == Standard_True);
1095
1096     // detect Core profile
1097     if (!isCoreProfile)
1098     {
1099       GLint aProfile = 0;
1100       ::glGetIntegerv (GL_CONTEXT_PROFILE_MASK, &aProfile);
1101       isCoreProfile = (aProfile & GL_CONTEXT_CORE_PROFILE_BIT) != 0;
1102     }
1103   }
1104 #endif
1105
1106   core11     = NULL;
1107   if (!isCoreProfile)
1108   {
1109     core11 = (OpenGl_GlCore11* )(&(*myFuncs));
1110   }
1111   core11fwd  = (OpenGl_GlCore11Fwd* )(&(*myFuncs));
1112   core15     = NULL;
1113   core15fwd  = NULL;
1114   core20     = NULL;
1115   core20fwd  = NULL;
1116   core32     = NULL;
1117   core32back = NULL;
1118   core33     = NULL;
1119   core33back = NULL;
1120   core41     = NULL;
1121   core41back = NULL;
1122   core42     = NULL;
1123   core42back = NULL;
1124   core43     = NULL;
1125   core43back = NULL;
1126   core44     = NULL;
1127   core44back = NULL;
1128   arbTBO     = NULL;
1129   arbTboRGB32 = Standard_False;
1130   arbIns     = NULL;
1131   arbDbg     = NULL;
1132   arbFBO     = NULL;
1133   arbFBOBlit = NULL;
1134   extGS      = NULL;
1135   myDefaultVao = 0;
1136
1137 #if defined(GL_ES_VERSION_2_0)
1138
1139   hasTexRGBA8 = IsGlGreaterEqual (3, 0)
1140              || CheckExtension ("GL_OES_rgb8_rgba8");
1141   // NPOT textures has limited support within OpenGL ES 2.0
1142   // which are relaxed by OpenGL ES 3.0 or some extensions
1143   //arbNPTW     = IsGlGreaterEqual (3, 0)
1144   //           || CheckExtension ("GL_OES_texture_npot")
1145   //           || CheckExtension ("GL_NV_texture_npot_2D_mipmap");
1146   arbNPTW     = Standard_True;
1147   arbTexRG    = IsGlGreaterEqual (3, 0)
1148              || CheckExtension ("GL_EXT_texture_rg");
1149   extBgra     = CheckExtension ("GL_EXT_texture_format_BGRA8888");
1150   extAnis = CheckExtension ("GL_EXT_texture_filter_anisotropic");
1151   extPDS  = CheckExtension ("GL_OES_packed_depth_stencil");
1152
1153   core11fwd = (OpenGl_GlCore11Fwd* )(&(*myFuncs));
1154   if (IsGlGreaterEqual (2, 0))
1155   {
1156     // enable compatible functions
1157     core20    = (OpenGl_GlCore20*    )(&(*myFuncs));
1158     core20fwd = (OpenGl_GlCore20Fwd* )(&(*myFuncs));
1159     core15fwd = (OpenGl_GlCore15Fwd* )(&(*myFuncs));
1160     arbFBO    = (OpenGl_ArbFBO*      )(&(*myFuncs));
1161   }
1162   if (IsGlGreaterEqual (3, 0)
1163    && FindProc ("glBlitFramebuffer", myFuncs->glBlitFramebuffer))
1164   {
1165     arbFBOBlit = (OpenGl_ArbFBOBlit* )(&(*myFuncs));
1166   }
1167   if (IsGlGreaterEqual (3, 1)
1168    && FindProc ("glTexStorage2DMultisample", myFuncs->glTexStorage2DMultisample))
1169   {
1170     // MSAA RenderBuffers have been defined in OpenGL ES 3.0,
1171     // but MSAA Textures - only in OpenGL ES 3.1+
1172     ::glGetIntegerv (GL_MAX_SAMPLES, &myMaxMsaaSamples);
1173   }
1174
1175   hasUintIndex = IsGlGreaterEqual (3, 0)
1176               || CheckExtension ("GL_OES_element_index_uint");
1177   hasHighp     = CheckExtension ("GL_OES_fragment_precision_high");
1178   GLint aRange[2] = {0, 0};
1179   GLint aPrec     = 0;
1180   ::glGetShaderPrecisionFormat (GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, aRange, &aPrec);
1181   if (aPrec != 0)
1182   {
1183     hasHighp = Standard_True;
1184   }
1185
1186   arbTexFloat = IsGlGreaterEqual (3, 0)
1187              && FindProc ("glTexImage3D", myFuncs->glTexImage3D);
1188
1189   const Standard_Boolean hasTexBuffer32  = IsGlGreaterEqual (3, 2) && FindProc ("glTexBuffer", myFuncs->glTexBuffer);
1190   const Standard_Boolean hasExtTexBuffer = CheckExtension ("GL_EXT_texture_buffer") && FindProc ("glTexBufferEXT", myFuncs->glTexBuffer);
1191
1192   if (hasTexBuffer32 || hasExtTexBuffer)
1193   {
1194     arbTBO = reinterpret_cast<OpenGl_ArbTBO*> (myFuncs.get());
1195   }
1196
1197   // initialize debug context extension
1198   if (CheckExtension ("GL_KHR_debug"))
1199   {
1200     // this functionality become a part of OpenGL ES 3.2
1201     arbDbg = NULL;
1202     // According to GL_KHR_debug spec, all functions should have KHR suffix.
1203     // However, some implementations can export these functions without suffix.
1204     if (FindProc ("glDebugMessageControlKHR",  myFuncs->glDebugMessageControl)
1205      && FindProc ("glDebugMessageInsertKHR",   myFuncs->glDebugMessageInsert)
1206      && FindProc ("glDebugMessageCallbackKHR", myFuncs->glDebugMessageCallback)
1207      && FindProc ("glGetDebugMessageLogKHR",   myFuncs->glGetDebugMessageLog))
1208     {
1209       arbDbg = (OpenGl_ArbDbg* )(&(*myFuncs));
1210     }
1211
1212     if (arbDbg != NULL
1213      && caps->contextDebug)
1214     {
1215       // setup default callback
1216       myIsGlDebugCtx = Standard_True;
1217       arbDbg->glDebugMessageCallback (debugCallbackWrap, this);
1218       ::glEnable (GL_DEBUG_OUTPUT);
1219       if (caps->contextSyncDebug)
1220       {
1221         // note that some broken implementations (e.g. simulators) might generate error message on this call
1222         ::glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS);
1223       }
1224     }
1225   }
1226
1227 #else
1228
1229   myTexClamp = IsGlGreaterEqual (1, 2) ? GL_CLAMP_TO_EDGE : GL_CLAMP;
1230
1231   hasTexRGBA8 = Standard_True;
1232   arbNPTW     = CheckExtension ("GL_ARB_texture_non_power_of_two");
1233   arbTexFloat = IsGlGreaterEqual (3, 0)
1234              || CheckExtension ("GL_ARB_texture_float");
1235   extBgra     = CheckExtension ("GL_EXT_bgra");
1236   extAnis     = CheckExtension ("GL_EXT_texture_filter_anisotropic");
1237   extPDS      = CheckExtension ("GL_EXT_packed_depth_stencil");
1238   atiMem      = CheckExtension ("GL_ATI_meminfo");
1239   nvxMem      = CheckExtension ("GL_NVX_gpu_memory_info");
1240
1241   GLint aStereo = GL_FALSE;
1242   glGetIntegerv (GL_STEREO, &aStereo);
1243   myIsStereoBuffers = aStereo == 1;
1244
1245   // get number of maximum clipping planes
1246   glGetIntegerv (GL_MAX_CLIP_PLANES,  &myMaxClipPlanes);
1247 #endif
1248
1249   glGetIntegerv (GL_MAX_TEXTURE_SIZE, &myMaxTexDim);
1250
1251   if (extAnis)
1252   {
1253     glGetIntegerv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &myAnisoMax);
1254   }
1255
1256   myClippingState.Init (myMaxClipPlanes);
1257
1258 #if !defined(GL_ES_VERSION_2_0)
1259
1260   bool has12 = false;
1261   bool has13 = false;
1262   bool has14 = false;
1263   bool has15 = false;
1264   bool has20 = false;
1265   bool has21 = false;
1266   bool has30 = false;
1267   bool has31 = false;
1268   bool has32 = false;
1269   bool has33 = false;
1270   bool has40 = false;
1271   bool has41 = false;
1272   bool has42 = false;
1273   bool has43 = false;
1274   bool has44 = false;
1275
1276   //! Make record shorter to retrieve function pointer using variable with same name
1277   #define FindProcShort(theFunc) FindProc(#theFunc, myFuncs->theFunc)
1278
1279   // retrieve platform-dependent extensions
1280 #if defined(HAVE_EGL)
1281   //
1282 #elif defined(_WIN32)
1283   if (FindProcShort (wglGetExtensionsStringARB))
1284   {
1285     const char* aWglExts = myFuncs->wglGetExtensionsStringARB (wglGetCurrentDC());
1286     if (CheckExtension (aWglExts, "WGL_EXT_swap_control"))
1287     {
1288       FindProcShort (wglSwapIntervalEXT);
1289     }
1290     if (CheckExtension (aWglExts, "WGL_ARB_pixel_format"))
1291     {
1292       FindProcShort (wglChoosePixelFormatARB);
1293     }
1294     if (CheckExtension (aWglExts, "WGL_ARB_create_context_profile"))
1295     {
1296       FindProcShort (wglCreateContextAttribsARB);
1297     }
1298     if (CheckExtension (aWglExts, "WGL_NV_DX_interop"))
1299     {
1300       FindProcShort (wglDXSetResourceShareHandleNV);
1301       FindProcShort (wglDXOpenDeviceNV);
1302       FindProcShort (wglDXCloseDeviceNV);
1303       FindProcShort (wglDXRegisterObjectNV);
1304       FindProcShort (wglDXUnregisterObjectNV);
1305       FindProcShort (wglDXObjectAccessNV);
1306       FindProcShort (wglDXLockObjectsNV);
1307       FindProcShort (wglDXUnlockObjectsNV);
1308     }
1309   }
1310 #elif defined(__APPLE__)
1311     //
1312 #else
1313     const char* aGlxExts = ::glXQueryExtensionsString ((Display* )myDisplay, DefaultScreen ((Display* )myDisplay));
1314     if (CheckExtension (aGlxExts, "GLX_EXT_swap_control"))
1315     {
1316       FindProcShort (glXSwapIntervalEXT);
1317     }
1318     if (CheckExtension (aGlxExts, "GLX_SGI_swap_control"))
1319     {
1320       FindProcShort (glXSwapIntervalSGI);
1321     }
1322     //extSwapTear = CheckExtension (aGlxExts, "GLX_EXT_swap_control_tear");
1323 #endif
1324
1325   // load OpenGL 1.2 new functions
1326   has12 = IsGlGreaterEqual (1, 2)
1327        && FindProcShort (glBlendColor)
1328        && FindProcShort (glBlendEquation)
1329        && FindProcShort (glDrawRangeElements)
1330        && FindProcShort (glTexImage3D)
1331        && FindProcShort (glTexSubImage3D)
1332        && FindProcShort (glCopyTexSubImage3D);
1333
1334   // load OpenGL 1.3 new functions
1335   has13 = IsGlGreaterEqual (1, 3)
1336        && FindProcShort (glActiveTexture)
1337        && FindProcShort (glSampleCoverage)
1338        && FindProcShort (glCompressedTexImage3D)
1339        && FindProcShort (glCompressedTexImage2D)
1340        && FindProcShort (glCompressedTexImage1D)
1341        && FindProcShort (glCompressedTexSubImage3D)
1342        && FindProcShort (glCompressedTexSubImage2D)
1343        && FindProcShort (glCompressedTexSubImage1D)
1344        && FindProcShort (glGetCompressedTexImage);
1345
1346   if (!isCoreProfile)
1347   {
1348     has13 = has13
1349        && FindProcShort (glClientActiveTexture)
1350        && FindProcShort (glMultiTexCoord1d)
1351        && FindProcShort (glMultiTexCoord1dv)
1352        && FindProcShort (glMultiTexCoord1f)
1353        && FindProcShort (glMultiTexCoord1fv)
1354        && FindProcShort (glMultiTexCoord1i)
1355        && FindProcShort (glMultiTexCoord1iv)
1356        && FindProcShort (glMultiTexCoord1s)
1357        && FindProcShort (glMultiTexCoord1sv)
1358        && FindProcShort (glMultiTexCoord2d)
1359        && FindProcShort (glMultiTexCoord2dv)
1360        && FindProcShort (glMultiTexCoord2f)
1361        && FindProcShort (glMultiTexCoord2fv)
1362        && FindProcShort (glMultiTexCoord2i)
1363        && FindProcShort (glMultiTexCoord2iv)
1364        && FindProcShort (glMultiTexCoord2s)
1365        && FindProcShort (glMultiTexCoord2sv)
1366        && FindProcShort (glMultiTexCoord3d)
1367        && FindProcShort (glMultiTexCoord3dv)
1368        && FindProcShort (glMultiTexCoord3f)
1369        && FindProcShort (glMultiTexCoord3fv)
1370        && FindProcShort (glMultiTexCoord3i)
1371        && FindProcShort (glMultiTexCoord3iv)
1372        && FindProcShort (glMultiTexCoord3s)
1373        && FindProcShort (glMultiTexCoord3sv)
1374        && FindProcShort (glMultiTexCoord4d)
1375        && FindProcShort (glMultiTexCoord4dv)
1376        && FindProcShort (glMultiTexCoord4f)
1377        && FindProcShort (glMultiTexCoord4fv)
1378        && FindProcShort (glMultiTexCoord4i)
1379        && FindProcShort (glMultiTexCoord4iv)
1380        && FindProcShort (glMultiTexCoord4s)
1381        && FindProcShort (glMultiTexCoord4sv)
1382        && FindProcShort (glLoadTransposeMatrixf)
1383        && FindProcShort (glLoadTransposeMatrixd)
1384        && FindProcShort (glMultTransposeMatrixf)
1385        && FindProcShort (glMultTransposeMatrixd);
1386   }
1387
1388   // load OpenGL 1.4 new functions
1389   has14 = IsGlGreaterEqual (1, 4)
1390        && FindProcShort (glBlendFuncSeparate)
1391        && FindProcShort (glMultiDrawArrays)
1392        && FindProcShort (glMultiDrawElements)
1393        && FindProcShort (glPointParameterf)
1394        && FindProcShort (glPointParameterfv)
1395        && FindProcShort (glPointParameteri)
1396        && FindProcShort (glPointParameteriv);
1397
1398   // load OpenGL 1.5 new functions
1399   has15 = IsGlGreaterEqual (1, 5)
1400        && FindProcShort (glGenQueries)
1401        && FindProcShort (glDeleteQueries)
1402        && FindProcShort (glIsQuery)
1403        && FindProcShort (glBeginQuery)
1404        && FindProcShort (glEndQuery)
1405        && FindProcShort (glGetQueryiv)
1406        && FindProcShort (glGetQueryObjectiv)
1407        && FindProcShort (glGetQueryObjectuiv)
1408        && FindProcShort (glBindBuffer)
1409        && FindProcShort (glDeleteBuffers)
1410        && FindProcShort (glGenBuffers)
1411        && FindProcShort (glIsBuffer)
1412        && FindProcShort (glBufferData)
1413        && FindProcShort (glBufferSubData)
1414        && FindProcShort (glGetBufferSubData)
1415        && FindProcShort (glMapBuffer)
1416        && FindProcShort (glUnmapBuffer)
1417        && FindProcShort (glGetBufferParameteriv)
1418        && FindProcShort (glGetBufferPointerv);
1419
1420   // load OpenGL 2.0 new functions
1421   has20 = IsGlGreaterEqual (2, 0)
1422        && FindProcShort (glBlendEquationSeparate)
1423        && FindProcShort (glDrawBuffers)
1424        && FindProcShort (glStencilOpSeparate)
1425        && FindProcShort (glStencilFuncSeparate)
1426        && FindProcShort (glStencilMaskSeparate)
1427        && FindProcShort (glAttachShader)
1428        && FindProcShort (glBindAttribLocation)
1429        && FindProcShort (glCompileShader)
1430        && FindProcShort (glCreateProgram)
1431        && FindProcShort (glCreateShader)
1432        && FindProcShort (glDeleteProgram)
1433        && FindProcShort (glDeleteShader)
1434        && FindProcShort (glDetachShader)
1435        && FindProcShort (glDisableVertexAttribArray)
1436        && FindProcShort (glEnableVertexAttribArray)
1437        && FindProcShort (glGetActiveAttrib)
1438        && FindProcShort (glGetActiveUniform)
1439        && FindProcShort (glGetAttachedShaders)
1440        && FindProcShort (glGetAttribLocation)
1441        && FindProcShort (glGetProgramiv)
1442        && FindProcShort (glGetProgramInfoLog)
1443        && FindProcShort (glGetShaderiv)
1444        && FindProcShort (glGetShaderInfoLog)
1445        && FindProcShort (glGetShaderSource)
1446        && FindProcShort (glGetUniformLocation)
1447        && FindProcShort (glGetUniformfv)
1448        && FindProcShort (glGetUniformiv)
1449        && FindProcShort (glGetVertexAttribdv)
1450        && FindProcShort (glGetVertexAttribfv)
1451        && FindProcShort (glGetVertexAttribiv)
1452        && FindProcShort (glGetVertexAttribPointerv)
1453        && FindProcShort (glIsProgram)
1454        && FindProcShort (glIsShader)
1455        && FindProcShort (glLinkProgram)
1456        && FindProcShort (glShaderSource)
1457        && FindProcShort (glUseProgram)
1458        && FindProcShort (glUniform1f)
1459        && FindProcShort (glUniform2f)
1460        && FindProcShort (glUniform3f)
1461        && FindProcShort (glUniform4f)
1462        && FindProcShort (glUniform1i)
1463        && FindProcShort (glUniform2i)
1464        && FindProcShort (glUniform3i)
1465        && FindProcShort (glUniform4i)
1466        && FindProcShort (glUniform1fv)
1467        && FindProcShort (glUniform2fv)
1468        && FindProcShort (glUniform3fv)
1469        && FindProcShort (glUniform4fv)
1470        && FindProcShort (glUniform1iv)
1471        && FindProcShort (glUniform2iv)
1472        && FindProcShort (glUniform3iv)
1473        && FindProcShort (glUniform4iv)
1474        && FindProcShort (glUniformMatrix2fv)
1475        && FindProcShort (glUniformMatrix3fv)
1476        && FindProcShort (glUniformMatrix4fv)
1477        && FindProcShort (glValidateProgram)
1478        && FindProcShort (glVertexAttrib1d)
1479        && FindProcShort (glVertexAttrib1dv)
1480        && FindProcShort (glVertexAttrib1f)
1481        && FindProcShort (glVertexAttrib1fv)
1482        && FindProcShort (glVertexAttrib1s)
1483        && FindProcShort (glVertexAttrib1sv)
1484        && FindProcShort (glVertexAttrib2d)
1485        && FindProcShort (glVertexAttrib2dv)
1486        && FindProcShort (glVertexAttrib2f)
1487        && FindProcShort (glVertexAttrib2fv)
1488        && FindProcShort (glVertexAttrib2s)
1489        && FindProcShort (glVertexAttrib2sv)
1490        && FindProcShort (glVertexAttrib3d)
1491        && FindProcShort (glVertexAttrib3dv)
1492        && FindProcShort (glVertexAttrib3f)
1493        && FindProcShort (glVertexAttrib3fv)
1494        && FindProcShort (glVertexAttrib3s)
1495        && FindProcShort (glVertexAttrib3sv)
1496        && FindProcShort (glVertexAttrib4Nbv)
1497        && FindProcShort (glVertexAttrib4Niv)
1498        && FindProcShort (glVertexAttrib4Nsv)
1499        && FindProcShort (glVertexAttrib4Nub)
1500        && FindProcShort (glVertexAttrib4Nubv)
1501        && FindProcShort (glVertexAttrib4Nuiv)
1502        && FindProcShort (glVertexAttrib4Nusv)
1503        && FindProcShort (glVertexAttrib4bv)
1504        && FindProcShort (glVertexAttrib4d)
1505        && FindProcShort (glVertexAttrib4dv)
1506        && FindProcShort (glVertexAttrib4f)
1507        && FindProcShort (glVertexAttrib4fv)
1508        && FindProcShort (glVertexAttrib4iv)
1509        && FindProcShort (glVertexAttrib4s)
1510        && FindProcShort (glVertexAttrib4sv)
1511        && FindProcShort (glVertexAttrib4ubv)
1512        && FindProcShort (glVertexAttrib4uiv)
1513        && FindProcShort (glVertexAttrib4usv)
1514        && FindProcShort (glVertexAttribPointer);
1515
1516   // load OpenGL 2.1 new functions
1517   has21 = IsGlGreaterEqual (2, 1)
1518        && FindProcShort (glUniformMatrix2x3fv)
1519        && FindProcShort (glUniformMatrix3x2fv)
1520        && FindProcShort (glUniformMatrix2x4fv)
1521        && FindProcShort (glUniformMatrix4x2fv)
1522        && FindProcShort (glUniformMatrix3x4fv)
1523        && FindProcShort (glUniformMatrix4x3fv);
1524
1525   // load GL_ARB_framebuffer_object (added to OpenGL 3.0 core)
1526   const bool hasFBO = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_framebuffer_object"))
1527        && FindProcShort (glIsRenderbuffer)
1528        && FindProcShort (glBindRenderbuffer)
1529        && FindProcShort (glDeleteRenderbuffers)
1530        && FindProcShort (glGenRenderbuffers)
1531        && FindProcShort (glRenderbufferStorage)
1532        && FindProcShort (glGetRenderbufferParameteriv)
1533        && FindProcShort (glIsFramebuffer)
1534        && FindProcShort (glBindFramebuffer)
1535        && FindProcShort (glDeleteFramebuffers)
1536        && FindProcShort (glGenFramebuffers)
1537        && FindProcShort (glCheckFramebufferStatus)
1538        && FindProcShort (glFramebufferTexture1D)
1539        && FindProcShort (glFramebufferTexture2D)
1540        && FindProcShort (glFramebufferTexture3D)
1541        && FindProcShort (glFramebufferRenderbuffer)
1542        && FindProcShort (glGetFramebufferAttachmentParameteriv)
1543        && FindProcShort (glGenerateMipmap)
1544        && FindProcShort (glBlitFramebuffer)
1545        && FindProcShort (glRenderbufferStorageMultisample)
1546        && FindProcShort (glFramebufferTextureLayer);
1547
1548   // load GL_ARB_vertex_array_object (added to OpenGL 3.0 core)
1549   const bool hasVAO = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_vertex_array_object"))
1550        && FindProcShort (glBindVertexArray)
1551        && FindProcShort (glDeleteVertexArrays)
1552        && FindProcShort (glGenVertexArrays)
1553        && FindProcShort (glIsVertexArray);
1554
1555   // load GL_ARB_map_buffer_range (added to OpenGL 3.0 core)
1556   const bool hasMapBufferRange = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_map_buffer_range"))
1557        && FindProcShort (glMapBufferRange)
1558        && FindProcShort (glFlushMappedBufferRange);
1559
1560   // load OpenGL 3.0 new functions
1561   has30 = IsGlGreaterEqual (3, 0)
1562        && hasFBO
1563        && hasVAO
1564        && hasMapBufferRange
1565        && FindProcShort (glColorMaski)
1566        && FindProcShort (glGetBooleani_v)
1567        && FindProcShort (glGetIntegeri_v)
1568        && FindProcShort (glEnablei)
1569        && FindProcShort (glDisablei)
1570        && FindProcShort (glIsEnabledi)
1571        && FindProcShort (glBeginTransformFeedback)
1572        && FindProcShort (glEndTransformFeedback)
1573        && FindProcShort (glBindBufferRange)
1574        && FindProcShort (glBindBufferBase)
1575        && FindProcShort (glTransformFeedbackVaryings)
1576        && FindProcShort (glGetTransformFeedbackVarying)
1577        && FindProcShort (glClampColor)
1578        && FindProcShort (glBeginConditionalRender)
1579        && FindProcShort (glEndConditionalRender)
1580        && FindProcShort (glVertexAttribIPointer)
1581        && FindProcShort (glGetVertexAttribIiv)
1582        && FindProcShort (glGetVertexAttribIuiv)
1583        && FindProcShort (glVertexAttribI1i)
1584        && FindProcShort (glVertexAttribI2i)
1585        && FindProcShort (glVertexAttribI3i)
1586        && FindProcShort (glVertexAttribI4i)
1587        && FindProcShort (glVertexAttribI1ui)
1588        && FindProcShort (glVertexAttribI2ui)
1589        && FindProcShort (glVertexAttribI3ui)
1590        && FindProcShort (glVertexAttribI4ui)
1591        && FindProcShort (glVertexAttribI1iv)
1592        && FindProcShort (glVertexAttribI2iv)
1593        && FindProcShort (glVertexAttribI3iv)
1594        && FindProcShort (glVertexAttribI4iv)
1595        && FindProcShort (glVertexAttribI1uiv)
1596        && FindProcShort (glVertexAttribI2uiv)
1597        && FindProcShort (glVertexAttribI3uiv)
1598        && FindProcShort (glVertexAttribI4uiv)
1599        && FindProcShort (glVertexAttribI4bv)
1600        && FindProcShort (glVertexAttribI4sv)
1601        && FindProcShort (glVertexAttribI4ubv)
1602        && FindProcShort (glVertexAttribI4usv)
1603        && FindProcShort (glGetUniformuiv)
1604        && FindProcShort (glBindFragDataLocation)
1605        && FindProcShort (glGetFragDataLocation)
1606        && FindProcShort (glUniform1ui)
1607        && FindProcShort (glUniform2ui)
1608        && FindProcShort (glUniform3ui)
1609        && FindProcShort (glUniform4ui)
1610        && FindProcShort (glUniform1uiv)
1611        && FindProcShort (glUniform2uiv)
1612        && FindProcShort (glUniform3uiv)
1613        && FindProcShort (glUniform4uiv)
1614        && FindProcShort (glTexParameterIiv)
1615        && FindProcShort (glTexParameterIuiv)
1616        && FindProcShort (glGetTexParameterIiv)
1617        && FindProcShort (glGetTexParameterIuiv)
1618        && FindProcShort (glClearBufferiv)
1619        && FindProcShort (glClearBufferuiv)
1620        && FindProcShort (glClearBufferfv)
1621        && FindProcShort (glClearBufferfi)
1622        && FindProcShort (glGetStringi);
1623
1624   // load GL_ARB_uniform_buffer_object (added to OpenGL 3.1 core)
1625   const bool hasUBO = (IsGlGreaterEqual (3, 1) || CheckExtension ("GL_ARB_uniform_buffer_object"))
1626        && FindProcShort (glGetUniformIndices)
1627        && FindProcShort (glGetActiveUniformsiv)
1628        && FindProcShort (glGetActiveUniformName)
1629        && FindProcShort (glGetUniformBlockIndex)
1630        && FindProcShort (glGetActiveUniformBlockiv)
1631        && FindProcShort (glGetActiveUniformBlockName)
1632        && FindProcShort (glUniformBlockBinding);
1633
1634   // load GL_ARB_copy_buffer (added to OpenGL 3.1 core)
1635   const bool hasCopyBufSubData = (IsGlGreaterEqual (3, 1) || CheckExtension ("GL_ARB_copy_buffer"))
1636        && FindProcShort (glCopyBufferSubData);
1637
1638   if (has30)
1639   {
1640     // NPOT textures are required by OpenGL 2.0 specifications
1641     // but doesn't hardware accelerated by some ancient OpenGL 2.1 hardware (GeForce FX, RadeOn 9700 etc.)
1642     arbNPTW  = Standard_True;
1643     arbTexRG = Standard_True;
1644   }
1645
1646   // load OpenGL 3.1 new functions
1647   has31 = IsGlGreaterEqual (3, 1)
1648        && hasUBO
1649        && hasCopyBufSubData
1650        && FindProcShort (glDrawArraysInstanced)
1651        && FindProcShort (glDrawElementsInstanced)
1652        && FindProcShort (glTexBuffer)
1653        && FindProcShort (glPrimitiveRestartIndex);
1654
1655   // load GL_ARB_draw_elements_base_vertex (added to OpenGL 3.2 core)
1656   const bool hasDrawElemsBaseVert = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_draw_elements_base_vertex"))
1657        && FindProcShort (glDrawElementsBaseVertex)
1658        && FindProcShort (glDrawRangeElementsBaseVertex)
1659        && FindProcShort (glDrawElementsInstancedBaseVertex)
1660        && FindProcShort (glMultiDrawElementsBaseVertex);
1661
1662   // load GL_ARB_provoking_vertex (added to OpenGL 3.2 core)
1663   const bool hasProvokingVert = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_provoking_vertex"))
1664        && FindProcShort (glProvokingVertex);
1665
1666   // load GL_ARB_sync (added to OpenGL 3.2 core)
1667   const bool hasSync = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_sync"))
1668        && FindProcShort (glFenceSync)
1669        && FindProcShort (glIsSync)
1670        && FindProcShort (glDeleteSync)
1671        && FindProcShort (glClientWaitSync)
1672        && FindProcShort (glWaitSync)
1673        && FindProcShort (glGetInteger64v)
1674        && FindProcShort (glGetSynciv);
1675
1676   // load GL_ARB_texture_multisample (added to OpenGL 3.2 core)
1677   const bool hasTextureMultisample = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_texture_multisample"))
1678        && FindProcShort (glTexImage2DMultisample)
1679        && FindProcShort (glTexImage3DMultisample)
1680        && FindProcShort (glGetMultisamplefv)
1681        && FindProcShort (glSampleMaski);
1682
1683   // load OpenGL 3.2 new functions
1684   has32 = IsGlGreaterEqual (3, 2)
1685        && hasDrawElemsBaseVert
1686        && hasProvokingVert
1687        && hasSync
1688        && hasTextureMultisample
1689        && FindProcShort (glGetInteger64i_v)
1690        && FindProcShort (glGetBufferParameteri64v)
1691        && FindProcShort (glFramebufferTexture);
1692
1693   // load GL_ARB_blend_func_extended (added to OpenGL 3.3 core)
1694   const bool hasBlendFuncExtended = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_blend_func_extended"))
1695        && FindProcShort (glBindFragDataLocationIndexed)
1696        && FindProcShort (glGetFragDataIndex);
1697
1698   // load GL_ARB_sampler_objects (added to OpenGL 3.3 core)
1699   const bool hasSamplerObjects = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_sampler_objects"))
1700        && FindProcShort (glGenSamplers)
1701        && FindProcShort (glDeleteSamplers)
1702        && FindProcShort (glIsSampler)
1703        && FindProcShort (glBindSampler)
1704        && FindProcShort (glSamplerParameteri)
1705        && FindProcShort (glSamplerParameteriv)
1706        && FindProcShort (glSamplerParameterf)
1707        && FindProcShort (glSamplerParameterfv)
1708        && FindProcShort (glSamplerParameterIiv)
1709        && FindProcShort (glSamplerParameterIuiv)
1710        && FindProcShort (glGetSamplerParameteriv)
1711        && FindProcShort (glGetSamplerParameterIiv)
1712        && FindProcShort (glGetSamplerParameterfv)
1713        && FindProcShort (glGetSamplerParameterIuiv);
1714
1715   // load GL_ARB_timer_query (added to OpenGL 3.3 core)
1716   const bool hasTimerQuery = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_timer_query"))
1717        && FindProcShort (glQueryCounter)
1718        && FindProcShort (glGetQueryObjecti64v)
1719        && FindProcShort (glGetQueryObjectui64v);
1720
1721   // load GL_ARB_vertex_type_2_10_10_10_rev (added to OpenGL 3.3 core)
1722   const bool hasVertType21010101rev = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_vertex_type_2_10_10_10_rev"))
1723        && FindProcShort (glVertexAttribP1ui)
1724        && FindProcShort (glVertexAttribP1uiv)
1725        && FindProcShort (glVertexAttribP2ui)
1726        && FindProcShort (glVertexAttribP2uiv)
1727        && FindProcShort (glVertexAttribP3ui)
1728        && FindProcShort (glVertexAttribP3uiv)
1729        && FindProcShort (glVertexAttribP4ui)
1730        && FindProcShort (glVertexAttribP4uiv);
1731
1732   if ( hasVertType21010101rev
1733    && !isCoreProfile)
1734   {
1735     // load deprecated functions
1736     const bool hasVertType21010101revExt =
1737           FindProcShort (glVertexP2ui)
1738        && FindProcShort (glVertexP2uiv)
1739        && FindProcShort (glVertexP3ui)
1740        && FindProcShort (glVertexP3uiv)
1741        && FindProcShort (glVertexP4ui)
1742        && FindProcShort (glVertexP4uiv)
1743        && FindProcShort (glTexCoordP1ui)
1744        && FindProcShort (glTexCoordP1uiv)
1745        && FindProcShort (glTexCoordP2ui)
1746        && FindProcShort (glTexCoordP2uiv)
1747        && FindProcShort (glTexCoordP3ui)
1748        && FindProcShort (glTexCoordP3uiv)
1749        && FindProcShort (glTexCoordP4ui)
1750        && FindProcShort (glTexCoordP4uiv)
1751        && FindProcShort (glMultiTexCoordP1ui)
1752        && FindProcShort (glMultiTexCoordP1uiv)
1753        && FindProcShort (glMultiTexCoordP2ui)
1754        && FindProcShort (glMultiTexCoordP2uiv)
1755        && FindProcShort (glMultiTexCoordP3ui)
1756        && FindProcShort (glMultiTexCoordP3uiv)
1757        && FindProcShort (glMultiTexCoordP4ui)
1758        && FindProcShort (glMultiTexCoordP4uiv)
1759        && FindProcShort (glNormalP3ui)
1760        && FindProcShort (glNormalP3uiv)
1761        && FindProcShort (glColorP3ui)
1762        && FindProcShort (glColorP3uiv)
1763        && FindProcShort (glColorP4ui)
1764        && FindProcShort (glColorP4uiv)
1765        && FindProcShort (glSecondaryColorP3ui)
1766        && FindProcShort (glSecondaryColorP3uiv);
1767     (void )hasVertType21010101revExt;
1768   }
1769
1770   // load OpenGL 3.3 extra functions
1771   has33 = IsGlGreaterEqual (3, 3)
1772        && hasBlendFuncExtended
1773        && hasSamplerObjects
1774        && hasTimerQuery
1775        && hasVertType21010101rev
1776        && FindProcShort (glVertexAttribDivisor);
1777
1778   // load GL_ARB_draw_indirect (added to OpenGL 4.0 core)
1779   const bool hasDrawIndirect = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_draw_indirect"))
1780        && FindProcShort (glDrawArraysIndirect)
1781        && FindProcShort (glDrawElementsIndirect);
1782
1783   // load GL_ARB_gpu_shader_fp64 (added to OpenGL 4.0 core)
1784   const bool hasShaderFP64 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_gpu_shader_fp64"))
1785        && FindProcShort (glUniform1d)
1786        && FindProcShort (glUniform2d)
1787        && FindProcShort (glUniform3d)
1788        && FindProcShort (glUniform4d)
1789        && FindProcShort (glUniform1dv)
1790        && FindProcShort (glUniform2dv)
1791        && FindProcShort (glUniform3dv)
1792        && FindProcShort (glUniform4dv)
1793        && FindProcShort (glUniformMatrix2dv)
1794        && FindProcShort (glUniformMatrix3dv)
1795        && FindProcShort (glUniformMatrix4dv)
1796        && FindProcShort (glUniformMatrix2x3dv)
1797        && FindProcShort (glUniformMatrix2x4dv)
1798        && FindProcShort (glUniformMatrix3x2dv)
1799        && FindProcShort (glUniformMatrix3x4dv)
1800        && FindProcShort (glUniformMatrix4x2dv)
1801        && FindProcShort (glUniformMatrix4x3dv)
1802        && FindProcShort (glGetUniformdv);
1803
1804   // load GL_ARB_shader_subroutine (added to OpenGL 4.0 core)
1805   const bool hasShaderSubroutine = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_shader_subroutine"))
1806        && FindProcShort (glGetSubroutineUniformLocation)
1807        && FindProcShort (glGetSubroutineIndex)
1808        && FindProcShort (glGetActiveSubroutineUniformiv)
1809        && FindProcShort (glGetActiveSubroutineUniformName)
1810        && FindProcShort (glGetActiveSubroutineName)
1811        && FindProcShort (glUniformSubroutinesuiv)
1812        && FindProcShort (glGetUniformSubroutineuiv)
1813        && FindProcShort (glGetProgramStageiv);
1814
1815   // load GL_ARB_tessellation_shader (added to OpenGL 4.0 core)
1816   const bool hasTessellationShader = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_tessellation_shader"))
1817        && FindProcShort (glPatchParameteri)
1818        && FindProcShort (glPatchParameterfv);
1819
1820   // load GL_ARB_transform_feedback2 (added to OpenGL 4.0 core)
1821   const bool hasTrsfFeedback2 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_transform_feedback2"))
1822        && FindProcShort (glBindTransformFeedback)
1823        && FindProcShort (glDeleteTransformFeedbacks)
1824        && FindProcShort (glGenTransformFeedbacks)
1825        && FindProcShort (glIsTransformFeedback)
1826        && FindProcShort (glPauseTransformFeedback)
1827        && FindProcShort (glResumeTransformFeedback)
1828        && FindProcShort (glDrawTransformFeedback);
1829
1830   // load GL_ARB_transform_feedback3 (added to OpenGL 4.0 core)
1831   const bool hasTrsfFeedback3 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_transform_feedback3"))
1832        && FindProcShort (glDrawTransformFeedbackStream)
1833        && FindProcShort (glBeginQueryIndexed)
1834        && FindProcShort (glEndQueryIndexed)
1835        && FindProcShort (glGetQueryIndexediv);
1836
1837   // load OpenGL 4.0 new functions
1838   has40 = IsGlGreaterEqual (4, 0)
1839       && hasDrawIndirect
1840       && hasShaderFP64
1841       && hasShaderSubroutine
1842       && hasTessellationShader
1843       && hasTrsfFeedback2
1844       && hasTrsfFeedback3
1845       && FindProcShort (glMinSampleShading)
1846       && FindProcShort (glBlendEquationi)
1847       && FindProcShort (glBlendEquationSeparatei)
1848       && FindProcShort (glBlendFunci)
1849       && FindProcShort (glBlendFuncSeparatei);
1850
1851   // load GL_ARB_ES2_compatibility (added to OpenGL 4.1 core)
1852   const bool hasES2Compatibility = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_ES2_compatibility"))
1853        && FindProcShort (glReleaseShaderCompiler)
1854        && FindProcShort (glShaderBinary)
1855        && FindProcShort (glGetShaderPrecisionFormat)
1856        && FindProcShort (glDepthRangef)
1857        && FindProcShort (glClearDepthf);
1858
1859   // load GL_ARB_get_program_binary (added to OpenGL 4.1 core)
1860   const bool hasGetProgramBinary = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_get_program_binary"))
1861        && FindProcShort (glGetProgramBinary)
1862        && FindProcShort (glProgramBinary)
1863        && FindProcShort (glProgramParameteri);
1864
1865
1866   // load GL_ARB_separate_shader_objects (added to OpenGL 4.1 core)
1867   const bool hasSeparateShaderObjects = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_separate_shader_objects"))
1868        && FindProcShort (glUseProgramStages)
1869        && FindProcShort (glActiveShaderProgram)
1870        && FindProcShort (glCreateShaderProgramv)
1871        && FindProcShort (glBindProgramPipeline)
1872        && FindProcShort (glDeleteProgramPipelines)
1873        && FindProcShort (glGenProgramPipelines)
1874        && FindProcShort (glIsProgramPipeline)
1875        && FindProcShort (glGetProgramPipelineiv)
1876        && FindProcShort (glProgramUniform1i)
1877        && FindProcShort (glProgramUniform1iv)
1878        && FindProcShort (glProgramUniform1f)
1879        && FindProcShort (glProgramUniform1fv)
1880        && FindProcShort (glProgramUniform1d)
1881        && FindProcShort (glProgramUniform1dv)
1882        && FindProcShort (glProgramUniform1ui)
1883        && FindProcShort (glProgramUniform1uiv)
1884        && FindProcShort (glProgramUniform2i)
1885        && FindProcShort (glProgramUniform2iv)
1886        && FindProcShort (glProgramUniform2f)
1887        && FindProcShort (glProgramUniform2fv)
1888        && FindProcShort (glProgramUniform2d)
1889        && FindProcShort (glProgramUniform2dv)
1890        && FindProcShort (glProgramUniform2ui)
1891        && FindProcShort (glProgramUniform2uiv)
1892        && FindProcShort (glProgramUniform3i)
1893        && FindProcShort (glProgramUniform3iv)
1894        && FindProcShort (glProgramUniform3f)
1895        && FindProcShort (glProgramUniform3fv)
1896        && FindProcShort (glProgramUniform3d)
1897        && FindProcShort (glProgramUniform3dv)
1898        && FindProcShort (glProgramUniform3ui)
1899        && FindProcShort (glProgramUniform3uiv)
1900        && FindProcShort (glProgramUniform4i)
1901        && FindProcShort (glProgramUniform4iv)
1902        && FindProcShort (glProgramUniform4f)
1903        && FindProcShort (glProgramUniform4fv)
1904        && FindProcShort (glProgramUniform4d)
1905        && FindProcShort (glProgramUniform4dv)
1906        && FindProcShort (glProgramUniform4ui)
1907        && FindProcShort (glProgramUniform4uiv)
1908        && FindProcShort (glProgramUniformMatrix2fv)
1909        && FindProcShort (glProgramUniformMatrix3fv)
1910        && FindProcShort (glProgramUniformMatrix4fv)
1911        && FindProcShort (glProgramUniformMatrix2dv)
1912        && FindProcShort (glProgramUniformMatrix3dv)
1913        && FindProcShort (glProgramUniformMatrix4dv)
1914        && FindProcShort (glProgramUniformMatrix2x3fv)
1915        && FindProcShort (glProgramUniformMatrix3x2fv)
1916        && FindProcShort (glProgramUniformMatrix2x4fv)
1917        && FindProcShort (glProgramUniformMatrix4x2fv)
1918        && FindProcShort (glProgramUniformMatrix3x4fv)
1919        && FindProcShort (glProgramUniformMatrix4x3fv)
1920        && FindProcShort (glProgramUniformMatrix2x3dv)
1921        && FindProcShort (glProgramUniformMatrix3x2dv)
1922        && FindProcShort (glProgramUniformMatrix2x4dv)
1923        && FindProcShort (glProgramUniformMatrix4x2dv)
1924        && FindProcShort (glProgramUniformMatrix3x4dv)
1925        && FindProcShort (glProgramUniformMatrix4x3dv)
1926        && FindProcShort (glValidateProgramPipeline)
1927        && FindProcShort (glGetProgramPipelineInfoLog);
1928
1929   // load GL_ARB_vertex_attrib_64bit (added to OpenGL 4.1 core)
1930   const bool hasVertAttrib64bit = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_vertex_attrib_64bit"))
1931        && FindProcShort (glVertexAttribL1d)
1932        && FindProcShort (glVertexAttribL2d)
1933        && FindProcShort (glVertexAttribL3d)
1934        && FindProcShort (glVertexAttribL4d)
1935        && FindProcShort (glVertexAttribL1dv)
1936        && FindProcShort (glVertexAttribL2dv)
1937        && FindProcShort (glVertexAttribL3dv)
1938        && FindProcShort (glVertexAttribL4dv)
1939        && FindProcShort (glVertexAttribLPointer)
1940        && FindProcShort (glGetVertexAttribLdv);
1941
1942   // load GL_ARB_viewport_array (added to OpenGL 4.1 core)
1943   const bool hasViewportArray = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_viewport_array"))
1944        && FindProcShort (glViewportArrayv)
1945        && FindProcShort (glViewportIndexedf)
1946        && FindProcShort (glViewportIndexedfv)
1947        && FindProcShort (glScissorArrayv)
1948        && FindProcShort (glScissorIndexed)
1949        && FindProcShort (glScissorIndexedv)
1950        && FindProcShort (glDepthRangeArrayv)
1951        && FindProcShort (glDepthRangeIndexed)
1952        && FindProcShort (glGetFloati_v)
1953        && FindProcShort (glGetDoublei_v);
1954
1955   has41 = IsGlGreaterEqual (4, 1)
1956        && hasES2Compatibility
1957        && hasGetProgramBinary
1958        && hasSeparateShaderObjects
1959        && hasVertAttrib64bit
1960        && hasViewportArray;
1961
1962   // load GL_ARB_base_instance (added to OpenGL 4.2 core)
1963   const bool hasBaseInstance = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_base_instance"))
1964        && FindProcShort (glDrawArraysInstancedBaseInstance)
1965        && FindProcShort (glDrawElementsInstancedBaseInstance)
1966        && FindProcShort (glDrawElementsInstancedBaseVertexBaseInstance);
1967
1968   // load GL_ARB_transform_feedback_instanced (added to OpenGL 4.2 core)
1969   const bool hasTrsfFeedbackInstanced = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_transform_feedback_instanced"))
1970        && FindProcShort (glDrawTransformFeedbackInstanced)
1971        && FindProcShort (glDrawTransformFeedbackStreamInstanced);
1972
1973   // load GL_ARB_internalformat_query (added to OpenGL 4.2 core)
1974   const bool hasInternalFormatQuery = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_internalformat_query"))
1975        && FindProcShort (glGetInternalformativ);
1976
1977   // load GL_ARB_shader_atomic_counters (added to OpenGL 4.2 core)
1978   const bool hasShaderAtomicCounters = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_shader_atomic_counters"))
1979        && FindProcShort (glGetActiveAtomicCounterBufferiv);
1980
1981   // load GL_ARB_shader_image_load_store (added to OpenGL 4.2 core)
1982   const bool hasShaderImgLoadStore = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_shader_image_load_store"))
1983        && FindProcShort (glBindImageTexture)
1984        && FindProcShort (glMemoryBarrier);
1985
1986   // load GL_ARB_texture_storage (added to OpenGL 4.2 core)
1987   const bool hasTextureStorage = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_texture_storage"))
1988        && FindProcShort (glTexStorage1D)
1989        && FindProcShort (glTexStorage2D)
1990        && FindProcShort (glTexStorage3D);
1991
1992   has42 = IsGlGreaterEqual (4, 2)
1993        && hasBaseInstance
1994        && hasTrsfFeedbackInstanced
1995        && hasInternalFormatQuery
1996        && hasShaderAtomicCounters
1997        && hasShaderImgLoadStore
1998        && hasTextureStorage;
1999
2000   has43 = IsGlGreaterEqual (4, 3)
2001        && FindProcShort (glClearBufferData)
2002        && FindProcShort (glClearBufferSubData)
2003        && FindProcShort (glDispatchCompute)
2004        && FindProcShort (glDispatchComputeIndirect)
2005        && FindProcShort (glCopyImageSubData)
2006        && FindProcShort (glFramebufferParameteri)
2007        && FindProcShort (glGetFramebufferParameteriv)
2008        && FindProcShort (glGetInternalformati64v)
2009        && FindProcShort (glInvalidateTexSubImage)
2010        && FindProcShort (glInvalidateTexImage)
2011        && FindProcShort (glInvalidateBufferSubData)
2012        && FindProcShort (glInvalidateBufferData)
2013        && FindProcShort (glInvalidateFramebuffer)
2014        && FindProcShort (glInvalidateSubFramebuffer)
2015        && FindProcShort (glMultiDrawArraysIndirect)
2016        && FindProcShort (glMultiDrawElementsIndirect)
2017        && FindProcShort (glGetProgramInterfaceiv)
2018        && FindProcShort (glGetProgramResourceIndex)
2019        && FindProcShort (glGetProgramResourceName)
2020        && FindProcShort (glGetProgramResourceiv)
2021        && FindProcShort (glGetProgramResourceLocation)
2022        && FindProcShort (glGetProgramResourceLocationIndex)
2023        && FindProcShort (glShaderStorageBlockBinding)
2024        && FindProcShort (glTexBufferRange)
2025        && FindProcShort (glTexStorage2DMultisample)
2026        && FindProcShort (glTexStorage3DMultisample)
2027        && FindProcShort (glTextureView)
2028        && FindProcShort (glBindVertexBuffer)
2029        && FindProcShort (glVertexAttribFormat)
2030        && FindProcShort (glVertexAttribIFormat)
2031        && FindProcShort (glVertexAttribLFormat)
2032        && FindProcShort (glVertexAttribBinding)
2033        && FindProcShort (glVertexBindingDivisor)
2034        && FindProcShort (glDebugMessageControl)
2035        && FindProcShort (glDebugMessageInsert)
2036        && FindProcShort (glDebugMessageCallback)
2037        && FindProcShort (glGetDebugMessageLog)
2038        && FindProcShort (glPushDebugGroup)
2039        && FindProcShort (glPopDebugGroup)
2040        && FindProcShort (glObjectLabel)
2041        && FindProcShort (glGetObjectLabel)
2042        && FindProcShort (glObjectPtrLabel)
2043        && FindProcShort (glGetObjectPtrLabel);
2044
2045   // load GL_ARB_clear_texture (added to OpenGL 4.4 core)
2046   bool arbTexClear = (IsGlGreaterEqual (4, 4) || CheckExtension ("GL_ARB_clear_texture"))
2047        && FindProcShort (glClearTexImage)
2048        && FindProcShort (glClearTexSubImage);
2049
2050   has44 = IsGlGreaterEqual (4, 4)
2051        && arbTexClear
2052        && FindProcShort (glBufferStorage)
2053        && FindProcShort (glBindBuffersBase)
2054        && FindProcShort (glBindBuffersRange)
2055        && FindProcShort (glBindTextures)
2056        && FindProcShort (glBindSamplers)
2057        && FindProcShort (glBindImageTextures)
2058        && FindProcShort (glBindVertexBuffers);
2059
2060   // initialize debug context extension
2061   if (CheckExtension ("GL_ARB_debug_output"))
2062   {
2063     arbDbg = NULL;
2064     if (has43)
2065     {
2066       arbDbg = (OpenGl_ArbDbg* )(&(*myFuncs));
2067     }
2068     else if (FindProc ("glDebugMessageControlARB",  myFuncs->glDebugMessageControl)
2069           && FindProc ("glDebugMessageInsertARB",   myFuncs->glDebugMessageInsert)
2070           && FindProc ("glDebugMessageCallbackARB", myFuncs->glDebugMessageCallback)
2071           && FindProc ("glGetDebugMessageLogARB",   myFuncs->glGetDebugMessageLog))
2072     {
2073       arbDbg = (OpenGl_ArbDbg* )(&(*myFuncs));
2074     }
2075
2076     if (arbDbg != NULL
2077      && caps->contextDebug)
2078     {
2079       // setup default callback
2080       myIsGlDebugCtx = Standard_True;
2081       arbDbg->glDebugMessageCallback (debugCallbackWrap, this);
2082       if (has43)
2083       {
2084         ::glEnable (GL_DEBUG_OUTPUT);
2085       }
2086       if (caps->contextSyncDebug)
2087       {
2088         ::glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS);
2089       }
2090     }
2091   }
2092
2093   // initialize TBO extension (ARB)
2094   if (!has31
2095    && CheckExtension ("GL_ARB_texture_buffer_object")
2096    && FindProc ("glTexBufferARB", myFuncs->glTexBuffer))
2097   {
2098     arbTBO = (OpenGl_ArbTBO* )(&(*myFuncs));
2099   }
2100   arbTboRGB32 = CheckExtension ("GL_ARB_texture_buffer_object_rgb32");
2101
2102   // initialize hardware instancing extension (ARB)
2103   if (!has31
2104    && CheckExtension ("GL_ARB_draw_instanced")
2105    && FindProc ("glDrawArraysInstancedARB",   myFuncs->glDrawArraysInstanced)
2106    && FindProc ("glDrawElementsInstancedARB", myFuncs->glDrawElementsInstanced))
2107   {
2108     arbIns = (OpenGl_ArbIns* )(&(*myFuncs));
2109   }
2110
2111   // initialize FBO extension (ARB)
2112   if (hasFBO)
2113   {
2114     arbFBO     = (OpenGl_ArbFBO*     )(&(*myFuncs));
2115     arbFBOBlit = (OpenGl_ArbFBOBlit* )(&(*myFuncs));
2116     extPDS = Standard_True; // extension for EXT, but part of ARB
2117   }
2118
2119   // initialize GS extension (EXT)
2120   if (CheckExtension ("GL_EXT_geometry_shader4")
2121    && FindProcShort (glProgramParameteriEXT))
2122   {
2123     extGS = (OpenGl_ExtGS* )(&(*myFuncs));
2124   }
2125
2126   // initialize bindless texture extension (ARB)
2127   if (CheckExtension ("GL_ARB_bindless_texture")
2128    && FindProcShort (glGetTextureHandleARB)
2129    && FindProcShort (glGetTextureSamplerHandleARB)
2130    && FindProcShort (glMakeTextureHandleResidentARB)
2131    && FindProcShort (glMakeTextureHandleNonResidentARB)
2132    && FindProcShort (glGetImageHandleARB)
2133    && FindProcShort (glMakeImageHandleResidentARB)
2134    && FindProcShort (glMakeImageHandleNonResidentARB)
2135    && FindProcShort (glUniformHandleui64ARB)
2136    && FindProcShort (glUniformHandleui64vARB)
2137    && FindProcShort (glProgramUniformHandleui64ARB)
2138    && FindProcShort (glProgramUniformHandleui64vARB)
2139    && FindProcShort (glIsTextureHandleResidentARB)
2140    && FindProcShort (glIsImageHandleResidentARB)
2141    && FindProcShort (glVertexAttribL1ui64ARB)
2142    && FindProcShort (glVertexAttribL1ui64vARB)
2143    && FindProcShort (glGetVertexAttribLui64vARB))
2144   {
2145     arbTexBindless = (OpenGl_ArbTexBindless* )(&(*myFuncs));
2146   }
2147
2148   if (!has12)
2149   {
2150     checkWrongVersion (1, 2);
2151     myGlVerMajor = 1;
2152     myGlVerMinor = 1;
2153     return;
2154   }
2155   else if (!has13)
2156   {
2157     checkWrongVersion (1, 3);
2158     myGlVerMajor = 1;
2159     myGlVerMinor = 2;
2160     return;
2161   }
2162   else if (!has14)
2163   {
2164     checkWrongVersion (1, 4);
2165     myGlVerMajor = 1;
2166     myGlVerMinor = 3;
2167     return;
2168   }
2169   else if (!has15)
2170   {
2171     checkWrongVersion (1, 5);
2172     myGlVerMajor = 1;
2173     myGlVerMinor = 4;
2174     return;
2175   }
2176   if (!isCoreProfile)
2177   {
2178     core15 = (OpenGl_GlCore15* )(&(*myFuncs));
2179   }
2180   core15fwd = (OpenGl_GlCore15Fwd* )(&(*myFuncs));
2181
2182   if (!has20)
2183   {
2184     checkWrongVersion (2, 0);
2185     myGlVerMajor = 1;
2186     myGlVerMinor = 5;
2187     return;
2188   }
2189
2190   const char* aGlslVer = (const char* )::glGetString (GL_SHADING_LANGUAGE_VERSION);
2191   if (aGlslVer == NULL
2192   || *aGlslVer == '\0')
2193   {
2194     // broken context has been detected
2195     TCollection_ExtendedString aMsg = TCollection_ExtendedString()
2196       + "Error! OpenGL context reports version "
2197       + myGlVerMajor  + "." + myGlVerMinor
2198       + " but reports wrong GLSL version";
2199     PushMessage (GL_DEBUG_SOURCE_APPLICATION,
2200                  GL_DEBUG_TYPE_ERROR,
2201                  0,
2202                  GL_DEBUG_SEVERITY_HIGH,
2203                  aMsg);
2204     myGlVerMajor = 1;
2205     myGlVerMinor = 5;
2206     return;
2207   }
2208
2209   if (!isCoreProfile)
2210   {
2211     core20  = (OpenGl_GlCore20*    )(&(*myFuncs));
2212   }
2213   core20fwd = (OpenGl_GlCore20Fwd* )(&(*myFuncs));
2214
2215   if (!has21)
2216   {
2217     checkWrongVersion (2, 1);
2218     myGlVerMajor = 2;
2219     myGlVerMinor = 0;
2220     return;
2221   }
2222
2223   if (!has30)
2224   {
2225     checkWrongVersion (3, 0);
2226     myGlVerMajor = 2;
2227     myGlVerMinor = 1;
2228     return;
2229   }
2230
2231   // MSAA RenderBuffers have been defined in OpenGL 3.0,
2232   // but MSAA Textures - only in OpenGL 3.2+
2233   if (!has32
2234    && CheckExtension ("GL_ARB_texture_multisample")
2235    && FindProcShort (glTexImage2DMultisample))
2236   {
2237     GLint aNbColorSamples = 0, aNbDepthSamples = 0;
2238     ::glGetIntegerv (GL_MAX_COLOR_TEXTURE_SAMPLES, &aNbColorSamples);
2239     ::glGetIntegerv (GL_MAX_DEPTH_TEXTURE_SAMPLES, &aNbDepthSamples);
2240     myMaxMsaaSamples = Min (aNbColorSamples, aNbDepthSamples);
2241   }
2242   if (!has43
2243    && CheckExtension ("GL_ARB_texture_storage_multisample")
2244    && FindProcShort (glTexStorage2DMultisample))
2245   {
2246     //
2247   }
2248
2249   if (!has31)
2250   {
2251     checkWrongVersion (3, 1);
2252     myGlVerMajor = 3;
2253     myGlVerMinor = 0;
2254     return;
2255   }
2256   arbTBO = (OpenGl_ArbTBO* )(&(*myFuncs));
2257   arbIns = (OpenGl_ArbIns* )(&(*myFuncs));
2258
2259   if (!has32)
2260   {
2261     checkWrongVersion (3, 2);
2262     myGlVerMajor = 3;
2263     myGlVerMinor = 1;
2264     return;
2265   }
2266   core32 = (OpenGl_GlCore32* )(&(*myFuncs));
2267   if (isCoreProfile)
2268   {
2269     core32->glGenVertexArrays (1, &myDefaultVao);
2270   }
2271   else
2272   {
2273     core32back = (OpenGl_GlCore32Back* )(&(*myFuncs));
2274   }
2275   ::glGetIntegerv (GL_MAX_SAMPLES, &myMaxMsaaSamples);
2276
2277   if (!has33)
2278   {
2279     checkWrongVersion (3, 3);
2280     myGlVerMajor = 3;
2281     myGlVerMinor = 2;
2282     return;
2283   }
2284   core33 = (OpenGl_GlCore33* )(&(*myFuncs));
2285   if (!isCoreProfile)
2286   {
2287     core33back = (OpenGl_GlCore33Back* )(&(*myFuncs));
2288   }
2289
2290   // initialize sampler object
2291   myTexSampler = new OpenGl_Sampler();
2292   myTexSampler->Init (*this);
2293
2294   if (!has40)
2295   {
2296     checkWrongVersion (4, 0);
2297     myGlVerMajor = 3;
2298     myGlVerMinor = 3;
2299     return;
2300   }
2301   arbTboRGB32 = Standard_True; // in core since OpenGL 4.0
2302
2303   if (!has41)
2304   {
2305     checkWrongVersion (4, 1);
2306     myGlVerMajor = 4;
2307     myGlVerMinor = 0;
2308     return;
2309   }
2310   core41 = (OpenGl_GlCore41* )(&(*myFuncs));
2311   if (!isCoreProfile)
2312   {
2313     core41back = (OpenGl_GlCore41Back* )(&(*myFuncs));
2314   }
2315
2316   if(!has42)
2317   {
2318     checkWrongVersion (4, 2);
2319     myGlVerMajor = 4;
2320     myGlVerMinor = 1;
2321     return;
2322   }
2323   core42 = (OpenGl_GlCore42* )(&(*myFuncs));
2324   if (!isCoreProfile)
2325   {
2326     core42back = (OpenGl_GlCore42Back* )(&(*myFuncs));
2327   }
2328
2329   if (!has43)
2330   {
2331     checkWrongVersion (4, 3);
2332     myGlVerMajor = 4;
2333     myGlVerMinor = 2;
2334     return;
2335   }
2336   core43 = (OpenGl_GlCore43* )(&(*myFuncs));
2337   if (!isCoreProfile)
2338   {
2339     core43back = (OpenGl_GlCore43Back* )(&(*myFuncs));
2340   }
2341
2342   if (!has44)
2343   {
2344     checkWrongVersion (4, 4);
2345     myGlVerMajor = 4;
2346     myGlVerMinor = 3;
2347     return;
2348   }
2349   core44 = (OpenGl_GlCore44* )(&(*myFuncs));
2350   if (!isCoreProfile)
2351   {
2352     core44back = (OpenGl_GlCore44Back* )(&(*myFuncs));
2353   }
2354 #endif
2355 }
2356
2357 // =======================================================================
2358 // function : MemoryInfo
2359 // purpose  :
2360 // =======================================================================
2361 Standard_Size OpenGl_Context::AvailableMemory() const
2362 {
2363 #if !defined(GL_ES_VERSION_2_0)
2364   if (atiMem)
2365   {
2366     // this is actually information for VBO pool
2367     // however because pools are mostly shared
2368     // it can be used for total GPU memory estimations
2369     GLint aMemInfo[4];
2370     aMemInfo[0] = 0;
2371     glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aMemInfo);
2372     // returned value is in KiB, however this maybe changed in future
2373     return Standard_Size(aMemInfo[0]) * 1024;
2374   }
2375   else if (nvxMem)
2376   {
2377     // current available dedicated video memory (in KiB), currently unused GPU memory
2378     GLint aMemInfo = 0;
2379     glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aMemInfo);
2380     return Standard_Size(aMemInfo) * 1024;
2381   }
2382 #endif
2383   return 0;
2384 }
2385
2386 // =======================================================================
2387 // function : MemoryInfo
2388 // purpose  :
2389 // =======================================================================
2390 TCollection_AsciiString OpenGl_Context::MemoryInfo() const
2391 {
2392   TCollection_AsciiString anInfo;
2393 #if !defined(GL_ES_VERSION_2_0)
2394   if (atiMem)
2395   {
2396     GLint aValues[4];
2397     memset (aValues, 0, sizeof(aValues));
2398     glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aValues);
2399
2400     // total memory free in the pool
2401     anInfo += TCollection_AsciiString ("  GPU free memory:    ") + (aValues[0] / 1024) + " MiB\n";
2402
2403     // largest available free block in the pool
2404     anInfo += TCollection_AsciiString ("  Largest free block: ") + (aValues[1] / 1024) + " MiB\n";
2405     if (aValues[2] != aValues[0])
2406     {
2407       // total auxiliary memory free
2408       anInfo += TCollection_AsciiString ("  Free memory:        ") + (aValues[2] / 1024) + " MiB\n";
2409     }
2410   }
2411   else if (nvxMem)
2412   {
2413     //current available dedicated video memory (in KiB), currently unused GPU memory
2414     GLint aValue = 0;
2415     glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aValue);
2416     anInfo += TCollection_AsciiString ("  GPU free memory:    ") + (aValue / 1024) + " MiB\n";
2417
2418     // dedicated video memory, total size (in KiB) of the GPU memory
2419     GLint aDedicated = 0;
2420     glGetIntegerv (GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &aDedicated);
2421     anInfo += TCollection_AsciiString ("  GPU memory:         ") + (aDedicated / 1024) + " MiB\n";
2422
2423     // total available memory, total size (in KiB) of the memory available for allocations
2424     glGetIntegerv (GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &aValue);
2425     if (aValue != aDedicated)
2426     {
2427       // different only for special configurations
2428       anInfo += TCollection_AsciiString ("  Total memory:       ") + (aValue / 1024) + " MiB\n";
2429     }
2430   }
2431 #endif
2432   return anInfo;
2433 }
2434
2435
2436 // =======================================================================
2437 // function : GetResource
2438 // purpose  :
2439 // =======================================================================
2440 const Handle(OpenGl_Resource)& OpenGl_Context::GetResource (const TCollection_AsciiString& theKey) const
2441 {
2442   return mySharedResources->IsBound (theKey) ? mySharedResources->Find (theKey) : NULL_GL_RESOURCE;
2443 }
2444
2445 // =======================================================================
2446 // function : ShareResource
2447 // purpose  :
2448 // =======================================================================
2449 Standard_Boolean OpenGl_Context::ShareResource (const TCollection_AsciiString& theKey,
2450                                                 const Handle(OpenGl_Resource)& theResource)
2451 {
2452   if (theKey.IsEmpty() || theResource.IsNull())
2453   {
2454     return Standard_False;
2455   }
2456   return mySharedResources->Bind (theKey, theResource);
2457 }
2458
2459 // =======================================================================
2460 // function : ReleaseResource
2461 // purpose  :
2462 // =======================================================================
2463 void OpenGl_Context::ReleaseResource (const TCollection_AsciiString& theKey,
2464                                       const Standard_Boolean         theToDelay)
2465 {
2466   if (!mySharedResources->IsBound (theKey))
2467   {
2468     return;
2469   }
2470   auto& aRes = mySharedResources->Find (theKey);
2471   if (aRes->GetRefCount() > 1)
2472   {
2473     return;
2474   }
2475
2476   if (theToDelay)
2477   {
2478     myDelayed->Bind (theKey, 1);
2479   }
2480   else
2481   {
2482     aRes->Release (this);
2483     mySharedResources->UnBind (theKey);
2484   }
2485 }
2486
2487 // =======================================================================
2488 // function : ReleaseDelayed
2489 // purpose  :
2490 // =======================================================================
2491 void OpenGl_Context::ReleaseDelayed()
2492 {
2493   // release queued elements
2494   while (!myUnusedResources->IsEmpty())
2495   {
2496     myUnusedResources->First()->Release (this);
2497     myUnusedResources->RemoveFirst();
2498   }
2499
2500   // release delayed shared resources
2501   NCollection_Vector<TCollection_AsciiString> aDeadList;
2502   for (NCollection_DataMap<TCollection_AsciiString, Standard_Integer>::Iterator anIter (*myDelayed);
2503        anIter.More(); anIter.Next())
2504   {
2505     if (++anIter.ChangeValue() <= 2)
2506     {
2507       continue; // postpone release one more frame to ensure noone use it periodically
2508     }
2509
2510     const TCollection_AsciiString& aKey = anIter.Key();
2511     if (!mySharedResources->IsBound (aKey))
2512     {
2513       // mixed unshared strategy delayed/undelayed was used!
2514       aDeadList.Append (aKey);
2515       continue;
2516     }
2517
2518     auto& aRes = mySharedResources->ChangeFind (aKey);
2519     if (aRes->GetRefCount() > 1)
2520     {
2521       // should be only 1 instance in mySharedResources
2522       // if not - resource was reused again
2523       aDeadList.Append (aKey);
2524       continue;
2525     }
2526
2527     // release resource if no one requiested it more than 2 redraw calls
2528     aRes->Release (this);
2529     mySharedResources->UnBind (aKey);
2530     aDeadList.Append (aKey);
2531   }
2532
2533   for (Standard_Integer anIter = 0; anIter < aDeadList.Length(); ++anIter)
2534   {
2535     myDelayed->UnBind (aDeadList.Value (anIter));
2536   }
2537 }
2538
2539 // =======================================================================
2540 // function : BindProgram
2541 // purpose  :
2542 // =======================================================================
2543 Standard_Boolean OpenGl_Context::BindProgram (const Handle(OpenGl_ShaderProgram)& theProgram)
2544 {
2545   if (core20fwd == NULL)
2546   {
2547     return Standard_False;
2548   }
2549
2550   if (theProgram.IsNull()
2551   || !theProgram->IsValid())
2552   {
2553     if (!myActiveProgram.IsNull())
2554     {
2555       core20fwd->glUseProgram (OpenGl_ShaderProgram::NO_PROGRAM);
2556       myActiveProgram.Nullify();
2557     }
2558     return Standard_False;
2559   }
2560
2561   myActiveProgram = theProgram;
2562   core20fwd->glUseProgram (theProgram->ProgramId());
2563   return Standard_True;
2564 }
2565
2566 // =======================================================================
2567 // function : BindDefaultVao
2568 // purpose  :
2569 // =======================================================================
2570 void OpenGl_Context::BindDefaultVao()
2571 {
2572 #if !defined(GL_ES_VERSION_2_0)
2573   if (myDefaultVao == 0
2574    || core32 == NULL)
2575   {
2576     return;
2577   }
2578
2579   core32->glBindVertexArray (myDefaultVao);
2580 #endif
2581 }
2582
2583 // =======================================================================
2584 // function : SetDefaultFrameBuffer
2585 // purpose  :
2586 // =======================================================================
2587 Handle(OpenGl_FrameBuffer) OpenGl_Context::SetDefaultFrameBuffer (const Handle(OpenGl_FrameBuffer)& theFbo)
2588 {
2589   Handle(OpenGl_FrameBuffer) aFbo = myDefaultFbo;
2590   myDefaultFbo = theFbo;
2591   return aFbo;
2592 }
2593
2594 // =======================================================================
2595 // function : SetShadingMaterial
2596 // purpose  :
2597 // =======================================================================
2598 void OpenGl_Context::SetShadingMaterial (const OpenGl_AspectFace* theAspect,
2599                                          const OpenGl_Vec4* theHighlightColor)
2600 {
2601   if (!myActiveProgram.IsNull())
2602   {
2603     myActiveProgram->SetUniform (this,
2604                                  myActiveProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE),
2605                                  theAspect->Aspect()->ToMapTexture() ? 1 : 0);
2606     myActiveProgram->SetUniform (this,
2607                                  myActiveProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE),
2608                                  theAspect->Aspect()->Distinguish() ? 1 : 0);
2609
2610     OpenGl_Material aParams;
2611     for (Standard_Integer anIndex = 0; anIndex < 2; ++anIndex)
2612     {
2613       const GLint aLoc = myActiveProgram->GetStateLocation (anIndex == 0
2614                                                           ? OpenGl_OCCT_FRONT_MATERIAL
2615                                                           : OpenGl_OCCT_BACK_MATERIAL);
2616       if (aLoc == OpenGl_ShaderProgram::INVALID_LOCATION)
2617       {
2618         continue;
2619       }
2620
2621       if (anIndex == 0 || !theAspect->Aspect()->Distinguish())
2622       {
2623         const Graphic3d_MaterialAspect& aSrcMat      = theAspect->Aspect()->FrontMaterial();
2624         const Quantity_Color&           aSrcIntColor = theAspect->Aspect()->InteriorColor();
2625         aParams.Init (aSrcMat, aSrcIntColor);
2626         aParams.Diffuse.a() = 1.0f - (float )aSrcMat.Transparency();
2627       }
2628       else
2629       {
2630         const Graphic3d_MaterialAspect& aSrcMat      = theAspect->Aspect()->BackMaterial();
2631         const Quantity_Color&           aSrcIntColor = theAspect->Aspect()->BackInteriorColor();
2632         aParams.Init (aSrcMat, aSrcIntColor);
2633         aParams.Diffuse.a() = 1.0f - (float )aSrcMat.Transparency();
2634       }
2635       if (theHighlightColor != NULL)
2636       {
2637         aParams.SetColor (*theHighlightColor);
2638       }
2639
2640       myActiveProgram->SetUniform (this, aLoc, OpenGl_Material::NbOfVec4(),
2641                                    aParams.Packed());
2642     }
2643   }
2644 }
2645
2646 // =======================================================================
2647 // function : SetColor4fv
2648 // purpose  :
2649 // =======================================================================
2650 void OpenGl_Context::SetColor4fv (const OpenGl_Vec4& theColor)
2651 {
2652   if (!myActiveProgram.IsNull())
2653   {
2654     myActiveProgram->SetUniform (this, myActiveProgram->GetStateLocation (OpenGl_OCCT_COLOR), theColor);
2655   }
2656 #if !defined(GL_ES_VERSION_2_0)
2657   else if (core11 != NULL)
2658   {
2659     core11->glColor4fv (theColor.GetData());
2660   }
2661 #endif
2662 }
2663
2664 // =======================================================================
2665 // function : SetTypeOfLine
2666 // purpose  :
2667 // =======================================================================
2668 void OpenGl_Context::SetTypeOfLine (const Aspect_TypeOfLine  theType,
2669                                     const Standard_ShortReal theFactor)
2670 {
2671   Standard_Integer aPattern = 0xFFFF;
2672   switch (theType)
2673   {
2674     case Aspect_TOL_DASH:
2675     {
2676       aPattern = 0xFFC0;
2677       break;
2678     }
2679     case Aspect_TOL_DOT:
2680     {
2681       aPattern = 0xCCCC;
2682       break;
2683     }
2684     case Aspect_TOL_DOTDASH:
2685     {
2686       aPattern = 0xFF18;
2687       break;
2688     }
2689     case Aspect_TOL_SOLID:
2690     {
2691       aPattern = 0xFFFF;
2692       break;
2693     }
2694     case Aspect_TOL_USERDEFINED:
2695     {
2696       aPattern = 0xFF24;
2697       break;
2698     }
2699   }
2700
2701   if (!myActiveProgram.IsNull())
2702   {
2703     myActiveProgram->SetUniform (this, "uPattern", aPattern);
2704     myActiveProgram->SetUniform (this, "uFactor",  theFactor);
2705     return;
2706   }
2707
2708 #if !defined(GL_ES_VERSION_2_0)
2709   if (theType != Aspect_TOL_SOLID)
2710   {
2711   #ifdef HAVE_GL2PS
2712     if (IsFeedback())
2713     {
2714       gl2psEnable (GL2PS_LINE_STIPPLE);
2715     }
2716   #endif
2717
2718     if (core11 != NULL)
2719     {
2720       core11fwd->glEnable (GL_LINE_STIPPLE);
2721
2722       core11->glLineStipple (static_cast<GLint>    (theFactor),
2723                              static_cast<GLushort> (aPattern));
2724     }
2725   }
2726   else
2727   {
2728     if (core11 != NULL)
2729     {
2730       core11fwd->glDisable (GL_LINE_STIPPLE);
2731     }
2732
2733   #ifdef HAVE_GL2PS
2734     if (IsFeedback())
2735     {
2736       gl2psDisable (GL2PS_LINE_STIPPLE);
2737     }
2738   #endif
2739   }
2740 #endif
2741 }
2742
2743 // =======================================================================
2744 // function : SetLineWidth
2745 // purpose  :
2746 // =======================================================================
2747 void OpenGl_Context::SetLineWidth (const Standard_ShortReal theWidth)
2748 {
2749   if (core11 != NULL)
2750   {
2751     // glLineWidth() is still defined within Core Profile, but has no effect with values != 1.0f
2752     core11fwd->glLineWidth (theWidth * myResolutionRatio);
2753   }
2754 #ifdef HAVE_GL2PS
2755   if (IsFeedback())
2756   {
2757     gl2psLineWidth (theWidth);
2758   }
2759 #endif
2760 }
2761
2762 // =======================================================================
2763 // function : SetTextureMatrix
2764 // purpose  :
2765 // =======================================================================
2766 void OpenGl_Context::SetTextureMatrix (const Handle(Graphic3d_TextureParams)& theParams)
2767 {
2768   if (theParams.IsNull())
2769   {
2770     return;
2771   }
2772   else if (!myActiveProgram.IsNull())
2773   {
2774     const GLint aUniLoc = myActiveProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_TRSF2D);
2775     if (aUniLoc == OpenGl_ShaderProgram::INVALID_LOCATION)
2776     {
2777       return;
2778     }
2779
2780     // pack transformation parameters
2781     OpenGl_Vec4 aTrsf[2];
2782     aTrsf[0].xy() = theParams->Translation();
2783     aTrsf[0].zw() = theParams->Scale();
2784     aTrsf[1].x()  = std::sin (-theParams->Rotation() * static_cast<float> (M_PI / 180.0));
2785     aTrsf[1].y()  = std::cos (-theParams->Rotation() * static_cast<float> (M_PI / 180.0));
2786     myActiveProgram->SetUniform (this, aUniLoc, 2, aTrsf);
2787     return;
2788   }
2789
2790 #if !defined(GL_ES_VERSION_2_0)
2791   if (core11 != NULL)
2792   {
2793     GLint aMatrixMode = GL_TEXTURE;
2794     ::glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
2795
2796     core11->glMatrixMode (GL_TEXTURE);
2797     OpenGl_Mat4 aTextureMat;
2798     const Graphic3d_Vec2& aScale = theParams->Scale();
2799     const Graphic3d_Vec2& aTrans = theParams->Translation();
2800     Graphic3d_TransformUtils::Scale     (aTextureMat,  aScale.x(),  aScale.y(), 1.0f);
2801     Graphic3d_TransformUtils::Translate (aTextureMat, -aTrans.x(), -aTrans.y(), 0.0f);
2802     Graphic3d_TransformUtils::Rotate    (aTextureMat, -theParams->Rotation(), 0.0f, 0.0f, 1.0f);
2803     core11->glLoadMatrixf (aTextureMat);
2804     core11->glMatrixMode (aMatrixMode);
2805   }
2806 #endif
2807 }
2808
2809 // =======================================================================
2810 // function : SetPointSize
2811 // purpose  :
2812 // =======================================================================
2813 void OpenGl_Context::SetPointSize (const Standard_ShortReal theSize)
2814 {
2815   if (!myActiveProgram.IsNull())
2816   {
2817     myActiveProgram->SetUniform (this, myActiveProgram->GetStateLocation (OpenGl_OCCT_POINT_SIZE), theSize);
2818   #if !defined(GL_ES_VERSION_2_0)
2819     //myContext->core11fwd->glEnable (GL_VERTEX_PROGRAM_POINT_SIZE);
2820   #endif
2821   }
2822 #if !defined(GL_ES_VERSION_2_0)
2823   //else
2824   {
2825     core11fwd->glPointSize (theSize);
2826     if (core20fwd != NULL)
2827     {
2828       //myContext->core11fwd->glDisable (GL_VERTEX_PROGRAM_POINT_SIZE);
2829     }
2830   }
2831 #endif
2832 }
2833
2834 // =======================================================================
2835 // function : SetPointSpriteOrigin
2836 // purpose  :
2837 // =======================================================================
2838 void OpenGl_Context::SetPointSpriteOrigin()
2839 {
2840 #if !defined(GL_ES_VERSION_2_0)
2841   if (core15fwd == NULL)
2842   {
2843     return;
2844   }
2845
2846   const int aNewState = !myActiveProgram.IsNull() ? GL_UPPER_LEFT : GL_LOWER_LEFT;
2847   if (myPointSpriteOrig != aNewState)
2848   {
2849     myPointSpriteOrig = aNewState;
2850     core15fwd->glPointParameteri (GL_POINT_SPRITE_COORD_ORIGIN, aNewState);
2851   }
2852 #endif
2853 }
2854
2855 // =======================================================================
2856 // function : SetGlNormalizeEnabled
2857 // purpose  :
2858 // =======================================================================
2859 Standard_Boolean OpenGl_Context::SetGlNormalizeEnabled (Standard_Boolean isEnabled)
2860 {
2861   if (isEnabled == myIsGlNormalizeEnabled)
2862   {
2863     return myIsGlNormalizeEnabled;
2864   }
2865
2866   Standard_Boolean anOldGlNormalize = myIsGlNormalizeEnabled;
2867
2868   myIsGlNormalizeEnabled = isEnabled;
2869
2870 #if !defined(GL_ES_VERSION_2_0)
2871   if (core11 != NULL)
2872   {
2873     if (isEnabled)
2874     {
2875       ::glEnable  (GL_NORMALIZE);
2876     }
2877     else
2878     {
2879       ::glDisable (GL_NORMALIZE);
2880     }
2881   }
2882 #endif
2883
2884   return anOldGlNormalize;
2885 }
2886
2887 // =======================================================================
2888 // function : SetPolygonMode
2889 // purpose  :
2890 // =======================================================================
2891 Standard_Integer OpenGl_Context::SetPolygonMode (const Standard_Integer theMode)
2892 {
2893   if (myPolygonMode == theMode)
2894   {
2895     return myPolygonMode;
2896   }
2897
2898   const Standard_Integer anOldPolygonMode = myPolygonMode;
2899
2900   myPolygonMode = theMode;
2901
2902 #if !defined(GL_ES_VERSION_2_0)
2903   ::glPolygonMode (GL_FRONT_AND_BACK, (GLenum)theMode);
2904 #endif
2905
2906   return anOldPolygonMode;
2907 }
2908
2909 // =======================================================================
2910 // function : SetPolygonHatchEnabled
2911 // purpose  :
2912 // =======================================================================
2913 bool OpenGl_Context::SetPolygonHatchEnabled (const bool theIsEnabled)
2914 {
2915   if (myHatchStyles.IsNull())
2916   {
2917     return false;
2918   }
2919   else if (myHatchStyles->IsEnabled() == theIsEnabled)
2920   {
2921     return theIsEnabled;
2922   }
2923
2924   return myHatchStyles->SetEnabled (this, theIsEnabled);
2925 }
2926
2927 // =======================================================================
2928 // function : SetPolygonHatchStyle
2929 // purpose  :
2930 // =======================================================================
2931 Standard_Integer OpenGl_Context::SetPolygonHatchStyle (const Standard_Integer theType)
2932 {
2933   if (myHatchStyles.IsNull())
2934   {
2935     if (!GetResource ("OpenGl_LineAttributes", myHatchStyles))
2936     {
2937       // share and register for release once the resource is no longer used
2938       myHatchStyles = new OpenGl_LineAttributes();
2939       ShareResource ("OpenGl_LineAttributes", myHatchStyles);
2940       myHatchStyles->Init (this);
2941     }
2942   }
2943   if (myHatchStyles->TypeOfHatch() == theType)
2944   {
2945     return theType;
2946   }
2947
2948   return myHatchStyles->SetTypeOfHatch (this, theType);
2949 }
2950
2951 // =======================================================================
2952 // function : ApplyModelWorldMatrix
2953 // purpose  :
2954 // =======================================================================
2955 void OpenGl_Context::ApplyModelWorldMatrix()
2956 {
2957 #if !defined(GL_ES_VERSION_2_0)
2958   if (core11 != NULL)
2959   {
2960     core11->glMatrixMode (GL_MODELVIEW);
2961     core11->glLoadMatrixf (ModelWorldState.Current());
2962   }
2963 #endif
2964
2965   if (!myShaderManager->IsEmpty())
2966   {
2967     myShaderManager->UpdateModelWorldStateTo (ModelWorldState.Current());
2968   }
2969 }
2970
2971 // =======================================================================
2972 // function : ApplyWorldViewMatrix
2973 // purpose  :
2974 // =======================================================================
2975 void OpenGl_Context::ApplyWorldViewMatrix()
2976 {
2977 #if !defined(GL_ES_VERSION_2_0)
2978   if (core11 != NULL)
2979   {
2980     core11->glMatrixMode (GL_MODELVIEW);
2981     core11->glLoadMatrixf (WorldViewState.Current());
2982   }
2983 #endif
2984
2985   if (!myShaderManager->IsEmpty())
2986   {
2987     myShaderManager->UpdateModelWorldStateTo (THE_IDENTITY_MATRIX);
2988     myShaderManager->UpdateWorldViewStateTo (WorldViewState.Current());
2989   }
2990 }
2991
2992 // =======================================================================
2993 // function : ApplyModelViewMatrix
2994 // purpose  :
2995 // =======================================================================
2996 void OpenGl_Context::ApplyModelViewMatrix()
2997 {
2998 #if !defined(GL_ES_VERSION_2_0)
2999   if (core11 != NULL)
3000   {
3001     OpenGl_Mat4 aModelView = WorldViewState.Current() * ModelWorldState.Current();
3002     core11->glMatrixMode (GL_MODELVIEW);
3003     core11->glLoadMatrixf (aModelView.GetData());
3004   }
3005 #endif
3006
3007   if (!myShaderManager->IsEmpty())
3008   {
3009     myShaderManager->UpdateModelWorldStateTo (ModelWorldState.Current());
3010     myShaderManager->UpdateWorldViewStateTo (WorldViewState.Current());
3011   }
3012 }
3013
3014 // =======================================================================
3015 // function : ApplyProjectionMatrix
3016 // purpose  :
3017 // =======================================================================
3018 void OpenGl_Context::ApplyProjectionMatrix()
3019 {
3020 #if !defined(GL_ES_VERSION_2_0)
3021   if (core11 != NULL)
3022   {
3023     core11->glMatrixMode (GL_PROJECTION);
3024     core11->glLoadMatrixf (ProjectionState.Current().GetData());
3025   }
3026 #endif
3027
3028   if (!myShaderManager->IsEmpty())
3029   {
3030     myShaderManager->UpdateProjectionStateTo (ProjectionState.Current());
3031   }
3032 }
3033
3034
3035 // =======================================================================
3036 // function : EnableFeatures
3037 // purpose  :
3038 // =======================================================================
3039 void OpenGl_Context::EnableFeatures() const
3040 {
3041   //
3042 }
3043
3044 // =======================================================================
3045 // function : DisableFeatures
3046 // purpose  :
3047 // =======================================================================
3048 void OpenGl_Context::DisableFeatures() const
3049 {
3050 #if !defined(GL_ES_VERSION_2_0)
3051   glPixelTransferi (GL_MAP_COLOR, GL_FALSE);
3052 #endif
3053
3054   /*
3055   * Disable stuff that's likely to slow down glDrawPixels.
3056   * (Omit as much of this as possible, when you know in advance
3057   * that the OpenGL state will already be set correctly.)
3058   */
3059   glDisable(GL_DITHER);
3060   glDisable(GL_BLEND);
3061   glDisable(GL_DEPTH_TEST);
3062   glDisable(GL_TEXTURE_2D);
3063   glDisable(GL_STENCIL_TEST);
3064
3065 #if !defined(GL_ES_VERSION_2_0)
3066   glDisable(GL_LIGHTING);
3067   glDisable(GL_ALPHA_TEST);
3068   glDisable(GL_FOG);
3069   glDisable(GL_LOGIC_OP);
3070   glDisable(GL_TEXTURE_1D);
3071
3072   glPixelTransferi(GL_MAP_COLOR, GL_FALSE);
3073   glPixelTransferi(GL_RED_SCALE, 1);
3074   glPixelTransferi(GL_RED_BIAS, 0);
3075   glPixelTransferi(GL_GREEN_SCALE, 1);
3076   glPixelTransferi(GL_GREEN_BIAS, 0);
3077   glPixelTransferi(GL_BLUE_SCALE, 1);
3078   glPixelTransferi(GL_BLUE_BIAS, 0);
3079   glPixelTransferi(GL_ALPHA_SCALE, 1);
3080   glPixelTransferi(GL_ALPHA_BIAS, 0);
3081
3082   /*
3083   * Disable extensions that could slow down glDrawPixels.
3084   * (Actually, you should check for the presence of the proper
3085   * extension before making these calls.  I've omitted that
3086   * code for simplicity.)
3087   */
3088
3089   if ((myGlVerMajor >= 1) && (myGlVerMinor >= 2))
3090   {
3091 #ifdef GL_EXT_convolution
3092     if (CheckExtension ("GL_CONVOLUTION_1D_EXT"))
3093       glDisable(GL_CONVOLUTION_1D_EXT);
3094
3095     if (CheckExtension ("GL_CONVOLUTION_2D_EXT"))
3096       glDisable(GL_CONVOLUTION_2D_EXT);
3097
3098     if (CheckExtension ("GL_SEPARABLE_2D_EXT"))
3099       glDisable(GL_SEPARABLE_2D_EXT);
3100 #endif
3101
3102 #ifdef GL_EXT_histogram
3103     if (CheckExtension ("GL_SEPARABLE_2D_EXT"))
3104       glDisable(GL_HISTOGRAM_EXT);
3105
3106     if (CheckExtension ("GL_MINMAX_EXT"))
3107       glDisable(GL_MINMAX_EXT);
3108 #endif
3109
3110 #ifdef GL_EXT_texture3D
3111     if (CheckExtension ("GL_TEXTURE_3D_EXT"))
3112       glDisable(GL_TEXTURE_3D_EXT);
3113 #endif
3114   }
3115 #endif
3116 }