0031845: Modeling Algorithms - BRepOffsetAPI_MakeThickSolid fails
[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>
d850414a 34#include <OpenGl_TextureSetPairIterator.hxx>
299e0ab9 35#include <OpenGl_Workspace.hxx>
bf5f0ca2 36#include <OpenGl_Aspects.hxx>
158f2931 37
79f4f036 38#include <Graphic3d_TransformUtils.hxx>
56689b27 39#include <Graphic3d_RenderingParams.hxx>
faff3767 40#include <Image_SupportedFormats.hxx>
cbf18624 41#include <Message_Messenger.hxx>
a174a3c5 42#include <NCollection_Vector.hxx>
2bd4c032 43#include <Standard_ProgramError.hxx>
158f2931 44#include <Standard_WarningDisableFunctionCast.hxx>
2bd4c032 45
f5f4ebd0 46IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Context,Standard_Transient)
47
da8bb41d 48#if defined(HAVE_EGL)
49 #include <EGL/egl.h>
50 #ifdef _MSC_VER
51 #pragma comment(lib, "libEGL.lib")
52 #endif
53#elif defined(_WIN32)
5f8b738e 54 //
55#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
56 #include <dlfcn.h>
f978241f 57 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
58 //
59 #else
60 #include <OpenGL/OpenGL.h>
26d9c835 61 #include <CoreGraphics/CoreGraphics.h>
f978241f 62 #endif
5f8b738e 63#else
64 #include <GL/glx.h> // glXGetProcAddress()
65#endif
66
565baee6 67#ifdef __EMSCRIPTEN__
d4cefcc0 68 #include <emscripten.h>
565baee6 69 #include <emscripten/html5.h>
70
71 //! Check if WebGL extension is available and activate it
72 //! (usage of extension without activation will generate errors).
73 static bool checkEnableWebGlExtension (const OpenGl_Context& theCtx,
74 const char* theExtName)
75 {
76 if (!theCtx.CheckExtension (theExtName))
77 {
78 return false;
79 }
80 if (EMSCRIPTEN_WEBGL_CONTEXT_HANDLE aWebGlCtx = emscripten_webgl_get_current_context())
81 {
82 if (emscripten_webgl_enable_extension (aWebGlCtx, theExtName))
83 {
84 return true;
85 }
86 }
87 return false;
88 }
89#endif
90
5e27df78 91namespace
92{
93 static const Handle(OpenGl_Resource) NULL_GL_RESOURCE;
458e3c0d 94 static const OpenGl_Mat4 THE_IDENTITY_MATRIX;
26d9c835 95
96 //! Add key-value pair to the dictionary.
97 static void addInfo (TColStd_IndexedDataMapOfStringString& theDict,
98 const TCollection_AsciiString& theKey,
99 const TCollection_AsciiString& theValue)
100 {
101 theDict.ChangeFromIndex (theDict.Add (theKey, theValue)) = theValue;
102 }
103
104 //! Add key-value pair to the dictionary.
105 static void addInfo (TColStd_IndexedDataMapOfStringString& theDict,
106 const TCollection_AsciiString& theKey,
107 const char* theValue)
108 {
109 TCollection_AsciiString aValue (theValue != NULL ? theValue : "");
110 theDict.ChangeFromIndex (theDict.Add (theKey, aValue)) = aValue;
111 }
01ca42b2 112}
5e27df78 113
2166f0fa
SK
114// =======================================================================
115// function : OpenGl_Context
116// purpose :
117// =======================================================================
58655684 118OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
01ca42b2 119: core11 (NULL),
120 core11fwd (NULL),
121 core15 (NULL),
122 core15fwd (NULL),
123 core20 (NULL),
124 core20fwd (NULL),
872f98d9 125 core30 (NULL),
126 core30fwd (NULL),
01ca42b2 127 core32 (NULL),
128 core32back (NULL),
25ef750e 129 core33 (NULL),
130 core33back (NULL),
01ca42b2 131 core41 (NULL),
132 core41back (NULL),
133 core42 (NULL),
134 core42back (NULL),
135 core43 (NULL),
136 core43back (NULL),
137 core44 (NULL),
138 core44back (NULL),
9491df8c 139 core45 (NULL),
140 core45back (NULL),
58655684 141 caps (!theCaps.IsNull() ? theCaps : new OpenGl_Caps()),
d4cefcc0 142 hasGetBufferData (Standard_False),
ca3c13d1 143#if defined(GL_ES_VERSION_2_0)
144 hasHighp (Standard_False),
e99a2f7c 145 hasUintIndex(Standard_False),
ca3c13d1 146 hasTexRGBA8(Standard_False),
147#else
148 hasHighp (Standard_True),
e99a2f7c 149 hasUintIndex(Standard_True),
ca3c13d1 150 hasTexRGBA8(Standard_True),
ba00aab7 151#endif
67312b79 152 hasTexFloatLinear (Standard_False),
ba00aab7 153 hasTexSRGB (Standard_False),
154 hasFboSRGB (Standard_False),
155 hasSRGBControl (Standard_False),
156#if defined(GL_ES_VERSION_2_0)
157 hasFlatShading (OpenGl_FeatureNotAvailable),
158#else
c39bb31b 159 hasFlatShading (OpenGl_FeatureInCore),
ca3c13d1 160#endif
59515ca6 161 hasGlslBitwiseOps (OpenGl_FeatureNotAvailable),
a1073ae2 162 hasDrawBuffers (OpenGl_FeatureNotAvailable),
163 hasFloatBuffer (OpenGl_FeatureNotAvailable),
164 hasHalfFloatBuffer (OpenGl_FeatureNotAvailable),
165 hasSampleVariables (OpenGl_FeatureNotAvailable),
2a332745 166 hasGeometryStage (OpenGl_FeatureNotAvailable),
a1073ae2 167 arbDrawBuffers (Standard_False),
25ef750e 168 arbNPTW (Standard_False),
169 arbTexRG (Standard_False),
74fb257d 170 arbTexFloat (Standard_False),
cc8cbabe 171 arbSamplerObject (NULL),
25ef750e 172 arbTexBindless (NULL),
5e27df78 173 arbTBO (NULL),
25ef750e 174 arbTboRGB32 (Standard_False),
5e27df78 175 arbIns (NULL),
58655684 176 arbDbg (NULL),
01ca42b2 177 arbFBO (NULL),
b86bb3df 178 arbFBOBlit (NULL),
a1073ae2 179 arbSampleShading (Standard_False),
4b52faa5 180 arbDepthClamp (Standard_False),
1ce0716b 181 extFragDepth (Standard_False),
a1073ae2 182 extDrawBuffers (Standard_False),
37eb4787 183 extGS (NULL),
bf75be98 184 extBgra(Standard_False),
185 extAnis(Standard_False),
30f0ad28 186 extPDS (Standard_False),
f0430952 187 atiMem (Standard_False),
188 nvxMem (Standard_False),
a1073ae2 189 oesSampleVariables (Standard_False),
8c3237d4 190 oesStdDerivatives (Standard_False),
5e27df78 191 mySharedResources (new OpenGl_ResourcesMap()),
a174a3c5 192 myDelayed (new OpenGl_DelayReleaseMap()),
3125ebb6 193 myUnusedResources (new OpenGl_ResourcesStack()),
4269bd1b 194 myClippingState (),
5f8b738e 195 myGlLibHandle (NULL),
01ca42b2 196 myFuncs (new OpenGl_GlFunctions()),
faff3767 197 mySupportedFormats (new Image_SupportedFormats()),
2f6cb3ac 198 myAnisoMax (1),
ca3c13d1 199 myTexClamp (GL_CLAMP_TO_EDGE),
eafb234b 200 myMaxTexDim (1024),
cc8cbabe 201 myMaxTexCombined (1),
5c225e8e 202 myMaxTexUnitsFFP (1),
6997ff1c 203 myMaxDumpSizeX (1024),
204 myMaxDumpSizeY (1024),
4269bd1b 205 myMaxClipPlanes (6),
3c4b62a4 206 myMaxMsaaSamples(0),
a1073ae2 207 myMaxDrawBuffers (1),
208 myMaxColorAttachments (1),
5f8b738e 209 myGlVerMajor (0),
210 myGlVerMinor (0),
b5ac8292 211 myIsInitialized (Standard_False),
212 myIsStereoBuffers (Standard_False),
7d9e854b 213 myIsGlNormalizeEnabled (Standard_False),
72f6dc61 214 mySpriteTexUnit (Graphic3d_TextureUnit_PointSprite),
3a9b5dc8 215 myHasRayTracing (Standard_False),
216 myHasRayTracingTextures (Standard_False),
217 myHasRayTracingAdaptiveSampling (Standard_False),
e084dbbc 218 myHasRayTracingAdaptiveSamplingAtomic (Standard_False),
67312b79 219 myHasPBR (Standard_False),
72f6dc61 220 myPBREnvLUTTexUnit (Graphic3d_TextureUnit_PbrEnvironmentLUT),
221 myPBRDiffIBLMapSHTexUnit (Graphic3d_TextureUnit_PbrIblDiffuseSH),
222 myPBRSpecIBLMapTexUnit (Graphic3d_TextureUnit_PbrIblSpecular),
d84e8669 223 myShadowMapTexUnit (Graphic3d_TextureUnit_ShadowMap),
78c4e836 224 myDepthPeelingDepthTexUnit (Graphic3d_TextureUnit_DepthPeelingDepth),
225 myDepthPeelingFrontColorTexUnit (Graphic3d_TextureUnit_DepthPeelingFrontColor),
15669413 226 myFrameStats (new OpenGl_FrameStats()),
72f6dc61 227 myActiveMockTextures (0),
76fada68 228 myActiveHatchType (Aspect_HS_SOLID),
229 myHatchIsEnabled (false),
ca3c13d1 230#if !defined(GL_ES_VERSION_2_0)
fd59283a 231 myPointSpriteOrig (GL_UPPER_LEFT),
7d3e64ef 232 myRenderMode (GL_RENDER),
08669adf 233 myShadeModel (GL_SMOOTH),
6d0e6be5 234 myPolygonMode (GL_FILL),
ca3c13d1 235#else
fd59283a 236 myPointSpriteOrig (0),
ca3c13d1 237 myRenderMode (0),
08669adf 238 myShadeModel (0),
6d0e6be5 239 myPolygonMode (0),
ca3c13d1 240#endif
b6472664 241 myToCullBackFaces (false),
38a0206f 242 myReadBuffer (0),
c3487460 243 myDrawBuffers (0, 7),
4e1523ef 244 myDefaultVao (0),
f88457e6 245 myColorMask (true),
c40eb6b9 246 myAlphaToCoverage (false),
ba00aab7 247 myIsGlDebugCtx (false),
248 myIsSRgbWindow (false),
56689b27 249 myResolution (Graphic3d_RenderingParams::THE_DEFAULT_RESOLUTION),
250 myResolutionRatio (1.0f),
251 myLineWidthScale (1.0f),
2a332745 252 myLineFeather (1.0f),
56689b27 253 myRenderScale (1.0f),
254 myRenderScaleInv (1.0f)
2166f0fa 255{
3bffef55 256 myViewport[0] = 0;
257 myViewport[1] = 0;
258 myViewport[2] = 0;
259 myViewport[3] = 0;
56689b27 260 myViewportVirt[0] = 0;
261 myViewportVirt[1] = 0;
262 myViewportVirt[2] = 0;
263 myViewportVirt[3] = 0;
3bffef55 264
8d1a539c 265 myPolygonOffset.Mode = Aspect_POM_Off;
266 myPolygonOffset.Factor = 0.0f;
267 myPolygonOffset.Units = 0.0f;
268
4e1523ef 269 // system-dependent fields
270#if defined(HAVE_EGL)
271 myDisplay = (Aspect_Display )EGL_NO_DISPLAY;
272 myWindow = (Aspect_Drawable )EGL_NO_SURFACE;
458c2c58 273 myGContext = (Aspect_RenderingContext )EGL_NO_CONTEXT;
4e1523ef 274#elif defined(_WIN32)
275 myWindow = NULL;
276 myWindowDC = NULL;
277 myGContext = NULL;
278#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
5f8b738e 279 // Vendors can not extend functionality on this system
280 // and developers are limited to OpenGL support provided by Mac OS X SDK.
281 // We retrieve function pointers from system library
282 // to generalize extensions support on all platforms.
283 // In this way we also reach binary compatibility benefit between OS releases
284 // if some newest functionality is optionally used.
285 // Notice that GL version / extension availability checks are required
286 // because function pointers may be available but not functionality itself
287 // (depends on renderer).
a2e4f780 288#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
289 myGContext = NULL;
290 myGlLibHandle = dlopen ("/System/Library/Frameworks/OpenGLES.framework/OpenGLES", RTLD_LAZY);
291#else
4e1523ef 292 myGContext = NULL;
5f8b738e 293 myGlLibHandle = dlopen ("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
a2e4f780 294#endif
4e1523ef 295#else
296 myDisplay = NULL;
297 myWindow = 0;
298 myGContext = 0;
5f8b738e 299#endif
a2e4f780 300
01ca42b2 301 memset (myFuncs.operator->(), 0, sizeof(OpenGl_GlFunctions));
30f0ad28 302 myShaderManager = new OpenGl_ShaderManager (this);
2166f0fa
SK
303}
304
305// =======================================================================
306// function : ~OpenGl_Context
307// purpose :
308// =======================================================================
309OpenGl_Context::~OpenGl_Context()
310{
5e27df78 311 // release clean up queue
312 ReleaseDelayed();
313
4e1523ef 314#if !defined(GL_ES_VERSION_2_0)
315 // release default VAO
316 if (myDefaultVao != 0
317 && IsValid()
318 && core32 != NULL)
319 {
320 core32->glDeleteVertexArrays (1, &myDefaultVao);
321 }
322 myDefaultVao = 0;
323#endif
324
72f6dc61 325 // release mock textures
326 if (!myTextureRgbaBlack.IsNull())
327 {
328 myTextureRgbaBlack->Release (this);
329 myTextureRgbaBlack.Nullify();
330 }
331 if (!myTextureRgbaWhite.IsNull())
332 {
333 myTextureRgbaWhite->Release (this);
334 myTextureRgbaWhite.Nullify();
335 }
336
a2e4f780 337 // release default FBO
338 if (!myDefaultFbo.IsNull())
339 {
340 myDefaultFbo->Release (this);
341 myDefaultFbo.Nullify();
342 }
343
5e27df78 344 // release shared resources if any
4796758e 345 if (mySharedResources->GetRefCount() <= 1)
5e27df78 346 {
392ac980 347 myShaderManager.Nullify();
5e27df78 348 for (NCollection_DataMap<TCollection_AsciiString, Handle(OpenGl_Resource)>::Iterator anIter (*mySharedResources);
349 anIter.More(); anIter.Next())
350 {
351 anIter.Value()->Release (this);
352 }
e1c659da 353
354 // release delayed resources added during deletion of shared resources
355 while (!myUnusedResources->IsEmpty())
356 {
357 myUnusedResources->First()->Release (this);
358 myUnusedResources->RemoveFirst();
359 }
5e27df78 360 }
c357e426 361 else if (myShaderManager->IsSameContext (this))
392ac980 362 {
363 myShaderManager->SetContext (NULL);
364 }
5e27df78 365 mySharedResources.Nullify();
a174a3c5 366 myDelayed.Nullify();
5e27df78 367
cbf18624 368 if (arbDbg != NULL
4e1523ef 369 && myIsGlDebugCtx
f8c8ba7a 370 && IsValid())
cbf18624 371 {
372 // reset callback
0deb6f04 373 #if !defined(GL_ES_VERSION_2_0)
cbf18624 374 void* aPtr = NULL;
3b523c4c 375 glGetPointerv (GL_DEBUG_CALLBACK_USER_PARAM, &aPtr);
cbf18624 376 if (aPtr == this)
0deb6f04 377 #endif
cbf18624 378 {
0deb6f04 379 arbDbg->glDebugMessageCallback (NULL, NULL);
cbf18624 380 }
4e1523ef 381 myIsGlDebugCtx = Standard_False;
cbf18624 382 }
5f8b738e 383}
384
05e2200b 385// =======================================================================
386// function : forcedRelease
387// purpose :
388// =======================================================================
389void OpenGl_Context::forcedRelease()
390{
391 ReleaseDelayed();
392 for (NCollection_DataMap<TCollection_AsciiString, Handle(OpenGl_Resource)>::Iterator anIter (*mySharedResources);
393 anIter.More(); anIter.Next())
394 {
395 anIter.Value()->Release (this);
396 }
397 mySharedResources->Clear();
398 myShaderManager->clear();
399 myShaderManager->SetContext (NULL);
e1c659da 400
401 // release delayed resources added during deletion of shared resources
402 while (!myUnusedResources->IsEmpty())
403 {
404 myUnusedResources->First()->Release (this);
405 myUnusedResources->RemoveFirst();
406 }
05e2200b 407}
408
3bffef55 409// =======================================================================
410// function : ResizeViewport
411// purpose :
412// =======================================================================
413void OpenGl_Context::ResizeViewport (const Standard_Integer* theRect)
414{
415 core11fwd->glViewport (theRect[0], theRect[1], theRect[2], theRect[3]);
416 myViewport[0] = theRect[0];
417 myViewport[1] = theRect[1];
418 myViewport[2] = theRect[2];
419 myViewport[3] = theRect[3];
56689b27 420 if (HasRenderScale())
421 {
422 myViewportVirt[0] = Standard_Integer(theRect[0] * myRenderScaleInv);
423 myViewportVirt[1] = Standard_Integer(theRect[1] * myRenderScaleInv);
424 myViewportVirt[2] = Standard_Integer(theRect[2] * myRenderScaleInv);
425 myViewportVirt[3] = Standard_Integer(theRect[3] * myRenderScaleInv);
426 }
427 else
428 {
429 myViewportVirt[0] = theRect[0];
430 myViewportVirt[1] = theRect[1];
431 myViewportVirt[2] = theRect[2];
432 myViewportVirt[3] = theRect[3];
433 }
3bffef55 434}
435
ca3c13d1 436#if !defined(GL_ES_VERSION_2_0)
38a0206f 437inline Standard_Integer stereoToMonoBuffer (const Standard_Integer theBuffer)
438{
439 switch (theBuffer)
b5ac8292 440 {
38a0206f 441 case GL_BACK_LEFT:
442 case GL_BACK_RIGHT:
443 return GL_BACK;
444 case GL_FRONT_LEFT:
445 case GL_FRONT_RIGHT:
446 return GL_FRONT;
447 default:
448 return theBuffer;
b5ac8292 449 }
450}
38a0206f 451#endif
b5ac8292 452
453// =======================================================================
38a0206f 454// function : SetReadBuffer
b5ac8292 455// purpose :
456// =======================================================================
38a0206f 457void OpenGl_Context::SetReadBuffer (const Standard_Integer theReadBuffer)
b5ac8292 458{
ca3c13d1 459#if !defined(GL_ES_VERSION_2_0)
38a0206f 460 myReadBuffer = !myIsStereoBuffers ? stereoToMonoBuffer (theReadBuffer) : theReadBuffer;
461 if (myReadBuffer < GL_COLOR_ATTACHMENT0
462 && arbFBO != NULL)
b5ac8292 463 {
38a0206f 464 arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
b5ac8292 465 }
38a0206f 466 ::glReadBuffer (myReadBuffer);
467#else
468 (void )theReadBuffer;
ca3c13d1 469#endif
b5ac8292 470}
471
472// =======================================================================
38a0206f 473// function : SetDrawBuffer
b5ac8292 474// purpose :
475// =======================================================================
38a0206f 476void OpenGl_Context::SetDrawBuffer (const Standard_Integer theDrawBuffer)
b5ac8292 477{
ca3c13d1 478#if !defined(GL_ES_VERSION_2_0)
a1073ae2 479 const Standard_Integer aDrawBuffer = !myIsStereoBuffers ? stereoToMonoBuffer (theDrawBuffer) : theDrawBuffer;
480 if (aDrawBuffer < GL_COLOR_ATTACHMENT0
38a0206f 481 && arbFBO != NULL)
b5ac8292 482 {
38a0206f 483 arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
b5ac8292 484 }
a1073ae2 485 ::glDrawBuffer (aDrawBuffer);
486
c3487460 487 myDrawBuffers.Init (GL_NONE);
488 myDrawBuffers.SetValue (0, aDrawBuffer);
38a0206f 489#else
490 (void )theDrawBuffer;
ca3c13d1 491#endif
b5ac8292 492}
493
a1073ae2 494// =======================================================================
495// function : SetDrawBuffers
496// purpose :
497// =======================================================================
498void OpenGl_Context::SetDrawBuffers (const Standard_Integer theNb, const Standard_Integer* theDrawBuffers)
499{
500 Standard_ASSERT_RETURN (hasDrawBuffers, "Multiple draw buffers feature is not supported by the context", Standard_ASSERT_DO_NOTHING());
501
c3487460 502 if (myDrawBuffers.Length() < theNb)
503 {
504 // should actually never happen here
505 myDrawBuffers.Resize (0, theNb - 1, false);
506 }
507 myDrawBuffers.Init (GL_NONE);
a1073ae2 508
509 Standard_Boolean useDefaultFbo = Standard_False;
510 for (Standard_Integer anI = 0; anI < theNb; ++anI)
511 {
b17e5bae 512 if (theDrawBuffers[anI] < GL_COLOR_ATTACHMENT0 && theDrawBuffers[anI] != GL_NONE)
a1073ae2 513 {
514 useDefaultFbo = Standard_True;
515 }
c3487460 516 else
a1073ae2 517 {
b17e5bae 518 myDrawBuffers.SetValue (anI, theDrawBuffers[anI]);
a1073ae2 519 }
520 }
521 if (arbFBO != NULL && useDefaultFbo)
522 {
523 arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
524 }
525
526 myFuncs->glDrawBuffers (theNb, (const GLenum*)theDrawBuffers);
527}
528
ba00aab7 529// =======================================================================
530// function : SetFrameBufferSRGB
531// purpose :
532// =======================================================================
e5c11edd 533void OpenGl_Context::SetFrameBufferSRGB (bool theIsFbo, bool theIsFboSRgb)
ba00aab7 534{
535 if (!hasFboSRGB)
536 {
537 myIsSRgbActive = false;
538 return;
539 }
540 myIsSRgbActive = ToRenderSRGB()
e5c11edd 541 && (theIsFbo || myIsSRgbWindow)
542 && theIsFboSRgb;
ba00aab7 543 if (!hasSRGBControl)
544 {
545 return;
546 }
547
548 if (myIsSRgbActive)
549 {
550 core11fwd->glEnable (GL_FRAMEBUFFER_SRGB);
551 }
552 else
553 {
554 core11fwd->glDisable (GL_FRAMEBUFFER_SRGB);
555 }
556}
557
b6472664 558// =======================================================================
559// function : SetCullBackFaces
560// purpose :
561// =======================================================================
562void OpenGl_Context::SetCullBackFaces (bool theToEnable)
563{
564 if (myToCullBackFaces == theToEnable)
565 {
566 return;
567 }
568
569 myToCullBackFaces = theToEnable;
570 if (theToEnable)
571 {
572 //glCullFace (GL_BACK); GL_BACK by default
573 core11fwd->glEnable (GL_CULL_FACE);
574 }
575 else
576 {
577 core11fwd->glDisable (GL_CULL_FACE);
578 }
579}
580
b5ac8292 581// =======================================================================
582// function : FetchState
583// purpose :
584// =======================================================================
585void OpenGl_Context::FetchState()
586{
ca3c13d1 587#if !defined(GL_ES_VERSION_2_0)
b5ac8292 588 // cache feedback mode state
4e1523ef 589 if (core11 != NULL)
590 {
591 ::glGetIntegerv (GL_RENDER_MODE, &myRenderMode);
08669adf 592 ::glGetIntegerv (GL_SHADE_MODEL, &myShadeModel);
4e1523ef 593 }
b5ac8292 594
a1073ae2 595 // cache read buffers state
38a0206f 596 ::glGetIntegerv (GL_READ_BUFFER, &myReadBuffer);
a1073ae2 597
598 // cache draw buffers state
c3487460 599 if (myDrawBuffers.Length() < myMaxDrawBuffers)
600 {
601 myDrawBuffers.Resize (0, myMaxDrawBuffers - 1, false);
602 }
603 myDrawBuffers.Init (GL_NONE);
a1073ae2 604
c3487460 605 Standard_Integer aDrawBuffer = GL_NONE;
a1073ae2 606 if (myMaxDrawBuffers == 1)
607 {
a1073ae2 608 ::glGetIntegerv (GL_DRAW_BUFFER, &aDrawBuffer);
c3487460 609 myDrawBuffers.SetValue (0, aDrawBuffer);
a1073ae2 610 }
611 else
612 {
a1073ae2 613 for (Standard_Integer anI = 0; anI < myMaxDrawBuffers; ++anI)
614 {
615 ::glGetIntegerv (GL_DRAW_BUFFER0 + anI, &aDrawBuffer);
c3487460 616 myDrawBuffers.SetValue (anI, aDrawBuffer);
a1073ae2 617 }
618 }
ca3c13d1 619#endif
b5ac8292 620}
621
5e27df78 622// =======================================================================
623// function : Share
624// purpose :
625// =======================================================================
626void OpenGl_Context::Share (const Handle(OpenGl_Context)& theShareCtx)
627{
628 if (!theShareCtx.IsNull())
629 {
630 mySharedResources = theShareCtx->mySharedResources;
a174a3c5 631 myDelayed = theShareCtx->myDelayed;
3125ebb6 632 myUnusedResources = theShareCtx->myUnusedResources;
392ac980 633 myShaderManager = theShareCtx->myShaderManager;
5e27df78 634 }
635}
636
4fe56619 637#if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
638
86fa64d9 639// =======================================================================
640// function : IsCurrent
641// purpose :
642// =======================================================================
643Standard_Boolean OpenGl_Context::IsCurrent() const
644{
da8bb41d 645#if defined(HAVE_EGL)
646 if ((EGLDisplay )myDisplay == EGL_NO_DISPLAY
da8bb41d 647 || (EGLContext )myGContext == EGL_NO_CONTEXT)
648 {
649 return Standard_False;
650 }
651
652 return (((EGLDisplay )myDisplay == eglGetCurrentDisplay())
653 && ((EGLContext )myGContext == eglGetCurrentContext())
654 && ((EGLSurface )myWindow == eglGetCurrentSurface (EGL_DRAW)));
655#elif defined(_WIN32)
86fa64d9 656 if (myWindowDC == NULL || myGContext == NULL)
657 {
658 return Standard_False;
659 }
660 return (( (HDC )myWindowDC == wglGetCurrentDC())
661 && ((HGLRC )myGContext == wglGetCurrentContext()));
662#else
663 if (myDisplay == NULL || myWindow == 0 || myGContext == 0)
664 {
665 return Standard_False;
666 }
667
668 return ( ((Display* )myDisplay == glXGetCurrentDisplay())
669 && ((GLXContext )myGContext == glXGetCurrentContext())
670 && ((GLXDrawable )myWindow == glXGetCurrentDrawable()));
671#endif
672}
673
2bd4c032 674// =======================================================================
675// function : MakeCurrent
676// purpose :
677// =======================================================================
678Standard_Boolean OpenGl_Context::MakeCurrent()
679{
da8bb41d 680#if defined(HAVE_EGL)
681 if ((EGLDisplay )myDisplay == EGL_NO_DISPLAY
da8bb41d 682 || (EGLContext )myGContext == EGL_NO_CONTEXT)
683 {
684 Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
685 return Standard_False;
686 }
687
688 if (eglMakeCurrent ((EGLDisplay )myDisplay, (EGLSurface )myWindow, (EGLSurface )myWindow, (EGLContext )myGContext) != EGL_TRUE)
689 {
690 // if there is no current context it might be impossible to use glGetError() correctly
3b523c4c 691 PushMessage (GL_DEBUG_SOURCE_WINDOW_SYSTEM, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
da8bb41d 692 "eglMakeCurrent() has failed!");
693 myIsInitialized = Standard_False;
694 return Standard_False;
695 }
696#elif defined(_WIN32)
86fa64d9 697 if (myWindowDC == NULL || myGContext == NULL)
2bd4c032 698 {
86fa64d9 699 Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
700 return Standard_False;
701 }
702
703 // technically it should be safe to activate already bound GL context
704 // however some drivers (Intel etc.) may FAIL doing this for unknown reason
705 if (IsCurrent())
706 {
392ac980 707 myShaderManager->SetContext (this);
86fa64d9 708 return Standard_True;
709 }
710 else if (wglMakeCurrent ((HDC )myWindowDC, (HGLRC )myGContext) != TRUE)
711 {
712 // notice that glGetError() couldn't be used here!
713 wchar_t* aMsgBuff = NULL;
714 DWORD anErrorCode = GetLastError();
715 FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
716 NULL, anErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (wchar_t* )&aMsgBuff, 0, NULL);
cbf18624 717 TCollection_ExtendedString aMsg ("wglMakeCurrent() has failed. ");
86fa64d9 718 if (aMsgBuff != NULL)
719 {
cbf18624 720 aMsg += (Standard_ExtString )aMsgBuff;
86fa64d9 721 LocalFree (aMsgBuff);
722 }
3b523c4c 723 PushMessage (GL_DEBUG_SOURCE_WINDOW_SYSTEM, GL_DEBUG_TYPE_ERROR, (unsigned int )anErrorCode, GL_DEBUG_SEVERITY_HIGH, aMsg);
fd4a6963 724 myIsInitialized = Standard_False;
2bd4c032 725 return Standard_False;
726 }
727#else
86fa64d9 728 if (myDisplay == NULL || myWindow == 0 || myGContext == 0)
729 {
730 Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
731 return Standard_False;
732 }
733
734 if (!glXMakeCurrent ((Display* )myDisplay, (GLXDrawable )myWindow, (GLXContext )myGContext))
2bd4c032 735 {
736 // if there is no current context it might be impossible to use glGetError() correctly
3b523c4c 737 PushMessage (GL_DEBUG_SOURCE_WINDOW_SYSTEM, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
cbf18624 738 "glXMakeCurrent() has failed!");
fd4a6963 739 myIsInitialized = Standard_False;
2bd4c032 740 return Standard_False;
741 }
742#endif
392ac980 743 myShaderManager->SetContext (this);
2bd4c032 744 return Standard_True;
745}
746
5e27df78 747// =======================================================================
748// function : SwapBuffers
749// purpose :
750// =======================================================================
751void OpenGl_Context::SwapBuffers()
752{
da8bb41d 753#if defined(HAVE_EGL)
754 if ((EGLSurface )myWindow != EGL_NO_SURFACE)
755 {
756 eglSwapBuffers ((EGLDisplay )myDisplay, (EGLSurface )myWindow);
757 }
758#elif defined(_WIN32)
5e27df78 759 if ((HDC )myWindowDC != NULL)
760 {
761 ::SwapBuffers ((HDC )myWindowDC);
762 glFlush();
763 }
764#else
765 if ((Display* )myDisplay != NULL)
766 {
767 glXSwapBuffers ((Display* )myDisplay, (GLXDrawable )myWindow);
768 }
769#endif
770}
771
4fe56619 772#endif // __APPLE__
773
f978241f 774// =======================================================================
775// function : SetSwapInterval
776// purpose :
777// =======================================================================
778Standard_Boolean OpenGl_Context::SetSwapInterval (const Standard_Integer theInterval)
779{
780#if defined(HAVE_EGL)
781 if (::eglSwapInterval ((EGLDisplay )myDisplay, theInterval) == EGL_TRUE)
782 {
783 return Standard_True;
784 }
785#elif defined(_WIN32)
786 if (myFuncs->wglSwapIntervalEXT != NULL)
787 {
788 myFuncs->wglSwapIntervalEXT (theInterval);
789 return Standard_True;
790 }
791#elif defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
92cc34d7 792 (void )theInterval; // vsync cannot be turned OFF on iOS
f978241f 793#elif defined(__APPLE__)
794 if (::CGLSetParameter (CGLGetCurrentContext(), kCGLCPSwapInterval, &theInterval) == kCGLNoError)
795 {
796 return Standard_True;
797 }
798#else
799 if (theInterval == -1
800 && myFuncs->glXSwapIntervalEXT != NULL)
801 {
802 typedef int (*glXSwapIntervalEXT_t_x)(Display* theDisplay, GLXDrawable theDrawable, int theInterval);
803 glXSwapIntervalEXT_t_x aFuncPtr = (glXSwapIntervalEXT_t_x )myFuncs->glXSwapIntervalEXT;
804 aFuncPtr ((Display* )myDisplay, (GLXDrawable )myWindow, theInterval);
805 return Standard_True;
806 }
807 else if (myFuncs->glXSwapIntervalSGI != NULL)
808 {
809 myFuncs->glXSwapIntervalSGI (theInterval);
810 return Standard_True;
811 }
812#endif
813 return Standard_False;
814}
815
5f8b738e 816// =======================================================================
817// function : findProc
818// purpose :
819// =======================================================================
820void* OpenGl_Context::findProc (const char* theFuncName)
821{
da8bb41d 822#if defined(HAVE_EGL)
823 return (void* )eglGetProcAddress (theFuncName);
824#elif defined(_WIN32)
7c65581d 825 return (void* )wglGetProcAddress (theFuncName);
5f8b738e 826#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
827 return (myGlLibHandle != NULL) ? dlsym (myGlLibHandle, theFuncName) : NULL;
828#else
829 return (void* )glXGetProcAddress ((const GLubyte* )theFuncName);
830#endif
2166f0fa
SK
831}
832
833// =======================================================================
834// function : CheckExtension
835// purpose :
836// =======================================================================
2bd4c032 837Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtName) const
2166f0fa 838{
5f8b738e 839 if (theExtName == NULL)
840 {
0797d9d3 841#ifdef OCCT_DEBUG
5f8b738e 842 std::cerr << "CheckExtension called with NULL string!\n";
63c629aa 843#endif
5f8b738e 844 return Standard_False;
845 }
59515ca6 846 else if (caps->contextNoExtensions)
847 {
848 return Standard_False;
849 }
5f8b738e 850
4e1523ef 851#if !defined(GL_ES_VERSION_2_0)
5f8b738e 852 // available since OpenGL 3.0
853 // and the ONLY way to check extensions with OpenGL 3.1+ core profile
4e1523ef 854 if (IsGlGreaterEqual (3, 0)
855 && myFuncs->glGetStringi != NULL)
5f8b738e 856 {
857 GLint anExtNb = 0;
4e1523ef 858 ::glGetIntegerv (GL_NUM_EXTENSIONS, &anExtNb);
859 const size_t anExtNameLen = strlen (theExtName);
5f8b738e 860 for (GLint anIter = 0; anIter < anExtNb; ++anIter)
861 {
4e1523ef 862 const char* anExtension = (const char* )myFuncs->glGetStringi (GL_EXTENSIONS, (GLuint )anIter);
863 const size_t aTestExtNameLen = strlen (anExtension);
864 if (aTestExtNameLen == anExtNameLen
865 && strncmp (anExtension, theExtName, anExtNameLen) == 0)
5f8b738e 866 {
867 return Standard_True;
868 }
869 }
870 return Standard_False;
4e1523ef 871 }
872#endif
5f8b738e 873
874 // use old way with huge string for all extensions
875 const char* anExtString = (const char* )glGetString (GL_EXTENSIONS);
876 if (anExtString == NULL)
877 {
7e7c2f0b 878 Messenger()->Send ("TKOpenGL: glGetString (GL_EXTENSIONS) has returned NULL! No GL context?", Message_Warning);
2166f0fa
SK
879 return Standard_False;
880 }
58655684 881 return CheckExtension (anExtString, theExtName);
882}
883
884// =======================================================================
885// function : CheckExtension
886// purpose :
887// =======================================================================
888Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtString,
889 const char* theExtName)
890{
891 if (theExtString == NULL)
892 {
893 return Standard_False;
894 }
2166f0fa
SK
895
896 // Search for theExtName in the extensions string.
897 // Use of strstr() is not sufficient because extension names can be prefixes of other extension names.
58655684 898 char* aPtrIter = (char* )theExtString;
899 const char* aPtrEnd = aPtrIter + strlen (theExtString);
900 const size_t anExtNameLen = strlen (theExtName);
2166f0fa
SK
901 while (aPtrIter < aPtrEnd)
902 {
6a7d83c4 903 const size_t n = strcspn (aPtrIter, " ");
5f8b738e 904 if ((n == anExtNameLen) && (strncmp (aPtrIter, theExtName, anExtNameLen) == 0))
905 {
2166f0fa 906 return Standard_True;
5f8b738e 907 }
2166f0fa
SK
908 aPtrIter += (n + 1);
909 }
910 return Standard_False;
911}
912
4fe56619 913#if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
914
2166f0fa
SK
915// =======================================================================
916// function : Init
917// purpose :
918// =======================================================================
4e1523ef 919Standard_Boolean OpenGl_Context::Init (const Standard_Boolean theIsCoreProfile)
2166f0fa 920{
2bd4c032 921 if (myIsInitialized)
5f8b738e 922 {
f0430952 923 return Standard_True;
5f8b738e 924 }
2bd4c032 925
da8bb41d 926#if defined(HAVE_EGL)
927 myDisplay = (Aspect_Display )eglGetCurrentDisplay();
928 myGContext = (Aspect_RenderingContext )eglGetCurrentContext();
929 myWindow = (Aspect_Drawable )eglGetCurrentSurface(EGL_DRAW);
930#elif defined(_WIN32)
2bd4c032 931 myWindowDC = (Aspect_Handle )wglGetCurrentDC();
932 myGContext = (Aspect_RenderingContext )wglGetCurrentContext();
933#else
934 myDisplay = (Aspect_Display )glXGetCurrentDisplay();
935 myGContext = (Aspect_RenderingContext )glXGetCurrentContext();
936 myWindow = (Aspect_Drawable )glXGetCurrentDrawable();
937#endif
f0430952 938 if (myGContext == NULL)
939 {
940 return Standard_False;
941 }
2bd4c032 942
4e1523ef 943 init (theIsCoreProfile);
2bd4c032 944 myIsInitialized = Standard_True;
f0430952 945 return Standard_True;
2bd4c032 946}
947
4fe56619 948#endif // __APPLE__
949
2bd4c032 950// =======================================================================
951// function : Init
952// purpose :
953// =======================================================================
da8bb41d 954#if defined(HAVE_EGL)
955Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable theEglSurface,
956 const Aspect_Display theEglDisplay,
4e1523ef 957 const Aspect_RenderingContext theEglContext,
958 const Standard_Boolean theIsCoreProfile)
da8bb41d 959#elif defined(_WIN32)
f0430952 960Standard_Boolean OpenGl_Context::Init (const Aspect_Handle theWindow,
961 const Aspect_Handle theWindowDC,
4e1523ef 962 const Aspect_RenderingContext theGContext,
963 const Standard_Boolean theIsCoreProfile)
4fe56619 964#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
a2e4f780 965
966#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
967Standard_Boolean OpenGl_Context::Init (EAGLContext* theGContext,
4e1523ef 968 const Standard_Boolean theIsCoreProfile)
a2e4f780 969#else
970Standard_Boolean OpenGl_Context::Init (NSOpenGLContext* theGContext,
971 const Standard_Boolean theIsCoreProfile)
972#endif
973
2bd4c032 974#else
f0430952 975Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable theWindow,
976 const Aspect_Display theDisplay,
4e1523ef 977 const Aspect_RenderingContext theGContext,
978 const Standard_Boolean theIsCoreProfile)
2bd4c032 979#endif
980{
981 Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called only once!");
da8bb41d 982#if defined(HAVE_EGL)
983 myWindow = theEglSurface;
984 myGContext = theEglContext;
985 myDisplay = theEglDisplay;
986#elif defined(_WIN32)
2bd4c032 987 myWindow = theWindow;
988 myGContext = theGContext;
2bd4c032 989 myWindowDC = theWindowDC;
4fe56619 990#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
a2e4f780 991 myGContext = theGContext;
2bd4c032 992#else
4fe56619 993 myWindow = theWindow;
994 myGContext = theGContext;
2bd4c032 995 myDisplay = theDisplay;
996#endif
86fa64d9 997 if (myGContext == NULL || !MakeCurrent())
f0430952 998 {
999 return Standard_False;
1000 }
2bd4c032 1001
4e1523ef 1002 init (theIsCoreProfile);
2bd4c032 1003 myIsInitialized = Standard_True;
f0430952 1004 return Standard_True;
5f8b738e 1005}
1006
1007// =======================================================================
1008// function : ResetErrors
1009// purpose :
1010// =======================================================================
f9f740d6 1011bool OpenGl_Context::ResetErrors (const bool theToPrintErrors)
5f8b738e 1012{
3c4b62a4 1013 int aPrevErr = 0;
1014 int anErr = ::glGetError();
f9f740d6 1015 const bool hasError = anErr != GL_NO_ERROR;
3c4b62a4 1016 if (!theToPrintErrors)
5f8b738e 1017 {
3c4b62a4 1018 for (; anErr != GL_NO_ERROR && aPrevErr != anErr; aPrevErr = anErr, anErr = ::glGetError())
1019 {
1020 //
1021 }
f9f740d6 1022 return hasError;
3c4b62a4 1023 }
1024
1025 for (; anErr != GL_NO_ERROR && aPrevErr != anErr; aPrevErr = anErr, anErr = ::glGetError())
1026 {
1027 TCollection_ExtendedString anErrId;
1028 switch (anErr)
1029 {
1030 case GL_INVALID_ENUM: anErrId = "GL_INVALID_ENUM"; break;
1031 case GL_INVALID_VALUE: anErrId = "GL_INVALID_VALUE"; break;
1032 case GL_INVALID_OPERATION: anErrId = "GL_INVALID_OPERATION"; break;
1033 #ifdef GL_STACK_OVERFLOW
1034 case GL_STACK_OVERFLOW: anErrId = "GL_STACK_OVERFLOW"; break;
1035 case GL_STACK_UNDERFLOW: anErrId = "GL_STACK_UNDERFLOW"; break;
1036 #endif
1037 case GL_OUT_OF_MEMORY: anErrId = "GL_OUT_OF_MEMORY"; break;
1038 case GL_INVALID_FRAMEBUFFER_OPERATION:
1039 anErrId = "GL_INVALID_FRAMEBUFFER_OPERATION";
1040 break;
1041 default:
1042 anErrId = TCollection_ExtendedString("#") + anErr;
1043 break;
1044 }
1045
1046 const TCollection_ExtendedString aMsg = TCollection_ExtendedString ("Unhandled GL error: ") + anErrId;
82f443b6 1047 PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, 0, GL_DEBUG_SEVERITY_LOW, aMsg);
5f8b738e 1048 }
f9f740d6 1049 return hasError;
5f8b738e 1050}
1051
1052// =======================================================================
4e1523ef 1053// function : ReadGlVersion
5f8b738e 1054// purpose :
1055// =======================================================================
4e1523ef 1056void OpenGl_Context::ReadGlVersion (Standard_Integer& theGlVerMajor,
1057 Standard_Integer& theGlVerMinor)
5f8b738e 1058{
1059 // reset values
4e1523ef 1060 theGlVerMajor = 0;
1061 theGlVerMinor = 0;
5f8b738e 1062
c64efd9e 1063 bool toCheckVer3 = true;
1064#if defined(__EMSCRIPTEN__)
1065 // WebGL 1.0 prints annoying invalid enumeration warnings to console.
1066 toCheckVer3 = false;
1067 if (EMSCRIPTEN_WEBGL_CONTEXT_HANDLE aWebGlCtx = emscripten_webgl_get_current_context())
5f8b738e 1068 {
c64efd9e 1069 EmscriptenWebGLContextAttributes anAttribs = {};
1070 if (emscripten_webgl_get_context_attributes (aWebGlCtx, &anAttribs) == EMSCRIPTEN_RESULT_SUCCESS)
1071 {
1072 toCheckVer3 = anAttribs.majorVersion >= 2;
1073 }
5f8b738e 1074 }
c64efd9e 1075#endif
1076
1077 // Available since OpenGL 3.0 and OpenGL ES 3.0.
1078 if (toCheckVer3)
4e1523ef 1079 {
c64efd9e 1080 GLint aMajor = 0, aMinor = 0;
1081 glGetIntegerv (GL_MAJOR_VERSION, &aMajor);
1082 glGetIntegerv (GL_MINOR_VERSION, &aMinor);
1083 // glGetError() sometimes does not report an error here even if
1084 // GL does not know GL_MAJOR_VERSION and GL_MINOR_VERSION constants.
1085 // This happens on some renderers like e.g. Cygwin MESA.
1086 // Thus checking additionally if GL has put anything to
1087 // the output variables.
1088 if (::glGetError() == GL_NO_ERROR && aMajor != 0 && aMinor != 0)
4e1523ef 1089 {
c64efd9e 1090 theGlVerMajor = aMajor;
1091 theGlVerMinor = aMinor;
1092 return;
1093 }
1094 for (GLenum anErr = ::glGetError(), aPrevErr = GL_NO_ERROR;; aPrevErr = anErr, anErr = ::glGetError())
1095 {
1096 if (anErr == GL_NO_ERROR
1097 || anErr == aPrevErr)
1098 {
1099 break;
1100 }
4e1523ef 1101 }
1102 }
5f8b738e 1103
1104 // Read version string.
ca3c13d1 1105 // Notice that only first two numbers split by point '2.1 XXXXX' are significant.
5f8b738e 1106 // Following trash (after space) is vendor-specific.
1107 // New drivers also returns micro version of GL like '3.3.0' which has no meaning
1108 // and should be considered as vendor-specific too.
1109 const char* aVerStr = (const char* )glGetString (GL_VERSION);
1110 if (aVerStr == NULL || *aVerStr == '\0')
1111 {
1112 // invalid GL context
1113 return;
1114 }
1115
ca3c13d1 1116//#if defined(GL_ES_VERSION_2_0)
1117 // skip "OpenGL ES-** " section
1118 for (; *aVerStr != '\0'; ++aVerStr)
1119 {
1120 if (*aVerStr >= '0' && *aVerStr <= '9')
1121 {
1122 break;
1123 }
1124 }
1125//#endif
1126
5f8b738e 1127 // parse string for major number
1128 char aMajorStr[32];
1129 char aMinorStr[32];
1130 size_t aMajIter = 0;
1131 while (aVerStr[aMajIter] >= '0' && aVerStr[aMajIter] <= '9')
1132 {
1133 ++aMajIter;
1134 }
1135 if (aMajIter == 0 || aMajIter >= sizeof(aMajorStr))
1136 {
1137 return;
1138 }
1139 memcpy (aMajorStr, aVerStr, aMajIter);
1140 aMajorStr[aMajIter] = '\0';
1141
1142 // parse string for minor number
86325709 1143 aVerStr += aMajIter + 1;
1144 size_t aMinIter = 0;
5f8b738e 1145 while (aVerStr[aMinIter] >= '0' && aVerStr[aMinIter] <= '9')
1146 {
1147 ++aMinIter;
1148 }
86325709 1149 if (aMinIter == 0 || aMinIter >= sizeof(aMinorStr))
5f8b738e 1150 {
1151 return;
1152 }
86325709 1153 memcpy (aMinorStr, aVerStr, aMinIter);
1154 aMinorStr[aMinIter] = '\0';
5f8b738e 1155
1156 // read numbers
4e1523ef 1157 theGlVerMajor = atoi (aMajorStr);
1158 theGlVerMinor = atoi (aMinorStr);
5f8b738e 1159
4e1523ef 1160 if (theGlVerMajor <= 0)
5f8b738e 1161 {
4e1523ef 1162 theGlVerMajor = 0;
1163 theGlVerMinor = 0;
5f8b738e 1164 }
1165}
1166
58655684 1167static Standard_CString THE_DBGMSG_UNKNOWN = "UNKNOWN";
1168static Standard_CString THE_DBGMSG_SOURCES[] =
1169{
3b523c4c 1170 ".OpenGL", // GL_DEBUG_SOURCE_API
1171 ".WinSystem", // GL_DEBUG_SOURCE_WINDOW_SYSTEM
1172 ".GLSL", // GL_DEBUG_SOURCE_SHADER_COMPILER
1173 ".3rdParty", // GL_DEBUG_SOURCE_THIRD_PARTY
1174 "", // GL_DEBUG_SOURCE_APPLICATION
1175 ".Other" // GL_DEBUG_SOURCE_OTHER
58655684 1176};
1177
1178static Standard_CString THE_DBGMSG_TYPES[] =
1179{
3b523c4c 1180 "Error", // GL_DEBUG_TYPE_ERROR
1181 "Deprecated", // GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR
1182 "Undef. behavior", // GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR
1183 "Portability", // GL_DEBUG_TYPE_PORTABILITY
1184 "Performance", // GL_DEBUG_TYPE_PERFORMANCE
1185 "Other" // GL_DEBUG_TYPE_OTHER
58655684 1186};
1187
3b523c4c 1188static Standard_CString THE_DBGMSG_SEV_HIGH = "High"; // GL_DEBUG_SEVERITY_HIGH
1189static Standard_CString THE_DBGMSG_SEV_MEDIUM = "Medium"; // GL_DEBUG_SEVERITY_MEDIUM
1190static Standard_CString THE_DBGMSG_SEV_LOW = "Low"; // GL_DEBUG_SEVERITY_LOW
58655684 1191
cbf18624 1192//! Callback for GL_ARB_debug_output extension
58655684 1193static void APIENTRY debugCallbackWrap(unsigned int theSource,
1194 unsigned int theType,
1195 unsigned int theId,
1196 unsigned int theSeverity,
1197 int /*theLength*/,
1198 const char* theMessage,
9293178b 1199 const void* theUserParam)
cbf18624 1200{
1201 OpenGl_Context* aCtx = (OpenGl_Context* )theUserParam;
1202 aCtx->PushMessage (theSource, theType, theId, theSeverity, theMessage);
1203}
1204
1205// =======================================================================
1206// function : PushMessage
1207// purpose :
1208// =======================================================================
1209void OpenGl_Context::PushMessage (const unsigned int theSource,
1210 const unsigned int theType,
1211 const unsigned int theId,
1212 const unsigned int theSeverity,
1213 const TCollection_ExtendedString& theMessage)
58655684 1214{
c87535af 1215 if (caps->suppressExtraMsg
3b523c4c 1216 && theSource >= GL_DEBUG_SOURCE_API
1217 && theSource <= GL_DEBUG_SOURCE_OTHER
1218 && myFilters[theSource - GL_DEBUG_SOURCE_API].Contains (theId))
c87535af 1219 {
1220 return;
1221 }
1222
3b523c4c 1223 Standard_CString& aSrc = (theSource >= GL_DEBUG_SOURCE_API
1224 && theSource <= GL_DEBUG_SOURCE_OTHER)
1225 ? THE_DBGMSG_SOURCES[theSource - GL_DEBUG_SOURCE_API]
58655684 1226 : THE_DBGMSG_UNKNOWN;
3b523c4c 1227 Standard_CString& aType = (theType >= GL_DEBUG_TYPE_ERROR
1228 && theType <= GL_DEBUG_TYPE_OTHER)
1229 ? THE_DBGMSG_TYPES[theType - GL_DEBUG_TYPE_ERROR]
58655684 1230 : THE_DBGMSG_UNKNOWN;
3b523c4c 1231 Standard_CString& aSev = theSeverity == GL_DEBUG_SEVERITY_HIGH
58655684 1232 ? THE_DBGMSG_SEV_HIGH
3b523c4c 1233 : (theSeverity == GL_DEBUG_SEVERITY_MEDIUM
58655684 1234 ? THE_DBGMSG_SEV_MEDIUM
1235 : THE_DBGMSG_SEV_LOW);
3b523c4c 1236 Message_Gravity aGrav = theSeverity == GL_DEBUG_SEVERITY_HIGH
cbf18624 1237 ? Message_Alarm
3b523c4c 1238 : (theSeverity == GL_DEBUG_SEVERITY_MEDIUM
cbf18624 1239 ? Message_Warning
1240 : Message_Info);
1241
1242 TCollection_ExtendedString aMsg;
1243 aMsg += "TKOpenGl"; aMsg += aSrc;
1244 aMsg += " | Type: "; aMsg += aType;
1245 aMsg += " | ID: "; aMsg += (Standard_Integer )theId;
1246 aMsg += " | Severity: "; aMsg += aSev;
1247 aMsg += " | Message:\n ";
1248 aMsg += theMessage;
7e7c2f0b 1249 Messenger()->Send (aMsg, aGrav);
58655684 1250}
1251
c87535af 1252// =======================================================================
1253// function : ExcludeMessage
1254// purpose :
1255// ======================================================================
1256Standard_Boolean OpenGl_Context::ExcludeMessage (const unsigned int theSource,
1257 const unsigned int theId)
1258{
3b523c4c 1259 return theSource >= GL_DEBUG_SOURCE_API
1260 && theSource <= GL_DEBUG_SOURCE_OTHER
1261 && myFilters[theSource - GL_DEBUG_SOURCE_API].Add (theId);
c87535af 1262}
1263
1264// =======================================================================
1265// function : IncludeMessage
1266// purpose :
1267// ======================================================================
1268Standard_Boolean OpenGl_Context::IncludeMessage (const unsigned int theSource,
1269 const unsigned int theId)
1270{
3b523c4c 1271 return theSource >= GL_DEBUG_SOURCE_API
1272 && theSource <= GL_DEBUG_SOURCE_OTHER
1273 && myFilters[theSource - GL_DEBUG_SOURCE_API].Remove (theId);
c87535af 1274}
1275
ee51a9fe 1276// =======================================================================
1277// function : checkWrongVersion
1278// purpose :
1279// ======================================================================
0ae9ac21 1280void OpenGl_Context::checkWrongVersion (Standard_Integer theGlVerMajor, Standard_Integer theGlVerMinor,
1281 const char* theLastFailedProc)
ee51a9fe 1282{
1283 if (!IsGlGreaterEqual (theGlVerMajor, theGlVerMinor))
1284 {
1285 return;
1286 }
1287
0ae9ac21 1288 PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
1289 TCollection_AsciiString()
1290 + "Error! OpenGL context reports version "
1291 + myGlVerMajor + "." + myGlVerMinor
1292 + " but does not export required functions for " + theGlVerMajor + "." + theGlVerMinor
1293 + " (" + (theLastFailedProc != NULL ? theLastFailedProc : "") + ")\n"
1294 + "Please report this issue to OpenGL driver vendor '" + myVendor + "'");
1295
1296 // lower internal version
1297 if (theGlVerMinor > 0)
1298 {
1299 myGlVerMajor = theGlVerMajor;
1300 myGlVerMinor = theGlVerMinor - 1;
1301 return;
1302 }
1303#if defined(GL_ES_VERSION_2_0)
1304 switch (theGlVerMajor)
1305 {
1306 case 3: myGlVerMajor = 2; myGlVerMinor = 0; return;
1307 }
1308#else
1309 switch (theGlVerMajor)
1310 {
1311 case 2: myGlVerMajor = 1; myGlVerMinor = 5; return;
1312 case 3: myGlVerMajor = 2; myGlVerMinor = 1; return;
1313 case 4: myGlVerMajor = 3; myGlVerMinor = 3; return;
1314 }
1315#endif
ee51a9fe 1316}
1317
5f8b738e 1318// =======================================================================
1319// function : init
1320// purpose :
1321// =======================================================================
4e1523ef 1322void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
5f8b738e 1323{
1324 // read version
4e1523ef 1325 myGlVerMajor = 0;
1326 myGlVerMinor = 0;
3c4b62a4 1327 myMaxMsaaSamples = 0;
a1073ae2 1328 myMaxDrawBuffers = 1;
1329 myMaxColorAttachments = 1;
4e1523ef 1330 ReadGlVersion (myGlVerMajor, myGlVerMinor);
c87535af 1331 myVendor = (const char* )::glGetString (GL_VENDOR);
6997ff1c 1332 myVendor.LowerCase();
59515ca6 1333
faff3767 1334 // standard formats
1335 mySupportedFormats->Clear();
f4e7c307 1336 mySupportedFormats->Add (Image_Format_Gray);
1337 mySupportedFormats->Add (Image_Format_Alpha);
1338 mySupportedFormats->Add (Image_Format_RGB);
1339 mySupportedFormats->Add (Image_Format_RGB32);
1340 mySupportedFormats->Add (Image_Format_RGBA);
faff3767 1341
59515ca6 1342 if (caps->contextMajorVersionUpper != -1)
1343 {
1344 // synthetically restrict OpenGL version for testing
1345 Standard_Integer aCtxVer[2] = { myGlVerMajor, myGlVerMinor };
1346 bool isLowered = false;
1347 if (myGlVerMajor > caps->contextMajorVersionUpper)
1348 {
1349 isLowered = true;
1350 myGlVerMajor = caps->contextMajorVersionUpper;
1351 #if defined(GL_ES_VERSION_2_0)
1352 switch (myGlVerMajor)
1353 {
1354 case 2: myGlVerMinor = 0; break;
1355 }
1356 #else
1357 switch (myGlVerMajor)
1358 {
1359 case 1: myGlVerMinor = 5; break;
1360 case 2: myGlVerMinor = 1; break;
1361 case 3: myGlVerMinor = 3; break;
1362 }
1363 #endif
1364 }
1365 if (caps->contextMinorVersionUpper != -1
1366 && myGlVerMinor > caps->contextMinorVersionUpper)
1367 {
1368 isLowered = true;
1369 myGlVerMinor = caps->contextMinorVersionUpper;
1370 }
1371 if (isLowered)
1372 {
1373 PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_MEDIUM,
1374 TCollection_AsciiString ("OpenGL version ") + aCtxVer[0] + "." + aCtxVer[1]
1375 + " has been lowered to " + myGlVerMajor + "." + myGlVerMinor);
1376 }
1377 }
1378
be375252 1379 if (!caps->ffpEnable
1380 && !IsGlGreaterEqual (2, 0))
1381 {
1382 caps->ffpEnable = true;
1383 TCollection_ExtendedString aMsg =
1384 TCollection_ExtendedString("OpenGL driver is too old! Context info:\n")
1385 + " Vendor: " + (const char* )::glGetString (GL_VENDOR) + "\n"
1386 + " Renderer: " + (const char* )::glGetString (GL_RENDERER) + "\n"
1387 + " Version: " + (const char* )::glGetString (GL_VERSION) + "\n"
1388 + " Fallback using deprecated fixed-function pipeline.\n"
1389 + " Visualization might work incorrectly.\n"
1390 " Consider upgrading the graphics driver.";
1391 PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
1392 }
4e1523ef 1393
1394#if defined(GL_ES_VERSION_2_0)
1395 (void )theIsCoreProfile;
1396 const bool isCoreProfile = false;
1397#else
c87535af 1398
6997ff1c 1399 if (myVendor.Search ("nvidia") != -1)
c87535af 1400 {
1401 // Buffer detailed info: Buffer object 1 (bound to GL_ARRAY_BUFFER_ARB, usage hint is GL_STATIC_DRAW)
1402 // will use VIDEO memory as the source for buffer object operations.
3b523c4c 1403 ExcludeMessage (GL_DEBUG_SOURCE_API, 131185);
c87535af 1404 }
4e1523ef 1405 if (IsGlGreaterEqual (3, 0))
1406 {
1407 // retrieve auxiliary function in advance
1408 FindProc ("glGetStringi", myFuncs->glGetStringi);
1409 }
1410
d4271fe5 1411 bool isCoreProfile = false;
4e1523ef 1412 if (IsGlGreaterEqual (3, 2))
1413 {
d4271fe5 1414 isCoreProfile = (theIsCoreProfile == Standard_True);
4e1523ef 1415
d4271fe5 1416 // detect Core profile
c6ad5e5f 1417 if (!isCoreProfile)
4e1523ef 1418 {
d4271fe5 1419 GLint aProfile = 0;
1420 ::glGetIntegerv (GL_CONTEXT_PROFILE_MASK, &aProfile);
1421 isCoreProfile = (aProfile & GL_CONTEXT_CORE_PROFILE_BIT) != 0;
4e1523ef 1422 }
1423 }
4e1523ef 1424#endif
1425
1426 core11 = NULL;
1427 if (!isCoreProfile)
1428 {
1429 core11 = (OpenGl_GlCore11* )(&(*myFuncs));
1430 }
01ca42b2 1431 core11fwd = (OpenGl_GlCore11Fwd* )(&(*myFuncs));
1432 core15 = NULL;
1433 core15fwd = NULL;
1434 core20 = NULL;
1435 core20fwd = NULL;
872f98d9 1436 core30 = NULL;
1437 core30fwd = NULL;
01ca42b2 1438 core32 = NULL;
1439 core32back = NULL;
25ef750e 1440 core33 = NULL;
1441 core33back = NULL;
01ca42b2 1442 core41 = NULL;
1443 core41back = NULL;
1444 core42 = NULL;
1445 core42back = NULL;
1446 core43 = NULL;
1447 core43back = NULL;
1448 core44 = NULL;
1449 core44back = NULL;
9491df8c 1450 core45 = NULL;
1451 core45back = NULL;
01ca42b2 1452 arbTBO = NULL;
25ef750e 1453 arbTboRGB32 = Standard_False;
01ca42b2 1454 arbIns = NULL;
1455 arbDbg = NULL;
1456 arbFBO = NULL;
b86bb3df 1457 arbFBOBlit = NULL;
01ca42b2 1458 extGS = NULL;
4e1523ef 1459 myDefaultVao = 0;
01ca42b2 1460
cc8cbabe 1461 //! Make record shorter to retrieve function pointer using variable with same name
0ae9ac21 1462 const char* aLastFailedProc = NULL;
1463 #define FindProcShort(theFunc) FindProcVerbose(aLastFailedProc, #theFunc, myFuncs->theFunc)
cc8cbabe 1464
ca3c13d1 1465#if defined(GL_ES_VERSION_2_0)
1466
1467 hasTexRGBA8 = IsGlGreaterEqual (3, 0)
1468 || CheckExtension ("GL_OES_rgb8_rgba8");
ba00aab7 1469 hasTexSRGB = IsGlGreaterEqual (3, 0);
1470 hasFboSRGB = IsGlGreaterEqual (3, 0);
1471 hasSRGBControl = CheckExtension ("GL_EXT_sRGB_write_control");
05e2200b 1472 // NPOT textures has limited support within OpenGL ES 2.0
1473 // which are relaxed by OpenGL ES 3.0 or some extensions
1474 //arbNPTW = IsGlGreaterEqual (3, 0)
1475 // || CheckExtension ("GL_OES_texture_npot")
1476 // || CheckExtension ("GL_NV_texture_npot_2D_mipmap");
1477 arbNPTW = Standard_True;
ca3c13d1 1478 arbTexRG = IsGlGreaterEqual (3, 0)
1479 || CheckExtension ("GL_EXT_texture_rg");
1480 extBgra = CheckExtension ("GL_EXT_texture_format_BGRA8888");
1481 extAnis = CheckExtension ("GL_EXT_texture_filter_anisotropic");
e473b95f 1482 extPDS = IsGlGreaterEqual (3, 0)
1483 || CheckExtension ("GL_OES_packed_depth_stencil");
565baee6 1484#ifdef __EMSCRIPTEN__
1485 if (!extPDS
1486 && checkEnableWebGlExtension (*this, "GL_WEBGL_depth_texture"))
1487 {
1488 extPDS = true; // WebGL 1.0 extension (in WebGL 2.0 core)
1489 }
1490#endif
ca3c13d1 1491
faff3767 1492 if (extBgra)
1493 {
1494 // no BGR on OpenGL ES - only BGRA as extension
f4e7c307 1495 mySupportedFormats->Add (Image_Format_BGR32);
1496 mySupportedFormats->Add (Image_Format_BGRA);
faff3767 1497 }
1498
ca3c13d1 1499 core11fwd = (OpenGl_GlCore11Fwd* )(&(*myFuncs));
1500 if (IsGlGreaterEqual (2, 0))
1501 {
1502 // enable compatible functions
1503 core20 = (OpenGl_GlCore20* )(&(*myFuncs));
1504 core20fwd = (OpenGl_GlCore20Fwd* )(&(*myFuncs));
1505 core15fwd = (OpenGl_GlCore15Fwd* )(&(*myFuncs));
b86bb3df 1506 arbFBO = (OpenGl_ArbFBO* )(&(*myFuncs));
1507 }
1508 if (IsGlGreaterEqual (3, 0)
cc8cbabe 1509 && FindProcShort (glBlitFramebuffer))
b86bb3df 1510 {
1511 arbFBOBlit = (OpenGl_ArbFBOBlit* )(&(*myFuncs));
ca3c13d1 1512 }
cc8cbabe 1513 if (IsGlGreaterEqual (3, 0)
1514 && FindProcShort (glGenSamplers)
1515 && FindProcShort (glDeleteSamplers)
1516 && FindProcShort (glIsSampler)
1517 && FindProcShort (glBindSampler)
1518 && FindProcShort (glSamplerParameteri)
1519 && FindProcShort (glSamplerParameteriv)
1520 && FindProcShort (glSamplerParameterf)
1521 && FindProcShort (glSamplerParameterfv)
1522 && FindProcShort (glGetSamplerParameteriv)
1523 && FindProcShort (glGetSamplerParameterfv))
1524 //&& FindProcShort (glSamplerParameterIiv) // only on Desktop or with extensions GL_OES_texture_border_clamp/GL_EXT_texture_border_clamp
1525 //&& FindProcShort (glSamplerParameterIuiv)
1526 //&& FindProcShort (glGetSamplerParameterIiv)
1527 //&& FindProcShort (glGetSamplerParameterIuiv))
1528 {
1529 arbSamplerObject = (OpenGl_ArbSamplerObject* )(&(*myFuncs));
1530 }
1ce0716b 1531 extFragDepth = !IsGlGreaterEqual(3, 0)
1532 && CheckExtension ("GL_EXT_frag_depth");
3c4b62a4 1533 if (IsGlGreaterEqual (3, 1)
0ae9ac21 1534 && FindProcShort (glTexStorage2DMultisample))
3c4b62a4 1535 {
1536 // MSAA RenderBuffers have been defined in OpenGL ES 3.0,
1537 // but MSAA Textures - only in OpenGL ES 3.1+
1538 ::glGetIntegerv (GL_MAX_SAMPLES, &myMaxMsaaSamples);
1539 }
ca3c13d1 1540
e99a2f7c 1541 hasUintIndex = IsGlGreaterEqual (3, 0)
1542 || CheckExtension ("GL_OES_element_index_uint");
1543 hasHighp = CheckExtension ("GL_OES_fragment_precision_high");
ca3c13d1 1544 GLint aRange[2] = {0, 0};
447c4115 1545 GLint aPrec = 0;
1546 ::glGetShaderPrecisionFormat (GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, aRange, &aPrec);
1547 if (aPrec != 0)
ca3c13d1 1548 {
1549 hasHighp = Standard_True;
1550 }
74fb257d 1551
59ec2cce 1552 arbTexFloat = (IsGlGreaterEqual (3, 0)
1553 && FindProcShort (glTexImage3D))
1554 || CheckExtension ("GL_OES_texture_float");
67312b79 1555 hasTexFloatLinear = arbTexFloat
1556 && CheckExtension ("GL_OES_texture_float_linear");
20aeeb7b 1557
872f98d9 1558 const bool hasTexBuffer32 = IsGlGreaterEqual (3, 2) && FindProcShort (glTexBuffer);
1559 const bool hasExtTexBuffer = CheckExtension ("GL_EXT_texture_buffer") && FindProc ("glTexBufferEXT", myFuncs->glTexBuffer);
20aeeb7b 1560 if (hasTexBuffer32 || hasExtTexBuffer)
1561 {
1562 arbTBO = reinterpret_cast<OpenGl_ArbTBO*> (myFuncs.get());
1563 }
0deb6f04 1564
872f98d9 1565 bool hasInstanced = IsGlGreaterEqual (3, 0)
1566 && FindProcShort (glVertexAttribDivisor)
1567 && FindProcShort (glDrawArraysInstanced)
1568 && FindProcShort (glDrawElementsInstanced);
1569 if (!hasInstanced)
1570 {
1571 hasInstanced = CheckExtension ("GL_ANGLE_instanced_arrays")
1572 && FindProc ("glVertexAttribDivisorANGLE", myFuncs->glVertexAttribDivisor)
1573 && FindProc ("glDrawArraysInstancedANGLE", myFuncs->glDrawArraysInstanced)
1574 && FindProc ("glDrawElementsInstancedANGLE", myFuncs->glDrawElementsInstanced);
1575 }
1576 if (hasInstanced)
1577 {
1578 arbIns = (OpenGl_ArbIns* )(&(*myFuncs));
1579 }
1580
1581 const bool hasVAO = IsGlGreaterEqual (3, 0)
1582 && FindProcShort (glBindVertexArray)
1583 && FindProcShort (glDeleteVertexArrays)
1584 && FindProcShort (glGenVertexArrays)
1585 && FindProcShort (glIsVertexArray);
7465bfa6 1586#ifndef __EMSCRIPTEN__ // latest Emscripten does not pretend having / simulating mapping buffer functions
872f98d9 1587 const bool hasMapBufferRange = IsGlGreaterEqual (3, 0)
1588 && FindProcShort (glMapBufferRange)
7465bfa6 1589 && FindProcShort (glUnmapBuffer)
1590 && FindProcShort (glGetBufferPointerv)
872f98d9 1591 && FindProcShort (glFlushMappedBufferRange);
7465bfa6 1592#endif
872f98d9 1593
1594 // load OpenGL ES 3.0 new functions
1595 const bool has30es = IsGlGreaterEqual (3, 0)
1596 && hasVAO
7465bfa6 1597 #ifndef __EMSCRIPTEN__
872f98d9 1598 && hasMapBufferRange
7465bfa6 1599 #endif
872f98d9 1600 && hasInstanced
1601 && arbSamplerObject != NULL
1602 && arbFBOBlit != NULL
1603 && FindProcShort (glReadBuffer)
1604 && FindProcShort (glDrawRangeElements)
1605 && FindProcShort (glTexImage3D)
1606 && FindProcShort (glTexSubImage3D)
1607 && FindProcShort (glCopyTexSubImage3D)
1608 && FindProcShort (glCompressedTexImage3D)
1609 && FindProcShort (glCompressedTexSubImage3D)
1610 && FindProcShort (glGenQueries)
1611 && FindProcShort (glDeleteQueries)
1612 && FindProcShort (glIsQuery)
1613 && FindProcShort (glBeginQuery)
1614 && FindProcShort (glEndQuery)
1615 && FindProcShort (glGetQueryiv)
1616 && FindProcShort (glGetQueryObjectuiv)
872f98d9 1617 && FindProcShort (glDrawBuffers)
1618 && FindProcShort (glUniformMatrix2x3fv)
1619 && FindProcShort (glUniformMatrix3x2fv)
1620 && FindProcShort (glUniformMatrix2x4fv)
1621 && FindProcShort (glUniformMatrix4x2fv)
1622 && FindProcShort (glUniformMatrix3x4fv)
1623 && FindProcShort (glUniformMatrix4x3fv)
1624 && FindProcShort (glRenderbufferStorageMultisample)
1625 && FindProcShort (glFramebufferTextureLayer)
1626 && FindProcShort (glGetIntegeri_v)
1627 && FindProcShort (glBeginTransformFeedback)
1628 && FindProcShort (glEndTransformFeedback)
1629 && FindProcShort (glBindBufferRange)
1630 && FindProcShort (glBindBufferBase)
1631 && FindProcShort (glTransformFeedbackVaryings)
1632 && FindProcShort (glGetTransformFeedbackVarying)
1633 && FindProcShort (glVertexAttribIPointer)
1634 && FindProcShort (glGetVertexAttribIiv)
1635 && FindProcShort (glGetVertexAttribIuiv)
1636 && FindProcShort (glVertexAttribI4i)
1637 && FindProcShort (glVertexAttribI4ui)
1638 && FindProcShort (glVertexAttribI4iv)
1639 && FindProcShort (glVertexAttribI4uiv)
1640 && FindProcShort (glGetUniformuiv)
1641 && FindProcShort (glGetFragDataLocation)
1642 && FindProcShort (glUniform1ui)
1643 && FindProcShort (glUniform2ui)
1644 && FindProcShort (glUniform3ui)
1645 && FindProcShort (glUniform4ui)
1646 && FindProcShort (glUniform1uiv)
1647 && FindProcShort (glUniform2uiv)
1648 && FindProcShort (glUniform3uiv)
1649 && FindProcShort (glUniform4uiv)
1650 && FindProcShort (glClearBufferiv)
1651 && FindProcShort (glClearBufferuiv)
1652 && FindProcShort (glClearBufferfv)
1653 && FindProcShort (glClearBufferfi)
1654 && FindProcShort (glGetStringi)
1655 && FindProcShort (glCopyBufferSubData)
1656 && FindProcShort (glGetUniformIndices)
1657 && FindProcShort (glGetActiveUniformsiv)
1658 && FindProcShort (glGetUniformBlockIndex)
1659 && FindProcShort (glGetActiveUniformBlockiv)
1660 && FindProcShort (glGetActiveUniformBlockName)
1661 && FindProcShort (glUniformBlockBinding)
1662 && FindProcShort (glFenceSync)
1663 && FindProcShort (glIsSync)
1664 && FindProcShort (glDeleteSync)
1665 && FindProcShort (glClientWaitSync)
1666 && FindProcShort (glWaitSync)
1667 && FindProcShort (glGetInteger64v)
1668 && FindProcShort (glGetSynciv)
1669 && FindProcShort (glGetInteger64i_v)
1670 && FindProcShort (glGetBufferParameteri64v)
1671 && FindProcShort (glBindTransformFeedback)
1672 && FindProcShort (glDeleteTransformFeedbacks)
1673 && FindProcShort (glGenTransformFeedbacks)
1674 && FindProcShort (glIsTransformFeedback)
1675 && FindProcShort (glPauseTransformFeedback)
1676 && FindProcShort (glResumeTransformFeedback)
1677 && FindProcShort (glGetProgramBinary)
1678 && FindProcShort (glProgramBinary)
1679 && FindProcShort (glProgramParameteri)
1680 && FindProcShort (glInvalidateFramebuffer)
1681 && FindProcShort (glInvalidateSubFramebuffer)
1682 && FindProcShort (glTexStorage2D)
1683 && FindProcShort (glTexStorage3D)
1684 && FindProcShort (glGetInternalformativ);
1685 if (!has30es)
1686 {
1687 checkWrongVersion (3, 0, aLastFailedProc);
1688 }
1689 else
1690 {
1691 core30 = (OpenGl_GlCore30* )(&(*myFuncs));
1692 core30fwd = (OpenGl_GlCore30Fwd* )(&(*myFuncs));
d4cefcc0 1693 hasGetBufferData = true;
872f98d9 1694 }
1695
1696 // load OpenGL ES 3.1 new functions
1697 const bool has31es = IsGlGreaterEqual (3, 1)
1698 && has30es
1699 && FindProcShort (glDispatchCompute)
1700 && FindProcShort (glDispatchComputeIndirect)
1701 && FindProcShort (glDrawArraysIndirect)
1702 && FindProcShort (glDrawElementsIndirect)
1703 && FindProcShort (glFramebufferParameteri)
1704 && FindProcShort (glGetFramebufferParameteriv)
1705 && FindProcShort (glGetProgramInterfaceiv)
1706 && FindProcShort (glGetProgramResourceIndex)
1707 && FindProcShort (glGetProgramResourceName)
1708 && FindProcShort (glGetProgramResourceiv)
1709 && FindProcShort (glGetProgramResourceLocation)
1710 && FindProcShort (glUseProgramStages)
1711 && FindProcShort (glActiveShaderProgram)
1712 && FindProcShort (glCreateShaderProgramv)
1713 && FindProcShort (glBindProgramPipeline)
1714 && FindProcShort (glDeleteProgramPipelines)
1715 && FindProcShort (glGenProgramPipelines)
1716 && FindProcShort (glIsProgramPipeline)
1717 && FindProcShort (glGetProgramPipelineiv)
1718 && FindProcShort (glProgramUniform1i)
1719 && FindProcShort (glProgramUniform2i)
1720 && FindProcShort (glProgramUniform3i)
1721 && FindProcShort (glProgramUniform4i)
1722 && FindProcShort (glProgramUniform1ui)
1723 && FindProcShort (glProgramUniform2ui)
1724 && FindProcShort (glProgramUniform3ui)
1725 && FindProcShort (glProgramUniform4ui)
1726 && FindProcShort (glProgramUniform1f)
1727 && FindProcShort (glProgramUniform2f)
1728 && FindProcShort (glProgramUniform3f)
1729 && FindProcShort (glProgramUniform4f)
1730 && FindProcShort (glProgramUniform1iv)
1731 && FindProcShort (glProgramUniform2iv)
1732 && FindProcShort (glProgramUniform3iv)
1733 && FindProcShort (glProgramUniform4iv)
1734 && FindProcShort (glProgramUniform1uiv)
1735 && FindProcShort (glProgramUniform2uiv)
1736 && FindProcShort (glProgramUniform3uiv)
1737 && FindProcShort (glProgramUniform4uiv)
1738 && FindProcShort (glProgramUniform1fv)
1739 && FindProcShort (glProgramUniform2fv)
1740 && FindProcShort (glProgramUniform3fv)
1741 && FindProcShort (glProgramUniform4fv)
1742 && FindProcShort (glProgramUniformMatrix2fv)
1743 && FindProcShort (glProgramUniformMatrix3fv)
1744 && FindProcShort (glProgramUniformMatrix4fv)
1745 && FindProcShort (glProgramUniformMatrix2x3fv)
1746 && FindProcShort (glProgramUniformMatrix3x2fv)
1747 && FindProcShort (glProgramUniformMatrix2x4fv)
1748 && FindProcShort (glProgramUniformMatrix4x2fv)
1749 && FindProcShort (glProgramUniformMatrix3x4fv)
1750 && FindProcShort (glProgramUniformMatrix4x3fv)
1751 && FindProcShort (glValidateProgramPipeline)
1752 && FindProcShort (glGetProgramPipelineInfoLog)
1753 && FindProcShort (glBindImageTexture)
1754 && FindProcShort (glGetBooleani_v)
1755 && FindProcShort (glMemoryBarrier)
1756 && FindProcShort (glMemoryBarrierByRegion)
1757 && FindProcShort (glTexStorage2DMultisample)
1758 && FindProcShort (glGetMultisamplefv)
1759 && FindProcShort (glSampleMaski)
1760 && FindProcShort (glGetTexLevelParameteriv)
1761 && FindProcShort (glGetTexLevelParameterfv)
1762 && FindProcShort (glBindVertexBuffer)
1763 && FindProcShort (glVertexAttribFormat)
1764 && FindProcShort (glVertexAttribIFormat)
1765 && FindProcShort (glVertexAttribBinding)
1766 && FindProcShort (glVertexBindingDivisor);
1767 if (!has31es)
1768 {
1769 checkWrongVersion (3, 1, aLastFailedProc);
1770 }
1771
0deb6f04 1772 // initialize debug context extension
872f98d9 1773 if (IsGlGreaterEqual (3, 2)
1774 || CheckExtension ("GL_KHR_debug"))
0deb6f04 1775 {
1776 // this functionality become a part of OpenGL ES 3.2
1777 arbDbg = NULL;
872f98d9 1778 if (IsGlGreaterEqual (3, 2)
1779 && FindProcShort (glDebugMessageControl)
1780 && FindProcShort (glDebugMessageInsert)
1781 && FindProcShort (glDebugMessageCallback)
1782 && FindProcShort (glGetDebugMessageLog))
1783 {
1784 arbDbg = (OpenGl_ArbDbg* )(&(*myFuncs));
1785 }
0deb6f04 1786 // According to GL_KHR_debug spec, all functions should have KHR suffix.
1787 // However, some implementations can export these functions without suffix.
872f98d9 1788 else if (!IsGlGreaterEqual (3, 2)
1789 && FindProc ("glDebugMessageControlKHR", myFuncs->glDebugMessageControl)
0deb6f04 1790 && FindProc ("glDebugMessageInsertKHR", myFuncs->glDebugMessageInsert)
1791 && FindProc ("glDebugMessageCallbackKHR", myFuncs->glDebugMessageCallback)
1792 && FindProc ("glGetDebugMessageLogKHR", myFuncs->glGetDebugMessageLog))
1793 {
1794 arbDbg = (OpenGl_ArbDbg* )(&(*myFuncs));
1795 }
1796
1797 if (arbDbg != NULL
1798 && caps->contextDebug)
1799 {
1800 // setup default callback
1801 myIsGlDebugCtx = Standard_True;
1802 arbDbg->glDebugMessageCallback (debugCallbackWrap, this);
1803 ::glEnable (GL_DEBUG_OUTPUT);
1804 if (caps->contextSyncDebug)
1805 {
1806 // note that some broken implementations (e.g. simulators) might generate error message on this call
1807 ::glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS);
1808 }
1809 }
1810 }
1811
872f98d9 1812 // load OpenGL ES 3.2 new functions
1813 const bool has32es = IsGlGreaterEqual (3, 2)
1814 && has31es
1815 && hasTexBuffer32
1816 && arbDbg != NULL
1817 && FindProcShort (glBlendBarrier)
1818 && FindProcShort (glCopyImageSubData)
1819 && FindProcShort (glPushDebugGroup)
1820 && FindProcShort (glPopDebugGroup)
1821 && FindProcShort (glObjectLabel)
1822 && FindProcShort (glGetObjectLabel)
1823 && FindProcShort (glObjectPtrLabel)
1824 && FindProcShort (glGetObjectPtrLabel)
1825 && FindProcShort (glGetPointerv)
1826 && FindProcShort (glEnablei)
1827 && FindProcShort (glDisablei)
1828 && FindProcShort (glBlendEquationi)
1829 && FindProcShort (glBlendEquationSeparatei)
1830 && FindProcShort (glBlendFunci)
1831 && FindProcShort (glBlendFuncSeparatei)
1832 && FindProcShort (glColorMaski)
1833 && FindProcShort (glIsEnabledi)
1834 && FindProcShort (glDrawElementsBaseVertex)
1835 && FindProcShort (glDrawRangeElementsBaseVertex)
1836 && FindProcShort (glDrawElementsInstancedBaseVertex)
1837 && FindProcShort (glFramebufferTexture)
1838 && FindProcShort (glPrimitiveBoundingBox)
1839 && FindProcShort (glGetGraphicsResetStatus)
1840 && FindProcShort (glReadnPixels)
1841 && FindProcShort (glGetnUniformfv)
1842 && FindProcShort (glGetnUniformiv)
1843 && FindProcShort (glGetnUniformuiv)
1844 && FindProcShort (glMinSampleShading)
1845 && FindProcShort (glPatchParameteri)
1846 && FindProcShort (glTexParameterIiv)
1847 && FindProcShort (glTexParameterIuiv)
1848 && FindProcShort (glGetTexParameterIiv)
1849 && FindProcShort (glGetTexParameterIuiv)
1850 && FindProcShort (glSamplerParameterIiv)
1851 && FindProcShort (glSamplerParameterIuiv)
1852 && FindProcShort (glGetSamplerParameterIiv)
1853 && FindProcShort (glGetSamplerParameterIuiv)
1854 && FindProcShort (glTexBufferRange)
1855 && FindProcShort (glTexStorage3DMultisample);
1856 if (!has32es)
1857 {
1858 checkWrongVersion (3, 2, aLastFailedProc);
1859 }
1860
a1073ae2 1861 extDrawBuffers = CheckExtension ("GL_EXT_draw_buffers") && FindProc ("glDrawBuffersEXT", myFuncs->glDrawBuffers);
1862 arbDrawBuffers = CheckExtension ("GL_ARB_draw_buffers") && FindProc ("glDrawBuffersARB", myFuncs->glDrawBuffers);
1863
0ae9ac21 1864 if (IsGlGreaterEqual (3, 0) && FindProcShort (glDrawBuffers))
a1073ae2 1865 {
1866 hasDrawBuffers = OpenGl_FeatureInCore;
1867 }
1868 else if (extDrawBuffers || arbDrawBuffers)
1869 {
1870 hasDrawBuffers = OpenGl_FeatureInExtensions;
1871 }
1872
1873 hasFloatBuffer = IsGlGreaterEqual (3, 2) ? OpenGl_FeatureInCore :
1874 CheckExtension ("GL_EXT_color_buffer_float") ? OpenGl_FeatureInExtensions
1875 : OpenGl_FeatureNotAvailable;
1876 hasHalfFloatBuffer = IsGlGreaterEqual (3, 2) ? OpenGl_FeatureInCore :
1877 CheckExtension ("GL_EXT_color_buffer_half_float") ? OpenGl_FeatureInExtensions
1878 : OpenGl_FeatureNotAvailable;
1879
1880 oesSampleVariables = CheckExtension ("GL_OES_sample_variables");
8c3237d4 1881 oesStdDerivatives = CheckExtension ("GL_OES_standard_derivatives");
a1073ae2 1882 hasSampleVariables = IsGlGreaterEqual (3, 2) ? OpenGl_FeatureInCore :
1883 oesSampleVariables ? OpenGl_FeatureInExtensions
1884 : OpenGl_FeatureNotAvailable;
59515ca6 1885 hasGlslBitwiseOps = IsGlGreaterEqual (3, 0)
1886 ? OpenGl_FeatureInCore
1887 : OpenGl_FeatureNotAvailable;
c39bb31b 1888 // without hasHighp, dFdx/dFdy precision is considered too low for flat shading (visual artifacts)
1889 hasFlatShading = IsGlGreaterEqual (3, 0)
1890 ? OpenGl_FeatureInCore
1891 : (oesStdDerivatives && hasHighp
1892 ? OpenGl_FeatureInExtensions
1893 : OpenGl_FeatureNotAvailable);
1894 if (!IsGlGreaterEqual (3, 1)
6997ff1c 1895 && myVendor.Search("qualcomm") != -1)
c39bb31b 1896 {
1897 // dFdx/dFdy are completely broken on tested Adreno devices with versions below OpenGl ES 3.1
1898 hasFlatShading = OpenGl_FeatureNotAvailable;
1899 }
2a332745 1900
1901 hasGeometryStage = IsGlGreaterEqual (3, 2)
1902 ? OpenGl_FeatureInCore
1903 : (CheckExtension ("GL_EXT_geometry_shader") && CheckExtension ("GL_EXT_shader_io_blocks")
1904 ? OpenGl_FeatureInExtensions
1905 : OpenGl_FeatureNotAvailable);
ca3c13d1 1906#else
1907
1908 myTexClamp = IsGlGreaterEqual (1, 2) ? GL_CLAMP_TO_EDGE : GL_CLAMP;
1909
1910 hasTexRGBA8 = Standard_True;
faff3767 1911 hasTexSRGB = IsGlGreaterEqual (2, 1);
ba00aab7 1912 hasFboSRGB = IsGlGreaterEqual (2, 1);
1913 hasSRGBControl = hasFboSRGB;
a1073ae2 1914 arbDrawBuffers = CheckExtension ("GL_ARB_draw_buffers");
1915 arbNPTW = CheckExtension ("GL_ARB_texture_non_power_of_two");
1916 arbTexFloat = IsGlGreaterEqual (3, 0)
1917 || CheckExtension ("GL_ARB_texture_float");
67312b79 1918 hasTexFloatLinear = arbTexFloat;
a1073ae2 1919 arbSampleShading = CheckExtension ("GL_ARB_sample_shading");
4b52faa5 1920 arbDepthClamp = IsGlGreaterEqual (3, 2)
1921 || CheckExtension ("GL_ARB_depth_clamp")
1922 || CheckExtension ("NV_depth_clamp");
faff3767 1923 extBgra = IsGlGreaterEqual (1, 2)
1924 || CheckExtension ("GL_EXT_bgra");
a1073ae2 1925 extAnis = CheckExtension ("GL_EXT_texture_filter_anisotropic");
1926 extPDS = CheckExtension ("GL_EXT_packed_depth_stencil");
1927 atiMem = CheckExtension ("GL_ATI_meminfo");
1928 nvxMem = CheckExtension ("GL_NVX_gpu_memory_info");
1929
faff3767 1930 if (extBgra)
1931 {
f4e7c307 1932 mySupportedFormats->Add (Image_Format_BGR);
1933 mySupportedFormats->Add (Image_Format_BGR32);
1934 mySupportedFormats->Add (Image_Format_BGRA);
faff3767 1935 }
1936
a1073ae2 1937 hasDrawBuffers = IsGlGreaterEqual (2, 0) ? OpenGl_FeatureInCore :
1938 arbDrawBuffers ? OpenGl_FeatureInExtensions
1939 : OpenGl_FeatureNotAvailable;
1940
59515ca6 1941 hasGlslBitwiseOps = IsGlGreaterEqual (3, 0)
1942 ? OpenGl_FeatureInCore
1943 : CheckExtension ("GL_EXT_gpu_shader4")
1944 ? OpenGl_FeatureInExtensions
1945 : OpenGl_FeatureNotAvailable;
1946
a1073ae2 1947 hasFloatBuffer = hasHalfFloatBuffer = IsGlGreaterEqual (3, 0) ? OpenGl_FeatureInCore :
1948 CheckExtension ("GL_ARB_color_buffer_float") ? OpenGl_FeatureInExtensions
1949 : OpenGl_FeatureNotAvailable;
1950
2a332745 1951 hasGeometryStage = IsGlGreaterEqual (3, 2)
1952 ? OpenGl_FeatureInCore
1953 : OpenGl_FeatureNotAvailable;
1954
a1073ae2 1955 hasSampleVariables = IsGlGreaterEqual (4, 0) ? OpenGl_FeatureInCore :
1956 arbSampleShading ? OpenGl_FeatureInExtensions
1957 : OpenGl_FeatureNotAvailable;
bf75be98 1958
ca3c13d1 1959 GLint aStereo = GL_FALSE;
b5ac8292 1960 glGetIntegerv (GL_STEREO, &aStereo);
1961 myIsStereoBuffers = aStereo == 1;
1962
ca3c13d1 1963 // get number of maximum clipping planes
1964 glGetIntegerv (GL_MAX_CLIP_PLANES, &myMaxClipPlanes);
1965#endif
1966
a1073ae2 1967 if (hasDrawBuffers)
1968 {
1969 glGetIntegerv (GL_MAX_DRAW_BUFFERS, &myMaxDrawBuffers);
1970 glGetIntegerv (GL_MAX_COLOR_ATTACHMENTS, &myMaxColorAttachments);
c3487460 1971 if (myDrawBuffers.Length() < myMaxDrawBuffers)
1972 {
1973 myDrawBuffers.Resize (0, myMaxDrawBuffers - 1, false);
1974 }
a1073ae2 1975 }
1976
ca3c13d1 1977 glGetIntegerv (GL_MAX_TEXTURE_SIZE, &myMaxTexDim);
737e9a8d 1978#if !defined(GL_ES_VERSION_2_0)
5c225e8e 1979 if (IsGlGreaterEqual (1, 3) && core11 != NULL)
737e9a8d 1980 {
1981 // this is a maximum of texture units for FFP functionality,
5c225e8e 1982 // usually smaller than combined texture units available for GLSL
1983 glGetIntegerv (GL_MAX_TEXTURE_UNITS, &myMaxTexUnitsFFP);
1984 myMaxTexCombined = myMaxTexUnitsFFP;
737e9a8d 1985 }
1986#endif
5c225e8e 1987 if (IsGlGreaterEqual (2, 0))
1988 {
1989 glGetIntegerv (GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &myMaxTexCombined);
1990 }
737e9a8d 1991 mySpriteTexUnit = myMaxTexCombined >= 2
72f6dc61 1992 ? Graphic3d_TextureUnit_PointSprite
737e9a8d 1993 : Graphic3d_TextureUnit_0;
ca3c13d1 1994
6997ff1c 1995 GLint aMaxVPortSize[2] = {0, 0};
1996 glGetIntegerv (GL_MAX_VIEWPORT_DIMS, aMaxVPortSize);
1997 myMaxDumpSizeX = Min (aMaxVPortSize[0], myMaxTexDim);
1998 myMaxDumpSizeY = Min (aMaxVPortSize[1], myMaxTexDim);
1999 if (myVendor == "intel")
2000 {
2001 // Intel drivers have known bug with empty dump for images with width>=5462
2002 myMaxDumpSizeX = Min (myMaxDumpSizeX, 4096);
2003 }
2004
bf75be98 2005 if (extAnis)
2006 {
2007 glGetIntegerv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &myAnisoMax);
2008 }
f0430952 2009
25c35042 2010 myClippingState.Init();
4269bd1b 2011
ca3c13d1 2012#if !defined(GL_ES_VERSION_2_0)
2013
01ca42b2 2014 bool has12 = false;
2015 bool has13 = false;
2016 bool has14 = false;
2017 bool has15 = false;
2018 bool has20 = false;
2019 bool has21 = false;
2020 bool has30 = false;
2021 bool has31 = false;
2022 bool has32 = false;
2023 bool has33 = false;
2024 bool has40 = false;
2025 bool has41 = false;
2026 bool has42 = false;
2027 bool has43 = false;
2028 bool has44 = false;
9491df8c 2029 bool has45 = false;
01ca42b2 2030
4e1523ef 2031 // retrieve platform-dependent extensions
f978241f 2032#if defined(HAVE_EGL)
2033 //
2034#elif defined(_WIN32)
01ca42b2 2035 if (FindProcShort (wglGetExtensionsStringARB))
2036 {
2037 const char* aWglExts = myFuncs->wglGetExtensionsStringARB (wglGetCurrentDC());
2038 if (CheckExtension (aWglExts, "WGL_EXT_swap_control"))
2039 {
2040 FindProcShort (wglSwapIntervalEXT);
2041 }
2042 if (CheckExtension (aWglExts, "WGL_ARB_pixel_format"))
2043 {
2044 FindProcShort (wglChoosePixelFormatARB);
2045 }
2046 if (CheckExtension (aWglExts, "WGL_ARB_create_context_profile"))
2047 {
2048 FindProcShort (wglCreateContextAttribsARB);
2049 }
2050 if (CheckExtension (aWglExts, "WGL_NV_DX_interop"))
2051 {
2052 FindProcShort (wglDXSetResourceShareHandleNV);
2053 FindProcShort (wglDXOpenDeviceNV);
2054 FindProcShort (wglDXCloseDeviceNV);
2055 FindProcShort (wglDXRegisterObjectNV);
2056 FindProcShort (wglDXUnregisterObjectNV);
2057 FindProcShort (wglDXObjectAccessNV);
2058 FindProcShort (wglDXLockObjectsNV);
2059 FindProcShort (wglDXUnlockObjectsNV);
2060 }
2eacd0b8 2061 if (CheckExtension (aWglExts, "WGL_AMD_gpu_association"))
2062 {
2063 FindProcShort (wglGetGPUIDsAMD);
2064 FindProcShort (wglGetGPUInfoAMD);
2065 FindProcShort (wglGetContextGPUIDAMD);
2066 }
01ca42b2 2067 }
f978241f 2068#elif defined(__APPLE__)
2069 //
2070#else
2071 const char* aGlxExts = ::glXQueryExtensionsString ((Display* )myDisplay, DefaultScreen ((Display* )myDisplay));
2072 if (CheckExtension (aGlxExts, "GLX_EXT_swap_control"))
2073 {
2074 FindProcShort (glXSwapIntervalEXT);
2075 }
2076 if (CheckExtension (aGlxExts, "GLX_SGI_swap_control"))
2077 {
2078 FindProcShort (glXSwapIntervalSGI);
2079 }
26d9c835 2080 if (CheckExtension (aGlxExts, "GLX_MESA_query_renderer"))
2081 {
2082 FindProcShort (glXQueryRendererIntegerMESA);
2083 FindProcShort (glXQueryCurrentRendererIntegerMESA);
2084 FindProcShort (glXQueryRendererStringMESA);
2085 FindProcShort (glXQueryCurrentRendererStringMESA);
2086 }
f978241f 2087 //extSwapTear = CheckExtension (aGlxExts, "GLX_EXT_swap_control_tear");
01ca42b2 2088#endif
2089
01ca42b2 2090 // load OpenGL 1.2 new functions
2091 has12 = IsGlGreaterEqual (1, 2)
2092 && FindProcShort (glBlendColor)
2093 && FindProcShort (glBlendEquation)
2094 && FindProcShort (glDrawRangeElements)
2095 && FindProcShort (glTexImage3D)
2096 && FindProcShort (glTexSubImage3D)
2097 && FindProcShort (glCopyTexSubImage3D);
0ae9ac21 2098 if (!has12)
2099 {
2100 checkWrongVersion (1, 2, aLastFailedProc);
2101 }
01ca42b2 2102
2103 // load OpenGL 1.3 new functions
2104 has13 = IsGlGreaterEqual (1, 3)
2105 && FindProcShort (glActiveTexture)
2106 && FindProcShort (glSampleCoverage)
2107 && FindProcShort (glCompressedTexImage3D)
2108 && FindProcShort (glCompressedTexImage2D)
2109 && FindProcShort (glCompressedTexImage1D)
2110 && FindProcShort (glCompressedTexSubImage3D)
2111 && FindProcShort (glCompressedTexSubImage2D)
2112 && FindProcShort (glCompressedTexSubImage1D)
4e1523ef 2113 && FindProcShort (glGetCompressedTexImage);
2114
2115 if (!isCoreProfile)
2116 {
2117 has13 = has13
01ca42b2 2118 && FindProcShort (glClientActiveTexture)
2119 && FindProcShort (glMultiTexCoord1d)
2120 && FindProcShort (glMultiTexCoord1dv)
2121 && FindProcShort (glMultiTexCoord1f)
2122 && FindProcShort (glMultiTexCoord1fv)
2123 && FindProcShort (glMultiTexCoord1i)
2124 && FindProcShort (glMultiTexCoord1iv)
2125 && FindProcShort (glMultiTexCoord1s)
2126 && FindProcShort (glMultiTexCoord1sv)
2127 && FindProcShort (glMultiTexCoord2d)
2128 && FindProcShort (glMultiTexCoord2dv)
2129 && FindProcShort (glMultiTexCoord2f)
2130 && FindProcShort (glMultiTexCoord2fv)
2131 && FindProcShort (glMultiTexCoord2i)
2132 && FindProcShort (glMultiTexCoord2iv)
2133 && FindProcShort (glMultiTexCoord2s)
2134 && FindProcShort (glMultiTexCoord2sv)
2135 && FindProcShort (glMultiTexCoord3d)
2136 && FindProcShort (glMultiTexCoord3dv)
2137 && FindProcShort (glMultiTexCoord3f)
2138 && FindProcShort (glMultiTexCoord3fv)
2139 && FindProcShort (glMultiTexCoord3i)
2140 && FindProcShort (glMultiTexCoord3iv)
2141 && FindProcShort (glMultiTexCoord3s)
2142 && FindProcShort (glMultiTexCoord3sv)
2143 && FindProcShort (glMultiTexCoord4d)
2144 && FindProcShort (glMultiTexCoord4dv)
2145 && FindProcShort (glMultiTexCoord4f)
2146 && FindProcShort (glMultiTexCoord4fv)
2147 && FindProcShort (glMultiTexCoord4i)
2148 && FindProcShort (glMultiTexCoord4iv)
2149 && FindProcShort (glMultiTexCoord4s)
2150 && FindProcShort (glMultiTexCoord4sv)
2151 && FindProcShort (glLoadTransposeMatrixf)
2152 && FindProcShort (glLoadTransposeMatrixd)
2153 && FindProcShort (glMultTransposeMatrixf)
2154 && FindProcShort (glMultTransposeMatrixd);
4e1523ef 2155 }
0ae9ac21 2156 if (!has13)
2157 {
2158 checkWrongVersion (1, 3, aLastFailedProc);
2159 }
01ca42b2 2160
2161 // load OpenGL 1.4 new functions
2162 has14 = IsGlGreaterEqual (1, 4)
2163 && FindProcShort (glBlendFuncSeparate)
2164 && FindProcShort (glMultiDrawArrays)
2165 && FindProcShort (glMultiDrawElements)
2166 && FindProcShort (glPointParameterf)
2167 && FindProcShort (glPointParameterfv)
2168 && FindProcShort (glPointParameteri)
2169 && FindProcShort (glPointParameteriv);
0ae9ac21 2170 if (!has14)
2171 {
2172 checkWrongVersion (1, 4, aLastFailedProc);
2173 }
01ca42b2 2174
2175 // load OpenGL 1.5 new functions
2176 has15 = IsGlGreaterEqual (1, 5)
2177 && FindProcShort (glGenQueries)
2178 && FindProcShort (glDeleteQueries)
2179 && FindProcShort (glIsQuery)
2180 && FindProcShort (glBeginQuery)
2181 && FindProcShort (glEndQuery)
2182 && FindProcShort (glGetQueryiv)
2183 && FindProcShort (glGetQueryObjectiv)
2184 && FindProcShort (glGetQueryObjectuiv)
2185 && FindProcShort (glBindBuffer)
2186 && FindProcShort (glDeleteBuffers)
2187 && FindProcShort (glGenBuffers)
2188 && FindProcShort (glIsBuffer)
2189 && FindProcShort (glBufferData)
2190 && FindProcShort (glBufferSubData)
2191 && FindProcShort (glGetBufferSubData)
2192 && FindProcShort (glMapBuffer)
2193 && FindProcShort (glUnmapBuffer)
2194 && FindProcShort (glGetBufferParameteriv)
2195 && FindProcShort (glGetBufferPointerv);
0ae9ac21 2196 if (has15)
2197 {
2198 if (!isCoreProfile)
2199 {
2200 core15 = (OpenGl_GlCore15* )(&(*myFuncs));
2201 }
2202 core15fwd = (OpenGl_GlCore15Fwd* )(&(*myFuncs));
d4cefcc0 2203 hasGetBufferData = true;
0ae9ac21 2204 }
2205 else
2206 {
2207 checkWrongVersion (1, 5, aLastFailedProc);
2208 }
01ca42b2 2209
2210 // load OpenGL 2.0 new functions
2211 has20 = IsGlGreaterEqual (2, 0)
2212 && FindProcShort (glBlendEquationSeparate)
2213 && FindProcShort (glDrawBuffers)
2214 && FindProcShort (glStencilOpSeparate)
2215 && FindProcShort (glStencilFuncSeparate)
2216 && FindProcShort (glStencilMaskSeparate)
2217 && FindProcShort (glAttachShader)
2218 && FindProcShort (glBindAttribLocation)
2219 && FindProcShort (glCompileShader)
2220 && FindProcShort (glCreateProgram)
2221 && FindProcShort (glCreateShader)
2222 && FindProcShort (glDeleteProgram)
2223 && FindProcShort (glDeleteShader)
2224 && FindProcShort (glDetachShader)
2225 && FindProcShort (glDisableVertexAttribArray)
2226 && FindProcShort (glEnableVertexAttribArray)
2227 && FindProcShort (glGetActiveAttrib)
2228 && FindProcShort (glGetActiveUniform)
2229 && FindProcShort (glGetAttachedShaders)
2230 && FindProcShort (glGetAttribLocation)
2231 && FindProcShort (glGetProgramiv)
2232 && FindProcShort (glGetProgramInfoLog)
2233 && FindProcShort (glGetShaderiv)
2234 && FindProcShort (glGetShaderInfoLog)
2235 && FindProcShort (glGetShaderSource)
2236 && FindProcShort (glGetUniformLocation)
2237 && FindProcShort (glGetUniformfv)
2238 && FindProcShort (glGetUniformiv)
2239 && FindProcShort (glGetVertexAttribdv)
2240 && FindProcShort (glGetVertexAttribfv)
2241 && FindProcShort (glGetVertexAttribiv)
2242 && FindProcShort (glGetVertexAttribPointerv)
2243 && FindProcShort (glIsProgram)
2244 && FindProcShort (glIsShader)
2245 && FindProcShort (glLinkProgram)
2246 && FindProcShort (glShaderSource)
2247 && FindProcShort (glUseProgram)
2248 && FindProcShort (glUniform1f)
2249 && FindProcShort (glUniform2f)
2250 && FindProcShort (glUniform3f)
2251 && FindProcShort (glUniform4f)
2252 && FindProcShort (glUniform1i)
2253 && FindProcShort (glUniform2i)
2254 && FindProcShort (glUniform3i)
2255 && FindProcShort (glUniform4i)
2256 && FindProcShort (glUniform1fv)
2257 && FindProcShort (glUniform2fv)
2258 && FindProcShort (glUniform3fv)
2259 && FindProcShort (glUniform4fv)
2260 && FindProcShort (glUniform1iv)
2261 && FindProcShort (glUniform2iv)
2262 && FindProcShort (glUniform3iv)
2263 && FindProcShort (glUniform4iv)
2264 && FindProcShort (glUniformMatrix2fv)
2265 && FindProcShort (glUniformMatrix3fv)
2266 && FindProcShort (glUniformMatrix4fv)
2267 && FindProcShort (glValidateProgram)
2268 && FindProcShort (glVertexAttrib1d)
2269 && FindProcShort (glVertexAttrib1dv)
2270 && FindProcShort (glVertexAttrib1f)
2271 && FindProcShort (glVertexAttrib1fv)
2272 && FindProcShort (glVertexAttrib1s)
2273 && FindProcShort (glVertexAttrib1sv)
2274 && FindProcShort (glVertexAttrib2d)
2275 && FindProcShort (glVertexAttrib2dv)
2276 && FindProcShort (glVertexAttrib2f)
2277 && FindProcShort (glVertexAttrib2fv)
2278 && FindProcShort (glVertexAttrib2s)
2279 && FindProcShort (glVertexAttrib2sv)
2280 && FindProcShort (glVertexAttrib3d)
2281 && FindProcShort (glVertexAttrib3dv)
2282 && FindProcShort (glVertexAttrib3f)
2283 && FindProcShort (glVertexAttrib3fv)
2284 && FindProcShort (glVertexAttrib3s)
2285 && FindProcShort (glVertexAttrib3sv)
2286 && FindProcShort (glVertexAttrib4Nbv)
2287 && FindProcShort (glVertexAttrib4Niv)
2288 && FindProcShort (glVertexAttrib4Nsv)
2289 && FindProcShort (glVertexAttrib4Nub)
2290 && FindProcShort (glVertexAttrib4Nubv)
2291 && FindProcShort (glVertexAttrib4Nuiv)
2292 && FindProcShort (glVertexAttrib4Nusv)
2293 && FindProcShort (glVertexAttrib4bv)
2294 && FindProcShort (glVertexAttrib4d)
2295 && FindProcShort (glVertexAttrib4dv)
2296 && FindProcShort (glVertexAttrib4f)
2297 && FindProcShort (glVertexAttrib4fv)
2298 && FindProcShort (glVertexAttrib4iv)
2299 && FindProcShort (glVertexAttrib4s)
2300 && FindProcShort (glVertexAttrib4sv)
2301 && FindProcShort (glVertexAttrib4ubv)
2302 && FindProcShort (glVertexAttrib4uiv)
2303 && FindProcShort (glVertexAttrib4usv)
2304 && FindProcShort (glVertexAttribPointer);
0ae9ac21 2305 if (has20)
2306 {
2307 const char* aGlslVer = (const char* )::glGetString (GL_SHADING_LANGUAGE_VERSION);
2308 if (aGlslVer == NULL
2309 || *aGlslVer == '\0')
2310 {
2311 // broken context has been detected
2312 PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
2313 TCollection_AsciiString("Error! OpenGL context reports version ")
2314 + myGlVerMajor + "." + myGlVerMinor + " but reports wrong GLSL version");
2315 myGlVerMajor = 1;
2316 myGlVerMinor = 5;
2317 }
2318 else
2319 {
2320 if (!isCoreProfile)
2321 {
2322 core20 = (OpenGl_GlCore20* )(&(*myFuncs));
2323 }
2324 core20fwd = (OpenGl_GlCore20Fwd* )(&(*myFuncs));
2325 }
2326 }
2327 else
2328 {
2329 checkWrongVersion (2, 0, aLastFailedProc);
2330 }
01ca42b2 2331
2332 // load OpenGL 2.1 new functions
2333 has21 = IsGlGreaterEqual (2, 1)
2334 && FindProcShort (glUniformMatrix2x3fv)
2335 && FindProcShort (glUniformMatrix3x2fv)
2336 && FindProcShort (glUniformMatrix2x4fv)
2337 && FindProcShort (glUniformMatrix4x2fv)
2338 && FindProcShort (glUniformMatrix3x4fv)
2339 && FindProcShort (glUniformMatrix4x3fv);
0ae9ac21 2340 if (!has21)
2341 {
2342 checkWrongVersion (2, 1, aLastFailedProc);
2343 }
01ca42b2 2344
2345 // load GL_ARB_framebuffer_object (added to OpenGL 3.0 core)
2346 const bool hasFBO = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_framebuffer_object"))
2347 && FindProcShort (glIsRenderbuffer)
2348 && FindProcShort (glBindRenderbuffer)
2349 && FindProcShort (glDeleteRenderbuffers)
2350 && FindProcShort (glGenRenderbuffers)
2351 && FindProcShort (glRenderbufferStorage)
2352 && FindProcShort (glGetRenderbufferParameteriv)
2353 && FindProcShort (glIsFramebuffer)
2354 && FindProcShort (glBindFramebuffer)
2355 && FindProcShort (glDeleteFramebuffers)
2356 && FindProcShort (glGenFramebuffers)
2357 && FindProcShort (glCheckFramebufferStatus)
2358 && FindProcShort (glFramebufferTexture1D)
2359 && FindProcShort (glFramebufferTexture2D)
2360 && FindProcShort (glFramebufferTexture3D)
2361 && FindProcShort (glFramebufferRenderbuffer)
2362 && FindProcShort (glGetFramebufferAttachmentParameteriv)
2363 && FindProcShort (glGenerateMipmap)
2364 && FindProcShort (glBlitFramebuffer)
2365 && FindProcShort (glRenderbufferStorageMultisample)
2366 && FindProcShort (glFramebufferTextureLayer);
2367
2368 // load GL_ARB_vertex_array_object (added to OpenGL 3.0 core)
2369 const bool hasVAO = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_vertex_array_object"))
2370 && FindProcShort (glBindVertexArray)
2371 && FindProcShort (glDeleteVertexArrays)
2372 && FindProcShort (glGenVertexArrays)
2373 && FindProcShort (glIsVertexArray);
2374
2375 // load GL_ARB_map_buffer_range (added to OpenGL 3.0 core)
2376 const bool hasMapBufferRange = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_map_buffer_range"))
2377 && FindProcShort (glMapBufferRange)
2378 && FindProcShort (glFlushMappedBufferRange);
2379
2380 // load OpenGL 3.0 new functions
2381 has30 = IsGlGreaterEqual (3, 0)
2382 && hasFBO
2383 && hasVAO
2384 && hasMapBufferRange
2385 && FindProcShort (glColorMaski)
2386 && FindProcShort (glGetBooleani_v)
2387 && FindProcShort (glGetIntegeri_v)
2388 && FindProcShort (glEnablei)
2389 && FindProcShort (glDisablei)
2390 && FindProcShort (glIsEnabledi)
2391 && FindProcShort (glBeginTransformFeedback)
2392 && FindProcShort (glEndTransformFeedback)
2393 && FindProcShort (glBindBufferRange)
2394 && FindProcShort (glBindBufferBase)
2395 && FindProcShort (glTransformFeedbackVaryings)
2396 && FindProcShort (glGetTransformFeedbackVarying)
2397 && FindProcShort (glClampColor)
2398 && FindProcShort (glBeginConditionalRender)
2399 && FindProcShort (glEndConditionalRender)
2400 && FindProcShort (glVertexAttribIPointer)
2401 && FindProcShort (glGetVertexAttribIiv)
2402 && FindProcShort (glGetVertexAttribIuiv)
2403 && FindProcShort (glVertexAttribI1i)
2404 && FindProcShort (glVertexAttribI2i)
2405 && FindProcShort (glVertexAttribI3i)
2406 && FindProcShort (glVertexAttribI4i)
2407 && FindProcShort (glVertexAttribI1ui)
2408 && FindProcShort (glVertexAttribI2ui)
2409 && FindProcShort (glVertexAttribI3ui)
2410 && FindProcShort (glVertexAttribI4ui)
2411 && FindProcShort (glVertexAttribI1iv)
2412 && FindProcShort (glVertexAttribI2iv)
2413 && FindProcShort (glVertexAttribI3iv)
2414 && FindProcShort (glVertexAttribI4iv)
2415 && FindProcShort (glVertexAttribI1uiv)
2416 && FindProcShort (glVertexAttribI2uiv)
2417 && FindProcShort (glVertexAttribI3uiv)
2418 && FindProcShort (glVertexAttribI4uiv)
2419 && FindProcShort (glVertexAttribI4bv)
2420 && FindProcShort (glVertexAttribI4sv)
2421 && FindProcShort (glVertexAttribI4ubv)
2422 && FindProcShort (glVertexAttribI4usv)
2423 && FindProcShort (glGetUniformuiv)
2424 && FindProcShort (glBindFragDataLocation)
2425 && FindProcShort (glGetFragDataLocation)
2426 && FindProcShort (glUniform1ui)
2427 && FindProcShort (glUniform2ui)
2428 && FindProcShort (glUniform3ui)
2429 && FindProcShort (glUniform4ui)
2430 && FindProcShort (glUniform1uiv)
2431 && FindProcShort (glUniform2uiv)
2432 && FindProcShort (glUniform3uiv)
2433 && FindProcShort (glUniform4uiv)
2434 && FindProcShort (glTexParameterIiv)
2435 && FindProcShort (glTexParameterIuiv)
2436 && FindProcShort (glGetTexParameterIiv)
2437 && FindProcShort (glGetTexParameterIuiv)
2438 && FindProcShort (glClearBufferiv)
2439 && FindProcShort (glClearBufferuiv)
2440 && FindProcShort (glClearBufferfv)
2441 && FindProcShort (glClearBufferfi)
2442 && FindProcShort (glGetStringi);
0ae9ac21 2443 if (!has30)
2444 {
2445 checkWrongVersion (3, 0, aLastFailedProc);
2446 }
01ca42b2 2447
2448 // load GL_ARB_uniform_buffer_object (added to OpenGL 3.1 core)
2449 const bool hasUBO = (IsGlGreaterEqual (3, 1) || CheckExtension ("GL_ARB_uniform_buffer_object"))
2450 && FindProcShort (glGetUniformIndices)
2451 && FindProcShort (glGetActiveUniformsiv)
2452 && FindProcShort (glGetActiveUniformName)
2453 && FindProcShort (glGetUniformBlockIndex)
2454 && FindProcShort (glGetActiveUniformBlockiv)
2455 && FindProcShort (glGetActiveUniformBlockName)
2456 && FindProcShort (glUniformBlockBinding);
2457
2458 // load GL_ARB_copy_buffer (added to OpenGL 3.1 core)
2459 const bool hasCopyBufSubData = (IsGlGreaterEqual (3, 1) || CheckExtension ("GL_ARB_copy_buffer"))
2460 && FindProcShort (glCopyBufferSubData);
2461
2462 if (has30)
2166f0fa 2463 {
01ca42b2 2464 // NPOT textures are required by OpenGL 2.0 specifications
2465 // but doesn't hardware accelerated by some ancient OpenGL 2.1 hardware (GeForce FX, RadeOn 9700 etc.)
2466 arbNPTW = Standard_True;
2467 arbTexRG = Standard_True;
872f98d9 2468
2469 if (!isCoreProfile)
2470 {
2471 core30 = (OpenGl_GlCore30* )(&(*myFuncs));
2472 }
2473 core30fwd = (OpenGl_GlCore30Fwd* )(&(*myFuncs));
2166f0fa
SK
2474 }
2475
01ca42b2 2476 // load OpenGL 3.1 new functions
2477 has31 = IsGlGreaterEqual (3, 1)
2478 && hasUBO
2479 && hasCopyBufSubData
2480 && FindProcShort (glDrawArraysInstanced)
2481 && FindProcShort (glDrawElementsInstanced)
2482 && FindProcShort (glTexBuffer)
2483 && FindProcShort (glPrimitiveRestartIndex);
0ae9ac21 2484 if (has31)
2485 {
2486 arbTBO = (OpenGl_ArbTBO* )(&(*myFuncs));
2487 arbIns = (OpenGl_ArbIns* )(&(*myFuncs));
2488 }
2489 else
2490 {
2491 checkWrongVersion (3, 1, aLastFailedProc);
2492
2493 // initialize TBO extension (ARB)
2494 if (CheckExtension ("GL_ARB_texture_buffer_object")
2495 && FindProc ("glTexBufferARB", myFuncs->glTexBuffer))
2496 {
2497 arbTBO = (OpenGl_ArbTBO* )(&(*myFuncs));
2498 }
2499
2500 // initialize hardware instancing extension (ARB)
2501 if (CheckExtension ("GL_ARB_draw_instanced")
2502 && FindProc ("glDrawArraysInstancedARB", myFuncs->glDrawArraysInstanced)
2503 && FindProc ("glDrawElementsInstancedARB", myFuncs->glDrawElementsInstanced))
2504 {
2505 arbIns = (OpenGl_ArbIns* )(&(*myFuncs));
2506 }
2507 }
2508
2509 arbTboRGB32 = CheckExtension ("GL_ARB_texture_buffer_object_rgb32");
01ca42b2 2510
2511 // load GL_ARB_draw_elements_base_vertex (added to OpenGL 3.2 core)
2512 const bool hasDrawElemsBaseVert = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_draw_elements_base_vertex"))
2513 && FindProcShort (glDrawElementsBaseVertex)
2514 && FindProcShort (glDrawRangeElementsBaseVertex)
2515 && FindProcShort (glDrawElementsInstancedBaseVertex)
2516 && FindProcShort (glMultiDrawElementsBaseVertex);
2517
2518 // load GL_ARB_provoking_vertex (added to OpenGL 3.2 core)
2519 const bool hasProvokingVert = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_provoking_vertex"))
2520 && FindProcShort (glProvokingVertex);
2521
2522 // load GL_ARB_sync (added to OpenGL 3.2 core)
2523 const bool hasSync = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_sync"))
2524 && FindProcShort (glFenceSync)
2525 && FindProcShort (glIsSync)
2526 && FindProcShort (glDeleteSync)
2527 && FindProcShort (glClientWaitSync)
2528 && FindProcShort (glWaitSync)
2529 && FindProcShort (glGetInteger64v)
2530 && FindProcShort (glGetSynciv);
2531
2532 // load GL_ARB_texture_multisample (added to OpenGL 3.2 core)
2533 const bool hasTextureMultisample = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_texture_multisample"))
2534 && FindProcShort (glTexImage2DMultisample)
2535 && FindProcShort (glTexImage3DMultisample)
2536 && FindProcShort (glGetMultisamplefv)
2537 && FindProcShort (glSampleMaski);
2538
2539 // load OpenGL 3.2 new functions
2540 has32 = IsGlGreaterEqual (3, 2)
2541 && hasDrawElemsBaseVert
2542 && hasProvokingVert
2543 && hasSync
2544 && hasTextureMultisample
2545 && FindProcShort (glGetInteger64i_v)
2546 && FindProcShort (glGetBufferParameteri64v)
2547 && FindProcShort (glFramebufferTexture);
0ae9ac21 2548 if (has32)
2549 {
2550 core32 = (OpenGl_GlCore32* )(&(*myFuncs));
2551 if (isCoreProfile)
2552 {
2553 core32->glGenVertexArrays (1, &myDefaultVao);
2554 }
2555 else
2556 {
2557 core32back = (OpenGl_GlCore32Back* )(&(*myFuncs));
2558 }
2559 ::glGetIntegerv (GL_MAX_SAMPLES, &myMaxMsaaSamples);
2560 }
2561 else
2562 {
2563 checkWrongVersion (3, 2, aLastFailedProc);
2564 }
01ca42b2 2565
2566 // load GL_ARB_blend_func_extended (added to OpenGL 3.3 core)
2567 const bool hasBlendFuncExtended = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_blend_func_extended"))
2568 && FindProcShort (glBindFragDataLocationIndexed)
2569 && FindProcShort (glGetFragDataIndex);
2570
2571 // load GL_ARB_sampler_objects (added to OpenGL 3.3 core)
2572 const bool hasSamplerObjects = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_sampler_objects"))
2573 && FindProcShort (glGenSamplers)
2574 && FindProcShort (glDeleteSamplers)
2575 && FindProcShort (glIsSampler)
2576 && FindProcShort (glBindSampler)
2577 && FindProcShort (glSamplerParameteri)
2578 && FindProcShort (glSamplerParameteriv)
2579 && FindProcShort (glSamplerParameterf)
2580 && FindProcShort (glSamplerParameterfv)
2581 && FindProcShort (glSamplerParameterIiv)
2582 && FindProcShort (glSamplerParameterIuiv)
2583 && FindProcShort (glGetSamplerParameteriv)
2584 && FindProcShort (glGetSamplerParameterIiv)
2585 && FindProcShort (glGetSamplerParameterfv)
2586 && FindProcShort (glGetSamplerParameterIuiv);
cc8cbabe 2587 if (hasSamplerObjects)
2588 {
2589 arbSamplerObject = (OpenGl_ArbSamplerObject* )(&(*myFuncs));
2590 }
01ca42b2 2591
2592 // load GL_ARB_timer_query (added to OpenGL 3.3 core)
2593 const bool hasTimerQuery = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_timer_query"))
2594 && FindProcShort (glQueryCounter)
2595 && FindProcShort (glGetQueryObjecti64v)
2596 && FindProcShort (glGetQueryObjectui64v);
2597
2598 // load GL_ARB_vertex_type_2_10_10_10_rev (added to OpenGL 3.3 core)
2599 const bool hasVertType21010101rev = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_vertex_type_2_10_10_10_rev"))
0e628baf 2600 && FindProcShort (glVertexAttribP1ui)
2601 && FindProcShort (glVertexAttribP1uiv)
2602 && FindProcShort (glVertexAttribP2ui)
2603 && FindProcShort (glVertexAttribP2uiv)
2604 && FindProcShort (glVertexAttribP3ui)
2605 && FindProcShort (glVertexAttribP3uiv)
2606 && FindProcShort (glVertexAttribP4ui)
2607 && FindProcShort (glVertexAttribP4uiv);
2608
2609 if ( hasVertType21010101rev
2610 && !isCoreProfile)
2611 {
2612 // load deprecated functions
2613 const bool hasVertType21010101revExt =
2614 FindProcShort (glVertexP2ui)
01ca42b2 2615 && FindProcShort (glVertexP2uiv)
2616 && FindProcShort (glVertexP3ui)
2617 && FindProcShort (glVertexP3uiv)
2618 && FindProcShort (glVertexP4ui)
2619 && FindProcShort (glVertexP4uiv)
2620 && FindProcShort (glTexCoordP1ui)
2621 && FindProcShort (glTexCoordP1uiv)
2622 && FindProcShort (glTexCoordP2ui)
2623 && FindProcShort (glTexCoordP2uiv)
2624 && FindProcShort (glTexCoordP3ui)
2625 && FindProcShort (glTexCoordP3uiv)
2626 && FindProcShort (glTexCoordP4ui)
2627 && FindProcShort (glTexCoordP4uiv)
2628 && FindProcShort (glMultiTexCoordP1ui)
2629 && FindProcShort (glMultiTexCoordP1uiv)
2630 && FindProcShort (glMultiTexCoordP2ui)
2631 && FindProcShort (glMultiTexCoordP2uiv)
2632 && FindProcShort (glMultiTexCoordP3ui)
2633 && FindProcShort (glMultiTexCoordP3uiv)
2634 && FindProcShort (glMultiTexCoordP4ui)
2635 && FindProcShort (glMultiTexCoordP4uiv)
2636 && FindProcShort (glNormalP3ui)
2637 && FindProcShort (glNormalP3uiv)
2638 && FindProcShort (glColorP3ui)
2639 && FindProcShort (glColorP3uiv)
2640 && FindProcShort (glColorP4ui)
2641 && FindProcShort (glColorP4uiv)
2642 && FindProcShort (glSecondaryColorP3ui)
0e628baf 2643 && FindProcShort (glSecondaryColorP3uiv);
2644 (void )hasVertType21010101revExt;
2645 }
01ca42b2 2646
2647 // load OpenGL 3.3 extra functions
2648 has33 = IsGlGreaterEqual (3, 3)
2649 && hasBlendFuncExtended
2650 && hasSamplerObjects
2651 && hasTimerQuery
2652 && hasVertType21010101rev
2653 && FindProcShort (glVertexAttribDivisor);
0ae9ac21 2654 if (has33)
2655 {
2656 core33 = (OpenGl_GlCore33* )(&(*myFuncs));
2657 if (!isCoreProfile)
2658 {
2659 core33back = (OpenGl_GlCore33Back* )(&(*myFuncs));
2660 }
2661 }
2662 else
2663 {
2664 checkWrongVersion (3, 3, aLastFailedProc);
2665 }
01ca42b2 2666
2667 // load GL_ARB_draw_indirect (added to OpenGL 4.0 core)
2668 const bool hasDrawIndirect = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_draw_indirect"))
2669 && FindProcShort (glDrawArraysIndirect)
2670 && FindProcShort (glDrawElementsIndirect);
2671
2672 // load GL_ARB_gpu_shader_fp64 (added to OpenGL 4.0 core)
2673 const bool hasShaderFP64 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_gpu_shader_fp64"))
2674 && FindProcShort (glUniform1d)
2675 && FindProcShort (glUniform2d)
2676 && FindProcShort (glUniform3d)
2677 && FindProcShort (glUniform4d)
2678 && FindProcShort (glUniform1dv)
2679 && FindProcShort (glUniform2dv)
2680 && FindProcShort (glUniform3dv)
2681 && FindProcShort (glUniform4dv)
2682 && FindProcShort (glUniformMatrix2dv)
2683 && FindProcShort (glUniformMatrix3dv)
2684 && FindProcShort (glUniformMatrix4dv)
2685 && FindProcShort (glUniformMatrix2x3dv)
2686 && FindProcShort (glUniformMatrix2x4dv)
2687 && FindProcShort (glUniformMatrix3x2dv)
2688 && FindProcShort (glUniformMatrix3x4dv)
2689 && FindProcShort (glUniformMatrix4x2dv)
2690 && FindProcShort (glUniformMatrix4x3dv)
2691 && FindProcShort (glGetUniformdv);
2692
2693 // load GL_ARB_shader_subroutine (added to OpenGL 4.0 core)
2694 const bool hasShaderSubroutine = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_shader_subroutine"))
2695 && FindProcShort (glGetSubroutineUniformLocation)
2696 && FindProcShort (glGetSubroutineIndex)
2697 && FindProcShort (glGetActiveSubroutineUniformiv)
2698 && FindProcShort (glGetActiveSubroutineUniformName)
2699 && FindProcShort (glGetActiveSubroutineName)
2700 && FindProcShort (glUniformSubroutinesuiv)
2701 && FindProcShort (glGetUniformSubroutineuiv)
2702 && FindProcShort (glGetProgramStageiv);
2703
2704 // load GL_ARB_tessellation_shader (added to OpenGL 4.0 core)
2705 const bool hasTessellationShader = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_tessellation_shader"))
2706 && FindProcShort (glPatchParameteri)
2707 && FindProcShort (glPatchParameterfv);
2708
2709 // load GL_ARB_transform_feedback2 (added to OpenGL 4.0 core)
2710 const bool hasTrsfFeedback2 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_transform_feedback2"))
2711 && FindProcShort (glBindTransformFeedback)
2712 && FindProcShort (glDeleteTransformFeedbacks)
2713 && FindProcShort (glGenTransformFeedbacks)
2714 && FindProcShort (glIsTransformFeedback)
2715 && FindProcShort (glPauseTransformFeedback)
2716 && FindProcShort (glResumeTransformFeedback)
2717 && FindProcShort (glDrawTransformFeedback);
2718
2719 // load GL_ARB_transform_feedback3 (added to OpenGL 4.0 core)
2720 const bool hasTrsfFeedback3 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_transform_feedback3"))
2721 && FindProcShort (glDrawTransformFeedbackStream)
2722 && FindProcShort (glBeginQueryIndexed)
2723 && FindProcShort (glEndQueryIndexed)
2724 && FindProcShort (glGetQueryIndexediv);
2725
2726 // load OpenGL 4.0 new functions
2727 has40 = IsGlGreaterEqual (4, 0)
2728 && hasDrawIndirect
2729 && hasShaderFP64
2730 && hasShaderSubroutine
2731 && hasTessellationShader
2732 && hasTrsfFeedback2
2733 && hasTrsfFeedback3
2734 && FindProcShort (glMinSampleShading)
2735 && FindProcShort (glBlendEquationi)
2736 && FindProcShort (glBlendEquationSeparatei)
2737 && FindProcShort (glBlendFunci)
2738 && FindProcShort (glBlendFuncSeparatei);
0ae9ac21 2739 if (has40)
2740 {
2741 arbTboRGB32 = Standard_True; // in core since OpenGL 4.0
2742 }
2743 else
2744 {
2745 checkWrongVersion (4, 0, aLastFailedProc);
2746 }
01ca42b2 2747
2748 // load GL_ARB_ES2_compatibility (added to OpenGL 4.1 core)
2749 const bool hasES2Compatibility = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_ES2_compatibility"))
2750 && FindProcShort (glReleaseShaderCompiler)
2751 && FindProcShort (glShaderBinary)
2752 && FindProcShort (glGetShaderPrecisionFormat)
2753 && FindProcShort (glDepthRangef)
2754 && FindProcShort (glClearDepthf);
2755
2756 // load GL_ARB_get_program_binary (added to OpenGL 4.1 core)
2757 const bool hasGetProgramBinary = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_get_program_binary"))
2758 && FindProcShort (glGetProgramBinary)
2759 && FindProcShort (glProgramBinary)
2760 && FindProcShort (glProgramParameteri);
2761
2762
2763 // load GL_ARB_separate_shader_objects (added to OpenGL 4.1 core)
2764 const bool hasSeparateShaderObjects = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_separate_shader_objects"))
2765 && FindProcShort (glUseProgramStages)
2766 && FindProcShort (glActiveShaderProgram)
2767 && FindProcShort (glCreateShaderProgramv)
2768 && FindProcShort (glBindProgramPipeline)
2769 && FindProcShort (glDeleteProgramPipelines)
2770 && FindProcShort (glGenProgramPipelines)
2771 && FindProcShort (glIsProgramPipeline)
2772 && FindProcShort (glGetProgramPipelineiv)
2773 && FindProcShort (glProgramUniform1i)
2774 && FindProcShort (glProgramUniform1iv)
2775 && FindProcShort (glProgramUniform1f)
2776 && FindProcShort (glProgramUniform1fv)
2777 && FindProcShort (glProgramUniform1d)
2778 && FindProcShort (glProgramUniform1dv)
2779 && FindProcShort (glProgramUniform1ui)
2780 && FindProcShort (glProgramUniform1uiv)
2781 && FindProcShort (glProgramUniform2i)
2782 && FindProcShort (glProgramUniform2iv)
2783 && FindProcShort (glProgramUniform2f)
2784 && FindProcShort (glProgramUniform2fv)
2785 && FindProcShort (glProgramUniform2d)
2786 && FindProcShort (glProgramUniform2dv)
2787 && FindProcShort (glProgramUniform2ui)
2788 && FindProcShort (glProgramUniform2uiv)
2789 && FindProcShort (glProgramUniform3i)
2790 && FindProcShort (glProgramUniform3iv)
2791 && FindProcShort (glProgramUniform3f)
2792 && FindProcShort (glProgramUniform3fv)
2793 && FindProcShort (glProgramUniform3d)
2794 && FindProcShort (glProgramUniform3dv)
2795 && FindProcShort (glProgramUniform3ui)
2796 && FindProcShort (glProgramUniform3uiv)
2797 && FindProcShort (glProgramUniform4i)
2798 && FindProcShort (glProgramUniform4iv)
2799 && FindProcShort (glProgramUniform4f)
2800 && FindProcShort (glProgramUniform4fv)
2801 && FindProcShort (glProgramUniform4d)
2802 && FindProcShort (glProgramUniform4dv)
2803 && FindProcShort (glProgramUniform4ui)
2804 && FindProcShort (glProgramUniform4uiv)
2805 && FindProcShort (glProgramUniformMatrix2fv)
2806 && FindProcShort (glProgramUniformMatrix3fv)
2807 && FindProcShort (glProgramUniformMatrix4fv)
2808 && FindProcShort (glProgramUniformMatrix2dv)
2809 && FindProcShort (glProgramUniformMatrix3dv)
2810 && FindProcShort (glProgramUniformMatrix4dv)
2811 && FindProcShort (glProgramUniformMatrix2x3fv)
2812 && FindProcShort (glProgramUniformMatrix3x2fv)
2813 && FindProcShort (glProgramUniformMatrix2x4fv)
2814 && FindProcShort (glProgramUniformMatrix4x2fv)
2815 && FindProcShort (glProgramUniformMatrix3x4fv)
2816 && FindProcShort (glProgramUniformMatrix4x3fv)
2817 && FindProcShort (glProgramUniformMatrix2x3dv)
2818 && FindProcShort (glProgramUniformMatrix3x2dv)
2819 && FindProcShort (glProgramUniformMatrix2x4dv)
2820 && FindProcShort (glProgramUniformMatrix4x2dv)
2821 && FindProcShort (glProgramUniformMatrix3x4dv)
2822 && FindProcShort (glProgramUniformMatrix4x3dv)
2823 && FindProcShort (glValidateProgramPipeline)
2824 && FindProcShort (glGetProgramPipelineInfoLog);
2825
2826 // load GL_ARB_vertex_attrib_64bit (added to OpenGL 4.1 core)
2827 const bool hasVertAttrib64bit = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_vertex_attrib_64bit"))
2828 && FindProcShort (glVertexAttribL1d)
2829 && FindProcShort (glVertexAttribL2d)
2830 && FindProcShort (glVertexAttribL3d)
2831 && FindProcShort (glVertexAttribL4d)
2832 && FindProcShort (glVertexAttribL1dv)
2833 && FindProcShort (glVertexAttribL2dv)
2834 && FindProcShort (glVertexAttribL3dv)
2835 && FindProcShort (glVertexAttribL4dv)
2836 && FindProcShort (glVertexAttribLPointer)
2837 && FindProcShort (glGetVertexAttribLdv);
2838
2839 // load GL_ARB_viewport_array (added to OpenGL 4.1 core)
2840 const bool hasViewportArray = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_viewport_array"))
2841 && FindProcShort (glViewportArrayv)
2842 && FindProcShort (glViewportIndexedf)
2843 && FindProcShort (glViewportIndexedfv)
2844 && FindProcShort (glScissorArrayv)
2845 && FindProcShort (glScissorIndexed)
2846 && FindProcShort (glScissorIndexedv)
2847 && FindProcShort (glDepthRangeArrayv)
2848 && FindProcShort (glDepthRangeIndexed)
2849 && FindProcShort (glGetFloati_v)
2850 && FindProcShort (glGetDoublei_v);
2851
2852 has41 = IsGlGreaterEqual (4, 1)
2853 && hasES2Compatibility
2854 && hasGetProgramBinary
2855 && hasSeparateShaderObjects
2856 && hasVertAttrib64bit
2857 && hasViewportArray;
0ae9ac21 2858 if (has41)
2859 {
2860 core41 = (OpenGl_GlCore41* )(&(*myFuncs));
2861 if (!isCoreProfile)
2862 {
2863 core41back = (OpenGl_GlCore41Back* )(&(*myFuncs));
2864 }
2865 }
2866 else
2867 {
2868 checkWrongVersion (4, 1, aLastFailedProc);
2869 }
01ca42b2 2870
2871 // load GL_ARB_base_instance (added to OpenGL 4.2 core)
2872 const bool hasBaseInstance = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_base_instance"))
2873 && FindProcShort (glDrawArraysInstancedBaseInstance)
2874 && FindProcShort (glDrawElementsInstancedBaseInstance)
2875 && FindProcShort (glDrawElementsInstancedBaseVertexBaseInstance);
2876
2877 // load GL_ARB_transform_feedback_instanced (added to OpenGL 4.2 core)
2878 const bool hasTrsfFeedbackInstanced = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_transform_feedback_instanced"))
2879 && FindProcShort (glDrawTransformFeedbackInstanced)
2880 && FindProcShort (glDrawTransformFeedbackStreamInstanced);
2881
2882 // load GL_ARB_internalformat_query (added to OpenGL 4.2 core)
2883 const bool hasInternalFormatQuery = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_internalformat_query"))
2884 && FindProcShort (glGetInternalformativ);
2885
2886 // load GL_ARB_shader_atomic_counters (added to OpenGL 4.2 core)
2887 const bool hasShaderAtomicCounters = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_shader_atomic_counters"))
2888 && FindProcShort (glGetActiveAtomicCounterBufferiv);
2889
2890 // load GL_ARB_shader_image_load_store (added to OpenGL 4.2 core)
2891 const bool hasShaderImgLoadStore = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_shader_image_load_store"))
2892 && FindProcShort (glBindImageTexture)
2893 && FindProcShort (glMemoryBarrier);
2894
2895 // load GL_ARB_texture_storage (added to OpenGL 4.2 core)
2896 const bool hasTextureStorage = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_texture_storage"))
2897 && FindProcShort (glTexStorage1D)
2898 && FindProcShort (glTexStorage2D)
c87535af 2899 && FindProcShort (glTexStorage3D);
01ca42b2 2900
2901 has42 = IsGlGreaterEqual (4, 2)
2902 && hasBaseInstance
2903 && hasTrsfFeedbackInstanced
2904 && hasInternalFormatQuery
2905 && hasShaderAtomicCounters
2906 && hasShaderImgLoadStore
2907 && hasTextureStorage;
0ae9ac21 2908 if (has42)
2909 {
2910 core42 = (OpenGl_GlCore42* )(&(*myFuncs));
2911 if (!isCoreProfile)
2912 {
2913 core42back = (OpenGl_GlCore42Back* )(&(*myFuncs));
2914 }
2915 }
2916 else
2917 {
2918 checkWrongVersion (4, 2, aLastFailedProc);
2919 }
01ca42b2 2920
2921 has43 = IsGlGreaterEqual (4, 3)
2922 && FindProcShort (glClearBufferData)
2923 && FindProcShort (glClearBufferSubData)
2924 && FindProcShort (glDispatchCompute)
2925 && FindProcShort (glDispatchComputeIndirect)
2926 && FindProcShort (glCopyImageSubData)
2927 && FindProcShort (glFramebufferParameteri)
2928 && FindProcShort (glGetFramebufferParameteriv)
2929 && FindProcShort (glGetInternalformati64v)
2930 && FindProcShort (glInvalidateTexSubImage)
2931 && FindProcShort (glInvalidateTexImage)
2932 && FindProcShort (glInvalidateBufferSubData)
2933 && FindProcShort (glInvalidateBufferData)
2934 && FindProcShort (glInvalidateFramebuffer)
2935 && FindProcShort (glInvalidateSubFramebuffer)
2936 && FindProcShort (glMultiDrawArraysIndirect)
2937 && FindProcShort (glMultiDrawElementsIndirect)
2938 && FindProcShort (glGetProgramInterfaceiv)
2939 && FindProcShort (glGetProgramResourceIndex)
2940 && FindProcShort (glGetProgramResourceName)
2941 && FindProcShort (glGetProgramResourceiv)
2942 && FindProcShort (glGetProgramResourceLocation)
2943 && FindProcShort (glGetProgramResourceLocationIndex)
2944 && FindProcShort (glShaderStorageBlockBinding)
2945 && FindProcShort (glTexBufferRange)
2946 && FindProcShort (glTexStorage2DMultisample)
2947 && FindProcShort (glTexStorage3DMultisample)
2948 && FindProcShort (glTextureView)
2949 && FindProcShort (glBindVertexBuffer)
2950 && FindProcShort (glVertexAttribFormat)
2951 && FindProcShort (glVertexAttribIFormat)
2952 && FindProcShort (glVertexAttribLFormat)
2953 && FindProcShort (glVertexAttribBinding)
2954 && FindProcShort (glVertexBindingDivisor)
2955 && FindProcShort (glDebugMessageControl)
2956 && FindProcShort (glDebugMessageInsert)
2957 && FindProcShort (glDebugMessageCallback)
2958 && FindProcShort (glGetDebugMessageLog)
2959 && FindProcShort (glPushDebugGroup)
2960 && FindProcShort (glPopDebugGroup)
2961 && FindProcShort (glObjectLabel)
2962 && FindProcShort (glGetObjectLabel)
2963 && FindProcShort (glObjectPtrLabel)
2964 && FindProcShort (glGetObjectPtrLabel);
0ae9ac21 2965 if (has43)
2966 {
2967 core43 = (OpenGl_GlCore43* )(&(*myFuncs));
2968 if (!isCoreProfile)
2969 {
2970 core43back = (OpenGl_GlCore43Back* )(&(*myFuncs));
2971 }
2972 }
2973 else
2974 {
2975 checkWrongVersion (4, 3, aLastFailedProc);
2976 }
01ca42b2 2977
2978 // load GL_ARB_clear_texture (added to OpenGL 4.4 core)
2979 bool arbTexClear = (IsGlGreaterEqual (4, 4) || CheckExtension ("GL_ARB_clear_texture"))
2980 && FindProcShort (glClearTexImage)
2981 && FindProcShort (glClearTexSubImage);
2982
2983 has44 = IsGlGreaterEqual (4, 4)
2984 && arbTexClear
2985 && FindProcShort (glBufferStorage)
2986 && FindProcShort (glBindBuffersBase)
2987 && FindProcShort (glBindBuffersRange)
2988 && FindProcShort (glBindTextures)
2989 && FindProcShort (glBindSamplers)
2990 && FindProcShort (glBindImageTextures)
2991 && FindProcShort (glBindVertexBuffers);
0ae9ac21 2992 if (has44)
2993 {
2994 core44 = (OpenGl_GlCore44* )(&(*myFuncs));
2995 if (!isCoreProfile)
2996 {
2997 core44back = (OpenGl_GlCore44Back* )(&(*myFuncs));
2998 }
2999 }
3000 else
3001 {
3002 checkWrongVersion (4, 4, aLastFailedProc);
3003 }
01ca42b2 3004
9491df8c 3005 has45 = IsGlGreaterEqual (4, 5)
3006 && FindProcShort (glBindVertexBuffers)
3007 && FindProcShort (glClipControl)
3008 && FindProcShort (glCreateTransformFeedbacks)
3009 && FindProcShort (glTransformFeedbackBufferBase)
3010 && FindProcShort (glTransformFeedbackBufferRange)
3011 && FindProcShort (glGetTransformFeedbackiv)
3012 && FindProcShort (glGetTransformFeedbacki_v)
3013 && FindProcShort (glGetTransformFeedbacki64_v)
3014 && FindProcShort (glCreateBuffers)
3015 && FindProcShort (glNamedBufferStorage)
3016 && FindProcShort (glNamedBufferData)
3017 && FindProcShort (glNamedBufferSubData)
3018 && FindProcShort (glCopyNamedBufferSubData)
3019 && FindProcShort (glClearNamedBufferData)
3020 && FindProcShort (glClearNamedBufferSubData)
3021 && FindProcShort (glMapNamedBuffer)
3022 && FindProcShort (glMapNamedBufferRange)
3023 && FindProcShort (glUnmapNamedBuffer)
3024 && FindProcShort (glFlushMappedNamedBufferRange)
3025 && FindProcShort (glGetNamedBufferParameteriv)
3026 && FindProcShort (glGetNamedBufferParameteri64v)
3027 && FindProcShort (glGetNamedBufferPointerv)
3028 && FindProcShort (glGetNamedBufferSubData)
3029 && FindProcShort (glCreateFramebuffers)
3030 && FindProcShort (glNamedFramebufferRenderbuffer)
3031 && FindProcShort (glNamedFramebufferParameteri)
3032 && FindProcShort (glNamedFramebufferTexture)
3033 && FindProcShort (glNamedFramebufferTextureLayer)
3034 && FindProcShort (glNamedFramebufferDrawBuffer)
3035 && FindProcShort (glNamedFramebufferDrawBuffers)
3036 && FindProcShort (glNamedFramebufferReadBuffer)
3037 && FindProcShort (glInvalidateNamedFramebufferData)
3038 && FindProcShort (glInvalidateNamedFramebufferSubData)
3039 && FindProcShort (glClearNamedFramebufferiv)
3040 && FindProcShort (glClearNamedFramebufferuiv)
3041 && FindProcShort (glClearNamedFramebufferfv)
3042 && FindProcShort (glClearNamedFramebufferfi)
3043 && FindProcShort (glBlitNamedFramebuffer)
3044 && FindProcShort (glCheckNamedFramebufferStatus)
3045 && FindProcShort (glGetNamedFramebufferParameteriv)
3046 && FindProcShort (glGetNamedFramebufferAttachmentParameteriv)
3047 && FindProcShort (glCreateRenderbuffers)
3048 && FindProcShort (glNamedRenderbufferStorage)
3049 && FindProcShort (glNamedRenderbufferStorageMultisample)
3050 && FindProcShort (glGetNamedRenderbufferParameteriv)
3051 && FindProcShort (glCreateTextures)
3052 && FindProcShort (glTextureBuffer)
3053 && FindProcShort (glTextureBufferRange)
3054 && FindProcShort (glTextureStorage1D)
3055 && FindProcShort (glTextureStorage2D)
3056 && FindProcShort (glTextureStorage3D)
3057 && FindProcShort (glTextureStorage2DMultisample)
3058 && FindProcShort (glTextureStorage3DMultisample)
3059 && FindProcShort (glTextureSubImage1D)
3060 && FindProcShort (glTextureSubImage2D)
3061 && FindProcShort (glTextureSubImage3D)
3062 && FindProcShort (glCompressedTextureSubImage1D)
3063 && FindProcShort (glCompressedTextureSubImage2D)
3064 && FindProcShort (glCompressedTextureSubImage3D)
3065 && FindProcShort (glCopyTextureSubImage1D)
3066 && FindProcShort (glCopyTextureSubImage2D)
3067 && FindProcShort (glCopyTextureSubImage3D)
3068 && FindProcShort (glTextureParameterf)
3069 && FindProcShort (glTextureParameterfv)
3070 && FindProcShort (glTextureParameteri)
3071 && FindProcShort (glTextureParameterIiv)
3072 && FindProcShort (glTextureParameterIuiv)
3073 && FindProcShort (glTextureParameteriv)
3074 && FindProcShort (glGenerateTextureMipmap)
3075 && FindProcShort (glBindTextureUnit)
3076 && FindProcShort (glGetTextureImage)
3077 && FindProcShort (glGetCompressedTextureImage)
3078 && FindProcShort (glGetTextureLevelParameterfv)
3079 && FindProcShort (glGetTextureLevelParameteriv)
3080 && FindProcShort (glGetTextureParameterfv)
3081 && FindProcShort (glGetTextureParameterIiv)
3082 && FindProcShort (glGetTextureParameterIuiv)
3083 && FindProcShort (glGetTextureParameteriv)
3084 && FindProcShort (glCreateVertexArrays)
3085 && FindProcShort (glDisableVertexArrayAttrib)
3086 && FindProcShort (glEnableVertexArrayAttrib)
3087 && FindProcShort (glVertexArrayElementBuffer)
3088 && FindProcShort (glVertexArrayVertexBuffer)
3089 && FindProcShort (glVertexArrayVertexBuffers)
3090 && FindProcShort (glVertexArrayAttribBinding)
3091 && FindProcShort (glVertexArrayAttribFormat)
3092 && FindProcShort (glVertexArrayAttribIFormat)
3093 && FindProcShort (glVertexArrayAttribLFormat)
3094 && FindProcShort (glVertexArrayBindingDivisor)
3095 && FindProcShort (glGetVertexArrayiv)
3096 && FindProcShort (glGetVertexArrayIndexediv)
3097 && FindProcShort (glGetVertexArrayIndexed64iv)
3098 && FindProcShort (glCreateSamplers)
3099 && FindProcShort (glCreateProgramPipelines)
3100 && FindProcShort (glCreateQueries)
3101 && FindProcShort (glGetQueryBufferObjecti64v)
3102 && FindProcShort (glGetQueryBufferObjectiv)
3103 && FindProcShort (glGetQueryBufferObjectui64v)
3104 && FindProcShort (glGetQueryBufferObjectuiv)
3105 && FindProcShort (glMemoryBarrierByRegion)
3106 && FindProcShort (glGetTextureSubImage)
3107 && FindProcShort (glGetCompressedTextureSubImage)
3108 && FindProcShort (glGetGraphicsResetStatus)
3109 && FindProcShort (glGetnCompressedTexImage)
3110 && FindProcShort (glGetnTexImage)
3111 && FindProcShort (glGetnUniformdv)
3112 && FindProcShort (glGetnUniformfv)
3113 && FindProcShort (glGetnUniformiv)
3114 && FindProcShort (glGetnUniformuiv)
3115 && FindProcShort (glReadnPixels)
3116 && FindProcShort (glGetnMapdv)
3117 && FindProcShort (glGetnMapfv)
3118 && FindProcShort (glGetnMapiv)
3119 && FindProcShort (glGetnPixelMapfv)
3120 && FindProcShort (glGetnPixelMapuiv)
3121 && FindProcShort (glGetnPixelMapusv)
3122 && FindProcShort (glGetnPolygonStipple)
3123 && FindProcShort (glGetnColorTable)
3124 && FindProcShort (glGetnConvolutionFilter)
3125 && FindProcShort (glGetnSeparableFilter)
3126 && FindProcShort (glGetnHistogram)
3127 && FindProcShort (glGetnMinmax)
3128 && FindProcShort (glTextureBarrier);
0ae9ac21 3129 if (has45)
3130 {
3131 core45 = (OpenGl_GlCore45* )(&(*myFuncs));
3132 if (!isCoreProfile)
3133 {
3134 core45back = (OpenGl_GlCore45Back* )(&(*myFuncs));
3135 }
3136 }
3137 else
3138 {
3139 checkWrongVersion (4, 5, aLastFailedProc);
3140 }
9491df8c 3141
0deb6f04 3142 // initialize debug context extension
3143 if (CheckExtension ("GL_ARB_debug_output"))
3144 {
3145 arbDbg = NULL;
3146 if (has43)
3147 {
3148 arbDbg = (OpenGl_ArbDbg* )(&(*myFuncs));
3149 }
3150 else if (FindProc ("glDebugMessageControlARB", myFuncs->glDebugMessageControl)
3151 && FindProc ("glDebugMessageInsertARB", myFuncs->glDebugMessageInsert)
3152 && FindProc ("glDebugMessageCallbackARB", myFuncs->glDebugMessageCallback)
3153 && FindProc ("glGetDebugMessageLogARB", myFuncs->glGetDebugMessageLog))
3154 {
3155 arbDbg = (OpenGl_ArbDbg* )(&(*myFuncs));
3156 }
3157
3158 if (arbDbg != NULL
3159 && caps->contextDebug)
3160 {
3161 // setup default callback
3162 myIsGlDebugCtx = Standard_True;
3163 arbDbg->glDebugMessageCallback (debugCallbackWrap, this);
3164 if (has43)
3165 {
3166 ::glEnable (GL_DEBUG_OUTPUT);
3167 }
3168 if (caps->contextSyncDebug)
3169 {
3170 ::glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS);
3171 }
3172 }
3173 }
3174
01ca42b2 3175 // initialize FBO extension (ARB)
3176 if (hasFBO)
2166f0fa 3177 {
b86bb3df 3178 arbFBO = (OpenGl_ArbFBO* )(&(*myFuncs));
3179 arbFBOBlit = (OpenGl_ArbFBOBlit* )(&(*myFuncs));
01ca42b2 3180 extPDS = Standard_True; // extension for EXT, but part of ARB
2166f0fa 3181 }
5f8b738e 3182
37eb4787 3183 // initialize GS extension (EXT)
01ca42b2 3184 if (CheckExtension ("GL_EXT_geometry_shader4")
3185 && FindProcShort (glProgramParameteriEXT))
37eb4787 3186 {
01ca42b2 3187 extGS = (OpenGl_ExtGS* )(&(*myFuncs));
37eb4787 3188 }
3189
25ef750e 3190 // initialize bindless texture extension (ARB)
3191 if (CheckExtension ("GL_ARB_bindless_texture")
3192 && FindProcShort (glGetTextureHandleARB)
3193 && FindProcShort (glGetTextureSamplerHandleARB)
3194 && FindProcShort (glMakeTextureHandleResidentARB)
3195 && FindProcShort (glMakeTextureHandleNonResidentARB)
3196 && FindProcShort (glGetImageHandleARB)
3197 && FindProcShort (glMakeImageHandleResidentARB)
3198 && FindProcShort (glMakeImageHandleNonResidentARB)
3199 && FindProcShort (glUniformHandleui64ARB)
3200 && FindProcShort (glUniformHandleui64vARB)
3201 && FindProcShort (glProgramUniformHandleui64ARB)
3202 && FindProcShort (glProgramUniformHandleui64vARB)
3203 && FindProcShort (glIsTextureHandleResidentARB)
3204 && FindProcShort (glIsImageHandleResidentARB)
3205 && FindProcShort (glVertexAttribL1ui64ARB)
3206 && FindProcShort (glVertexAttribL1ui64vARB)
3207 && FindProcShort (glGetVertexAttribLui64vARB))
3208 {
3209 arbTexBindless = (OpenGl_ArbTexBindless* )(&(*myFuncs));
3210 }
3211
0ae9ac21 3212 if (has30)
01ca42b2 3213 {
0ae9ac21 3214 // MSAA RenderBuffers have been defined in OpenGL 3.0,
3215 // but MSAA Textures - only in OpenGL 3.2+
3216 if (!has32
3217 && CheckExtension ("GL_ARB_texture_multisample")
3218 && FindProcShort (glTexImage2DMultisample))
3219 {
3220 GLint aNbColorSamples = 0, aNbDepthSamples = 0;
3221 ::glGetIntegerv (GL_MAX_COLOR_TEXTURE_SAMPLES, &aNbColorSamples);
3222 ::glGetIntegerv (GL_MAX_DEPTH_TEXTURE_SAMPLES, &aNbDepthSamples);
3223 myMaxMsaaSamples = Min (aNbColorSamples, aNbDepthSamples);
3224 }
3225 if (!has43
3226 && CheckExtension ("GL_ARB_texture_storage_multisample")
3227 && FindProcShort (glTexStorage2DMultisample))
3228 {
3229 //
3230 }
01ca42b2 3231 }
01ca42b2 3232
3a9b5dc8 3233 // check whether ray tracing mode is supported
3234 myHasRayTracing = has31
3235 && arbTboRGB32
3236 && arbFBOBlit != NULL;
3237
3238 // check whether textures in ray tracing mode are supported
3239 myHasRayTracingTextures = myHasRayTracing
3240 && arbTexBindless != NULL;
3241
3242 // check whether adaptive screen sampling in ray tracing mode is supported
3243 myHasRayTracingAdaptiveSampling = myHasRayTracing
e084dbbc 3244 && has44;
3245 myHasRayTracingAdaptiveSamplingAtomic = myHasRayTracingAdaptiveSampling
3246 && CheckExtension ("GL_NV_shader_atomic_float");
ca3c13d1 3247#endif
ba00aab7 3248
3249 if (arbFBO != NULL
3250 && hasFboSRGB)
3251 {
3252 // Detect if window buffer is considered by OpenGL as sRGB-ready
3253 // (linear RGB color written by shader is automatically converted into sRGB)
3254 // or not (offscreen FBO should be blit into window buffer with gamma correction).
3255 const GLenum aDefWinBuffer =
3256 #if !defined(GL_ES_VERSION_2_0)
3257 GL_BACK_LEFT;
3258 #else
3259 GL_BACK;
3260 #endif
3261 GLint aWinColorEncoding = 0; // GL_LINEAR
3262 arbFBO->glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, aDefWinBuffer, GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, &aWinColorEncoding);
3263 ResetErrors (true);
3264 myIsSRgbWindow = aWinColorEncoding == GL_SRGB;
3265
3266 // On desktop OpenGL, pixel formats are almost always sRGB-ready, even when not requested;
3267 // it is safe behavior on desktop where GL_FRAMEBUFFER_SRGB is disabled by default
3268 // (contrary to OpenGL ES, where it is enabled by default).
3269 // NVIDIA drivers, however, always return GL_LINEAR even for sRGB-ready pixel formats on Windows platform,
3270 // while AMD and Intel report GL_SRGB as expected.
3271 // macOS drivers seems to be also report GL_LINEAR even for [NSColorSpace sRGBColorSpace].
3272 #if !defined(GL_ES_VERSION_2_0)
3273 #ifdef __APPLE__
3274 myIsSRgbWindow = true;
3275 #else
3276 if (!myIsSRgbWindow
3277 && myVendor.Search ("nvidia") != -1)
3278 {
3279 myIsSRgbWindow = true;
3280 }
3281 #endif
3282 #endif
3283 if (!myIsSRgbWindow)
3284 {
a87b1b37 3285 Message::SendTrace ("OpenGl_Context, warning: window buffer is not sRGB-ready.\n"
3286 "Check OpenGL window creation parameters for optimal performance.");
ba00aab7 3287 }
3288 }
67312b79 3289
faff3767 3290 if (arbTexFloat)
3291 {
3292 mySupportedFormats->Add (Image_Format_GrayF);
3293 mySupportedFormats->Add (Image_Format_AlphaF);
3294 mySupportedFormats->Add (Image_Format_RGBF);
3295 mySupportedFormats->Add (Image_Format_RGBAF);
3296 if (arbTexRG)
3297 {
3298 mySupportedFormats->Add (Image_Format_RGF);
3299 }
3300 if (extBgra)
3301 {
3302 #if !defined(GL_ES_VERSION_2_0)
3303 mySupportedFormats->Add (Image_Format_BGRF);
3304 #endif
3305 mySupportedFormats->Add (Image_Format_BGRAF);
3306 }
3307 }
3308
3309#ifdef __EMSCRIPTEN__
3310 if (checkEnableWebGlExtension (*this, "GL_WEBGL_compressed_texture_s3tc")) // GL_WEBGL_compressed_texture_s3tc_srgb for sRGB formats
3311 {
3312 mySupportedFormats->Add (Image_CompressedFormat_RGB_S3TC_DXT1);
3313 mySupportedFormats->Add (Image_CompressedFormat_RGBA_S3TC_DXT1);
3314 mySupportedFormats->Add (Image_CompressedFormat_RGBA_S3TC_DXT3);
3315 mySupportedFormats->Add (Image_CompressedFormat_RGBA_S3TC_DXT5);
3316 }
3317#else
3318 if (CheckExtension ("GL_EXT_texture_compression_s3tc")) // GL_EXT_texture_sRGB for sRGB formats
3319 {
3320 mySupportedFormats->Add (Image_CompressedFormat_RGB_S3TC_DXT1);
3321 mySupportedFormats->Add (Image_CompressedFormat_RGBA_S3TC_DXT1);
3322 mySupportedFormats->Add (Image_CompressedFormat_RGBA_S3TC_DXT3);
3323 mySupportedFormats->Add (Image_CompressedFormat_RGBA_S3TC_DXT5);
3324 }
3325 else
3326 {
3327 if (CheckExtension ("GL_EXT_texture_compression_dxt1"))
3328 {
3329 mySupportedFormats->Add (Image_CompressedFormat_RGB_S3TC_DXT1);
3330 mySupportedFormats->Add (Image_CompressedFormat_RGBA_S3TC_DXT1);
3331 }
3332 if (CheckExtension ("GL_ANGLE_texture_compression_dxt3"))
3333 {
3334 mySupportedFormats->Add (Image_CompressedFormat_RGBA_S3TC_DXT3);
3335 }
3336 if (CheckExtension ("GL_ANGLE_texture_compression_dxt5"))
3337 {
3338 mySupportedFormats->Add (Image_CompressedFormat_RGBA_S3TC_DXT5);
3339 }
3340 }
3341#endif
3342
67312b79 3343 // check whether PBR shading model is supported
3344 myHasPBR = arbFBO != NULL
3345 && myMaxTexCombined >= 4
3346 && arbTexRG
3347 && arbTexFloat
3348 && (IsGlGreaterEqual (3, 0)
3349 #if !defined(GL_ES_VERSION_2_0)
3350 || (IsGlGreaterEqual (2, 1) && CheckExtension ("GL_EXT_gpu_shader4"))
3351 #endif
3352 );
78c4e836 3353
3354 myDepthPeelingDepthTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_DepthPeelingDepth); // -6
3355 myDepthPeelingFrontColorTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_DepthPeelingFrontColor); // -5
3356 myShadowMapTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_ShadowMap); // -4
3357 myPBREnvLUTTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_PbrEnvironmentLUT); // -3
3358 myPBRDiffIBLMapSHTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_PbrIblDiffuseSH); // -2
3359 myPBRSpecIBLMapTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_PbrIblSpecular); // -1
3360 if (!myHasPBR)
67312b79 3361 {
78c4e836 3362 myDepthPeelingDepthTexUnit = static_cast<Graphic3d_TextureUnit>(myDepthPeelingDepthTexUnit + 3);
3363 myDepthPeelingFrontColorTexUnit = static_cast<Graphic3d_TextureUnit>(myDepthPeelingFrontColorTexUnit + 3);
3364 myShadowMapTexUnit = static_cast<Graphic3d_TextureUnit>(myShadowMapTexUnit + 3);
67312b79 3365 }
2166f0fa 3366}
f0430952 3367
3368// =======================================================================
3369// function : MemoryInfo
3370// purpose :
3371// =======================================================================
3372Standard_Size OpenGl_Context::AvailableMemory() const
3373{
ca3c13d1 3374#if !defined(GL_ES_VERSION_2_0)
f0430952 3375 if (atiMem)
3376 {
3377 // this is actually information for VBO pool
3378 // however because pools are mostly shared
3379 // it can be used for total GPU memory estimations
3380 GLint aMemInfo[4];
3381 aMemInfo[0] = 0;
3382 glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aMemInfo);
3383 // returned value is in KiB, however this maybe changed in future
3384 return Standard_Size(aMemInfo[0]) * 1024;
3385 }
3386 else if (nvxMem)
3387 {
3388 // current available dedicated video memory (in KiB), currently unused GPU memory
3389 GLint aMemInfo = 0;
3390 glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aMemInfo);
3391 return Standard_Size(aMemInfo) * 1024;
3392 }
ca3c13d1 3393#endif
f0430952 3394 return 0;
3395}
3396
3397// =======================================================================
3398// function : MemoryInfo
3399// purpose :
3400// =======================================================================
3401TCollection_AsciiString OpenGl_Context::MemoryInfo() const
3402{
26d9c835 3403 TColStd_IndexedDataMapOfStringString aDict;
3404 MemoryInfo (aDict);
3405
3406 TCollection_AsciiString aText;
3407 for (TColStd_IndexedDataMapOfStringString::Iterator anIter (aDict); anIter.More(); anIter.Next())
3408 {
3409 if (!aText.IsEmpty())
3410 {
3411 aText += "\n";
3412 }
3413 aText += TCollection_AsciiString(" ") + anIter.Key() + ": " + anIter.Value();
3414 }
3415 return aText;
3416}
3417
3418// =======================================================================
3419// function : MemoryInfo
3420// purpose :
3421// =======================================================================
3422void OpenGl_Context::MemoryInfo (TColStd_IndexedDataMapOfStringString& theDict) const
3423{
3424#if defined(GL_ES_VERSION_2_0)
3425 (void )theDict;
3426#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
3427 GLint aGlRendId = 0;
3428 CGLGetParameter (CGLGetCurrentContext(), kCGLCPCurrentRendererID, &aGlRendId);
3429
3430 CGLRendererInfoObj aRendObj = NULL;
3431 CGOpenGLDisplayMask aDispMask = CGDisplayIDToOpenGLDisplayMask (kCGDirectMainDisplay);
3432 GLint aRendNb = 0;
3433 CGLQueryRendererInfo (aDispMask, &aRendObj, &aRendNb);
3434 for (GLint aRendIter = 0; aRendIter < aRendNb; ++aRendIter)
3435 {
3436 GLint aRendId = 0;
3437 if (CGLDescribeRenderer (aRendObj, aRendIter, kCGLRPRendererID, &aRendId) != kCGLNoError
3438 || aRendId != aGlRendId)
3439 {
3440 continue;
3441 }
3442
3443 //kCGLRPVideoMemoryMegabytes = 131;
3444 //kCGLRPTextureMemoryMegabytes = 132;
3445 GLint aVMem = 0;
3446 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
3447 if (CGLDescribeRenderer(aRendObj, aRendIter, kCGLRPVideoMemoryMegabytes, &aVMem) == kCGLNoError)
3448 {
3449 addInfo (theDict, "GPU memory", TCollection_AsciiString() + aVMem + " MiB");
3450 }
3451 if (CGLDescribeRenderer(aRendObj, aRendIter, kCGLRPTextureMemoryMegabytes, &aVMem) == kCGLNoError)
3452 {
3453 addInfo (theDict, "GPU Texture memory", TCollection_AsciiString() + aVMem + " MiB");
3454 }
3455 #else
3456 if (CGLDescribeRenderer(aRendObj, aRendIter, kCGLRPVideoMemory, &aVMem) == kCGLNoError)
3457 {
3458 addInfo (theDict, "GPU memory", TCollection_AsciiString() + (aVMem / (1024 * 1024)) + " MiB");
3459 }
3460 if (CGLDescribeRenderer(aRendObj, aRendIter, kCGLRPTextureMemory, &aVMem) == kCGLNoError)
3461 {
3462 addInfo (theDict, "GPU Texture memory", TCollection_AsciiString() + (aVMem / (1024 * 1024)) + " MiB");
3463 }
3464 #endif
3465 }
3466#endif
3467
ca3c13d1 3468#if !defined(GL_ES_VERSION_2_0)
f0430952 3469 if (atiMem)
3470 {
3471 GLint aValues[4];
3472 memset (aValues, 0, sizeof(aValues));
3473 glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aValues);
3474
3475 // total memory free in the pool
26d9c835 3476 addInfo (theDict, "GPU free memory", TCollection_AsciiString() + (aValues[0] / 1024) + " MiB");
f0430952 3477
26d9c835 3478 if (aValues[1] != aValues[0])
3479 {
3480 // largest available free block in the pool
3481 addInfo (theDict, "Largest free block", TCollection_AsciiString() + (aValues[1] / 1024) + " MiB");
3482 }
f0430952 3483 if (aValues[2] != aValues[0])
3484 {
3485 // total auxiliary memory free
26d9c835 3486 addInfo (theDict, "Free auxiliary memory", TCollection_AsciiString() + (aValues[2] / 1024) + " MiB");
f0430952 3487 }
3488 }
3489 else if (nvxMem)
3490 {
3491 //current available dedicated video memory (in KiB), currently unused GPU memory
3492 GLint aValue = 0;
3493 glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aValue);
26d9c835 3494 addInfo (theDict, "GPU free memory", TCollection_AsciiString() + (aValue / 1024) + " MiB");
f0430952 3495
3496 // dedicated video memory, total size (in KiB) of the GPU memory
3497 GLint aDedicated = 0;
3498 glGetIntegerv (GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &aDedicated);
26d9c835 3499 addInfo (theDict, "GPU memory", TCollection_AsciiString() + (aDedicated / 1024) + " MiB");
f0430952 3500
3501 // total available memory, total size (in KiB) of the memory available for allocations
3502 glGetIntegerv (GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &aValue);
3503 if (aValue != aDedicated)
3504 {
3505 // different only for special configurations
26d9c835 3506 addInfo (theDict, "Total memory", TCollection_AsciiString() + (aValue / 1024) + " MiB");
3507 }
3508 }
2eacd0b8 3509#if defined(_WIN32)
3510 else if (myFuncs->wglGetGPUInfoAMD != NULL
3511 && myFuncs->wglGetContextGPUIDAMD != NULL)
3512 {
3513 GLuint aTotalMemMiB = 0;
3514 UINT anAmdId = myFuncs->wglGetContextGPUIDAMD ((HGLRC )myGContext);
3515 if (anAmdId != 0)
3516 {
3517 if (myFuncs->wglGetGPUInfoAMD (anAmdId, WGL_GPU_RAM_AMD, GL_UNSIGNED_INT, sizeof(aTotalMemMiB), &aTotalMemMiB) > 0)
3518 {
3519 addInfo (theDict, "GPU memory", TCollection_AsciiString() + (int )aTotalMemMiB + " MiB");
3520 }
3521 }
3522 }
3523#endif
26d9c835 3524#endif
3525
3526#if !defined(GL_ES_VERSION_2_0) && !defined(__APPLE__) && !defined(_WIN32)
3527 // GLX_RENDERER_VENDOR_ID_MESA
3528 if (myFuncs->glXQueryCurrentRendererIntegerMESA != NULL)
3529 {
3530 unsigned int aVMemMiB = 0;
3531 if (myFuncs->glXQueryCurrentRendererIntegerMESA (GLX_RENDERER_VIDEO_MEMORY_MESA, &aVMemMiB) != False)
3532 {
3533 addInfo (theDict, "GPU memory", TCollection_AsciiString() + int(aVMemMiB) + " MiB");
f0430952 3534 }
3535 }
ca3c13d1 3536#endif
f0430952 3537}
5e27df78 3538
26d9c835 3539// =======================================================================
3540// function : DiagnosticInfo
3541// purpose :
3542// =======================================================================
3543void OpenGl_Context::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
3544 Graphic3d_DiagnosticInfo theFlags) const
3545{
3546 if ((theFlags & Graphic3d_DiagnosticInfo_NativePlatform) != 0)
3547 {
3548 #if defined(HAVE_EGL)
6cde53c4 3549 addInfo (theDict, "EGLVersion", ::eglQueryString ((EGLDisplay )myDisplay, EGL_VERSION));
3550 addInfo (theDict, "EGLVendor", ::eglQueryString ((EGLDisplay )myDisplay, EGL_VENDOR));
3551 addInfo (theDict, "EGLClientAPIs", ::eglQueryString ((EGLDisplay )myDisplay, EGL_CLIENT_APIS));
26d9c835 3552 if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
3553 {
6cde53c4 3554 addInfo (theDict, "EGLExtensions", ::eglQueryString ((EGLDisplay )myDisplay, EGL_EXTENSIONS));
26d9c835 3555 }
3556 #elif defined(_WIN32)
3557 if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0
3558 && myFuncs->wglGetExtensionsStringARB != NULL)
3559 {
3560 const char* aWglExts = myFuncs->wglGetExtensionsStringARB ((HDC )myWindowDC);
3561 addInfo (theDict, "WGLExtensions", aWglExts);
3562 }
3563 #elif defined(__APPLE__)
3564 //
3565 #else
3566 Display* aDisplay = (Display*)myDisplay;
3567 const int aScreen = DefaultScreen(aDisplay);
3568 addInfo (theDict, "GLXDirectRendering", ::glXIsDirect (aDisplay, (GLXContext )myGContext) ? "Yes" : "No");
3569 addInfo (theDict, "GLXVendor", ::glXQueryServerString (aDisplay, aScreen, GLX_VENDOR));
3570 addInfo (theDict, "GLXVersion", ::glXQueryServerString (aDisplay, aScreen, GLX_VERSION));
3571 if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
3572 {
3573 const char* aGlxExts = ::glXQueryExtensionsString (aDisplay, aScreen);
3574 addInfo(theDict, "GLXExtensions", aGlxExts);
3575 }
3576
3577 addInfo (theDict, "GLXClientVendor", ::glXGetClientString (aDisplay, GLX_VENDOR));
3578 addInfo (theDict, "GLXClientVersion", ::glXGetClientString (aDisplay, GLX_VERSION));
3579 if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
3580 {
3581 addInfo (theDict, "GLXClientExtensions", ::glXGetClientString (aDisplay, GLX_EXTENSIONS));
3582 }
3583 #endif
3584 }
3585
3586 if ((theFlags & Graphic3d_DiagnosticInfo_Device) != 0)
3587 {
59515ca6 3588 Standard_Integer aDriverVer[2] = {};
3589 ReadGlVersion (aDriverVer[0], aDriverVer[1]);
26d9c835 3590 addInfo (theDict, "GLvendor", (const char*)::glGetString (GL_VENDOR));
3591 addInfo (theDict, "GLdevice", (const char*)::glGetString (GL_RENDERER));
565baee6 3592 #ifdef __EMSCRIPTEN__
3593 if (checkEnableWebGlExtension (*this, "GL_WEBGL_debug_renderer_info"))
3594 {
3595 if (const char* aVendor = (const char*)::glGetString (0x9245))
3596 {
3597 addInfo (theDict, "GLunmaskedVendor", aVendor);
3598 }
3599 if (const char* aDevice = (const char*)::glGetString (0x9246))
3600 {
3601 addInfo (theDict, "GLunmaskedDevice", aDevice);
3602 }
3603 }
3604 #endif
3605
26d9c835 3606 addInfo (theDict, "GLversion", (const char*)::glGetString (GL_VERSION));
59515ca6 3607 if (myGlVerMajor != aDriverVer[0]
3608 || myGlVerMinor != aDriverVer[1])
3609 {
3610 addInfo (theDict, "GLversionOcct", TCollection_AsciiString (myGlVerMajor) + "." + TCollection_AsciiString (myGlVerMinor));
3611 }
048e1b3b 3612 if (IsGlGreaterEqual (2, 0))
3613 {
3614 addInfo (theDict, "GLSLversion", (const char*)::glGetString (GL_SHADING_LANGUAGE_VERSION));
3615 }
26d9c835 3616 if (myIsGlDebugCtx)
3617 {
3618 addInfo (theDict, "GLdebug", "ON");
3619 }
3620 }
3621
3622 if ((theFlags & Graphic3d_DiagnosticInfo_Limits) != 0)
3623 {
3624 addInfo (theDict, "Max texture size", TCollection_AsciiString(myMaxTexDim));
6997ff1c 3625 addInfo (theDict, "Max FBO dump size", TCollection_AsciiString() + myMaxDumpSizeX + "x" + myMaxDumpSizeY);
cc8cbabe 3626 addInfo (theDict, "Max combined texture units", TCollection_AsciiString(myMaxTexCombined));
26d9c835 3627 addInfo (theDict, "Max MSAA samples", TCollection_AsciiString(myMaxMsaaSamples));
3628 }
3629
3630 if ((theFlags & Graphic3d_DiagnosticInfo_FrameBuffer) != 0)
3631 {
3632 GLint aViewport[4] = {};
3633 ::glGetIntegerv (GL_VIEWPORT, aViewport);
3634 addInfo (theDict, "Viewport", TCollection_AsciiString() + aViewport[2] + "x" + aViewport[3]);
3635 }
3636
3637 if ((theFlags & Graphic3d_DiagnosticInfo_Memory) != 0)
3638 {
3639 MemoryInfo (theDict);
3640 }
3641
3642 if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
3643 {
3644 #if !defined(GL_ES_VERSION_2_0)
3645 if (IsGlGreaterEqual (3, 0)
3646 && myFuncs->glGetStringi != NULL)
3647 {
3648 TCollection_AsciiString anExtList;
3649 GLint anExtNb = 0;
3650 ::glGetIntegerv (GL_NUM_EXTENSIONS, &anExtNb);
3651 for (GLint anIter = 0; anIter < anExtNb; ++anIter)
3652 {
3653 const char* anExtension = (const char*)myFuncs->glGetStringi (GL_EXTENSIONS, (GLuint)anIter);
3654 if (!anExtList.IsEmpty())
3655 {
3656 anExtList += " ";
3657 }
3658 anExtList += anExtension;
3659 }
3660 addInfo(theDict, "GLextensions", anExtList);
3661 }
3662 else
3663 #endif
3664 {
3665 addInfo (theDict, "GLextensions", (const char*)::glGetString (GL_EXTENSIONS));
3666 }
3667 }
3668}
5e27df78 3669
3670// =======================================================================
3671// function : GetResource
3672// purpose :
3673// =======================================================================
3674const Handle(OpenGl_Resource)& OpenGl_Context::GetResource (const TCollection_AsciiString& theKey) const
3675{
3676 return mySharedResources->IsBound (theKey) ? mySharedResources->Find (theKey) : NULL_GL_RESOURCE;
3677}
3678
3679// =======================================================================
3680// function : ShareResource
3681// purpose :
3682// =======================================================================
3683Standard_Boolean OpenGl_Context::ShareResource (const TCollection_AsciiString& theKey,
3684 const Handle(OpenGl_Resource)& theResource)
3685{
3686 if (theKey.IsEmpty() || theResource.IsNull())
3687 {
3688 return Standard_False;
3689 }
3690 return mySharedResources->Bind (theKey, theResource);
3691}
3692
3693// =======================================================================
3694// function : ReleaseResource
3695// purpose :
3696// =======================================================================
a174a3c5 3697void OpenGl_Context::ReleaseResource (const TCollection_AsciiString& theKey,
3698 const Standard_Boolean theToDelay)
5e27df78 3699{
3700 if (!mySharedResources->IsBound (theKey))
3701 {
3702 return;
3703 }
71c810df 3704 const Handle(OpenGl_Resource)& aRes = mySharedResources->Find (theKey);
5e27df78 3705 if (aRes->GetRefCount() > 1)
3706 {
3707 return;
3708 }
3709
a174a3c5 3710 if (theToDelay)
3711 {
3712 myDelayed->Bind (theKey, 1);
3713 }
3714 else
3715 {
3716 aRes->Release (this);
3717 mySharedResources->UnBind (theKey);
3718 }
5e27df78 3719}
3720
3721// =======================================================================
5e27df78 3722// function : ReleaseDelayed
3723// purpose :
3724// =======================================================================
3725void OpenGl_Context::ReleaseDelayed()
3726{
a174a3c5 3727 // release queued elements
3125ebb6 3728 while (!myUnusedResources->IsEmpty())
5e27df78 3729 {
3125ebb6 3730 myUnusedResources->First()->Release (this);
3731 myUnusedResources->RemoveFirst();
5e27df78 3732 }
a174a3c5 3733
265d4508 3734 // release delayed shared resources
a174a3c5 3735 NCollection_Vector<TCollection_AsciiString> aDeadList;
3736 for (NCollection_DataMap<TCollection_AsciiString, Standard_Integer>::Iterator anIter (*myDelayed);
3737 anIter.More(); anIter.Next())
3738 {
3739 if (++anIter.ChangeValue() <= 2)
3740 {
3741 continue; // postpone release one more frame to ensure noone use it periodically
3742 }
3743
3744 const TCollection_AsciiString& aKey = anIter.Key();
3745 if (!mySharedResources->IsBound (aKey))
3746 {
3747 // mixed unshared strategy delayed/undelayed was used!
3748 aDeadList.Append (aKey);
3749 continue;
3750 }
3751
71c810df 3752 const Handle(OpenGl_Resource)& aRes = mySharedResources->ChangeFind (aKey);
a174a3c5 3753 if (aRes->GetRefCount() > 1)
3754 {
3755 // should be only 1 instance in mySharedResources
3756 // if not - resource was reused again
3757 aDeadList.Append (aKey);
3758 continue;
3759 }
3760
3761 // release resource if no one requiested it more than 2 redraw calls
3762 aRes->Release (this);
3763 mySharedResources->UnBind (aKey);
3764 aDeadList.Append (aKey);
3765 }
3766
3767 for (Standard_Integer anIter = 0; anIter < aDeadList.Length(); ++anIter)
3768 {
3769 myDelayed->UnBind (aDeadList.Value (anIter));
3770 }
5e27df78 3771}
7d3e64ef 3772
cc8cbabe 3773// =======================================================================
3774// function : BindTextures
3775// purpose :
3776// =======================================================================
72f6dc61 3777Handle(OpenGl_TextureSet) OpenGl_Context::BindTextures (const Handle(OpenGl_TextureSet)& theTextures,
3778 const Handle(OpenGl_ShaderProgram)& theProgram)
cc8cbabe 3779{
72f6dc61 3780 const Standard_Integer aTextureSetBits = !theTextures.IsNull() ? theTextures->TextureSetBits() : 0;
3781 const Standard_Integer aProgramBits = !theProgram.IsNull() ? theProgram->TextureSetBits() : 0;
3782 Standard_Integer aMissingBits = aProgramBits & ~aTextureSetBits;
3783 if (aMissingBits != 0
3784 && myTextureRgbaBlack.IsNull())
cc8cbabe 3785 {
72f6dc61 3786 // allocate mock textures
3787 myTextureRgbaBlack = new OpenGl_Texture();
3788 myTextureRgbaWhite = new OpenGl_Texture();
3789 Image_PixMap anImage;
3790 anImage.InitZero (Image_Format_RGBA, 2, 2, 0, (Standard_Byte )0);
3791 if (!myTextureRgbaBlack->Init (this, OpenGl_TextureFormat::Create<GLubyte, 4>(), Graphic3d_Vec2i (2, 2), Graphic3d_TOT_2D, &anImage))
3792 {
3793 PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH,
3794 "Error: unable to create unit mock PBR texture map.");
3795 }
3796 anImage.InitZero (Image_Format_RGBA, 2, 2, 0, (Standard_Byte )255);
3797 if (!myTextureRgbaWhite->Init (this, OpenGl_TextureFormat::Create<GLubyte, 4>(), Graphic3d_Vec2i (2, 2), Graphic3d_TOT_2D, &anImage))
3798 {
3799 PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH,
3800 "Error: unable to create normal mock PBR texture map.");
3801 }
cc8cbabe 3802 }
3803
72f6dc61 3804 Handle(OpenGl_TextureSet) anOldTextures = myActiveTextures;
3805 if (myActiveTextures != theTextures)
cc8cbabe 3806 {
72f6dc61 3807 Handle(OpenGl_Context) aThisCtx (this);
d850414a 3808 for (OpenGl_TextureSetPairIterator aSlotIter (myActiveTextures, theTextures); aSlotIter.More(); aSlotIter.Next())
cc8cbabe 3809 {
d850414a 3810 const Graphic3d_TextureUnit aTexUnit = aSlotIter.Unit();
3811 const OpenGl_Texture* aTextureOld = aSlotIter.Texture1();
3812 const OpenGl_Texture* aTextureNew = aSlotIter.Texture2();
3813 if (aTextureNew == aTextureOld)
cc8cbabe 3814 {
d850414a 3815 continue;
cc8cbabe 3816 }
cc8cbabe 3817
d850414a 3818 if (aTextureNew != NULL
3819 && aTextureNew->IsValid())
cc8cbabe 3820 {
d850414a 3821 if (aTexUnit >= myMaxTexCombined)
cc8cbabe 3822 {
d850414a 3823 PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
3824 TCollection_AsciiString("Texture unit ") + aTexUnit + " for " + aTextureNew->ResourceId() + " exceeds hardware limit " + myMaxTexCombined);
72f6dc61 3825 continue;
3826 }
d850414a 3827
3828 aTextureNew->Bind (aThisCtx, aTexUnit);
3829 if (aTextureNew->Sampler()->ToUpdateParameters())
72f6dc61 3830 {
d850414a 3831 if (aTextureNew->Sampler()->IsImmutable())
cc8cbabe 3832 {
d850414a 3833 aTextureNew->Sampler()->Init (aThisCtx, *aTextureNew);
3834 }
3835 else
3836 {
faff3767 3837 OpenGl_Sampler::applySamplerParams (aThisCtx, aTextureNew->Sampler()->Parameters(), aTextureNew->Sampler().get(), aTextureNew->GetTarget(), aTextureNew->MaxMipmapLevel());
cc8cbabe 3838 }
72f6dc61 3839 }
d850414a 3840 #if !defined(GL_ES_VERSION_2_0)
3841 if (core11 != NULL)
72f6dc61 3842 {
d850414a 3843 OpenGl_Sampler::applyGlobalTextureParams (aThisCtx, *aTextureNew, aTextureNew->Sampler()->Parameters());
72f6dc61 3844 }
d850414a 3845 #endif
cc8cbabe 3846 }
d850414a 3847 else if (aTextureOld != NULL
3848 && aTextureOld->IsValid())
cc8cbabe 3849 {
d850414a 3850 aTextureOld->Unbind (aThisCtx, aTexUnit);
3851 #if !defined(GL_ES_VERSION_2_0)
3852 if (core11 != NULL)
3853 {
3854 OpenGl_Sampler::resetGlobalTextureParams (aThisCtx, *aTextureOld, aTextureOld->Sampler()->Parameters());
3855 }
3856 #endif
cc8cbabe 3857 }
3858 }
72f6dc61 3859 myActiveTextures = theTextures;
3860 }
3861
3862 if (myActiveMockTextures != aMissingBits)
3863 {
3864 myActiveMockTextures = aMissingBits;
3865 for (Standard_Integer aBitIter = 0; aMissingBits != 0; ++aBitIter)
cc8cbabe 3866 {
72f6dc61 3867 Standard_Integer aUnitMask = 1 << aBitIter;
3868 if ((aUnitMask & aMissingBits) != 0)
3869 {
3870 aMissingBits = aMissingBits & ~aUnitMask;
3871 if (aBitIter == Graphic3d_TextureUnit_Normal)
3872 {
3873 myTextureRgbaBlack->Bind (this, static_cast<Graphic3d_TextureUnit>(aBitIter));
3874 }
3875 else
3876 {
3877 myTextureRgbaWhite->Bind (this, static_cast<Graphic3d_TextureUnit>(aBitIter));
3878 }
3879 }
cc8cbabe 3880 }
cc8cbabe 3881 }
3882
cc8cbabe 3883 return anOldTextures;
3884}
3885
7d3e64ef 3886// =======================================================================
3887// function : BindProgram
3888// purpose :
3889// =======================================================================
8625ef7e 3890Standard_Boolean OpenGl_Context::BindProgram (const Handle(OpenGl_ShaderProgram)& theProgram)
7d3e64ef 3891{
8625ef7e 3892 if (core20fwd == NULL)
3893 {
3894 return Standard_False;
3895 }
8613985b 3896 else if (myActiveProgram == theProgram)
3897 {
3898 return Standard_True;
3899 }
8625ef7e 3900
7d3e64ef 3901 if (theProgram.IsNull()
3902 || !theProgram->IsValid())
3903 {
3904 if (!myActiveProgram.IsNull())
3905 {
3906 core20fwd->glUseProgram (OpenGl_ShaderProgram::NO_PROGRAM);
3907 myActiveProgram.Nullify();
3908 }
8625ef7e 3909 return Standard_False;
7d3e64ef 3910 }
3911
3912 myActiveProgram = theProgram;
3913 core20fwd->glUseProgram (theProgram->ProgramId());
8625ef7e 3914 return Standard_True;
3915}
3916
4e1523ef 3917// =======================================================================
3918// function : BindDefaultVao
3919// purpose :
3920// =======================================================================
3921void OpenGl_Context::BindDefaultVao()
3922{
3923#if !defined(GL_ES_VERSION_2_0)
3924 if (myDefaultVao == 0
3925 || core32 == NULL)
3926 {
3927 return;
3928 }
3929
3930 core32->glBindVertexArray (myDefaultVao);
3931#endif
3932}
3933
a2e4f780 3934// =======================================================================
3935// function : SetDefaultFrameBuffer
3936// purpose :
3937// =======================================================================
3938Handle(OpenGl_FrameBuffer) OpenGl_Context::SetDefaultFrameBuffer (const Handle(OpenGl_FrameBuffer)& theFbo)
3939{
3940 Handle(OpenGl_FrameBuffer) aFbo = myDefaultFbo;
3941 myDefaultFbo = theFbo;
3942 return aFbo;
3943}
3944
8625ef7e 3945// =======================================================================
299e0ab9 3946// function : SetShadingMaterial
3947// purpose :
3948// =======================================================================
bf5f0ca2 3949void OpenGl_Context::SetShadingMaterial (const OpenGl_Aspects* theAspect,
a1073ae2 3950 const Handle(Graphic3d_PresentationAttributes)& theHighlight)
299e0ab9 3951{
bf5f0ca2 3952 const Handle(Graphic3d_Aspects)& anAspect = (!theHighlight.IsNull() && !theHighlight->BasicFillAreaAspect().IsNull())
3953 ? (const Handle(Graphic3d_Aspects)& )theHighlight->BasicFillAreaAspect()
3954 : theAspect->Aspect();
8613985b 3955
3956 const bool toDistinguish = anAspect->Distinguish();
3957 const bool toMapTexture = anAspect->ToMapTexture();
3958 const Graphic3d_MaterialAspect& aMatFrontSrc = anAspect->FrontMaterial();
3959 const Graphic3d_MaterialAspect& aMatBackSrc = toDistinguish
3960 ? anAspect->BackMaterial()
3961 : aMatFrontSrc;
3962 const Quantity_Color& aFrontIntColor = anAspect->InteriorColor();
3963 const Quantity_Color& aBackIntColor = toDistinguish
3964 ? anAspect->BackInteriorColor()
3965 : aFrontIntColor;
3966
ba00aab7 3967 myMatFront.Init (*this, aMatFrontSrc, aFrontIntColor);
8613985b 3968 if (toDistinguish)
3969 {
ba00aab7 3970 myMatBack.Init (*this, aMatBackSrc, aBackIntColor);
8613985b 3971 }
3972 else
299e0ab9 3973 {
8613985b 3974 myMatBack = myMatFront;
3975 }
299e0ab9 3976
8613985b 3977 if (!theHighlight.IsNull()
3978 && theHighlight->BasicFillAreaAspect().IsNull())
3979 {
3980 myMatFront.SetColor (theHighlight->ColorRGBA());
3981 myMatBack .SetColor (theHighlight->ColorRGBA());
8613985b 3982 }
a1073ae2 3983
a71a71de 3984 Standard_ShortReal anAlphaFront = 1.0f;
3985 Standard_ShortReal anAlphaBack = 1.0f;
3986 if (CheckIsTransparent (theAspect, theHighlight, anAlphaFront, anAlphaBack))
8613985b 3987 {
67312b79 3988 myMatFront.Common.Diffuse.a() = anAlphaFront;
3989 myMatBack .Common.Diffuse.a() = anAlphaBack;
3990
3991 myMatFront.Pbr.BaseColor.a() = anAlphaFront;
3992 myMatBack .Pbr.BaseColor.a() = anAlphaBack;
299e0ab9 3993 }
8613985b 3994
3995 // do not update material properties in case of zero reflection mode,
3996 // because GL lighting will be disabled by OpenGl_PrimitiveArray::DrawArray() anyway.
c40eb6b9 3997 const OpenGl_MaterialState& aMatState = myShaderManager->MaterialState();
2a332745 3998 float anAlphaCutoff = anAspect->AlphaMode() == Graphic3d_AlphaMode_Mask
3999 ? anAspect->AlphaCutoff()
4000 : ShortRealLast();
4001 if (anAspect->ToDrawEdges())
4002 {
4003 if (anAspect->InteriorStyle() == Aspect_IS_EMPTY
4004 || (anAspect->InteriorStyle() == Aspect_IS_SOLID
4005 && anAspect->EdgeColorRGBA().Alpha() < 1.0f))
4006 {
4007 anAlphaCutoff = 0.285f;
4008 }
4009 }
dc89236f 4010 if (theAspect->ShadingModel() == Graphic3d_TOSM_UNLIT)
8613985b 4011 {
c40eb6b9 4012 if (anAlphaCutoff == aMatState.AlphaCutoff())
4013 {
4014 return;
4015 }
8613985b 4016 }
c40eb6b9 4017 else if (myMatFront == aMatState.FrontMaterial()
4018 && myMatBack == aMatState.BackMaterial()
4019 && toDistinguish == aMatState.ToDistinguish()
4020 && toMapTexture == aMatState.ToMapTexture()
4021 && anAlphaCutoff == aMatState.AlphaCutoff())
8613985b 4022 {
4023 return;
4024 }
4025
c40eb6b9 4026 myShaderManager->UpdateMaterialStateTo (myMatFront, myMatBack, anAlphaCutoff, toDistinguish, toMapTexture);
299e0ab9 4027}
4028
a1073ae2 4029// =======================================================================
4030// function : CheckIsTransparent
4031// purpose :
4032// =======================================================================
bf5f0ca2 4033Standard_Boolean OpenGl_Context::CheckIsTransparent (const OpenGl_Aspects* theAspect,
a1073ae2 4034 const Handle(Graphic3d_PresentationAttributes)& theHighlight,
a71a71de 4035 Standard_ShortReal& theAlphaFront,
4036 Standard_ShortReal& theAlphaBack)
a1073ae2 4037{
bf5f0ca2 4038 const Handle(Graphic3d_Aspects)& anAspect = (!theHighlight.IsNull() && !theHighlight->BasicFillAreaAspect().IsNull())
4039 ? (const Handle(Graphic3d_Aspects)& )theHighlight->BasicFillAreaAspect()
4040 : theAspect->Aspect();
a1073ae2 4041
4042 const bool toDistinguish = anAspect->Distinguish();
4043 const Graphic3d_MaterialAspect& aMatFrontSrc = anAspect->FrontMaterial();
4044 const Graphic3d_MaterialAspect& aMatBackSrc = toDistinguish
4045 ? anAspect->BackMaterial()
4046 : aMatFrontSrc;
4047
4048 // handling transparency
a1073ae2 4049 if (!theHighlight.IsNull()
4050 && theHighlight->BasicFillAreaAspect().IsNull())
4051 {
a71a71de 4052 theAlphaFront = theHighlight->ColorRGBA().Alpha();
4053 theAlphaBack = theHighlight->ColorRGBA().Alpha();
4054 }
4055 else
4056 {
4057 theAlphaFront = aMatFrontSrc.Alpha();
4058 theAlphaBack = aMatBackSrc .Alpha();
a1073ae2 4059 }
4060
c40eb6b9 4061 if (anAspect->AlphaMode() == Graphic3d_AlphaMode_BlendAuto)
4062 {
4063 return theAlphaFront < 1.0f
4064 || theAlphaBack < 1.0f;
4065 }
4066 return anAspect->AlphaMode() == Graphic3d_AlphaMode_Blend;
a1073ae2 4067}
4068
299e0ab9 4069// =======================================================================
8625ef7e 4070// function : SetColor4fv
4071// purpose :
4072// =======================================================================
4073void OpenGl_Context::SetColor4fv (const OpenGl_Vec4& theColor)
4074{
4075 if (!myActiveProgram.IsNull())
4076 {
ba00aab7 4077 if (const OpenGl_ShaderUniformLocation& aLoc = myActiveProgram->GetStateLocation (OpenGl_OCCT_COLOR))
4078 {
4079 myActiveProgram->SetUniform (this, aLoc, Vec4FromQuantityColor (theColor));
4080 }
8625ef7e 4081 }
4082#if !defined(GL_ES_VERSION_2_0)
4083 else if (core11 != NULL)
4084 {
4085 core11->glColor4fv (theColor.GetData());
4086 }
4087#endif
4088}
4089
ac116c22 4090// =======================================================================
4091// function : SetTypeOfLine
4092// purpose :
4093// =======================================================================
4094void OpenGl_Context::SetTypeOfLine (const Aspect_TypeOfLine theType,
4095 const Standard_ShortReal theFactor)
4096{
3f1675c9 4097 SetLineStipple (theFactor, Graphic3d_Aspects::DefaultLinePatternForType (theType));
4098}
ac116c22 4099
3f1675c9 4100// =======================================================================
4101// function : SetLineStipple
4102// purpose :
4103// =======================================================================
4104void OpenGl_Context::SetLineStipple (const Standard_ShortReal theFactor,
4105 const uint16_t thePattern)
4106{
c04c30b3 4107 if (!myActiveProgram.IsNull())
ac116c22 4108 {
59515ca6 4109 if (const OpenGl_ShaderUniformLocation aPatternLoc = myActiveProgram->GetStateLocation (OpenGl_OCCT_LINE_STIPPLE_PATTERN))
4110 {
4111 if (hasGlslBitwiseOps != OpenGl_FeatureNotAvailable)
4112 {
3f1675c9 4113 myActiveProgram->SetUniform (this, aPatternLoc, (Standard_Integer )thePattern);
59515ca6 4114 }
4115 else
4116 {
4117 Standard_Integer aPatArr[16] = {};
4118 for (unsigned int aBit = 0; aBit < 16; ++aBit)
4119 {
3f1675c9 4120 aPatArr[aBit] = ((unsigned int)(thePattern) & (1U << aBit)) != 0 ? 1 : 0;
59515ca6 4121 }
4122 myActiveProgram->SetUniform (this, aPatternLoc, 16, aPatArr);
4123 }
4124 myActiveProgram->SetUniform (this, myActiveProgram->GetStateLocation (OpenGl_OCCT_LINE_STIPPLE_FACTOR), theFactor);
4125 }
ac116c22 4126 return;
4127 }
4128
4129#if !defined(GL_ES_VERSION_2_0)
3f1675c9 4130 if (thePattern != 0xFFFF)
ac116c22 4131 {
ac116c22 4132 if (core11 != NULL)
4133 {
4134 core11fwd->glEnable (GL_LINE_STIPPLE);
4135
4136 core11->glLineStipple (static_cast<GLint> (theFactor),
3f1675c9 4137 static_cast<GLushort> (thePattern));
ac116c22 4138 }
4139 }
4140 else
4141 {
4142 if (core11 != NULL)
4143 {
4144 core11fwd->glDisable (GL_LINE_STIPPLE);
4145 }
ac116c22 4146 }
4147#endif
4148}
4149
4150// =======================================================================
4151// function : SetLineWidth
4152// purpose :
4153// =======================================================================
4154void OpenGl_Context::SetLineWidth (const Standard_ShortReal theWidth)
4155{
4156 if (core11 != NULL)
4157 {
4158 // glLineWidth() is still defined within Core Profile, but has no effect with values != 1.0f
56689b27 4159 core11fwd->glLineWidth (theWidth * myLineWidthScale);
ac116c22 4160 }
ac116c22 4161}
4162
79f4f036 4163// =======================================================================
4164// function : SetTextureMatrix
4165// purpose :
4166// =======================================================================
faff3767 4167void OpenGl_Context::SetTextureMatrix (const Handle(Graphic3d_TextureParams)& theParams,
4168 const Standard_Boolean theIsTopDown)
79f4f036 4169{
4170 if (theParams.IsNull())
4171 {
4172 return;
4173 }
faff3767 4174
4175 const Graphic3d_Vec2& aScale = theParams->Scale();
4176 const Graphic3d_Vec2& aTrans = theParams->Translation();
4177 if (!myActiveProgram.IsNull())
79f4f036 4178 {
4179 const GLint aUniLoc = myActiveProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_TRSF2D);
4180 if (aUniLoc == OpenGl_ShaderProgram::INVALID_LOCATION)
4181 {
4182 return;
4183 }
4184
4185 // pack transformation parameters
bc379358 4186 OpenGl_Vec4 aTrsf[2] =
4187 {
faff3767 4188 OpenGl_Vec4 (-aTrans.x(), -aTrans.y(), aScale.x(), aScale.y()),
bc379358 4189 OpenGl_Vec4 (static_cast<float> (std::sin (-theParams->Rotation() * M_PI / 180.0)),
4190 static_cast<float> (std::cos (-theParams->Rotation() * M_PI / 180.0)),
4191 0.0f, 0.0f)
4192 };
faff3767 4193 if (caps->isTopDownTextureUV != theIsTopDown)
4194 {
4195 // flip V
4196 aTrsf[0].y() = -aTrans.y() + 1.0f / aScale.y();
4197 aTrsf[0].w() = -aScale.y();
4198 }
79f4f036 4199 myActiveProgram->SetUniform (this, aUniLoc, 2, aTrsf);
4200 return;
4201 }
4202
4203#if !defined(GL_ES_VERSION_2_0)
4204 if (core11 != NULL)
4205 {
4206 GLint aMatrixMode = GL_TEXTURE;
4207 ::glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
4208
4209 core11->glMatrixMode (GL_TEXTURE);
4210 OpenGl_Mat4 aTextureMat;
faff3767 4211 if (caps->isTopDownTextureUV != theIsTopDown)
4212 {
4213 // flip V
4214 Graphic3d_TransformUtils::Scale (aTextureMat, aScale.x(), -aScale.y(), 1.0f);
4215 Graphic3d_TransformUtils::Translate (aTextureMat, -aTrans.x(), -aTrans.y() + 1.0f / aScale.y(), 0.0f);
4216 }
4217 else
4218 {
4219 Graphic3d_TransformUtils::Scale (aTextureMat, aScale.x(), aScale.y(), 1.0f);
4220 Graphic3d_TransformUtils::Translate (aTextureMat, -aTrans.x(), -aTrans.y(), 0.0f);
4221 }
4222 Graphic3d_TransformUtils::Rotate (aTextureMat, -theParams->Rotation(), 0.0f, 0.0f, 1.0f);
79f4f036 4223 core11->glLoadMatrixf (aTextureMat);
4224 core11->glMatrixMode (aMatrixMode);
4225 }
4226#endif
4227}
4228
8625ef7e 4229// =======================================================================
4230// function : SetPointSize
4231// purpose :
4232// =======================================================================
4233void OpenGl_Context::SetPointSize (const Standard_ShortReal theSize)
4234{
4235 if (!myActiveProgram.IsNull())
4236 {
4237 myActiveProgram->SetUniform (this, myActiveProgram->GetStateLocation (OpenGl_OCCT_POINT_SIZE), theSize);
4238 #if !defined(GL_ES_VERSION_2_0)
4239 //myContext->core11fwd->glEnable (GL_VERTEX_PROGRAM_POINT_SIZE);
4240 #endif
4241 }
4242#if !defined(GL_ES_VERSION_2_0)
4243 //else
4244 {
4245 core11fwd->glPointSize (theSize);
4246 if (core20fwd != NULL)
4247 {
4248 //myContext->core11fwd->glDisable (GL_VERTEX_PROGRAM_POINT_SIZE);
4249 }
4250 }
4251#endif
7d3e64ef 4252}
7d9e854b 4253
fd59283a 4254// =======================================================================
4255// function : SetPointSpriteOrigin
4256// purpose :
4257// =======================================================================
4258void OpenGl_Context::SetPointSpriteOrigin()
4259{
4260#if !defined(GL_ES_VERSION_2_0)
4261 if (core15fwd == NULL)
4262 {
4263 return;
4264 }
4265
4266 const int aNewState = !myActiveProgram.IsNull() ? GL_UPPER_LEFT : GL_LOWER_LEFT;
4267 if (myPointSpriteOrig != aNewState)
4268 {
4269 myPointSpriteOrig = aNewState;
4270 core15fwd->glPointParameteri (GL_POINT_SPRITE_COORD_ORIGIN, aNewState);
4271 }
4272#endif
4273}
4274
7d9e854b 4275// =======================================================================
4276// function : SetGlNormalizeEnabled
4277// purpose :
4278// =======================================================================
4279Standard_Boolean OpenGl_Context::SetGlNormalizeEnabled (Standard_Boolean isEnabled)
4280{
4281 if (isEnabled == myIsGlNormalizeEnabled)
4282 {
4283 return myIsGlNormalizeEnabled;
4284 }
4285
4286 Standard_Boolean anOldGlNormalize = myIsGlNormalizeEnabled;
4287
4288 myIsGlNormalizeEnabled = isEnabled;
4289
4290#if !defined(GL_ES_VERSION_2_0)
39070532 4291 if (core11 != NULL)
7d9e854b 4292 {
39070532 4293 if (isEnabled)
4294 {
4295 ::glEnable (GL_NORMALIZE);
4296 }
4297 else
4298 {
4299 ::glDisable (GL_NORMALIZE);
4300 }
7d9e854b 4301 }
4302#endif
4303
4304 return anOldGlNormalize;
4305}
c827ea3a 4306
08669adf 4307// =======================================================================
4308// function : SetShadeModel
4309// purpose :
4310// =======================================================================
4311void OpenGl_Context::SetShadeModel (Graphic3d_TypeOfShadingModel theModel)
4312{
4313#if !defined(GL_ES_VERSION_2_0)
4314 if (core11 != NULL)
4315 {
4316 const Standard_Integer aModel = theModel == Graphic3d_TOSM_FACET
4317 || theModel == Graphic3d_TOSM_PBR_FACET ? GL_FLAT : GL_SMOOTH;
4318 if (myShadeModel == aModel)
4319 {
4320 return;
4321 }
4322 myShadeModel = aModel;
4323 core11->glShadeModel (aModel);
4324 }
4325#else
4326 (void )theModel;
4327#endif
4328}
4329
6d0e6be5 4330// =======================================================================
4331// function : SetPolygonMode
4332// purpose :
4333// =======================================================================
4334Standard_Integer OpenGl_Context::SetPolygonMode (const Standard_Integer theMode)
4335{
4336 if (myPolygonMode == theMode)
4337 {
4338 return myPolygonMode;
4339 }
4340
4341 const Standard_Integer anOldPolygonMode = myPolygonMode;
4342
4343 myPolygonMode = theMode;
4344
4345#if !defined(GL_ES_VERSION_2_0)
4346 ::glPolygonMode (GL_FRONT_AND_BACK, (GLenum)theMode);
4347#endif
4348
4349 return anOldPolygonMode;
4350}
4351
4352// =======================================================================
4353// function : SetPolygonHatchEnabled
4354// purpose :
4355// =======================================================================
4356bool OpenGl_Context::SetPolygonHatchEnabled (const bool theIsEnabled)
4357{
76fada68 4358 if (core11 == NULL)
6d0e6be5 4359 {
4360 return false;
4361 }
76fada68 4362 else if (myHatchIsEnabled == theIsEnabled)
6d0e6be5 4363 {
4364 return theIsEnabled;
4365 }
4366
76fada68 4367 const bool anOldIsEnabled = myHatchIsEnabled;
4368#if !defined(GL_ES_VERSION_2_0)
4369 if (theIsEnabled
4370 && myActiveHatchType != Aspect_HS_SOLID)
4371 {
4372 core11fwd->glEnable (GL_POLYGON_STIPPLE);
4373 }
4374 else
4375 {
4376 core11fwd->glDisable (GL_POLYGON_STIPPLE);
4377 }
4378#endif
4379 myHatchIsEnabled = theIsEnabled;
4380 return anOldIsEnabled;
6d0e6be5 4381}
4382
4383// =======================================================================
4384// function : SetPolygonHatchStyle
4385// purpose :
4386// =======================================================================
640d5fe2 4387Standard_Integer OpenGl_Context::SetPolygonHatchStyle (const Handle(Graphic3d_HatchStyle)& theStyle)
6d0e6be5 4388{
76fada68 4389 const Standard_Integer aNewStyle = !theStyle.IsNull() ? theStyle->HatchType() : Aspect_HS_SOLID;
4390 if (myActiveHatchType == aNewStyle
4391 || core11 == NULL)
ec7c343f 4392 {
76fada68 4393 return myActiveHatchType;
ec7c343f 4394 }
4395
76fada68 4396#if !defined(GL_ES_VERSION_2_0)
4397 if (aNewStyle == Aspect_HS_SOLID)
6d0e6be5 4398 {
76fada68 4399 if (myHatchIsEnabled)
6d0e6be5 4400 {
76fada68 4401 core11fwd->glDisable (GL_POLYGON_STIPPLE);
6d0e6be5 4402 }
76fada68 4403 return myActiveHatchType;
6d0e6be5 4404 }
76fada68 4405
4406 if (myHatchStyles.IsNull()
4407 && !GetResource ("OpenGl_LineAttributes", myHatchStyles))
6d0e6be5 4408 {
76fada68 4409 // share and register for release once the resource is no longer used
4410 myHatchStyles = new OpenGl_LineAttributes();
4411 ShareResource ("OpenGl_LineAttributes", myHatchStyles);
6d0e6be5 4412 }
4413
76fada68 4414 const Standard_Integer anOldType = myActiveHatchType;
4415 myActiveHatchType = aNewStyle;
4416 myHatchStyles->SetTypeOfHatch (this, theStyle);
4417 if (myHatchIsEnabled
4418 && anOldType == Aspect_HS_SOLID)
4419 {
4420 core11fwd->glEnable (GL_POLYGON_STIPPLE);
4421 }
4422 return anOldType;
4423#else
4424 return myActiveHatchType;
4425#endif
6d0e6be5 4426}
4427
8d1a539c 4428// =======================================================================
4429// function : SetPolygonOffset
4430// purpose :
4431// =======================================================================
4432void OpenGl_Context::SetPolygonOffset (const Graphic3d_PolygonOffset& theOffset)
4433{
4434 const bool toFillOld = (myPolygonOffset.Mode & Aspect_POM_Fill) == Aspect_POM_Fill;
4435 const bool toFillNew = (theOffset.Mode & Aspect_POM_Fill) == Aspect_POM_Fill;
4436 if (toFillNew != toFillOld)
4437 {
4438 if (toFillNew)
4439 {
4440 glEnable (GL_POLYGON_OFFSET_FILL);
4441 }
4442 else
4443 {
4444 glDisable (GL_POLYGON_OFFSET_FILL);
4445 }
4446 }
4447
4448#if !defined(GL_ES_VERSION_2_0)
4449 const bool toLineOld = (myPolygonOffset.Mode & Aspect_POM_Line) == Aspect_POM_Line;
4450 const bool toLineNew = (theOffset.Mode & Aspect_POM_Line) == Aspect_POM_Line;
4451 if (toLineNew != toLineOld)
4452 {
4453 if (toLineNew)
4454 {
4455 glEnable (GL_POLYGON_OFFSET_LINE);
4456 }
4457 else
4458 {
4459 glDisable (GL_POLYGON_OFFSET_LINE);
4460 }
4461 }
4462
4463 const bool toPointOld = (myPolygonOffset.Mode & Aspect_POM_Point) == Aspect_POM_Point;
4464 const bool toPointNew = (theOffset.Mode & Aspect_POM_Point) == Aspect_POM_Point;
4465 if (toPointNew != toPointOld)
4466 {
4467 if (toPointNew)
4468 {
4469 glEnable (GL_POLYGON_OFFSET_POINT);
4470 }
4471 else
4472 {
4473 glDisable (GL_POLYGON_OFFSET_POINT);
4474 }
4475 }
4476#endif
4477
4478 if (myPolygonOffset.Factor != theOffset.Factor
4479 || myPolygonOffset.Units != theOffset.Units)
4480 {
4481 glPolygonOffset (theOffset.Factor, theOffset.Units);
4482 }
4483 myPolygonOffset = theOffset;
4484}
4485
b40cdc2b 4486// =======================================================================
4487// function : SetCamera
4488// purpose :
4489// =======================================================================
4490void OpenGl_Context::SetCamera (const Handle(Graphic3d_Camera)& theCamera)
4491{
4492 myCamera = theCamera;
4493 if (!theCamera.IsNull())
4494 {
4495 ProjectionState.SetCurrent (theCamera->ProjectionMatrixF());
4496 WorldViewState .SetCurrent (theCamera->OrientationMatrixF());
4497 ApplyProjectionMatrix();
4498 ApplyWorldViewMatrix();
4499 }
4500}
4501
c827ea3a 4502// =======================================================================
4503// function : ApplyModelWorldMatrix
4504// purpose :
4505// =======================================================================
4506void OpenGl_Context::ApplyModelWorldMatrix()
4507{
8613985b 4508 if (myShaderManager->ModelWorldState().ModelWorldMatrix() != ModelWorldState.Current())
c827ea3a 4509 {
4510 myShaderManager->UpdateModelWorldStateTo (ModelWorldState.Current());
4511 }
4512}
4513
4514// =======================================================================
4515// function : ApplyWorldViewMatrix
4516// purpose :
4517// =======================================================================
4518void OpenGl_Context::ApplyWorldViewMatrix()
4519{
8613985b 4520 if (myShaderManager->ModelWorldState().ModelWorldMatrix() != THE_IDENTITY_MATRIX)
c827ea3a 4521 {
8613985b 4522 myShaderManager->UpdateModelWorldStateTo (THE_IDENTITY_MATRIX);
c827ea3a 4523 }
8613985b 4524 if (myShaderManager->WorldViewState().WorldViewMatrix() != WorldViewState.Current())
c827ea3a 4525 {
4526 myShaderManager->UpdateWorldViewStateTo (WorldViewState.Current());
4527 }
4528}
4529
4530// =======================================================================
4531// function : ApplyModelViewMatrix
4532// purpose :
4533// =======================================================================
4534void OpenGl_Context::ApplyModelViewMatrix()
4535{
8613985b 4536 if (myShaderManager->ModelWorldState().ModelWorldMatrix() != ModelWorldState.Current())
c827ea3a 4537 {
8613985b 4538 myShaderManager->UpdateModelWorldStateTo (ModelWorldState.Current());
c827ea3a 4539 }
8613985b 4540 if (myShaderManager->WorldViewState().WorldViewMatrix() != WorldViewState.Current())
c827ea3a 4541 {
8613985b 4542 myShaderManager->UpdateWorldViewStateTo (WorldViewState.Current());
c827ea3a 4543 }
4544}
4545
4546// =======================================================================
4547// function : ApplyProjectionMatrix
4548// purpose :
4549// =======================================================================
4550void OpenGl_Context::ApplyProjectionMatrix()
4551{
8613985b 4552 if (myShaderManager->ProjectionState().ProjectionMatrix() != ProjectionState.Current())
c827ea3a 4553 {
4554 myShaderManager->UpdateProjectionStateTo (ProjectionState.Current());
4555 }
4556}
c357e426 4557
c357e426 4558// =======================================================================
4559// function : EnableFeatures
4560// purpose :
4561// =======================================================================
4562void OpenGl_Context::EnableFeatures() const
4563{
4564 //
4565}
4566
4567// =======================================================================
4568// function : DisableFeatures
4569// purpose :
4570// =======================================================================
4571void OpenGl_Context::DisableFeatures() const
4572{
a0b49de4 4573 // Disable stuff that's likely to slow down glDrawPixels.
c357e426 4574 glDisable(GL_DITHER);
4575 glDisable(GL_BLEND);
4576 glDisable(GL_DEPTH_TEST);
c357e426 4577 glDisable(GL_STENCIL_TEST);
4578
4579#if !defined(GL_ES_VERSION_2_0)
a0b49de4 4580 if (core11 == NULL)
4581 {
4582 return;
4583 }
4584
4585 glDisable(GL_TEXTURE_1D);
4586 glDisable(GL_TEXTURE_2D);
4587
c357e426 4588 glDisable(GL_LIGHTING);
4589 glDisable(GL_ALPHA_TEST);
4590 glDisable(GL_FOG);
4591 glDisable(GL_LOGIC_OP);
c357e426 4592
4593 glPixelTransferi(GL_MAP_COLOR, GL_FALSE);
4594 glPixelTransferi(GL_RED_SCALE, 1);
4595 glPixelTransferi(GL_RED_BIAS, 0);
4596 glPixelTransferi(GL_GREEN_SCALE, 1);
4597 glPixelTransferi(GL_GREEN_BIAS, 0);
4598 glPixelTransferi(GL_BLUE_SCALE, 1);
4599 glPixelTransferi(GL_BLUE_BIAS, 0);
4600 glPixelTransferi(GL_ALPHA_SCALE, 1);
4601 glPixelTransferi(GL_ALPHA_BIAS, 0);
4602
c357e426 4603 if ((myGlVerMajor >= 1) && (myGlVerMinor >= 2))
4604 {
c357e426 4605 if (CheckExtension ("GL_CONVOLUTION_1D_EXT"))
4606 glDisable(GL_CONVOLUTION_1D_EXT);
4607
4608 if (CheckExtension ("GL_CONVOLUTION_2D_EXT"))
4609 glDisable(GL_CONVOLUTION_2D_EXT);
4610
4611 if (CheckExtension ("GL_SEPARABLE_2D_EXT"))
4612 glDisable(GL_SEPARABLE_2D_EXT);
c357e426 4613
c357e426 4614 if (CheckExtension ("GL_SEPARABLE_2D_EXT"))
4615 glDisable(GL_HISTOGRAM_EXT);
4616
4617 if (CheckExtension ("GL_MINMAX_EXT"))
4618 glDisable(GL_MINMAX_EXT);
c357e426 4619
c357e426 4620 if (CheckExtension ("GL_TEXTURE_3D_EXT"))
4621 glDisable(GL_TEXTURE_3D_EXT);
c357e426 4622 }
4623#endif
4624}
f88457e6 4625
31174e1a 4626// =======================================================================
4627// function : SetColorMaskRGBA
4628// purpose :
4629// =======================================================================
4630void OpenGl_Context::SetColorMaskRGBA (const NCollection_Vec4<bool>& theVal)
4631{
4632 glColorMask (theVal.r() ? GL_TRUE : GL_FALSE,
4633 theVal.g() ? GL_TRUE : GL_FALSE,
4634 theVal.b() ? GL_TRUE : GL_FALSE,
4635 theVal.a() ? GL_TRUE : GL_FALSE);
4636 myColorMask = theVal;
4637}
4638
f88457e6 4639// =======================================================================
4640// function : SetColorMask
4641// purpose :
4642// =======================================================================
4643bool OpenGl_Context::SetColorMask (bool theToWriteColor)
4644{
31174e1a 4645 const bool anOldValue = myColorMask.r();
4646 myColorMask.SetValues (theToWriteColor, theToWriteColor, theToWriteColor, caps->buffersOpaqueAlpha ? false : theToWriteColor);
f88457e6 4647 const GLboolean toWrite = theToWriteColor ? GL_TRUE : GL_FALSE;
31174e1a 4648 glColorMask (toWrite, toWrite, toWrite, myColorMask.a() ? GL_TRUE : GL_FALSE);
f88457e6 4649 return anOldValue;
4650}
c40eb6b9 4651
4652// =======================================================================
4653// function : SetSampleAlphaToCoverage
4654// purpose :
4655// =======================================================================
4656bool OpenGl_Context::SetSampleAlphaToCoverage (bool theToEnable)
4657{
2a332745 4658 bool toEnable = myAllowAlphaToCov && theToEnable;
4659 if (myAlphaToCoverage == toEnable)
c40eb6b9 4660 {
4661 return myAlphaToCoverage;
4662 }
4663
4664 if (core15fwd != NULL)
4665 {
2a332745 4666 if (toEnable)
c40eb6b9 4667 {
4668 //core15fwd->core15fwd->glSampleCoverage (1.0f, GL_FALSE);
4669 core15fwd->glEnable (GL_SAMPLE_ALPHA_TO_COVERAGE);
4670 }
4671 else
4672 {
4673 core15fwd->glDisable (GL_SAMPLE_ALPHA_TO_COVERAGE);
4674 }
4675 }
4676
4677 const bool anOldValue = myAlphaToCoverage;
2a332745 4678 myAlphaToCoverage = toEnable;
c40eb6b9 4679 return anOldValue;
4680}
bc73b006 4681
d4cefcc0 4682// =======================================================================
4683// function : GetBufferSubData
4684// purpose :
4685// =======================================================================
4686bool OpenGl_Context::GetBufferSubData (GLenum theTarget, GLintptr theOffset, GLsizeiptr theSize, void* theData)
4687{
4688 if (!hasGetBufferData)
4689 {
4690 return false;
4691 }
4692#ifdef __EMSCRIPTEN__
4693 EM_ASM_(
4694 {
4695 Module.ctx.getBufferSubData($0, $1, HEAPU8.subarray($2, $2 + $3));
4696 }, theTarget, theOffset, theData, theSize);
4697 return true;
4698#elif defined(GL_ES_VERSION_2_0)
4699 if (void* aData = core30fwd->glMapBufferRange (theTarget, theOffset, theSize, GL_MAP_READ_BIT))
4700 {
4701 memcpy (theData, aData, theSize);
4702 core30fwd->glUnmapBuffer (theTarget);
4703 return true;
4704 }
4705 return false;
4706#else
4707 core15fwd->glGetBufferSubData (theTarget, theOffset, theSize, theData);
4708 return true;
4709#endif
4710}
4711
bc73b006 4712// =======================================================================
4713// function : DumpJson
4714// purpose :
4715// =======================================================================
4716void OpenGl_Context::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
4717{
4718 OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
4719
4720 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myAnisoMax)
4721 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myTexClamp)
4722 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMaxTexDim)
4723 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMaxTexCombined)
4724 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMaxDumpSizeX)
4725 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMaxDumpSizeY)
4726 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMaxClipPlanes)
4727 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMaxMsaaSamples)
4728 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMaxDrawBuffers)
4729 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMaxColorAttachments)
4730 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myGlVerMajor)
4731 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myGlVerMinor)
4732 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsInitialized)
4733 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsStereoBuffers)
4734 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsGlNormalizeEnabled)
4735
4736 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myHasRayTracing)
4737 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myHasRayTracingTextures)
4738 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myHasRayTracingAdaptiveSampling)
4739 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myHasRayTracingAdaptiveSamplingAtomic)
4740
4741 for (int i = 0; i < 4; i++)
4742 {
4743 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myViewport[i])
4744 }
4745
4746 for (int i = 0; i < 4; i++)
4747 {
4748 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myViewportVirt[i])
4749 }
4750
4751 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myPointSpriteOrig)
4752 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myRenderMode)
4753 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myPolygonMode)
4754 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myPolygonOffset)
4755 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myToCullBackFaces)
4756 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myReadBuffer)
4757
4758 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myDefaultVao)
4759 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myColorMask)
4760 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myAllowAlphaToCov)
4761 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myAlphaToCoverage)
4762 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsGlDebugCtx)
4763
4764 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myResolution)
4765 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myResolutionRatio)
4766
4767 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myLineWidthScale)
4768 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myLineFeather)
4769 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myRenderScale)
4770 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myRenderScaleInv)
4771
4772 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &ModelWorldState)
4773 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &WorldViewState)
4774 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &ProjectionState)
4775}
4776
4777// =======================================================================
4778// function : DumpJsonOpenGlState
4779// purpose :
4780// =======================================================================
4781void OpenGl_Context::DumpJsonOpenGlState (Standard_OStream& theOStream, Standard_Integer)
4782{
4783 GLboolean isEnableBlend = glIsEnabled (GL_BLEND);
4784 GLboolean isEnableCullFace = glIsEnabled (GL_CULL_FACE);
4785 GLboolean isEnableDepthTest = glIsEnabled (GL_DEPTH_TEST);
4786
4787 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, isEnableBlend)
4788 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, isEnableCullFace)
4789 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, isEnableDepthTest)
4790}
4791