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