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