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