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