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