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