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