0032465: Visualization, TKOpenGles - invalid enum on GL_RGBA16F initialization in...
[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>
952a0565 29#include <OpenGl_GlCore46.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
a46ab511 46#if defined(_WIN32) && defined(max)
47 #undef max
48#endif
49#include <limits>
50
f5f4ebd0 51IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Context,Standard_Transient)
52
da8bb41d 53#if defined(HAVE_EGL)
54 #include <EGL/egl.h>
55 #ifdef _MSC_VER
56 #pragma comment(lib, "libEGL.lib")
57 #endif
58#elif defined(_WIN32)
5f8b738e 59 //
b69e576a 60#elif defined(HAVE_XLIB)
61 #include <GL/glx.h> // glXGetProcAddress()
62#elif defined(__APPLE__)
5f8b738e 63 #include <dlfcn.h>
f978241f 64 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
65 //
66 #else
67 #include <OpenGL/OpenGL.h>
26d9c835 68 #include <CoreGraphics/CoreGraphics.h>
f978241f 69 #endif
5f8b738e 70#else
b69e576a 71 //
5f8b738e 72#endif
73
565baee6 74#ifdef __EMSCRIPTEN__
d4cefcc0 75 #include <emscripten.h>
565baee6 76 #include <emscripten/html5.h>
565baee6 77#endif
78
5e27df78 79namespace
80{
81 static const Handle(OpenGl_Resource) NULL_GL_RESOURCE;
458e3c0d 82 static const OpenGl_Mat4 THE_IDENTITY_MATRIX;
26d9c835 83
84 //! Add key-value pair to the dictionary.
85 static void addInfo (TColStd_IndexedDataMapOfStringString& theDict,
86 const TCollection_AsciiString& theKey,
87 const TCollection_AsciiString& theValue)
88 {
89 theDict.ChangeFromIndex (theDict.Add (theKey, theValue)) = theValue;
90 }
91
92 //! Add key-value pair to the dictionary.
93 static void addInfo (TColStd_IndexedDataMapOfStringString& theDict,
94 const TCollection_AsciiString& theKey,
95 const char* theValue)
96 {
97 TCollection_AsciiString aValue (theValue != NULL ? theValue : "");
98 theDict.ChangeFromIndex (theDict.Add (theKey, aValue)) = aValue;
99 }
01ca42b2 100}
5e27df78 101
2166f0fa
SK
102// =======================================================================
103// function : OpenGl_Context
104// purpose :
105// =======================================================================
58655684 106OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
43eddb47 107: core11ffp (NULL),
01ca42b2 108 core11fwd (NULL),
109 core15 (NULL),
01ca42b2 110 core20 (NULL),
872f98d9 111 core30 (NULL),
01ca42b2 112 core32 (NULL),
25ef750e 113 core33 (NULL),
01ca42b2 114 core41 (NULL),
01ca42b2 115 core42 (NULL),
01ca42b2 116 core43 (NULL),
01ca42b2 117 core44 (NULL),
9491df8c 118 core45 (NULL),
952a0565 119 core46 (NULL),
43eddb47 120 core15fwd (NULL),
121 core20fwd (NULL),
58655684 122 caps (!theCaps.IsNull() ? theCaps : new OpenGl_Caps()),
d4cefcc0 123 hasGetBufferData (Standard_False),
ca3c13d1 124#if defined(GL_ES_VERSION_2_0)
e1d17ceb 125 hasPackRowLength (Standard_False),
126 hasUnpackRowLength (Standard_False),
ca3c13d1 127 hasHighp (Standard_False),
e99a2f7c 128 hasUintIndex(Standard_False),
ca3c13d1 129 hasTexRGBA8(Standard_False),
130#else
e1d17ceb 131 hasPackRowLength (Standard_True),
132 hasUnpackRowLength (Standard_True),
ca3c13d1 133 hasHighp (Standard_True),
e99a2f7c 134 hasUintIndex(Standard_True),
ca3c13d1 135 hasTexRGBA8(Standard_True),
ba00aab7 136#endif
67312b79 137 hasTexFloatLinear (Standard_False),
ba00aab7 138 hasTexSRGB (Standard_False),
139 hasFboSRGB (Standard_False),
140 hasSRGBControl (Standard_False),
8f8fe4a9 141 hasFboRenderMipmap (Standard_False),
ba00aab7 142#if defined(GL_ES_VERSION_2_0)
143 hasFlatShading (OpenGl_FeatureNotAvailable),
144#else
c39bb31b 145 hasFlatShading (OpenGl_FeatureInCore),
ca3c13d1 146#endif
59515ca6 147 hasGlslBitwiseOps (OpenGl_FeatureNotAvailable),
a1073ae2 148 hasDrawBuffers (OpenGl_FeatureNotAvailable),
149 hasFloatBuffer (OpenGl_FeatureNotAvailable),
150 hasHalfFloatBuffer (OpenGl_FeatureNotAvailable),
151 hasSampleVariables (OpenGl_FeatureNotAvailable),
2a332745 152 hasGeometryStage (OpenGl_FeatureNotAvailable),
a1073ae2 153 arbDrawBuffers (Standard_False),
25ef750e 154 arbNPTW (Standard_False),
155 arbTexRG (Standard_False),
74fb257d 156 arbTexFloat (Standard_False),
cc8cbabe 157 arbSamplerObject (NULL),
25ef750e 158 arbTexBindless (NULL),
5e27df78 159 arbTBO (NULL),
25ef750e 160 arbTboRGB32 (Standard_False),
e70625d6 161 arbClipControl (Standard_False),
5e27df78 162 arbIns (NULL),
58655684 163 arbDbg (NULL),
01ca42b2 164 arbFBO (NULL),
b86bb3df 165 arbFBOBlit (NULL),
a1073ae2 166 arbSampleShading (Standard_False),
4b52faa5 167 arbDepthClamp (Standard_False),
1ce0716b 168 extFragDepth (Standard_False),
a1073ae2 169 extDrawBuffers (Standard_False),
37eb4787 170 extGS (NULL),
bf75be98 171 extBgra(Standard_False),
172 extAnis(Standard_False),
30f0ad28 173 extPDS (Standard_False),
f0430952 174 atiMem (Standard_False),
175 nvxMem (Standard_False),
a1073ae2 176 oesSampleVariables (Standard_False),
8c3237d4 177 oesStdDerivatives (Standard_False),
b69e576a 178 myWindow (0),
179 myDisplay (0),
180 myGContext(0),
5e27df78 181 mySharedResources (new OpenGl_ResourcesMap()),
a174a3c5 182 myDelayed (new OpenGl_DelayReleaseMap()),
3125ebb6 183 myUnusedResources (new OpenGl_ResourcesStack()),
4269bd1b 184 myClippingState (),
5f8b738e 185 myGlLibHandle (NULL),
01ca42b2 186 myFuncs (new OpenGl_GlFunctions()),
faff3767 187 mySupportedFormats (new Image_SupportedFormats()),
2f6cb3ac 188 myAnisoMax (1),
ca3c13d1 189 myTexClamp (GL_CLAMP_TO_EDGE),
eafb234b 190 myMaxTexDim (1024),
cc8cbabe 191 myMaxTexCombined (1),
5c225e8e 192 myMaxTexUnitsFFP (1),
6997ff1c 193 myMaxDumpSizeX (1024),
194 myMaxDumpSizeY (1024),
4269bd1b 195 myMaxClipPlanes (6),
3c4b62a4 196 myMaxMsaaSamples(0),
a1073ae2 197 myMaxDrawBuffers (1),
198 myMaxColorAttachments (1),
5f8b738e 199 myGlVerMajor (0),
200 myGlVerMinor (0),
b5ac8292 201 myIsInitialized (Standard_False),
202 myIsStereoBuffers (Standard_False),
7d9e854b 203 myIsGlNormalizeEnabled (Standard_False),
72f6dc61 204 mySpriteTexUnit (Graphic3d_TextureUnit_PointSprite),
3a9b5dc8 205 myHasRayTracing (Standard_False),
206 myHasRayTracingTextures (Standard_False),
207 myHasRayTracingAdaptiveSampling (Standard_False),
e084dbbc 208 myHasRayTracingAdaptiveSamplingAtomic (Standard_False),
67312b79 209 myHasPBR (Standard_False),
72f6dc61 210 myPBREnvLUTTexUnit (Graphic3d_TextureUnit_PbrEnvironmentLUT),
211 myPBRDiffIBLMapSHTexUnit (Graphic3d_TextureUnit_PbrIblDiffuseSH),
212 myPBRSpecIBLMapTexUnit (Graphic3d_TextureUnit_PbrIblSpecular),
d84e8669 213 myShadowMapTexUnit (Graphic3d_TextureUnit_ShadowMap),
78c4e836 214 myDepthPeelingDepthTexUnit (Graphic3d_TextureUnit_DepthPeelingDepth),
215 myDepthPeelingFrontColorTexUnit (Graphic3d_TextureUnit_DepthPeelingFrontColor),
15669413 216 myFrameStats (new OpenGl_FrameStats()),
72f6dc61 217 myActiveMockTextures (0),
76fada68 218 myActiveHatchType (Aspect_HS_SOLID),
219 myHatchIsEnabled (false),
ca3c13d1 220#if !defined(GL_ES_VERSION_2_0)
fd59283a 221 myPointSpriteOrig (GL_UPPER_LEFT),
7d3e64ef 222 myRenderMode (GL_RENDER),
08669adf 223 myShadeModel (GL_SMOOTH),
6d0e6be5 224 myPolygonMode (GL_FILL),
ca3c13d1 225#else
fd59283a 226 myPointSpriteOrig (0),
ca3c13d1 227 myRenderMode (0),
08669adf 228 myShadeModel (0),
6d0e6be5 229 myPolygonMode (0),
ca3c13d1 230#endif
b6472664 231 myToCullBackFaces (false),
38a0206f 232 myReadBuffer (0),
c3487460 233 myDrawBuffers (0, 7),
4e1523ef 234 myDefaultVao (0),
f88457e6 235 myColorMask (true),
c40eb6b9 236 myAlphaToCoverage (false),
ba00aab7 237 myIsGlDebugCtx (false),
238 myIsSRgbWindow (false),
56689b27 239 myResolution (Graphic3d_RenderingParams::THE_DEFAULT_RESOLUTION),
240 myResolutionRatio (1.0f),
241 myLineWidthScale (1.0f),
2a332745 242 myLineFeather (1.0f),
56689b27 243 myRenderScale (1.0f),
244 myRenderScaleInv (1.0f)
2166f0fa 245{
3bffef55 246 myViewport[0] = 0;
247 myViewport[1] = 0;
248 myViewport[2] = 0;
249 myViewport[3] = 0;
56689b27 250 myViewportVirt[0] = 0;
251 myViewportVirt[1] = 0;
252 myViewportVirt[2] = 0;
253 myViewportVirt[3] = 0;
3bffef55 254
8d1a539c 255 myPolygonOffset.Mode = Aspect_POM_Off;
256 myPolygonOffset.Factor = 0.0f;
257 myPolygonOffset.Units = 0.0f;
258
4e1523ef 259 // system-dependent fields
260#if defined(HAVE_EGL)
261 myDisplay = (Aspect_Display )EGL_NO_DISPLAY;
262 myWindow = (Aspect_Drawable )EGL_NO_SURFACE;
458c2c58 263 myGContext = (Aspect_RenderingContext )EGL_NO_CONTEXT;
b69e576a 264#elif defined(__APPLE__) && !defined(HAVE_XLIB)
5f8b738e 265 // Vendors can not extend functionality on this system
266 // and developers are limited to OpenGL support provided by Mac OS X SDK.
267 // We retrieve function pointers from system library
268 // to generalize extensions support on all platforms.
269 // In this way we also reach binary compatibility benefit between OS releases
270 // if some newest functionality is optionally used.
271 // Notice that GL version / extension availability checks are required
272 // because function pointers may be available but not functionality itself
273 // (depends on renderer).
a2e4f780 274#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
a2e4f780 275 myGlLibHandle = dlopen ("/System/Library/Frameworks/OpenGLES.framework/OpenGLES", RTLD_LAZY);
276#else
5f8b738e 277 myGlLibHandle = dlopen ("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
a2e4f780 278#endif
5f8b738e 279#endif
a2e4f780 280
01ca42b2 281 memset (myFuncs.operator->(), 0, sizeof(OpenGl_GlFunctions));
30f0ad28 282 myShaderManager = new OpenGl_ShaderManager (this);
2166f0fa
SK
283}
284
285// =======================================================================
286// function : ~OpenGl_Context
287// purpose :
288// =======================================================================
289OpenGl_Context::~OpenGl_Context()
290{
5e27df78 291 // release clean up queue
292 ReleaseDelayed();
293
4e1523ef 294#if !defined(GL_ES_VERSION_2_0)
295 // release default VAO
296 if (myDefaultVao != 0
297 && IsValid()
298 && core32 != NULL)
299 {
300 core32->glDeleteVertexArrays (1, &myDefaultVao);
301 }
302 myDefaultVao = 0;
303#endif
304
72f6dc61 305 // release mock textures
306 if (!myTextureRgbaBlack.IsNull())
307 {
308 myTextureRgbaBlack->Release (this);
309 myTextureRgbaBlack.Nullify();
310 }
311 if (!myTextureRgbaWhite.IsNull())
312 {
313 myTextureRgbaWhite->Release (this);
314 myTextureRgbaWhite.Nullify();
315 }
316
a2e4f780 317 // release default FBO
318 if (!myDefaultFbo.IsNull())
319 {
320 myDefaultFbo->Release (this);
321 myDefaultFbo.Nullify();
322 }
323
5e27df78 324 // release shared resources if any
4796758e 325 if (mySharedResources->GetRefCount() <= 1)
5e27df78 326 {
392ac980 327 myShaderManager.Nullify();
5e27df78 328 for (NCollection_DataMap<TCollection_AsciiString, Handle(OpenGl_Resource)>::Iterator anIter (*mySharedResources);
329 anIter.More(); anIter.Next())
330 {
331 anIter.Value()->Release (this);
332 }
e1c659da 333
334 // release delayed resources added during deletion of shared resources
335 while (!myUnusedResources->IsEmpty())
336 {
337 myUnusedResources->First()->Release (this);
338 myUnusedResources->RemoveFirst();
339 }
5e27df78 340 }
c357e426 341 else if (myShaderManager->IsSameContext (this))
392ac980 342 {
343 myShaderManager->SetContext (NULL);
344 }
5e27df78 345 mySharedResources.Nullify();
a174a3c5 346 myDelayed.Nullify();
5e27df78 347
cbf18624 348 if (arbDbg != NULL
4e1523ef 349 && myIsGlDebugCtx
f8c8ba7a 350 && IsValid())
cbf18624 351 {
352 // reset callback
0deb6f04 353 #if !defined(GL_ES_VERSION_2_0)
cbf18624 354 void* aPtr = NULL;
3b523c4c 355 glGetPointerv (GL_DEBUG_CALLBACK_USER_PARAM, &aPtr);
cbf18624 356 if (aPtr == this)
0deb6f04 357 #endif
cbf18624 358 {
0deb6f04 359 arbDbg->glDebugMessageCallback (NULL, NULL);
cbf18624 360 }
4e1523ef 361 myIsGlDebugCtx = Standard_False;
cbf18624 362 }
5f8b738e 363}
364
05e2200b 365// =======================================================================
366// function : forcedRelease
367// purpose :
368// =======================================================================
369void OpenGl_Context::forcedRelease()
370{
371 ReleaseDelayed();
372 for (NCollection_DataMap<TCollection_AsciiString, Handle(OpenGl_Resource)>::Iterator anIter (*mySharedResources);
373 anIter.More(); anIter.Next())
374 {
375 anIter.Value()->Release (this);
376 }
377 mySharedResources->Clear();
378 myShaderManager->clear();
379 myShaderManager->SetContext (NULL);
e1c659da 380
381 // release delayed resources added during deletion of shared resources
382 while (!myUnusedResources->IsEmpty())
383 {
384 myUnusedResources->First()->Release (this);
385 myUnusedResources->RemoveFirst();
386 }
05e2200b 387}
388
3bffef55 389// =======================================================================
390// function : ResizeViewport
391// purpose :
392// =======================================================================
393void OpenGl_Context::ResizeViewport (const Standard_Integer* theRect)
394{
395 core11fwd->glViewport (theRect[0], theRect[1], theRect[2], theRect[3]);
396 myViewport[0] = theRect[0];
397 myViewport[1] = theRect[1];
398 myViewport[2] = theRect[2];
399 myViewport[3] = theRect[3];
56689b27 400 if (HasRenderScale())
401 {
402 myViewportVirt[0] = Standard_Integer(theRect[0] * myRenderScaleInv);
403 myViewportVirt[1] = Standard_Integer(theRect[1] * myRenderScaleInv);
404 myViewportVirt[2] = Standard_Integer(theRect[2] * myRenderScaleInv);
405 myViewportVirt[3] = Standard_Integer(theRect[3] * myRenderScaleInv);
406 }
407 else
408 {
409 myViewportVirt[0] = theRect[0];
410 myViewportVirt[1] = theRect[1];
411 myViewportVirt[2] = theRect[2];
412 myViewportVirt[3] = theRect[3];
413 }
3bffef55 414}
415
ca3c13d1 416#if !defined(GL_ES_VERSION_2_0)
38a0206f 417inline Standard_Integer stereoToMonoBuffer (const Standard_Integer theBuffer)
418{
419 switch (theBuffer)
b5ac8292 420 {
38a0206f 421 case GL_BACK_LEFT:
422 case GL_BACK_RIGHT:
423 return GL_BACK;
424 case GL_FRONT_LEFT:
425 case GL_FRONT_RIGHT:
426 return GL_FRONT;
427 default:
428 return theBuffer;
b5ac8292 429 }
430}
38a0206f 431#endif
b5ac8292 432
433// =======================================================================
38a0206f 434// function : SetReadBuffer
b5ac8292 435// purpose :
436// =======================================================================
38a0206f 437void OpenGl_Context::SetReadBuffer (const Standard_Integer theReadBuffer)
b5ac8292 438{
ca3c13d1 439#if !defined(GL_ES_VERSION_2_0)
38a0206f 440 myReadBuffer = !myIsStereoBuffers ? stereoToMonoBuffer (theReadBuffer) : theReadBuffer;
441 if (myReadBuffer < GL_COLOR_ATTACHMENT0
442 && arbFBO != NULL)
b5ac8292 443 {
38a0206f 444 arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
b5ac8292 445 }
38a0206f 446 ::glReadBuffer (myReadBuffer);
447#else
448 (void )theReadBuffer;
ca3c13d1 449#endif
b5ac8292 450}
451
452// =======================================================================
38a0206f 453// function : SetDrawBuffer
b5ac8292 454// purpose :
455// =======================================================================
38a0206f 456void OpenGl_Context::SetDrawBuffer (const Standard_Integer theDrawBuffer)
b5ac8292 457{
ca3c13d1 458#if !defined(GL_ES_VERSION_2_0)
a1073ae2 459 const Standard_Integer aDrawBuffer = !myIsStereoBuffers ? stereoToMonoBuffer (theDrawBuffer) : theDrawBuffer;
460 if (aDrawBuffer < GL_COLOR_ATTACHMENT0
38a0206f 461 && arbFBO != NULL)
b5ac8292 462 {
38a0206f 463 arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
b5ac8292 464 }
a1073ae2 465 ::glDrawBuffer (aDrawBuffer);
466
c3487460 467 myDrawBuffers.Init (GL_NONE);
468 myDrawBuffers.SetValue (0, aDrawBuffer);
38a0206f 469#else
470 (void )theDrawBuffer;
ca3c13d1 471#endif
b5ac8292 472}
473
a1073ae2 474// =======================================================================
475// function : SetDrawBuffers
476// purpose :
477// =======================================================================
478void OpenGl_Context::SetDrawBuffers (const Standard_Integer theNb, const Standard_Integer* theDrawBuffers)
479{
480 Standard_ASSERT_RETURN (hasDrawBuffers, "Multiple draw buffers feature is not supported by the context", Standard_ASSERT_DO_NOTHING());
481
c3487460 482 if (myDrawBuffers.Length() < theNb)
483 {
484 // should actually never happen here
485 myDrawBuffers.Resize (0, theNb - 1, false);
486 }
487 myDrawBuffers.Init (GL_NONE);
a1073ae2 488
489 Standard_Boolean useDefaultFbo = Standard_False;
490 for (Standard_Integer anI = 0; anI < theNb; ++anI)
491 {
b17e5bae 492 if (theDrawBuffers[anI] < GL_COLOR_ATTACHMENT0 && theDrawBuffers[anI] != GL_NONE)
a1073ae2 493 {
494 useDefaultFbo = Standard_True;
495 }
c3487460 496 else
a1073ae2 497 {
b17e5bae 498 myDrawBuffers.SetValue (anI, theDrawBuffers[anI]);
a1073ae2 499 }
500 }
501 if (arbFBO != NULL && useDefaultFbo)
502 {
503 arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
504 }
505
506 myFuncs->glDrawBuffers (theNb, (const GLenum*)theDrawBuffers);
507}
508
ba00aab7 509// =======================================================================
510// function : SetFrameBufferSRGB
511// purpose :
512// =======================================================================
e5c11edd 513void OpenGl_Context::SetFrameBufferSRGB (bool theIsFbo, bool theIsFboSRgb)
ba00aab7 514{
515 if (!hasFboSRGB)
516 {
517 myIsSRgbActive = false;
518 return;
519 }
520 myIsSRgbActive = ToRenderSRGB()
e5c11edd 521 && (theIsFbo || myIsSRgbWindow)
522 && theIsFboSRgb;
ba00aab7 523 if (!hasSRGBControl)
524 {
525 return;
526 }
527
528 if (myIsSRgbActive)
529 {
530 core11fwd->glEnable (GL_FRAMEBUFFER_SRGB);
531 }
532 else
533 {
534 core11fwd->glDisable (GL_FRAMEBUFFER_SRGB);
535 }
536}
537
b6472664 538// =======================================================================
539// function : SetCullBackFaces
540// purpose :
541// =======================================================================
542void OpenGl_Context::SetCullBackFaces (bool theToEnable)
543{
544 if (myToCullBackFaces == theToEnable)
545 {
546 return;
547 }
548
549 myToCullBackFaces = theToEnable;
550 if (theToEnable)
551 {
552 //glCullFace (GL_BACK); GL_BACK by default
553 core11fwd->glEnable (GL_CULL_FACE);
554 }
555 else
556 {
557 core11fwd->glDisable (GL_CULL_FACE);
558 }
559}
560
b5ac8292 561// =======================================================================
562// function : FetchState
563// purpose :
564// =======================================================================
565void OpenGl_Context::FetchState()
566{
ca3c13d1 567#if !defined(GL_ES_VERSION_2_0)
b5ac8292 568 // cache feedback mode state
43eddb47 569 if (core11ffp != NULL)
4e1523ef 570 {
571 ::glGetIntegerv (GL_RENDER_MODE, &myRenderMode);
08669adf 572 ::glGetIntegerv (GL_SHADE_MODEL, &myShadeModel);
4e1523ef 573 }
b5ac8292 574
a1073ae2 575 // cache read buffers state
38a0206f 576 ::glGetIntegerv (GL_READ_BUFFER, &myReadBuffer);
a1073ae2 577
578 // cache draw buffers state
c3487460 579 if (myDrawBuffers.Length() < myMaxDrawBuffers)
580 {
581 myDrawBuffers.Resize (0, myMaxDrawBuffers - 1, false);
582 }
583 myDrawBuffers.Init (GL_NONE);
a1073ae2 584
c3487460 585 Standard_Integer aDrawBuffer = GL_NONE;
a1073ae2 586 if (myMaxDrawBuffers == 1)
587 {
a1073ae2 588 ::glGetIntegerv (GL_DRAW_BUFFER, &aDrawBuffer);
c3487460 589 myDrawBuffers.SetValue (0, aDrawBuffer);
a1073ae2 590 }
591 else
592 {
a1073ae2 593 for (Standard_Integer anI = 0; anI < myMaxDrawBuffers; ++anI)
594 {
595 ::glGetIntegerv (GL_DRAW_BUFFER0 + anI, &aDrawBuffer);
c3487460 596 myDrawBuffers.SetValue (anI, aDrawBuffer);
a1073ae2 597 }
598 }
ca3c13d1 599#endif
b5ac8292 600}
601
5e27df78 602// =======================================================================
603// function : Share
604// purpose :
605// =======================================================================
606void OpenGl_Context::Share (const Handle(OpenGl_Context)& theShareCtx)
607{
608 if (!theShareCtx.IsNull())
609 {
610 mySharedResources = theShareCtx->mySharedResources;
a174a3c5 611 myDelayed = theShareCtx->myDelayed;
3125ebb6 612 myUnusedResources = theShareCtx->myUnusedResources;
392ac980 613 myShaderManager = theShareCtx->myShaderManager;
5e27df78 614 }
615}
616
b69e576a 617#if !defined(__APPLE__) || defined(HAVE_XLIB)
4fe56619 618
86fa64d9 619// =======================================================================
620// function : IsCurrent
621// purpose :
622// =======================================================================
623Standard_Boolean OpenGl_Context::IsCurrent() const
624{
da8bb41d 625#if defined(HAVE_EGL)
626 if ((EGLDisplay )myDisplay == EGL_NO_DISPLAY
da8bb41d 627 || (EGLContext )myGContext == EGL_NO_CONTEXT)
628 {
629 return Standard_False;
630 }
631
632 return (((EGLDisplay )myDisplay == eglGetCurrentDisplay())
633 && ((EGLContext )myGContext == eglGetCurrentContext())
634 && ((EGLSurface )myWindow == eglGetCurrentSurface (EGL_DRAW)));
635#elif defined(_WIN32)
b69e576a 636 if (myDisplay == NULL || myGContext == NULL)
86fa64d9 637 {
638 return Standard_False;
639 }
b69e576a 640 return (( (HDC )myDisplay == wglGetCurrentDC())
86fa64d9 641 && ((HGLRC )myGContext == wglGetCurrentContext()));
b69e576a 642#elif defined(HAVE_XLIB)
86fa64d9 643 if (myDisplay == NULL || myWindow == 0 || myGContext == 0)
644 {
645 return Standard_False;
646 }
647
648 return ( ((Display* )myDisplay == glXGetCurrentDisplay())
649 && ((GLXContext )myGContext == glXGetCurrentContext())
650 && ((GLXDrawable )myWindow == glXGetCurrentDrawable()));
b69e576a 651#else
652 return Standard_False;
86fa64d9 653#endif
654}
655
2bd4c032 656// =======================================================================
657// function : MakeCurrent
658// purpose :
659// =======================================================================
660Standard_Boolean OpenGl_Context::MakeCurrent()
661{
da8bb41d 662#if defined(HAVE_EGL)
663 if ((EGLDisplay )myDisplay == EGL_NO_DISPLAY
da8bb41d 664 || (EGLContext )myGContext == EGL_NO_CONTEXT)
665 {
666 Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
667 return Standard_False;
668 }
669
670 if (eglMakeCurrent ((EGLDisplay )myDisplay, (EGLSurface )myWindow, (EGLSurface )myWindow, (EGLContext )myGContext) != EGL_TRUE)
671 {
672 // if there is no current context it might be impossible to use glGetError() correctly
3b523c4c 673 PushMessage (GL_DEBUG_SOURCE_WINDOW_SYSTEM, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
da8bb41d 674 "eglMakeCurrent() has failed!");
675 myIsInitialized = Standard_False;
676 return Standard_False;
677 }
678#elif defined(_WIN32)
b69e576a 679 if (myDisplay == NULL || myGContext == NULL)
2bd4c032 680 {
86fa64d9 681 Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
682 return Standard_False;
683 }
684
685 // technically it should be safe to activate already bound GL context
686 // however some drivers (Intel etc.) may FAIL doing this for unknown reason
687 if (IsCurrent())
688 {
392ac980 689 myShaderManager->SetContext (this);
86fa64d9 690 return Standard_True;
691 }
b69e576a 692 else if (wglMakeCurrent ((HDC )myDisplay, (HGLRC )myGContext) != TRUE)
86fa64d9 693 {
694 // notice that glGetError() couldn't be used here!
695 wchar_t* aMsgBuff = NULL;
696 DWORD anErrorCode = GetLastError();
697 FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
698 NULL, anErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (wchar_t* )&aMsgBuff, 0, NULL);
cbf18624 699 TCollection_ExtendedString aMsg ("wglMakeCurrent() has failed. ");
86fa64d9 700 if (aMsgBuff != NULL)
701 {
cbf18624 702 aMsg += (Standard_ExtString )aMsgBuff;
86fa64d9 703 LocalFree (aMsgBuff);
704 }
3b523c4c 705 PushMessage (GL_DEBUG_SOURCE_WINDOW_SYSTEM, GL_DEBUG_TYPE_ERROR, (unsigned int )anErrorCode, GL_DEBUG_SEVERITY_HIGH, aMsg);
fd4a6963 706 myIsInitialized = Standard_False;
2bd4c032 707 return Standard_False;
708 }
b69e576a 709#elif defined(HAVE_XLIB)
86fa64d9 710 if (myDisplay == NULL || myWindow == 0 || myGContext == 0)
711 {
712 Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
713 return Standard_False;
714 }
715
716 if (!glXMakeCurrent ((Display* )myDisplay, (GLXDrawable )myWindow, (GLXContext )myGContext))
2bd4c032 717 {
718 // if there is no current context it might be impossible to use glGetError() correctly
3b523c4c 719 PushMessage (GL_DEBUG_SOURCE_WINDOW_SYSTEM, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
cbf18624 720 "glXMakeCurrent() has failed!");
fd4a6963 721 myIsInitialized = Standard_False;
2bd4c032 722 return Standard_False;
723 }
b69e576a 724#else
725 // not implemented
726 if (!myIsInitialized)
727 {
728 throw Standard_ProgramError ("OpenGl_Context::Init() should be called before!");
729 }
2bd4c032 730#endif
392ac980 731 myShaderManager->SetContext (this);
2bd4c032 732 return Standard_True;
733}
734
5e27df78 735// =======================================================================
736// function : SwapBuffers
737// purpose :
738// =======================================================================
739void OpenGl_Context::SwapBuffers()
740{
da8bb41d 741#if defined(HAVE_EGL)
742 if ((EGLSurface )myWindow != EGL_NO_SURFACE)
743 {
744 eglSwapBuffers ((EGLDisplay )myDisplay, (EGLSurface )myWindow);
745 }
746#elif defined(_WIN32)
b69e576a 747 if ((HDC )myDisplay != NULL)
5e27df78 748 {
b69e576a 749 ::SwapBuffers ((HDC )myDisplay);
5e27df78 750 glFlush();
751 }
b69e576a 752#elif defined(HAVE_XLIB)
5e27df78 753 if ((Display* )myDisplay != NULL)
754 {
755 glXSwapBuffers ((Display* )myDisplay, (GLXDrawable )myWindow);
756 }
b69e576a 757#else
758 //
5e27df78 759#endif
760}
761
4fe56619 762#endif // __APPLE__
763
f978241f 764// =======================================================================
765// function : SetSwapInterval
766// purpose :
767// =======================================================================
768Standard_Boolean OpenGl_Context::SetSwapInterval (const Standard_Integer theInterval)
769{
770#if defined(HAVE_EGL)
771 if (::eglSwapInterval ((EGLDisplay )myDisplay, theInterval) == EGL_TRUE)
772 {
773 return Standard_True;
774 }
775#elif defined(_WIN32)
776 if (myFuncs->wglSwapIntervalEXT != NULL)
777 {
778 myFuncs->wglSwapIntervalEXT (theInterval);
779 return Standard_True;
780 }
781#elif defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
92cc34d7 782 (void )theInterval; // vsync cannot be turned OFF on iOS
f978241f 783#elif defined(__APPLE__)
784 if (::CGLSetParameter (CGLGetCurrentContext(), kCGLCPSwapInterval, &theInterval) == kCGLNoError)
785 {
786 return Standard_True;
787 }
b69e576a 788#elif defined(HAVE_XLIB)
f978241f 789 if (theInterval == -1
790 && myFuncs->glXSwapIntervalEXT != NULL)
791 {
792 typedef int (*glXSwapIntervalEXT_t_x)(Display* theDisplay, GLXDrawable theDrawable, int theInterval);
793 glXSwapIntervalEXT_t_x aFuncPtr = (glXSwapIntervalEXT_t_x )myFuncs->glXSwapIntervalEXT;
794 aFuncPtr ((Display* )myDisplay, (GLXDrawable )myWindow, theInterval);
795 return Standard_True;
796 }
797 else if (myFuncs->glXSwapIntervalSGI != NULL)
798 {
799 myFuncs->glXSwapIntervalSGI (theInterval);
800 return Standard_True;
801 }
b69e576a 802#else
803 //
f978241f 804#endif
805 return Standard_False;
806}
807
5f8b738e 808// =======================================================================
809// function : findProc
810// purpose :
811// =======================================================================
812void* OpenGl_Context::findProc (const char* theFuncName)
813{
da8bb41d 814#if defined(HAVE_EGL)
815 return (void* )eglGetProcAddress (theFuncName);
816#elif defined(_WIN32)
7c65581d 817 return (void* )wglGetProcAddress (theFuncName);
b69e576a 818#elif defined(HAVE_XLIB)
819 return (void* )glXGetProcAddress ((const GLubyte* )theFuncName);
820#elif defined(__APPLE__)
5f8b738e 821 return (myGlLibHandle != NULL) ? dlsym (myGlLibHandle, theFuncName) : NULL;
822#else
b69e576a 823 (void )theFuncName;
824 return NULL;
5f8b738e 825#endif
2166f0fa
SK
826}
827
828// =======================================================================
829// function : CheckExtension
830// purpose :
831// =======================================================================
2bd4c032 832Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtName) const
2166f0fa 833{
5f8b738e 834 if (theExtName == NULL)
835 {
0797d9d3 836#ifdef OCCT_DEBUG
5f8b738e 837 std::cerr << "CheckExtension called with NULL string!\n";
63c629aa 838#endif
5f8b738e 839 return Standard_False;
840 }
59515ca6 841 else if (caps->contextNoExtensions)
842 {
843 return Standard_False;
844 }
5f8b738e 845
4e1523ef 846#if !defined(GL_ES_VERSION_2_0)
5f8b738e 847 // available since OpenGL 3.0
848 // and the ONLY way to check extensions with OpenGL 3.1+ core profile
4e1523ef 849 if (IsGlGreaterEqual (3, 0)
850 && myFuncs->glGetStringi != NULL)
5f8b738e 851 {
852 GLint anExtNb = 0;
4e1523ef 853 ::glGetIntegerv (GL_NUM_EXTENSIONS, &anExtNb);
854 const size_t anExtNameLen = strlen (theExtName);
5f8b738e 855 for (GLint anIter = 0; anIter < anExtNb; ++anIter)
856 {
4e1523ef 857 const char* anExtension = (const char* )myFuncs->glGetStringi (GL_EXTENSIONS, (GLuint )anIter);
858 const size_t aTestExtNameLen = strlen (anExtension);
859 if (aTestExtNameLen == anExtNameLen
860 && strncmp (anExtension, theExtName, anExtNameLen) == 0)
5f8b738e 861 {
862 return Standard_True;
863 }
864 }
865 return Standard_False;
4e1523ef 866 }
867#endif
5f8b738e 868
869 // use old way with huge string for all extensions
870 const char* anExtString = (const char* )glGetString (GL_EXTENSIONS);
871 if (anExtString == NULL)
872 {
7e7c2f0b 873 Messenger()->Send ("TKOpenGL: glGetString (GL_EXTENSIONS) has returned NULL! No GL context?", Message_Warning);
2166f0fa
SK
874 return Standard_False;
875 }
0770d850 876 if (!CheckExtension (anExtString, theExtName))
877 {
878 return Standard_False;
879 }
880
881#ifdef __EMSCRIPTEN__
882 //! Check if WebGL extension is available and activate it
883 //! (usage of extension without activation will generate errors).
884 if (EMSCRIPTEN_WEBGL_CONTEXT_HANDLE aWebGlCtx = emscripten_webgl_get_current_context())
885 {
886 if (emscripten_webgl_enable_extension (aWebGlCtx, theExtName))
887 {
888 return Standard_True;
889 }
890 }
891 return Standard_False;
892#else
893 return Standard_True;
894#endif
58655684 895}
896
897// =======================================================================
898// function : CheckExtension
899// purpose :
900// =======================================================================
901Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtString,
902 const char* theExtName)
903{
904 if (theExtString == NULL)
905 {
906 return Standard_False;
907 }
2166f0fa
SK
908
909 // Search for theExtName in the extensions string.
910 // Use of strstr() is not sufficient because extension names can be prefixes of other extension names.
58655684 911 char* aPtrIter = (char* )theExtString;
912 const char* aPtrEnd = aPtrIter + strlen (theExtString);
913 const size_t anExtNameLen = strlen (theExtName);
2166f0fa
SK
914 while (aPtrIter < aPtrEnd)
915 {
6a7d83c4 916 const size_t n = strcspn (aPtrIter, " ");
5f8b738e 917 if ((n == anExtNameLen) && (strncmp (aPtrIter, theExtName, anExtNameLen) == 0))
918 {
2166f0fa 919 return Standard_True;
5f8b738e 920 }
2166f0fa
SK
921 aPtrIter += (n + 1);
922 }
923 return Standard_False;
924}
925
b69e576a 926#if !defined(__APPLE__) || defined(HAVE_XLIB)
4fe56619 927
2166f0fa
SK
928// =======================================================================
929// function : Init
930// purpose :
931// =======================================================================
4e1523ef 932Standard_Boolean OpenGl_Context::Init (const Standard_Boolean theIsCoreProfile)
2166f0fa 933{
2bd4c032 934 if (myIsInitialized)
5f8b738e 935 {
f0430952 936 return Standard_True;
5f8b738e 937 }
2bd4c032 938
da8bb41d 939#if defined(HAVE_EGL)
940 myDisplay = (Aspect_Display )eglGetCurrentDisplay();
941 myGContext = (Aspect_RenderingContext )eglGetCurrentContext();
942 myWindow = (Aspect_Drawable )eglGetCurrentSurface(EGL_DRAW);
943#elif defined(_WIN32)
b69e576a 944 myDisplay = (Aspect_Handle )wglGetCurrentDC();
2bd4c032 945 myGContext = (Aspect_RenderingContext )wglGetCurrentContext();
b69e576a 946#elif defined(HAVE_XLIB)
2bd4c032 947 myDisplay = (Aspect_Display )glXGetCurrentDisplay();
948 myGContext = (Aspect_RenderingContext )glXGetCurrentContext();
949 myWindow = (Aspect_Drawable )glXGetCurrentDrawable();
b69e576a 950#else
951 //
2bd4c032 952#endif
f0430952 953 if (myGContext == NULL)
954 {
955 return Standard_False;
956 }
2bd4c032 957
4e1523ef 958 init (theIsCoreProfile);
2bd4c032 959 myIsInitialized = Standard_True;
f0430952 960 return Standard_True;
2bd4c032 961}
962
4fe56619 963#endif // __APPLE__
964
2bd4c032 965// =======================================================================
966// function : Init
967// purpose :
968// =======================================================================
b69e576a 969Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable theSurface,
f0430952 970 const Aspect_Display theDisplay,
b69e576a 971 const Aspect_RenderingContext theContext,
4e1523ef 972 const Standard_Boolean theIsCoreProfile)
2bd4c032 973{
974 Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called only once!");
b69e576a 975 myWindow = theSurface;
2bd4c032 976 myDisplay = theDisplay;
b69e576a 977 myGContext = theContext;
86fa64d9 978 if (myGContext == NULL || !MakeCurrent())
f0430952 979 {
980 return Standard_False;
981 }
2bd4c032 982
4e1523ef 983 init (theIsCoreProfile);
2bd4c032 984 myIsInitialized = Standard_True;
f0430952 985 return Standard_True;
5f8b738e 986}
987
a46ab511 988// =======================================================================
989// function : FormatGlEnumHex
990// purpose :
991// =======================================================================
992TCollection_AsciiString OpenGl_Context::FormatGlEnumHex (int theGlEnum)
993{
994 char aBuff[16];
995 Sprintf (aBuff, theGlEnum < (int )std::numeric_limits<uint16_t>::max()
996 ? "0x%04X"
997 : "0x%08X", theGlEnum);
998 return aBuff;
999}
1000
1001// =======================================================================
1002// function : FormatSize
1003// purpose :
1004// =======================================================================
1005TCollection_AsciiString OpenGl_Context::FormatSize (Standard_Size theSize)
1006{
1007 char aBuff[32];
1008 Sprintf (aBuff, "%" PRIu64, (uint64_t )theSize);
1009 return aBuff;
1010}
1011
1012// =======================================================================
1013// function : FormatPointer
1014// purpose :
1015// =======================================================================
1016TCollection_AsciiString OpenGl_Context::FormatPointer (const void* thePtr)
1017{
1018 char aBuff[32];
1019 Sprintf (aBuff, "0x%" PRIXPTR, (uintptr_t )thePtr);
1020 return aBuff;
1021}
1022
1023// =======================================================================
1024// function : FormatGlError
1025// purpose :
1026// =======================================================================
1027TCollection_AsciiString OpenGl_Context::FormatGlError (int theGlError)
1028{
1029 switch (theGlError)
1030 {
1031 case GL_INVALID_ENUM: return "GL_INVALID_ENUM";
1032 case GL_INVALID_VALUE: return "GL_INVALID_VALUE";
1033 case GL_INVALID_OPERATION: return "GL_INVALID_OPERATION";
1034 #ifdef GL_STACK_OVERFLOW
1035 case GL_STACK_OVERFLOW: return "GL_STACK_OVERFLOW";
1036 case GL_STACK_UNDERFLOW: return "GL_STACK_UNDERFLOW";
1037 #endif
1038 case GL_OUT_OF_MEMORY: return "GL_OUT_OF_MEMORY";
1039 case GL_INVALID_FRAMEBUFFER_OPERATION: return "GL_INVALID_FRAMEBUFFER_OPERATION";
1040 }
1041 return FormatGlEnumHex (theGlError);
1042}
1043
5f8b738e 1044// =======================================================================
1045// function : ResetErrors
1046// purpose :
1047// =======================================================================
f9f740d6 1048bool OpenGl_Context::ResetErrors (const bool theToPrintErrors)
5f8b738e 1049{
3c4b62a4 1050 int aPrevErr = 0;
1051 int anErr = ::glGetError();
f9f740d6 1052 const bool hasError = anErr != GL_NO_ERROR;
3c4b62a4 1053 if (!theToPrintErrors)
5f8b738e 1054 {
3c4b62a4 1055 for (; anErr != GL_NO_ERROR && aPrevErr != anErr; aPrevErr = anErr, anErr = ::glGetError())
1056 {
1057 //
1058 }
f9f740d6 1059 return hasError;
3c4b62a4 1060 }
1061
1062 for (; anErr != GL_NO_ERROR && aPrevErr != anErr; aPrevErr = anErr, anErr = ::glGetError())
1063 {
a46ab511 1064 const TCollection_ExtendedString aMsg = TCollection_ExtendedString ("Unhandled GL error: ") + FormatGlError (anErr);
1065 PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, 0, GL_DEBUG_SEVERITY_LOW, aMsg);
1066 }
1067 return hasError;
1068}
1069
1070// =======================================================================
1071// function : debugPrintError
1072// purpose :
1073// =======================================================================
1074bool OpenGl_GlFunctions::debugPrintError (const char* theName) const
1075{
1076 const int anErr = ::glGetError();
1077 if (anErr != GL_NO_ERROR)
1078 {
1079 Message::SendFail() << theName << "(), unhandled GL error: " << OpenGl_Context::FormatGlError (anErr);
1080 // there is no glSetError(), just emulate non-clear state
3c4b62a4 1081 switch (anErr)
1082 {
a46ab511 1083 case GL_INVALID_VALUE:
1084 {
1085 ::glLineWidth(-1.0f);
1086 ::glLineWidth( 1.0f);
3c4b62a4 1087 break;
a46ab511 1088 }
3c4b62a4 1089 default:
a46ab511 1090 case GL_INVALID_ENUM:
1091 {
1092 ::glEnable (0xFFFF);
3c4b62a4 1093 break;
a46ab511 1094 }
3c4b62a4 1095 }
5f8b738e 1096 }
a46ab511 1097 return anErr != GL_NO_ERROR;
5f8b738e 1098}
1099
1100// =======================================================================
4e1523ef 1101// function : ReadGlVersion
5f8b738e 1102// purpose :
1103// =======================================================================
4e1523ef 1104void OpenGl_Context::ReadGlVersion (Standard_Integer& theGlVerMajor,
1105 Standard_Integer& theGlVerMinor)
5f8b738e 1106{
1107 // reset values
4e1523ef 1108 theGlVerMajor = 0;
1109 theGlVerMinor = 0;
5f8b738e 1110
c64efd9e 1111 bool toCheckVer3 = true;
1112#if defined(__EMSCRIPTEN__)
1113 // WebGL 1.0 prints annoying invalid enumeration warnings to console.
1114 toCheckVer3 = false;
1115 if (EMSCRIPTEN_WEBGL_CONTEXT_HANDLE aWebGlCtx = emscripten_webgl_get_current_context())
5f8b738e 1116 {
c64efd9e 1117 EmscriptenWebGLContextAttributes anAttribs = {};
1118 if (emscripten_webgl_get_context_attributes (aWebGlCtx, &anAttribs) == EMSCRIPTEN_RESULT_SUCCESS)
1119 {
1120 toCheckVer3 = anAttribs.majorVersion >= 2;
1121 }
5f8b738e 1122 }
c64efd9e 1123#endif
1124
1125 // Available since OpenGL 3.0 and OpenGL ES 3.0.
1126 if (toCheckVer3)
4e1523ef 1127 {
c64efd9e 1128 GLint aMajor = 0, aMinor = 0;
1129 glGetIntegerv (GL_MAJOR_VERSION, &aMajor);
1130 glGetIntegerv (GL_MINOR_VERSION, &aMinor);
1131 // glGetError() sometimes does not report an error here even if
1132 // GL does not know GL_MAJOR_VERSION and GL_MINOR_VERSION constants.
1133 // This happens on some renderers like e.g. Cygwin MESA.
1134 // Thus checking additionally if GL has put anything to
1135 // the output variables.
1136 if (::glGetError() == GL_NO_ERROR && aMajor != 0 && aMinor != 0)
4e1523ef 1137 {
c64efd9e 1138 theGlVerMajor = aMajor;
1139 theGlVerMinor = aMinor;
1140 return;
1141 }
1142 for (GLenum anErr = ::glGetError(), aPrevErr = GL_NO_ERROR;; aPrevErr = anErr, anErr = ::glGetError())
1143 {
1144 if (anErr == GL_NO_ERROR
1145 || anErr == aPrevErr)
1146 {
1147 break;
1148 }
4e1523ef 1149 }
1150 }
5f8b738e 1151
1152 // Read version string.
ca3c13d1 1153 // Notice that only first two numbers split by point '2.1 XXXXX' are significant.
5f8b738e 1154 // Following trash (after space) is vendor-specific.
1155 // New drivers also returns micro version of GL like '3.3.0' which has no meaning
1156 // and should be considered as vendor-specific too.
1157 const char* aVerStr = (const char* )glGetString (GL_VERSION);
1158 if (aVerStr == NULL || *aVerStr == '\0')
1159 {
1160 // invalid GL context
1161 return;
1162 }
1163
ca3c13d1 1164//#if defined(GL_ES_VERSION_2_0)
1165 // skip "OpenGL ES-** " section
1166 for (; *aVerStr != '\0'; ++aVerStr)
1167 {
1168 if (*aVerStr >= '0' && *aVerStr <= '9')
1169 {
1170 break;
1171 }
1172 }
1173//#endif
1174
5f8b738e 1175 // parse string for major number
1176 char aMajorStr[32];
1177 char aMinorStr[32];
1178 size_t aMajIter = 0;
1179 while (aVerStr[aMajIter] >= '0' && aVerStr[aMajIter] <= '9')
1180 {
1181 ++aMajIter;
1182 }
1183 if (aMajIter == 0 || aMajIter >= sizeof(aMajorStr))
1184 {
1185 return;
1186 }
1187 memcpy (aMajorStr, aVerStr, aMajIter);
1188 aMajorStr[aMajIter] = '\0';
1189
1190 // parse string for minor number
86325709 1191 aVerStr += aMajIter + 1;
1192 size_t aMinIter = 0;
5f8b738e 1193 while (aVerStr[aMinIter] >= '0' && aVerStr[aMinIter] <= '9')
1194 {
1195 ++aMinIter;
1196 }
86325709 1197 if (aMinIter == 0 || aMinIter >= sizeof(aMinorStr))
5f8b738e 1198 {
1199 return;
1200 }
86325709 1201 memcpy (aMinorStr, aVerStr, aMinIter);
1202 aMinorStr[aMinIter] = '\0';
5f8b738e 1203
1204 // read numbers
4e1523ef 1205 theGlVerMajor = atoi (aMajorStr);
1206 theGlVerMinor = atoi (aMinorStr);
8f8fe4a9 1207#if defined(__EMSCRIPTEN__)
1208 if (theGlVerMajor >= 3)
1209 {
1210 if (!toCheckVer3
1211 || ::strstr (aVerStr, "WebGL 1.0") != NULL)
1212 {
1213 Message::SendWarning() << "Warning! OpenGL context reports version " << theGlVerMajor << "." << theGlVerMinor
1214 << " but WebGL 2.0 was unavailable\n"
1215 << "Fallback to OpenGL ES 2.0 will be used instead of reported version";
1216 theGlVerMajor = 2;
1217 theGlVerMinor = 0;
1218 }
1219 }
1220#endif
5f8b738e 1221
4e1523ef 1222 if (theGlVerMajor <= 0)
5f8b738e 1223 {
4e1523ef 1224 theGlVerMajor = 0;
1225 theGlVerMinor = 0;
5f8b738e 1226 }
1227}
1228
58655684 1229static Standard_CString THE_DBGMSG_UNKNOWN = "UNKNOWN";
1230static Standard_CString THE_DBGMSG_SOURCES[] =
1231{
3b523c4c 1232 ".OpenGL", // GL_DEBUG_SOURCE_API
1233 ".WinSystem", // GL_DEBUG_SOURCE_WINDOW_SYSTEM
1234 ".GLSL", // GL_DEBUG_SOURCE_SHADER_COMPILER
1235 ".3rdParty", // GL_DEBUG_SOURCE_THIRD_PARTY
1236 "", // GL_DEBUG_SOURCE_APPLICATION
1237 ".Other" // GL_DEBUG_SOURCE_OTHER
58655684 1238};
1239
1240static Standard_CString THE_DBGMSG_TYPES[] =
1241{
3b523c4c 1242 "Error", // GL_DEBUG_TYPE_ERROR
1243 "Deprecated", // GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR
1244 "Undef. behavior", // GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR
1245 "Portability", // GL_DEBUG_TYPE_PORTABILITY
1246 "Performance", // GL_DEBUG_TYPE_PERFORMANCE
1247 "Other" // GL_DEBUG_TYPE_OTHER
58655684 1248};
1249
3b523c4c 1250static Standard_CString THE_DBGMSG_SEV_HIGH = "High"; // GL_DEBUG_SEVERITY_HIGH
1251static Standard_CString THE_DBGMSG_SEV_MEDIUM = "Medium"; // GL_DEBUG_SEVERITY_MEDIUM
1252static Standard_CString THE_DBGMSG_SEV_LOW = "Low"; // GL_DEBUG_SEVERITY_LOW
58655684 1253
cbf18624 1254//! Callback for GL_ARB_debug_output extension
58655684 1255static void APIENTRY debugCallbackWrap(unsigned int theSource,
1256 unsigned int theType,
1257 unsigned int theId,
1258 unsigned int theSeverity,
1259 int /*theLength*/,
1260 const char* theMessage,
9293178b 1261 const void* theUserParam)
cbf18624 1262{
1263 OpenGl_Context* aCtx = (OpenGl_Context* )theUserParam;
1264 aCtx->PushMessage (theSource, theType, theId, theSeverity, theMessage);
1265}
1266
1267// =======================================================================
1268// function : PushMessage
1269// purpose :
1270// =======================================================================
1271void OpenGl_Context::PushMessage (const unsigned int theSource,
1272 const unsigned int theType,
1273 const unsigned int theId,
1274 const unsigned int theSeverity,
1275 const TCollection_ExtendedString& theMessage)
58655684 1276{
c87535af 1277 if (caps->suppressExtraMsg
3b523c4c 1278 && theSource >= GL_DEBUG_SOURCE_API
1279 && theSource <= GL_DEBUG_SOURCE_OTHER
1280 && myFilters[theSource - GL_DEBUG_SOURCE_API].Contains (theId))
c87535af 1281 {
1282 return;
1283 }
1284
3b523c4c 1285 Standard_CString& aSrc = (theSource >= GL_DEBUG_SOURCE_API
1286 && theSource <= GL_DEBUG_SOURCE_OTHER)
1287 ? THE_DBGMSG_SOURCES[theSource - GL_DEBUG_SOURCE_API]
58655684 1288 : THE_DBGMSG_UNKNOWN;
3b523c4c 1289 Standard_CString& aType = (theType >= GL_DEBUG_TYPE_ERROR
1290 && theType <= GL_DEBUG_TYPE_OTHER)
1291 ? THE_DBGMSG_TYPES[theType - GL_DEBUG_TYPE_ERROR]
58655684 1292 : THE_DBGMSG_UNKNOWN;
3b523c4c 1293 Standard_CString& aSev = theSeverity == GL_DEBUG_SEVERITY_HIGH
58655684 1294 ? THE_DBGMSG_SEV_HIGH
3b523c4c 1295 : (theSeverity == GL_DEBUG_SEVERITY_MEDIUM
58655684 1296 ? THE_DBGMSG_SEV_MEDIUM
1297 : THE_DBGMSG_SEV_LOW);
3b523c4c 1298 Message_Gravity aGrav = theSeverity == GL_DEBUG_SEVERITY_HIGH
cbf18624 1299 ? Message_Alarm
3b523c4c 1300 : (theSeverity == GL_DEBUG_SEVERITY_MEDIUM
cbf18624 1301 ? Message_Warning
1302 : Message_Info);
1303
1304 TCollection_ExtendedString aMsg;
1305 aMsg += "TKOpenGl"; aMsg += aSrc;
1306 aMsg += " | Type: "; aMsg += aType;
1307 aMsg += " | ID: "; aMsg += (Standard_Integer )theId;
1308 aMsg += " | Severity: "; aMsg += aSev;
1309 aMsg += " | Message:\n ";
1310 aMsg += theMessage;
7e7c2f0b 1311 Messenger()->Send (aMsg, aGrav);
58655684 1312}
1313
c87535af 1314// =======================================================================
1315// function : ExcludeMessage
1316// purpose :
1317// ======================================================================
1318Standard_Boolean OpenGl_Context::ExcludeMessage (const unsigned int theSource,
1319 const unsigned int theId)
1320{
3b523c4c 1321 return theSource >= GL_DEBUG_SOURCE_API
1322 && theSource <= GL_DEBUG_SOURCE_OTHER
1323 && myFilters[theSource - GL_DEBUG_SOURCE_API].Add (theId);
c87535af 1324}
1325
1326// =======================================================================
1327// function : IncludeMessage
1328// purpose :
1329// ======================================================================
1330Standard_Boolean OpenGl_Context::IncludeMessage (const unsigned int theSource,
1331 const unsigned int theId)
1332{
3b523c4c 1333 return theSource >= GL_DEBUG_SOURCE_API
1334 && theSource <= GL_DEBUG_SOURCE_OTHER
1335 && myFilters[theSource - GL_DEBUG_SOURCE_API].Remove (theId);
c87535af 1336}
1337
ee51a9fe 1338// =======================================================================
1339// function : checkWrongVersion
1340// purpose :
1341// ======================================================================
0ae9ac21 1342void OpenGl_Context::checkWrongVersion (Standard_Integer theGlVerMajor, Standard_Integer theGlVerMinor,
1343 const char* theLastFailedProc)
ee51a9fe 1344{
1345 if (!IsGlGreaterEqual (theGlVerMajor, theGlVerMinor))
1346 {
1347 return;
1348 }
1349
0ae9ac21 1350 PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
1351 TCollection_AsciiString()
1352 + "Error! OpenGL context reports version "
1353 + myGlVerMajor + "." + myGlVerMinor
1354 + " but does not export required functions for " + theGlVerMajor + "." + theGlVerMinor
1355 + " (" + (theLastFailedProc != NULL ? theLastFailedProc : "") + ")\n"
1356 + "Please report this issue to OpenGL driver vendor '" + myVendor + "'");
1357
1358 // lower internal version
1359 if (theGlVerMinor > 0)
1360 {
1361 myGlVerMajor = theGlVerMajor;
1362 myGlVerMinor = theGlVerMinor - 1;
1363 return;
1364 }
1365#if defined(GL_ES_VERSION_2_0)
1366 switch (theGlVerMajor)
1367 {
1368 case 3: myGlVerMajor = 2; myGlVerMinor = 0; return;
1369 }
1370#else
1371 switch (theGlVerMajor)
1372 {
1373 case 2: myGlVerMajor = 1; myGlVerMinor = 5; return;
1374 case 3: myGlVerMajor = 2; myGlVerMinor = 1; return;
1375 case 4: myGlVerMajor = 3; myGlVerMinor = 3; return;
1376 }
1377#endif
ee51a9fe 1378}
1379
5f8b738e 1380// =======================================================================
1381// function : init
1382// purpose :
1383// =======================================================================
4e1523ef 1384void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
5f8b738e 1385{
1386 // read version
4e1523ef 1387 myGlVerMajor = 0;
1388 myGlVerMinor = 0;
3c4b62a4 1389 myMaxMsaaSamples = 0;
a1073ae2 1390 myMaxDrawBuffers = 1;
1391 myMaxColorAttachments = 1;
e44b849d 1392 myDefaultVao = 0;
4e1523ef 1393 ReadGlVersion (myGlVerMajor, myGlVerMinor);
c87535af 1394 myVendor = (const char* )::glGetString (GL_VENDOR);
6997ff1c 1395 myVendor.LowerCase();
faff3767 1396 mySupportedFormats->Clear();
faff3767 1397
59515ca6 1398 if (caps->contextMajorVersionUpper != -1)
1399 {
1400 // synthetically restrict OpenGL version for testing
1401 Standard_Integer aCtxVer[2] = { myGlVerMajor, myGlVerMinor };
1402 bool isLowered = false;
1403 if (myGlVerMajor > caps->contextMajorVersionUpper)
1404 {
1405 isLowered = true;
1406 myGlVerMajor = caps->contextMajorVersionUpper;
1407 #if defined(GL_ES_VERSION_2_0)
1408 switch (myGlVerMajor)
1409 {
1410 case 2: myGlVerMinor = 0; break;
1411 }
1412 #else
1413 switch (myGlVerMajor)
1414 {
1415 case 1: myGlVerMinor = 5; break;
1416 case 2: myGlVerMinor = 1; break;
1417 case 3: myGlVerMinor = 3; break;
1418 }
1419 #endif
1420 }
1421 if (caps->contextMinorVersionUpper != -1
1422 && myGlVerMinor > caps->contextMinorVersionUpper)
1423 {
1424 isLowered = true;
1425 myGlVerMinor = caps->contextMinorVersionUpper;
1426 }
1427 if (isLowered)
1428 {
1429 PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_MEDIUM,
1430 TCollection_AsciiString ("OpenGL version ") + aCtxVer[0] + "." + aCtxVer[1]
1431 + " has been lowered to " + myGlVerMajor + "." + myGlVerMinor);
1432 }
1433 }
1434
be375252 1435 if (!caps->ffpEnable
1436 && !IsGlGreaterEqual (2, 0))
1437 {
1438 caps->ffpEnable = true;
1439 TCollection_ExtendedString aMsg =
1440 TCollection_ExtendedString("OpenGL driver is too old! Context info:\n")
1441 + " Vendor: " + (const char* )::glGetString (GL_VENDOR) + "\n"
1442 + " Renderer: " + (const char* )::glGetString (GL_RENDERER) + "\n"
1443 + " Version: " + (const char* )::glGetString (GL_VERSION) + "\n"
1444 + " Fallback using deprecated fixed-function pipeline.\n"
1445 + " Visualization might work incorrectly.\n"
1446 " Consider upgrading the graphics driver.";
1447 PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
1448 }
4e1523ef 1449
1450#if defined(GL_ES_VERSION_2_0)
1451 (void )theIsCoreProfile;
1452 const bool isCoreProfile = false;
1453#else
c87535af 1454
6997ff1c 1455 if (myVendor.Search ("nvidia") != -1)
c87535af 1456 {
1457 // Buffer detailed info: Buffer object 1 (bound to GL_ARRAY_BUFFER_ARB, usage hint is GL_STATIC_DRAW)
1458 // will use VIDEO memory as the source for buffer object operations.
3b523c4c 1459 ExcludeMessage (GL_DEBUG_SOURCE_API, 131185);
c87535af 1460 }
4e1523ef 1461 if (IsGlGreaterEqual (3, 0))
1462 {
1463 // retrieve auxiliary function in advance
1464 FindProc ("glGetStringi", myFuncs->glGetStringi);
1465 }
1466
d4271fe5 1467 bool isCoreProfile = false;
4e1523ef 1468 if (IsGlGreaterEqual (3, 2))
1469 {
d4271fe5 1470 isCoreProfile = (theIsCoreProfile == Standard_True);
4e1523ef 1471
d4271fe5 1472 // detect Core profile
c6ad5e5f 1473 if (!isCoreProfile)
4e1523ef 1474 {
d4271fe5 1475 GLint aProfile = 0;
1476 ::glGetIntegerv (GL_CONTEXT_PROFILE_MASK, &aProfile);
1477 isCoreProfile = (aProfile & GL_CONTEXT_CORE_PROFILE_BIT) != 0;
4e1523ef 1478 }
1479 }
4e1523ef 1480#endif
1481
e44b849d 1482 myFuncs->load (*this, isCoreProfile);
872f98d9 1483
4bf072e4 1484 // setup shader generator
1485 myShaderManager->SetGapiVersion (myGlVerMajor, myGlVerMinor);
1486 myShaderManager->SetEmulateDepthClamp (!arbDepthClamp);
1487
1488 bool toReverseDFdxSign = false;
1489#if defined(GL_ES_VERSION_2_0)
1490 // workaround Adreno driver bug computing reversed normal using dFdx/dFdy
1491 toReverseDFdxSign = myVendor.Search("qualcomm") != -1;
1492#endif
1493 myShaderManager->SetFlatShading (hasFlatShading != OpenGl_FeatureNotAvailable, toReverseDFdxSign);
1494#if defined(GL_ES_VERSION_2_0)
1495 myShaderManager->SetUseRedAlpha (false);
1496#else
43eddb47 1497 myShaderManager->SetUseRedAlpha (core11ffp == NULL);
4bf072e4 1498#endif
1499 #define checkGlslExtensionShort(theName) myShaderManager->EnableGlslExtension (Graphic3d_GlslExtension_ ## theName, CheckExtension (#theName))
1500#if defined(GL_ES_VERSION_2_0)
1501 checkGlslExtensionShort(GL_OES_standard_derivatives);
1502 checkGlslExtensionShort(GL_EXT_shader_texture_lod);
1503 checkGlslExtensionShort(GL_EXT_frag_depth);
1504#else
1505 checkGlslExtensionShort(GL_EXT_gpu_shader4);
1506#endif
1507
0deb6f04 1508 // initialize debug context extension
e44b849d 1509 if (arbDbg != NULL
1510 && caps->contextDebug)
1511 {
1512 // setup default callback
1513 myIsGlDebugCtx = Standard_True;
1514 arbDbg->glDebugMessageCallback (debugCallbackWrap, this);
1515 #if defined(GL_ES_VERSION_2_0)
1516 ::glEnable (GL_DEBUG_OUTPUT);
1517 #else
1518 if (core43 != NULL)
872f98d9 1519 {
e44b849d 1520 ::glEnable (GL_DEBUG_OUTPUT);
872f98d9 1521 }
e44b849d 1522 #endif
1523 if (caps->contextSyncDebug)
0deb6f04 1524 {
e44b849d 1525 // note that some broken implementations (e.g. simulators) might generate error message on this call
1526 ::glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS);
0deb6f04 1527 }
1528 }
1529
a1073ae2 1530 if (hasDrawBuffers)
1531 {
1532 glGetIntegerv (GL_MAX_DRAW_BUFFERS, &myMaxDrawBuffers);
1533 glGetIntegerv (GL_MAX_COLOR_ATTACHMENTS, &myMaxColorAttachments);
c3487460 1534 if (myDrawBuffers.Length() < myMaxDrawBuffers)
1535 {
1536 myDrawBuffers.Resize (0, myMaxDrawBuffers - 1, false);
1537 }
a1073ae2 1538 }
1539
ca3c13d1 1540 glGetIntegerv (GL_MAX_TEXTURE_SIZE, &myMaxTexDim);
737e9a8d 1541#if !defined(GL_ES_VERSION_2_0)
43eddb47 1542 if (IsGlGreaterEqual (1, 3) && core11ffp != NULL)
737e9a8d 1543 {
1544 // this is a maximum of texture units for FFP functionality,
5c225e8e 1545 // usually smaller than combined texture units available for GLSL
1546 glGetIntegerv (GL_MAX_TEXTURE_UNITS, &myMaxTexUnitsFFP);
1547 myMaxTexCombined = myMaxTexUnitsFFP;
737e9a8d 1548 }
1549#endif
5c225e8e 1550 if (IsGlGreaterEqual (2, 0))
1551 {
1552 glGetIntegerv (GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &myMaxTexCombined);
1553 }
737e9a8d 1554 mySpriteTexUnit = myMaxTexCombined >= 2
72f6dc61 1555 ? Graphic3d_TextureUnit_PointSprite
737e9a8d 1556 : Graphic3d_TextureUnit_0;
ca3c13d1 1557
6997ff1c 1558 GLint aMaxVPortSize[2] = {0, 0};
1559 glGetIntegerv (GL_MAX_VIEWPORT_DIMS, aMaxVPortSize);
1560 myMaxDumpSizeX = Min (aMaxVPortSize[0], myMaxTexDim);
1561 myMaxDumpSizeY = Min (aMaxVPortSize[1], myMaxTexDim);
1562 if (myVendor == "intel")
1563 {
1564 // Intel drivers have known bug with empty dump for images with width>=5462
1565 myMaxDumpSizeX = Min (myMaxDumpSizeX, 4096);
1566 }
1567
bf75be98 1568 if (extAnis)
1569 {
1570 glGetIntegerv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &myAnisoMax);
1571 }
f0430952 1572
25c35042 1573 myClippingState.Init();
4269bd1b 1574
e44b849d 1575#if defined(GL_ES_VERSION_2_0)
1576 if (IsGlGreaterEqual (3, 1)
1577 && myFuncs->glTexStorage2DMultisample != NULL)
0ae9ac21 1578 {
e44b849d 1579 // MSAA RenderBuffers have been defined in OpenGL ES 3.0,
1580 // but MSAA Textures - only in OpenGL ES 3.1+
0ae9ac21 1581 ::glGetIntegerv (GL_MAX_SAMPLES, &myMaxMsaaSamples);
1582 }
e44b849d 1583#else
43eddb47 1584 if (core30 != NULL)
0deb6f04 1585 {
e44b849d 1586 // MSAA RenderBuffers have been defined in OpenGL 3.0,
1587 // but MSAA Textures - only in OpenGL 3.2+
1588 if (core32 != NULL)
0deb6f04 1589 {
e44b849d 1590 ::glGetIntegerv (GL_MAX_SAMPLES, &myMaxMsaaSamples);
0deb6f04 1591 }
e44b849d 1592 else if (CheckExtension ("GL_ARB_texture_multisample")
1593 && myFuncs->glTexImage2DMultisample != NULL)
0deb6f04 1594 {
e44b849d 1595 GLint aNbColorSamples = 0, aNbDepthSamples = 0;
1596 ::glGetIntegerv (GL_MAX_COLOR_TEXTURE_SAMPLES, &aNbColorSamples);
1597 ::glGetIntegerv (GL_MAX_DEPTH_TEXTURE_SAMPLES, &aNbDepthSamples);
1598 myMaxMsaaSamples = Min (aNbColorSamples, aNbDepthSamples);
0deb6f04 1599 }
1600 }
e44b849d 1601#endif
0deb6f04 1602
e44b849d 1603#if !defined(GL_ES_VERSION_2_0)
1604 if (core32 != NULL && isCoreProfile)
2166f0fa 1605 {
e44b849d 1606 core32->glGenVertexArrays (1, &myDefaultVao);
2166f0fa 1607 }
5f8b738e 1608
e44b849d 1609 myTexClamp = IsGlGreaterEqual (1, 2) ? GL_CLAMP_TO_EDGE : GL_CLAMP;
37eb4787 1610
e44b849d 1611 GLint aStereo = GL_FALSE;
1612 glGetIntegerv (GL_STEREO, &aStereo);
1613 myIsStereoBuffers = aStereo == 1;
25ef750e 1614
e44b849d 1615 // get number of maximum clipping planes
1616 glGetIntegerv (GL_MAX_CLIP_PLANES, &myMaxClipPlanes);
93cdaa76 1617#endif
01ca42b2 1618
93cdaa76 1619#if defined(GL_ES_VERSION_2_0)
1620 // check whether ray tracing mode is supported
1621 myHasRayTracing = IsGlGreaterEqual (3, 2);
1622 myHasRayTracingTextures = myHasRayTracingAdaptiveSampling = myHasRayTracingAdaptiveSamplingAtomic = false;
1623#else
3a9b5dc8 1624 // check whether ray tracing mode is supported
e44b849d 1625 myHasRayTracing = IsGlGreaterEqual (3, 1)
3a9b5dc8 1626 && arbTboRGB32
1627 && arbFBOBlit != NULL;
1628
1629 // check whether textures in ray tracing mode are supported
1630 myHasRayTracingTextures = myHasRayTracing
1631 && arbTexBindless != NULL;
1632
1633 // check whether adaptive screen sampling in ray tracing mode is supported
1634 myHasRayTracingAdaptiveSampling = myHasRayTracing
e44b849d 1635 && core44 != NULL;
e084dbbc 1636 myHasRayTracingAdaptiveSamplingAtomic = myHasRayTracingAdaptiveSampling
1637 && CheckExtension ("GL_NV_shader_atomic_float");
ca3c13d1 1638#endif
ba00aab7 1639
1640 if (arbFBO != NULL
1641 && hasFboSRGB)
1642 {
1643 // Detect if window buffer is considered by OpenGL as sRGB-ready
1644 // (linear RGB color written by shader is automatically converted into sRGB)
1645 // or not (offscreen FBO should be blit into window buffer with gamma correction).
1646 const GLenum aDefWinBuffer =
1647 #if !defined(GL_ES_VERSION_2_0)
1648 GL_BACK_LEFT;
1649 #else
1650 GL_BACK;
1651 #endif
1652 GLint aWinColorEncoding = 0; // GL_LINEAR
1653 arbFBO->glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, aDefWinBuffer, GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, &aWinColorEncoding);
1654 ResetErrors (true);
1655 myIsSRgbWindow = aWinColorEncoding == GL_SRGB;
1656
1657 // On desktop OpenGL, pixel formats are almost always sRGB-ready, even when not requested;
1658 // it is safe behavior on desktop where GL_FRAMEBUFFER_SRGB is disabled by default
1659 // (contrary to OpenGL ES, where it is enabled by default).
1660 // NVIDIA drivers, however, always return GL_LINEAR even for sRGB-ready pixel formats on Windows platform,
1661 // while AMD and Intel report GL_SRGB as expected.
1662 // macOS drivers seems to be also report GL_LINEAR even for [NSColorSpace sRGBColorSpace].
1663 #if !defined(GL_ES_VERSION_2_0)
1664 #ifdef __APPLE__
1665 myIsSRgbWindow = true;
1666 #else
1667 if (!myIsSRgbWindow
1668 && myVendor.Search ("nvidia") != -1)
1669 {
1670 myIsSRgbWindow = true;
1671 }
1672 #endif
1673 #endif
1674 if (!myIsSRgbWindow)
1675 {
a87b1b37 1676 Message::SendTrace ("OpenGl_Context, warning: window buffer is not sRGB-ready.\n"
1677 "Check OpenGL window creation parameters for optimal performance.");
ba00aab7 1678 }
1679 }
67312b79 1680
e44b849d 1681 // standard formats
1682 mySupportedFormats->Add (Image_Format_Gray);
1683 mySupportedFormats->Add (Image_Format_Alpha);
1684 mySupportedFormats->Add (Image_Format_RGB);
1685 mySupportedFormats->Add (Image_Format_RGB32);
1686 mySupportedFormats->Add (Image_Format_RGBA);
1687 if (extBgra)
1688 {
1689 #if !defined(GL_ES_VERSION_2_0)
1690 // no BGR on OpenGL ES - only BGRA as extension
1691 mySupportedFormats->Add (Image_Format_BGR);
1692 #endif
1693 mySupportedFormats->Add (Image_Format_BGR32);
1694 mySupportedFormats->Add (Image_Format_BGRA);
1695 }
faff3767 1696 if (arbTexFloat)
1697 {
1698 mySupportedFormats->Add (Image_Format_GrayF);
1699 mySupportedFormats->Add (Image_Format_AlphaF);
1700 mySupportedFormats->Add (Image_Format_RGBF);
1701 mySupportedFormats->Add (Image_Format_RGBAF);
0770d850 1702 if (hasHalfFloatBuffer != OpenGl_FeatureNotAvailable)
1ac837b2 1703 {
1704 mySupportedFormats->Add (Image_Format_RGBAF_half);
1705 }
faff3767 1706 if (arbTexRG)
1707 {
1708 mySupportedFormats->Add (Image_Format_RGF);
0770d850 1709 if (hasHalfFloatBuffer != OpenGl_FeatureNotAvailable)
1ac837b2 1710 {
1711 mySupportedFormats->Add (Image_Format_RGF_half);
1712 }
faff3767 1713 }
1714 if (extBgra)
1715 {
1716 #if !defined(GL_ES_VERSION_2_0)
1717 mySupportedFormats->Add (Image_Format_BGRF);
1718 #endif
1719 mySupportedFormats->Add (Image_Format_BGRAF);
1720 }
1721 }
1722
1723#ifdef __EMSCRIPTEN__
0770d850 1724 if (CheckExtension ("GL_WEBGL_compressed_texture_s3tc")) // GL_WEBGL_compressed_texture_s3tc_srgb for sRGB formats
faff3767 1725 {
1726 mySupportedFormats->Add (Image_CompressedFormat_RGB_S3TC_DXT1);
1727 mySupportedFormats->Add (Image_CompressedFormat_RGBA_S3TC_DXT1);
1728 mySupportedFormats->Add (Image_CompressedFormat_RGBA_S3TC_DXT3);
1729 mySupportedFormats->Add (Image_CompressedFormat_RGBA_S3TC_DXT5);
1730 }
e44b849d 1731 if (!extPDS
0770d850 1732 && CheckExtension ("GL_WEBGL_depth_texture"))
e44b849d 1733 {
1734 extPDS = true; // WebGL 1.0 extension (in WebGL 2.0 core)
1735 }
faff3767 1736#else
1737 if (CheckExtension ("GL_EXT_texture_compression_s3tc")) // GL_EXT_texture_sRGB for sRGB formats
1738 {
1739 mySupportedFormats->Add (Image_CompressedFormat_RGB_S3TC_DXT1);
1740 mySupportedFormats->Add (Image_CompressedFormat_RGBA_S3TC_DXT1);
1741 mySupportedFormats->Add (Image_CompressedFormat_RGBA_S3TC_DXT3);
1742 mySupportedFormats->Add (Image_CompressedFormat_RGBA_S3TC_DXT5);
1743 }
1744 else
1745 {
1746 if (CheckExtension ("GL_EXT_texture_compression_dxt1"))
1747 {
1748 mySupportedFormats->Add (Image_CompressedFormat_RGB_S3TC_DXT1);
1749 mySupportedFormats->Add (Image_CompressedFormat_RGBA_S3TC_DXT1);
1750 }
1751 if (CheckExtension ("GL_ANGLE_texture_compression_dxt3"))
1752 {
1753 mySupportedFormats->Add (Image_CompressedFormat_RGBA_S3TC_DXT3);
1754 }
1755 if (CheckExtension ("GL_ANGLE_texture_compression_dxt5"))
1756 {
1757 mySupportedFormats->Add (Image_CompressedFormat_RGBA_S3TC_DXT5);
1758 }
1759 }
1760#endif
1761
67312b79 1762 // check whether PBR shading model is supported
1763 myHasPBR = arbFBO != NULL
1764 && myMaxTexCombined >= 4
67312b79 1765 && arbTexFloat
1766 && (IsGlGreaterEqual (3, 0)
8f8fe4a9 1767 #if defined(GL_ES_VERSION_2_0)
1ac837b2 1768 || hasHighp
1769 // || CheckExtension ("GL_EXT_shader_texture_lod") fallback is used when extension is unavailable
8f8fe4a9 1770 #else
67312b79 1771 || (IsGlGreaterEqual (2, 1) && CheckExtension ("GL_EXT_gpu_shader4"))
1772 #endif
1773 );
78c4e836 1774
1775 myDepthPeelingDepthTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_DepthPeelingDepth); // -6
1776 myDepthPeelingFrontColorTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_DepthPeelingFrontColor); // -5
1777 myShadowMapTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_ShadowMap); // -4
1778 myPBREnvLUTTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_PbrEnvironmentLUT); // -3
1779 myPBRDiffIBLMapSHTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_PbrIblDiffuseSH); // -2
1780 myPBRSpecIBLMapTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_PbrIblSpecular); // -1
1781 if (!myHasPBR)
67312b79 1782 {
78c4e836 1783 myDepthPeelingDepthTexUnit = static_cast<Graphic3d_TextureUnit>(myDepthPeelingDepthTexUnit + 3);
1784 myDepthPeelingFrontColorTexUnit = static_cast<Graphic3d_TextureUnit>(myDepthPeelingFrontColorTexUnit + 3);
1785 myShadowMapTexUnit = static_cast<Graphic3d_TextureUnit>(myShadowMapTexUnit + 3);
67312b79 1786 }
2166f0fa 1787}
f0430952 1788
1789// =======================================================================
1790// function : MemoryInfo
1791// purpose :
1792// =======================================================================
1793Standard_Size OpenGl_Context::AvailableMemory() const
1794{
ca3c13d1 1795#if !defined(GL_ES_VERSION_2_0)
f0430952 1796 if (atiMem)
1797 {
1798 // this is actually information for VBO pool
1799 // however because pools are mostly shared
1800 // it can be used for total GPU memory estimations
1801 GLint aMemInfo[4];
1802 aMemInfo[0] = 0;
1803 glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aMemInfo);
1804 // returned value is in KiB, however this maybe changed in future
1805 return Standard_Size(aMemInfo[0]) * 1024;
1806 }
1807 else if (nvxMem)
1808 {
1809 // current available dedicated video memory (in KiB), currently unused GPU memory
1810 GLint aMemInfo = 0;
1811 glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aMemInfo);
1812 return Standard_Size(aMemInfo) * 1024;
1813 }
ca3c13d1 1814#endif
f0430952 1815 return 0;
1816}
1817
1818// =======================================================================
1819// function : MemoryInfo
1820// purpose :
1821// =======================================================================
1822TCollection_AsciiString OpenGl_Context::MemoryInfo() const
1823{
26d9c835 1824 TColStd_IndexedDataMapOfStringString aDict;
1825 MemoryInfo (aDict);
1826
1827 TCollection_AsciiString aText;
1828 for (TColStd_IndexedDataMapOfStringString::Iterator anIter (aDict); anIter.More(); anIter.Next())
1829 {
1830 if (!aText.IsEmpty())
1831 {
1832 aText += "\n";
1833 }
1834 aText += TCollection_AsciiString(" ") + anIter.Key() + ": " + anIter.Value();
1835 }
1836 return aText;
1837}
1838
1839// =======================================================================
1840// function : MemoryInfo
1841// purpose :
1842// =======================================================================
1843void OpenGl_Context::MemoryInfo (TColStd_IndexedDataMapOfStringString& theDict) const
1844{
1845#if defined(GL_ES_VERSION_2_0)
1846 (void )theDict;
b69e576a 1847#elif defined(__APPLE__) && !defined(HAVE_XLIB)
26d9c835 1848 GLint aGlRendId = 0;
1849 CGLGetParameter (CGLGetCurrentContext(), kCGLCPCurrentRendererID, &aGlRendId);
1850
1851 CGLRendererInfoObj aRendObj = NULL;
1852 CGOpenGLDisplayMask aDispMask = CGDisplayIDToOpenGLDisplayMask (kCGDirectMainDisplay);
1853 GLint aRendNb = 0;
1854 CGLQueryRendererInfo (aDispMask, &aRendObj, &aRendNb);
1855 for (GLint aRendIter = 0; aRendIter < aRendNb; ++aRendIter)
1856 {
1857 GLint aRendId = 0;
1858 if (CGLDescribeRenderer (aRendObj, aRendIter, kCGLRPRendererID, &aRendId) != kCGLNoError
1859 || aRendId != aGlRendId)
1860 {
1861 continue;
1862 }
1863
1864 //kCGLRPVideoMemoryMegabytes = 131;
1865 //kCGLRPTextureMemoryMegabytes = 132;
1866 GLint aVMem = 0;
1867 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
1868 if (CGLDescribeRenderer(aRendObj, aRendIter, kCGLRPVideoMemoryMegabytes, &aVMem) == kCGLNoError)
1869 {
1870 addInfo (theDict, "GPU memory", TCollection_AsciiString() + aVMem + " MiB");
1871 }
1872 if (CGLDescribeRenderer(aRendObj, aRendIter, kCGLRPTextureMemoryMegabytes, &aVMem) == kCGLNoError)
1873 {
1874 addInfo (theDict, "GPU Texture memory", TCollection_AsciiString() + aVMem + " MiB");
1875 }
1876 #else
1877 if (CGLDescribeRenderer(aRendObj, aRendIter, kCGLRPVideoMemory, &aVMem) == kCGLNoError)
1878 {
1879 addInfo (theDict, "GPU memory", TCollection_AsciiString() + (aVMem / (1024 * 1024)) + " MiB");
1880 }
1881 if (CGLDescribeRenderer(aRendObj, aRendIter, kCGLRPTextureMemory, &aVMem) == kCGLNoError)
1882 {
1883 addInfo (theDict, "GPU Texture memory", TCollection_AsciiString() + (aVMem / (1024 * 1024)) + " MiB");
1884 }
1885 #endif
1886 }
1887#endif
1888
ca3c13d1 1889#if !defined(GL_ES_VERSION_2_0)
f0430952 1890 if (atiMem)
1891 {
1892 GLint aValues[4];
1893 memset (aValues, 0, sizeof(aValues));
1894 glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aValues);
1895
1896 // total memory free in the pool
26d9c835 1897 addInfo (theDict, "GPU free memory", TCollection_AsciiString() + (aValues[0] / 1024) + " MiB");
f0430952 1898
26d9c835 1899 if (aValues[1] != aValues[0])
1900 {
1901 // largest available free block in the pool
1902 addInfo (theDict, "Largest free block", TCollection_AsciiString() + (aValues[1] / 1024) + " MiB");
1903 }
f0430952 1904 if (aValues[2] != aValues[0])
1905 {
1906 // total auxiliary memory free
26d9c835 1907 addInfo (theDict, "Free auxiliary memory", TCollection_AsciiString() + (aValues[2] / 1024) + " MiB");
f0430952 1908 }
1909 }
1910 else if (nvxMem)
1911 {
1912 //current available dedicated video memory (in KiB), currently unused GPU memory
1913 GLint aValue = 0;
1914 glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aValue);
26d9c835 1915 addInfo (theDict, "GPU free memory", TCollection_AsciiString() + (aValue / 1024) + " MiB");
f0430952 1916
1917 // dedicated video memory, total size (in KiB) of the GPU memory
1918 GLint aDedicated = 0;
1919 glGetIntegerv (GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &aDedicated);
26d9c835 1920 addInfo (theDict, "GPU memory", TCollection_AsciiString() + (aDedicated / 1024) + " MiB");
f0430952 1921
1922 // total available memory, total size (in KiB) of the memory available for allocations
1923 glGetIntegerv (GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &aValue);
1924 if (aValue != aDedicated)
1925 {
1926 // different only for special configurations
26d9c835 1927 addInfo (theDict, "Total memory", TCollection_AsciiString() + (aValue / 1024) + " MiB");
1928 }
1929 }
2eacd0b8 1930#if defined(_WIN32)
1931 else if (myFuncs->wglGetGPUInfoAMD != NULL
1932 && myFuncs->wglGetContextGPUIDAMD != NULL)
1933 {
1934 GLuint aTotalMemMiB = 0;
1935 UINT anAmdId = myFuncs->wglGetContextGPUIDAMD ((HGLRC )myGContext);
1936 if (anAmdId != 0)
1937 {
1938 if (myFuncs->wglGetGPUInfoAMD (anAmdId, WGL_GPU_RAM_AMD, GL_UNSIGNED_INT, sizeof(aTotalMemMiB), &aTotalMemMiB) > 0)
1939 {
1940 addInfo (theDict, "GPU memory", TCollection_AsciiString() + (int )aTotalMemMiB + " MiB");
1941 }
1942 }
1943 }
1944#endif
26d9c835 1945#endif
1946
1947#if !defined(GL_ES_VERSION_2_0) && !defined(__APPLE__) && !defined(_WIN32)
1948 // GLX_RENDERER_VENDOR_ID_MESA
1949 if (myFuncs->glXQueryCurrentRendererIntegerMESA != NULL)
1950 {
1951 unsigned int aVMemMiB = 0;
1952 if (myFuncs->glXQueryCurrentRendererIntegerMESA (GLX_RENDERER_VIDEO_MEMORY_MESA, &aVMemMiB) != False)
1953 {
1954 addInfo (theDict, "GPU memory", TCollection_AsciiString() + int(aVMemMiB) + " MiB");
f0430952 1955 }
1956 }
ca3c13d1 1957#endif
f0430952 1958}
5e27df78 1959
26d9c835 1960// =======================================================================
1961// function : DiagnosticInfo
1962// purpose :
1963// =======================================================================
1964void OpenGl_Context::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
1965 Graphic3d_DiagnosticInfo theFlags) const
1966{
1967 if ((theFlags & Graphic3d_DiagnosticInfo_NativePlatform) != 0)
1968 {
1969 #if defined(HAVE_EGL)
6cde53c4 1970 addInfo (theDict, "EGLVersion", ::eglQueryString ((EGLDisplay )myDisplay, EGL_VERSION));
1971 addInfo (theDict, "EGLVendor", ::eglQueryString ((EGLDisplay )myDisplay, EGL_VENDOR));
1972 addInfo (theDict, "EGLClientAPIs", ::eglQueryString ((EGLDisplay )myDisplay, EGL_CLIENT_APIS));
26d9c835 1973 if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
1974 {
6cde53c4 1975 addInfo (theDict, "EGLExtensions", ::eglQueryString ((EGLDisplay )myDisplay, EGL_EXTENSIONS));
26d9c835 1976 }
1977 #elif defined(_WIN32)
1978 if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0
1979 && myFuncs->wglGetExtensionsStringARB != NULL)
1980 {
b69e576a 1981 const char* aWglExts = myFuncs->wglGetExtensionsStringARB ((HDC )myDisplay);
26d9c835 1982 addInfo (theDict, "WGLExtensions", aWglExts);
1983 }
b69e576a 1984 #elif defined(HAVE_XLIB)
26d9c835 1985 Display* aDisplay = (Display*)myDisplay;
1986 const int aScreen = DefaultScreen(aDisplay);
1987 addInfo (theDict, "GLXDirectRendering", ::glXIsDirect (aDisplay, (GLXContext )myGContext) ? "Yes" : "No");
1988 addInfo (theDict, "GLXVendor", ::glXQueryServerString (aDisplay, aScreen, GLX_VENDOR));
1989 addInfo (theDict, "GLXVersion", ::glXQueryServerString (aDisplay, aScreen, GLX_VERSION));
1990 if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
1991 {
1992 const char* aGlxExts = ::glXQueryExtensionsString (aDisplay, aScreen);
1993 addInfo(theDict, "GLXExtensions", aGlxExts);
1994 }
1995
1996 addInfo (theDict, "GLXClientVendor", ::glXGetClientString (aDisplay, GLX_VENDOR));
1997 addInfo (theDict, "GLXClientVersion", ::glXGetClientString (aDisplay, GLX_VERSION));
1998 if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
1999 {
2000 addInfo (theDict, "GLXClientExtensions", ::glXGetClientString (aDisplay, GLX_EXTENSIONS));
2001 }
b69e576a 2002 #else
2003 //
26d9c835 2004 #endif
2005 }
2006
2007 if ((theFlags & Graphic3d_DiagnosticInfo_Device) != 0)
2008 {
59515ca6 2009 Standard_Integer aDriverVer[2] = {};
2010 ReadGlVersion (aDriverVer[0], aDriverVer[1]);
26d9c835 2011 addInfo (theDict, "GLvendor", (const char*)::glGetString (GL_VENDOR));
2012 addInfo (theDict, "GLdevice", (const char*)::glGetString (GL_RENDERER));
565baee6 2013 #ifdef __EMSCRIPTEN__
0770d850 2014 if (CheckExtension ("GL_WEBGL_debug_renderer_info"))
565baee6 2015 {
2016 if (const char* aVendor = (const char*)::glGetString (0x9245))
2017 {
2018 addInfo (theDict, "GLunmaskedVendor", aVendor);
2019 }
2020 if (const char* aDevice = (const char*)::glGetString (0x9246))
2021 {
2022 addInfo (theDict, "GLunmaskedDevice", aDevice);
2023 }
2024 }
2025 #endif
2026
26d9c835 2027 addInfo (theDict, "GLversion", (const char*)::glGetString (GL_VERSION));
59515ca6 2028 if (myGlVerMajor != aDriverVer[0]
2029 || myGlVerMinor != aDriverVer[1])
2030 {
2031 addInfo (theDict, "GLversionOcct", TCollection_AsciiString (myGlVerMajor) + "." + TCollection_AsciiString (myGlVerMinor));
2032 }
048e1b3b 2033 if (IsGlGreaterEqual (2, 0))
2034 {
2035 addInfo (theDict, "GLSLversion", (const char*)::glGetString (GL_SHADING_LANGUAGE_VERSION));
2036 }
26d9c835 2037 if (myIsGlDebugCtx)
2038 {
2039 addInfo (theDict, "GLdebug", "ON");
2040 }
2041 }
2042
2043 if ((theFlags & Graphic3d_DiagnosticInfo_Limits) != 0)
2044 {
2045 addInfo (theDict, "Max texture size", TCollection_AsciiString(myMaxTexDim));
6997ff1c 2046 addInfo (theDict, "Max FBO dump size", TCollection_AsciiString() + myMaxDumpSizeX + "x" + myMaxDumpSizeY);
cc8cbabe 2047 addInfo (theDict, "Max combined texture units", TCollection_AsciiString(myMaxTexCombined));
26d9c835 2048 addInfo (theDict, "Max MSAA samples", TCollection_AsciiString(myMaxMsaaSamples));
2049 }
2050
2051 if ((theFlags & Graphic3d_DiagnosticInfo_FrameBuffer) != 0)
2052 {
2053 GLint aViewport[4] = {};
2054 ::glGetIntegerv (GL_VIEWPORT, aViewport);
2055 addInfo (theDict, "Viewport", TCollection_AsciiString() + aViewport[2] + "x" + aViewport[3]);
2056 }
2057
2058 if ((theFlags & Graphic3d_DiagnosticInfo_Memory) != 0)
2059 {
2060 MemoryInfo (theDict);
2061 }
2062
2063 if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
2064 {
2065 #if !defined(GL_ES_VERSION_2_0)
2066 if (IsGlGreaterEqual (3, 0)
2067 && myFuncs->glGetStringi != NULL)
2068 {
2069 TCollection_AsciiString anExtList;
2070 GLint anExtNb = 0;
2071 ::glGetIntegerv (GL_NUM_EXTENSIONS, &anExtNb);
2072 for (GLint anIter = 0; anIter < anExtNb; ++anIter)
2073 {
2074 const char* anExtension = (const char*)myFuncs->glGetStringi (GL_EXTENSIONS, (GLuint)anIter);
2075 if (!anExtList.IsEmpty())
2076 {
2077 anExtList += " ";
2078 }
2079 anExtList += anExtension;
2080 }
2081 addInfo(theDict, "GLextensions", anExtList);
2082 }
2083 else
2084 #endif
2085 {
2086 addInfo (theDict, "GLextensions", (const char*)::glGetString (GL_EXTENSIONS));
2087 }
2088 }
2089}
5e27df78 2090
2091// =======================================================================
2092// function : GetResource
2093// purpose :
2094// =======================================================================
2095const Handle(OpenGl_Resource)& OpenGl_Context::GetResource (const TCollection_AsciiString& theKey) const
2096{
2097 return mySharedResources->IsBound (theKey) ? mySharedResources->Find (theKey) : NULL_GL_RESOURCE;
2098}
2099
2100// =======================================================================
2101// function : ShareResource
2102// purpose :
2103// =======================================================================
2104Standard_Boolean OpenGl_Context::ShareResource (const TCollection_AsciiString& theKey,
2105 const Handle(OpenGl_Resource)& theResource)
2106{
2107 if (theKey.IsEmpty() || theResource.IsNull())
2108 {
2109 return Standard_False;
2110 }
2111 return mySharedResources->Bind (theKey, theResource);
2112}
2113
2114// =======================================================================
2115// function : ReleaseResource
2116// purpose :
2117// =======================================================================
a174a3c5 2118void OpenGl_Context::ReleaseResource (const TCollection_AsciiString& theKey,
2119 const Standard_Boolean theToDelay)
5e27df78 2120{
2121 if (!mySharedResources->IsBound (theKey))
2122 {
2123 return;
2124 }
71c810df 2125 const Handle(OpenGl_Resource)& aRes = mySharedResources->Find (theKey);
5e27df78 2126 if (aRes->GetRefCount() > 1)
2127 {
2128 return;
2129 }
2130
a174a3c5 2131 if (theToDelay)
2132 {
2133 myDelayed->Bind (theKey, 1);
2134 }
2135 else
2136 {
2137 aRes->Release (this);
2138 mySharedResources->UnBind (theKey);
2139 }
5e27df78 2140}
2141
2142// =======================================================================
5e27df78 2143// function : ReleaseDelayed
2144// purpose :
2145// =======================================================================
2146void OpenGl_Context::ReleaseDelayed()
2147{
a174a3c5 2148 // release queued elements
3125ebb6 2149 while (!myUnusedResources->IsEmpty())
5e27df78 2150 {
3125ebb6 2151 myUnusedResources->First()->Release (this);
2152 myUnusedResources->RemoveFirst();
5e27df78 2153 }
a174a3c5 2154
265d4508 2155 // release delayed shared resources
a174a3c5 2156 NCollection_Vector<TCollection_AsciiString> aDeadList;
2157 for (NCollection_DataMap<TCollection_AsciiString, Standard_Integer>::Iterator anIter (*myDelayed);
2158 anIter.More(); anIter.Next())
2159 {
2160 if (++anIter.ChangeValue() <= 2)
2161 {
5e6e5914 2162 continue; // postpone release one more frame to ensure no one uses it periodically
a174a3c5 2163 }
2164
2165 const TCollection_AsciiString& aKey = anIter.Key();
2166 if (!mySharedResources->IsBound (aKey))
2167 {
2168 // mixed unshared strategy delayed/undelayed was used!
2169 aDeadList.Append (aKey);
2170 continue;
2171 }
2172
71c810df 2173 const Handle(OpenGl_Resource)& aRes = mySharedResources->ChangeFind (aKey);
a174a3c5 2174 if (aRes->GetRefCount() > 1)
2175 {
2176 // should be only 1 instance in mySharedResources
2177 // if not - resource was reused again
2178 aDeadList.Append (aKey);
2179 continue;
2180 }
2181
43eddb47 2182 // release resource if no one requested it more than 2 redraw calls
a174a3c5 2183 aRes->Release (this);
2184 mySharedResources->UnBind (aKey);
2185 aDeadList.Append (aKey);
2186 }
2187
2188 for (Standard_Integer anIter = 0; anIter < aDeadList.Length(); ++anIter)
2189 {
2190 myDelayed->UnBind (aDeadList.Value (anIter));
2191 }
5e27df78 2192}
7d3e64ef 2193
cc8cbabe 2194// =======================================================================
2195// function : BindTextures
2196// purpose :
2197// =======================================================================
72f6dc61 2198Handle(OpenGl_TextureSet) OpenGl_Context::BindTextures (const Handle(OpenGl_TextureSet)& theTextures,
2199 const Handle(OpenGl_ShaderProgram)& theProgram)
cc8cbabe 2200{
72f6dc61 2201 const Standard_Integer aTextureSetBits = !theTextures.IsNull() ? theTextures->TextureSetBits() : 0;
2202 const Standard_Integer aProgramBits = !theProgram.IsNull() ? theProgram->TextureSetBits() : 0;
2203 Standard_Integer aMissingBits = aProgramBits & ~aTextureSetBits;
2204 if (aMissingBits != 0
2205 && myTextureRgbaBlack.IsNull())
cc8cbabe 2206 {
72f6dc61 2207 // allocate mock textures
2208 myTextureRgbaBlack = new OpenGl_Texture();
2209 myTextureRgbaWhite = new OpenGl_Texture();
2210 Image_PixMap anImage;
2211 anImage.InitZero (Image_Format_RGBA, 2, 2, 0, (Standard_Byte )0);
2212 if (!myTextureRgbaBlack->Init (this, OpenGl_TextureFormat::Create<GLubyte, 4>(), Graphic3d_Vec2i (2, 2), Graphic3d_TOT_2D, &anImage))
2213 {
2214 PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH,
2215 "Error: unable to create unit mock PBR texture map.");
2216 }
2217 anImage.InitZero (Image_Format_RGBA, 2, 2, 0, (Standard_Byte )255);
2218 if (!myTextureRgbaWhite->Init (this, OpenGl_TextureFormat::Create<GLubyte, 4>(), Graphic3d_Vec2i (2, 2), Graphic3d_TOT_2D, &anImage))
2219 {
2220 PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH,
2221 "Error: unable to create normal mock PBR texture map.");
2222 }
cc8cbabe 2223 }
2224
72f6dc61 2225 Handle(OpenGl_TextureSet) anOldTextures = myActiveTextures;
2226 if (myActiveTextures != theTextures)
cc8cbabe 2227 {
72f6dc61 2228 Handle(OpenGl_Context) aThisCtx (this);
d850414a 2229 for (OpenGl_TextureSetPairIterator aSlotIter (myActiveTextures, theTextures); aSlotIter.More(); aSlotIter.Next())
cc8cbabe 2230 {
d850414a 2231 const Graphic3d_TextureUnit aTexUnit = aSlotIter.Unit();
2232 const OpenGl_Texture* aTextureOld = aSlotIter.Texture1();
2233 const OpenGl_Texture* aTextureNew = aSlotIter.Texture2();
2234 if (aTextureNew == aTextureOld)
cc8cbabe 2235 {
d850414a 2236 continue;
cc8cbabe 2237 }
cc8cbabe 2238
d850414a 2239 if (aTextureNew != NULL
2240 && aTextureNew->IsValid())
cc8cbabe 2241 {
d850414a 2242 if (aTexUnit >= myMaxTexCombined)
cc8cbabe 2243 {
d850414a 2244 PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
2245 TCollection_AsciiString("Texture unit ") + aTexUnit + " for " + aTextureNew->ResourceId() + " exceeds hardware limit " + myMaxTexCombined);
72f6dc61 2246 continue;
2247 }
d850414a 2248
2249 aTextureNew->Bind (aThisCtx, aTexUnit);
2250 if (aTextureNew->Sampler()->ToUpdateParameters())
72f6dc61 2251 {
d850414a 2252 if (aTextureNew->Sampler()->IsImmutable())
cc8cbabe 2253 {
d850414a 2254 aTextureNew->Sampler()->Init (aThisCtx, *aTextureNew);
2255 }
2256 else
2257 {
faff3767 2258 OpenGl_Sampler::applySamplerParams (aThisCtx, aTextureNew->Sampler()->Parameters(), aTextureNew->Sampler().get(), aTextureNew->GetTarget(), aTextureNew->MaxMipmapLevel());
cc8cbabe 2259 }
72f6dc61 2260 }
d850414a 2261 #if !defined(GL_ES_VERSION_2_0)
43eddb47 2262 if (core11ffp != NULL)
72f6dc61 2263 {
d850414a 2264 OpenGl_Sampler::applyGlobalTextureParams (aThisCtx, *aTextureNew, aTextureNew->Sampler()->Parameters());
72f6dc61 2265 }
d850414a 2266 #endif
cc8cbabe 2267 }
d850414a 2268 else if (aTextureOld != NULL
2269 && aTextureOld->IsValid())
cc8cbabe 2270 {
d850414a 2271 aTextureOld->Unbind (aThisCtx, aTexUnit);
2272 #if !defined(GL_ES_VERSION_2_0)
43eddb47 2273 if (core11ffp != NULL)
d850414a 2274 {
2275 OpenGl_Sampler::resetGlobalTextureParams (aThisCtx, *aTextureOld, aTextureOld->Sampler()->Parameters());
2276 }
2277 #endif
cc8cbabe 2278 }
2279 }
72f6dc61 2280 myActiveTextures = theTextures;
2281 }
2282
2283 if (myActiveMockTextures != aMissingBits)
2284 {
2285 myActiveMockTextures = aMissingBits;
2286 for (Standard_Integer aBitIter = 0; aMissingBits != 0; ++aBitIter)
cc8cbabe 2287 {
72f6dc61 2288 Standard_Integer aUnitMask = 1 << aBitIter;
2289 if ((aUnitMask & aMissingBits) != 0)
2290 {
2291 aMissingBits = aMissingBits & ~aUnitMask;
2292 if (aBitIter == Graphic3d_TextureUnit_Normal)
2293 {
2294 myTextureRgbaBlack->Bind (this, static_cast<Graphic3d_TextureUnit>(aBitIter));
2295 }
2296 else
2297 {
2298 myTextureRgbaWhite->Bind (this, static_cast<Graphic3d_TextureUnit>(aBitIter));
2299 }
2300 }
cc8cbabe 2301 }
cc8cbabe 2302 }
2303
cc8cbabe 2304 return anOldTextures;
2305}
2306
7d3e64ef 2307// =======================================================================
2308// function : BindProgram
2309// purpose :
2310// =======================================================================
8625ef7e 2311Standard_Boolean OpenGl_Context::BindProgram (const Handle(OpenGl_ShaderProgram)& theProgram)
7d3e64ef 2312{
8625ef7e 2313 if (core20fwd == NULL)
2314 {
2315 return Standard_False;
2316 }
8613985b 2317 else if (myActiveProgram == theProgram)
2318 {
2319 return Standard_True;
2320 }
8625ef7e 2321
7d3e64ef 2322 if (theProgram.IsNull()
2323 || !theProgram->IsValid())
2324 {
2325 if (!myActiveProgram.IsNull())
2326 {
2327 core20fwd->glUseProgram (OpenGl_ShaderProgram::NO_PROGRAM);
2328 myActiveProgram.Nullify();
2329 }
8625ef7e 2330 return Standard_False;
7d3e64ef 2331 }
2332
2333 myActiveProgram = theProgram;
2334 core20fwd->glUseProgram (theProgram->ProgramId());
8625ef7e 2335 return Standard_True;
2336}
2337
4e1523ef 2338// =======================================================================
2339// function : BindDefaultVao
2340// purpose :
2341// =======================================================================
2342void OpenGl_Context::BindDefaultVao()
2343{
2344#if !defined(GL_ES_VERSION_2_0)
2345 if (myDefaultVao == 0
2346 || core32 == NULL)
2347 {
2348 return;
2349 }
2350
2351 core32->glBindVertexArray (myDefaultVao);
2352#endif
2353}
2354
a2e4f780 2355// =======================================================================
2356// function : SetDefaultFrameBuffer
2357// purpose :
2358// =======================================================================
2359Handle(OpenGl_FrameBuffer) OpenGl_Context::SetDefaultFrameBuffer (const Handle(OpenGl_FrameBuffer)& theFbo)
2360{
2361 Handle(OpenGl_FrameBuffer) aFbo = myDefaultFbo;
2362 myDefaultFbo = theFbo;
2363 return aFbo;
2364}
2365
8625ef7e 2366// =======================================================================
299e0ab9 2367// function : SetShadingMaterial
2368// purpose :
2369// =======================================================================
bf5f0ca2 2370void OpenGl_Context::SetShadingMaterial (const OpenGl_Aspects* theAspect,
a1073ae2 2371 const Handle(Graphic3d_PresentationAttributes)& theHighlight)
299e0ab9 2372{
bf5f0ca2 2373 const Handle(Graphic3d_Aspects)& anAspect = (!theHighlight.IsNull() && !theHighlight->BasicFillAreaAspect().IsNull())
2374 ? (const Handle(Graphic3d_Aspects)& )theHighlight->BasicFillAreaAspect()
2375 : theAspect->Aspect();
8613985b 2376
2377 const bool toDistinguish = anAspect->Distinguish();
2378 const bool toMapTexture = anAspect->ToMapTexture();
2379 const Graphic3d_MaterialAspect& aMatFrontSrc = anAspect->FrontMaterial();
2380 const Graphic3d_MaterialAspect& aMatBackSrc = toDistinguish
2381 ? anAspect->BackMaterial()
2382 : aMatFrontSrc;
2383 const Quantity_Color& aFrontIntColor = anAspect->InteriorColor();
2384 const Quantity_Color& aBackIntColor = toDistinguish
2385 ? anAspect->BackInteriorColor()
2386 : aFrontIntColor;
2387
941f6cae 2388 myMaterial.Init (*this, aMatFrontSrc, aFrontIntColor, aMatBackSrc, aBackIntColor);
8613985b 2389 if (!theHighlight.IsNull()
2390 && theHighlight->BasicFillAreaAspect().IsNull())
2391 {
941f6cae 2392 myMaterial.SetColor (theHighlight->ColorRGBA().GetRGB());
2393 myMaterial.SetColor (theHighlight->ColorRGBA().GetRGB());
8613985b 2394 }
a1073ae2 2395
941f6cae 2396 float anAlphaFront = 1.0f, anAlphaBack = 1.0f;
a71a71de 2397 if (CheckIsTransparent (theAspect, theHighlight, anAlphaFront, anAlphaBack))
8613985b 2398 {
941f6cae 2399 myMaterial.Common[0].Diffuse.a() = anAlphaFront;
2400 myMaterial.Common[1].Diffuse.a() = anAlphaBack;
67312b79 2401
941f6cae 2402 myMaterial.Pbr[0].BaseColor.a() = anAlphaFront;
2403 myMaterial.Pbr[1].BaseColor.a() = anAlphaBack;
299e0ab9 2404 }
8613985b 2405
2406 // do not update material properties in case of zero reflection mode,
2407 // because GL lighting will be disabled by OpenGl_PrimitiveArray::DrawArray() anyway.
c40eb6b9 2408 const OpenGl_MaterialState& aMatState = myShaderManager->MaterialState();
33425a46 2409 float anAlphaCutoff = (anAspect->AlphaMode() == Graphic3d_AlphaMode_Mask
2410 || anAspect->AlphaMode() == Graphic3d_AlphaMode_MaskBlend)
2a332745 2411 ? anAspect->AlphaCutoff()
2412 : ShortRealLast();
2413 if (anAspect->ToDrawEdges())
2414 {
2415 if (anAspect->InteriorStyle() == Aspect_IS_EMPTY
2416 || (anAspect->InteriorStyle() == Aspect_IS_SOLID
2417 && anAspect->EdgeColorRGBA().Alpha() < 1.0f))
2418 {
2419 anAlphaCutoff = 0.285f;
2420 }
2421 }
dc89236f 2422 if (theAspect->ShadingModel() == Graphic3d_TOSM_UNLIT)
8613985b 2423 {
c40eb6b9 2424 if (anAlphaCutoff == aMatState.AlphaCutoff())
2425 {
2426 return;
2427 }
8613985b 2428 }
941f6cae 2429 else if (myMaterial.IsEqual (aMatState.Material())
c40eb6b9 2430 && toDistinguish == aMatState.ToDistinguish()
2431 && toMapTexture == aMatState.ToMapTexture()
2432 && anAlphaCutoff == aMatState.AlphaCutoff())
8613985b 2433 {
2434 return;
2435 }
2436
941f6cae 2437 myShaderManager->UpdateMaterialStateTo (myMaterial, anAlphaCutoff, toDistinguish, toMapTexture);
299e0ab9 2438}
2439
a1073ae2 2440// =======================================================================
2441// function : CheckIsTransparent
2442// purpose :
2443// =======================================================================
bf5f0ca2 2444Standard_Boolean OpenGl_Context::CheckIsTransparent (const OpenGl_Aspects* theAspect,
a1073ae2 2445 const Handle(Graphic3d_PresentationAttributes)& theHighlight,
a71a71de 2446 Standard_ShortReal& theAlphaFront,
2447 Standard_ShortReal& theAlphaBack)
a1073ae2 2448{
bf5f0ca2 2449 const Handle(Graphic3d_Aspects)& anAspect = (!theHighlight.IsNull() && !theHighlight->BasicFillAreaAspect().IsNull())
2450 ? (const Handle(Graphic3d_Aspects)& )theHighlight->BasicFillAreaAspect()
2451 : theAspect->Aspect();
a1073ae2 2452
2453 const bool toDistinguish = anAspect->Distinguish();
2454 const Graphic3d_MaterialAspect& aMatFrontSrc = anAspect->FrontMaterial();
2455 const Graphic3d_MaterialAspect& aMatBackSrc = toDistinguish
2456 ? anAspect->BackMaterial()
2457 : aMatFrontSrc;
2458
2459 // handling transparency
a1073ae2 2460 if (!theHighlight.IsNull()
2461 && theHighlight->BasicFillAreaAspect().IsNull())
2462 {
a71a71de 2463 theAlphaFront = theHighlight->ColorRGBA().Alpha();
2464 theAlphaBack = theHighlight->ColorRGBA().Alpha();
2465 }
2466 else
2467 {
2468 theAlphaFront = aMatFrontSrc.Alpha();
2469 theAlphaBack = aMatBackSrc .Alpha();
a1073ae2 2470 }
2471
c40eb6b9 2472 if (anAspect->AlphaMode() == Graphic3d_AlphaMode_BlendAuto)
2473 {
2474 return theAlphaFront < 1.0f
2475 || theAlphaBack < 1.0f;
2476 }
33425a46 2477 // Graphic3d_AlphaMode_Mask and Graphic3d_AlphaMode_MaskBlend are not considered transparent here
c40eb6b9 2478 return anAspect->AlphaMode() == Graphic3d_AlphaMode_Blend;
a1073ae2 2479}
2480
299e0ab9 2481// =======================================================================
8625ef7e 2482// function : SetColor4fv
2483// purpose :
2484// =======================================================================
2485void OpenGl_Context::SetColor4fv (const OpenGl_Vec4& theColor)
2486{
2487 if (!myActiveProgram.IsNull())
2488 {
ba00aab7 2489 if (const OpenGl_ShaderUniformLocation& aLoc = myActiveProgram->GetStateLocation (OpenGl_OCCT_COLOR))
2490 {
2491 myActiveProgram->SetUniform (this, aLoc, Vec4FromQuantityColor (theColor));
2492 }
8625ef7e 2493 }
2494#if !defined(GL_ES_VERSION_2_0)
43eddb47 2495 else if (core11ffp != NULL)
8625ef7e 2496 {
43eddb47 2497 core11ffp->glColor4fv (theColor.GetData());
8625ef7e 2498 }
2499#endif
2500}
2501
ac116c22 2502// =======================================================================
2503// function : SetTypeOfLine
2504// purpose :
2505// =======================================================================
2506void OpenGl_Context::SetTypeOfLine (const Aspect_TypeOfLine theType,
2507 const Standard_ShortReal theFactor)
2508{
3f1675c9 2509 SetLineStipple (theFactor, Graphic3d_Aspects::DefaultLinePatternForType (theType));
2510}
ac116c22 2511
3f1675c9 2512// =======================================================================
2513// function : SetLineStipple
2514// purpose :
2515// =======================================================================
2516void OpenGl_Context::SetLineStipple (const Standard_ShortReal theFactor,
2517 const uint16_t thePattern)
2518{
c04c30b3 2519 if (!myActiveProgram.IsNull())
ac116c22 2520 {
59515ca6 2521 if (const OpenGl_ShaderUniformLocation aPatternLoc = myActiveProgram->GetStateLocation (OpenGl_OCCT_LINE_STIPPLE_PATTERN))
2522 {
2523 if (hasGlslBitwiseOps != OpenGl_FeatureNotAvailable)
2524 {
3f1675c9 2525 myActiveProgram->SetUniform (this, aPatternLoc, (Standard_Integer )thePattern);
59515ca6 2526 }
2527 else
2528 {
2529 Standard_Integer aPatArr[16] = {};
2530 for (unsigned int aBit = 0; aBit < 16; ++aBit)
2531 {
3f1675c9 2532 aPatArr[aBit] = ((unsigned int)(thePattern) & (1U << aBit)) != 0 ? 1 : 0;
59515ca6 2533 }
2534 myActiveProgram->SetUniform (this, aPatternLoc, 16, aPatArr);
2535 }
2536 myActiveProgram->SetUniform (this, myActiveProgram->GetStateLocation (OpenGl_OCCT_LINE_STIPPLE_FACTOR), theFactor);
2537 }
ac116c22 2538 return;
2539 }
2540
2541#if !defined(GL_ES_VERSION_2_0)
3f1675c9 2542 if (thePattern != 0xFFFF)
ac116c22 2543 {
43eddb47 2544 if (core11ffp != NULL)
ac116c22 2545 {
2546 core11fwd->glEnable (GL_LINE_STIPPLE);
2547
43eddb47 2548 core11ffp->glLineStipple (static_cast<GLint> (theFactor),
2549 static_cast<GLushort> (thePattern));
ac116c22 2550 }
2551 }
2552 else
2553 {
43eddb47 2554 if (core11ffp != NULL)
ac116c22 2555 {
2556 core11fwd->glDisable (GL_LINE_STIPPLE);
2557 }
ac116c22 2558 }
2559#endif
2560}
2561
2562// =======================================================================
2563// function : SetLineWidth
2564// purpose :
2565// =======================================================================
2566void OpenGl_Context::SetLineWidth (const Standard_ShortReal theWidth)
2567{
92996979 2568#if !defined(GL_ES_VERSION_2_0)
43eddb47 2569 if (core11ffp != NULL)
92996979 2570#endif
ac116c22 2571 {
2572 // glLineWidth() is still defined within Core Profile, but has no effect with values != 1.0f
56689b27 2573 core11fwd->glLineWidth (theWidth * myLineWidthScale);
ac116c22 2574 }
ac116c22 2575}
2576
79f4f036 2577// =======================================================================
2578// function : SetTextureMatrix
2579// purpose :
2580// =======================================================================
faff3767 2581void OpenGl_Context::SetTextureMatrix (const Handle(Graphic3d_TextureParams)& theParams,
2582 const Standard_Boolean theIsTopDown)
79f4f036 2583{
2584 if (theParams.IsNull())
2585 {
2586 return;
2587 }
faff3767 2588
2589 const Graphic3d_Vec2& aScale = theParams->Scale();
2590 const Graphic3d_Vec2& aTrans = theParams->Translation();
2591 if (!myActiveProgram.IsNull())
79f4f036 2592 {
2593 const GLint aUniLoc = myActiveProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_TRSF2D);
2594 if (aUniLoc == OpenGl_ShaderProgram::INVALID_LOCATION)
2595 {
2596 return;
2597 }
2598
2599 // pack transformation parameters
bc379358 2600 OpenGl_Vec4 aTrsf[2] =
2601 {
faff3767 2602 OpenGl_Vec4 (-aTrans.x(), -aTrans.y(), aScale.x(), aScale.y()),
bc379358 2603 OpenGl_Vec4 (static_cast<float> (std::sin (-theParams->Rotation() * M_PI / 180.0)),
2604 static_cast<float> (std::cos (-theParams->Rotation() * M_PI / 180.0)),
2605 0.0f, 0.0f)
2606 };
faff3767 2607 if (caps->isTopDownTextureUV != theIsTopDown)
2608 {
2609 // flip V
2610 aTrsf[0].y() = -aTrans.y() + 1.0f / aScale.y();
2611 aTrsf[0].w() = -aScale.y();
2612 }
79f4f036 2613 myActiveProgram->SetUniform (this, aUniLoc, 2, aTrsf);
2614 return;
2615 }
2616
2617#if !defined(GL_ES_VERSION_2_0)
43eddb47 2618 if (core11ffp != NULL)
79f4f036 2619 {
2620 GLint aMatrixMode = GL_TEXTURE;
2621 ::glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
2622
43eddb47 2623 core11ffp->glMatrixMode (GL_TEXTURE);
79f4f036 2624 OpenGl_Mat4 aTextureMat;
faff3767 2625 if (caps->isTopDownTextureUV != theIsTopDown)
2626 {
2627 // flip V
2628 Graphic3d_TransformUtils::Scale (aTextureMat, aScale.x(), -aScale.y(), 1.0f);
2629 Graphic3d_TransformUtils::Translate (aTextureMat, -aTrans.x(), -aTrans.y() + 1.0f / aScale.y(), 0.0f);
2630 }
2631 else
2632 {
2633 Graphic3d_TransformUtils::Scale (aTextureMat, aScale.x(), aScale.y(), 1.0f);
2634 Graphic3d_TransformUtils::Translate (aTextureMat, -aTrans.x(), -aTrans.y(), 0.0f);
2635 }
2636 Graphic3d_TransformUtils::Rotate (aTextureMat, -theParams->Rotation(), 0.0f, 0.0f, 1.0f);
a2af24d1 2637 core11ffp->glLoadMatrixf (aTextureMat.GetData());
43eddb47 2638 core11ffp->glMatrixMode (aMatrixMode);
79f4f036 2639 }
2640#endif
2641}
2642
8625ef7e 2643// =======================================================================
2644// function : SetPointSize
2645// purpose :
2646// =======================================================================
2647void OpenGl_Context::SetPointSize (const Standard_ShortReal theSize)
2648{
2649 if (!myActiveProgram.IsNull())
2650 {
2651 myActiveProgram->SetUniform (this, myActiveProgram->GetStateLocation (OpenGl_OCCT_POINT_SIZE), theSize);
2652 #if !defined(GL_ES_VERSION_2_0)
2653 //myContext->core11fwd->glEnable (GL_VERTEX_PROGRAM_POINT_SIZE);
2654 #endif
2655 }
2656#if !defined(GL_ES_VERSION_2_0)
2657 //else
2658 {
2659 core11fwd->glPointSize (theSize);
2660 if (core20fwd != NULL)
2661 {
2662 //myContext->core11fwd->glDisable (GL_VERTEX_PROGRAM_POINT_SIZE);
2663 }
2664 }
2665#endif
7d3e64ef 2666}
7d9e854b 2667
fd59283a 2668// =======================================================================
2669// function : SetPointSpriteOrigin
2670// purpose :
2671// =======================================================================
2672void OpenGl_Context::SetPointSpriteOrigin()
2673{
2674#if !defined(GL_ES_VERSION_2_0)
2675 if (core15fwd == NULL)
2676 {
2677 return;
2678 }
2679
2680 const int aNewState = !myActiveProgram.IsNull() ? GL_UPPER_LEFT : GL_LOWER_LEFT;
2681 if (myPointSpriteOrig != aNewState)
2682 {
2683 myPointSpriteOrig = aNewState;
2684 core15fwd->glPointParameteri (GL_POINT_SPRITE_COORD_ORIGIN, aNewState);
2685 }
2686#endif
2687}
2688
7d9e854b 2689// =======================================================================
2690// function : SetGlNormalizeEnabled
2691// purpose :
2692// =======================================================================
2693Standard_Boolean OpenGl_Context::SetGlNormalizeEnabled (Standard_Boolean isEnabled)
2694{
2695 if (isEnabled == myIsGlNormalizeEnabled)
2696 {
2697 return myIsGlNormalizeEnabled;
2698 }
2699
2700 Standard_Boolean anOldGlNormalize = myIsGlNormalizeEnabled;
7d9e854b 2701 myIsGlNormalizeEnabled = isEnabled;
7d9e854b 2702#if !defined(GL_ES_VERSION_2_0)
43eddb47 2703 if (core11ffp != NULL)
7d9e854b 2704 {
39070532 2705 if (isEnabled)
2706 {
43eddb47 2707 core11fwd->glEnable (GL_NORMALIZE);
39070532 2708 }
2709 else
2710 {
43eddb47 2711 core11fwd->glDisable (GL_NORMALIZE);
39070532 2712 }
7d9e854b 2713 }
2714#endif
2715
2716 return anOldGlNormalize;
2717}
c827ea3a 2718
08669adf 2719// =======================================================================
2720// function : SetShadeModel
2721// purpose :
2722// =======================================================================
2723void OpenGl_Context::SetShadeModel (Graphic3d_TypeOfShadingModel theModel)
2724{
2725#if !defined(GL_ES_VERSION_2_0)
43eddb47 2726 if (core11ffp != NULL)
08669adf 2727 {
2728 const Standard_Integer aModel = theModel == Graphic3d_TOSM_FACET
2729 || theModel == Graphic3d_TOSM_PBR_FACET ? GL_FLAT : GL_SMOOTH;
2730 if (myShadeModel == aModel)
2731 {
2732 return;
2733 }
2734 myShadeModel = aModel;
43eddb47 2735 core11ffp->glShadeModel (aModel);
08669adf 2736 }
2737#else
2738 (void )theModel;
2739#endif
2740}
2741
6d0e6be5 2742// =======================================================================
2743// function : SetPolygonMode
2744// purpose :
2745// =======================================================================
2746Standard_Integer OpenGl_Context::SetPolygonMode (const Standard_Integer theMode)
2747{
2748 if (myPolygonMode == theMode)
2749 {
2750 return myPolygonMode;
2751 }
2752
2753 const Standard_Integer anOldPolygonMode = myPolygonMode;
2754
2755 myPolygonMode = theMode;
2756
2757#if !defined(GL_ES_VERSION_2_0)
2758 ::glPolygonMode (GL_FRONT_AND_BACK, (GLenum)theMode);
2759#endif
2760
2761 return anOldPolygonMode;
2762}
2763
2764// =======================================================================
2765// function : SetPolygonHatchEnabled
2766// purpose :
2767// =======================================================================
2768bool OpenGl_Context::SetPolygonHatchEnabled (const bool theIsEnabled)
2769{
43eddb47 2770 if (core11ffp == NULL)
6d0e6be5 2771 {
2772 return false;
2773 }
76fada68 2774 else if (myHatchIsEnabled == theIsEnabled)
6d0e6be5 2775 {
2776 return theIsEnabled;
2777 }
2778
76fada68 2779 const bool anOldIsEnabled = myHatchIsEnabled;
2780#if !defined(GL_ES_VERSION_2_0)
2781 if (theIsEnabled
2782 && myActiveHatchType != Aspect_HS_SOLID)
2783 {
2784 core11fwd->glEnable (GL_POLYGON_STIPPLE);
2785 }
2786 else
2787 {
2788 core11fwd->glDisable (GL_POLYGON_STIPPLE);
2789 }
2790#endif
2791 myHatchIsEnabled = theIsEnabled;
2792 return anOldIsEnabled;
6d0e6be5 2793}
2794
2795// =======================================================================
2796// function : SetPolygonHatchStyle
2797// purpose :
2798// =======================================================================
640d5fe2 2799Standard_Integer OpenGl_Context::SetPolygonHatchStyle (const Handle(Graphic3d_HatchStyle)& theStyle)
6d0e6be5 2800{
76fada68 2801 const Standard_Integer aNewStyle = !theStyle.IsNull() ? theStyle->HatchType() : Aspect_HS_SOLID;
2802 if (myActiveHatchType == aNewStyle
43eddb47 2803 || core11ffp == NULL)
ec7c343f 2804 {
76fada68 2805 return myActiveHatchType;
ec7c343f 2806 }
2807
76fada68 2808#if !defined(GL_ES_VERSION_2_0)
2809 if (aNewStyle == Aspect_HS_SOLID)
6d0e6be5 2810 {
76fada68 2811 if (myHatchIsEnabled)
6d0e6be5 2812 {
76fada68 2813 core11fwd->glDisable (GL_POLYGON_STIPPLE);
6d0e6be5 2814 }
76fada68 2815 return myActiveHatchType;
6d0e6be5 2816 }
76fada68 2817
2818 if (myHatchStyles.IsNull()
2819 && !GetResource ("OpenGl_LineAttributes", myHatchStyles))
6d0e6be5 2820 {
76fada68 2821 // share and register for release once the resource is no longer used
2822 myHatchStyles = new OpenGl_LineAttributes();
2823 ShareResource ("OpenGl_LineAttributes", myHatchStyles);
6d0e6be5 2824 }
2825
76fada68 2826 const Standard_Integer anOldType = myActiveHatchType;
2827 myActiveHatchType = aNewStyle;
2828 myHatchStyles->SetTypeOfHatch (this, theStyle);
2829 if (myHatchIsEnabled
2830 && anOldType == Aspect_HS_SOLID)
2831 {
2832 core11fwd->glEnable (GL_POLYGON_STIPPLE);
2833 }
2834 return anOldType;
2835#else
2836 return myActiveHatchType;
2837#endif
6d0e6be5 2838}
2839
8d1a539c 2840// =======================================================================
2841// function : SetPolygonOffset
2842// purpose :
2843// =======================================================================
2844void OpenGl_Context::SetPolygonOffset (const Graphic3d_PolygonOffset& theOffset)
2845{
2846 const bool toFillOld = (myPolygonOffset.Mode & Aspect_POM_Fill) == Aspect_POM_Fill;
2847 const bool toFillNew = (theOffset.Mode & Aspect_POM_Fill) == Aspect_POM_Fill;
2848 if (toFillNew != toFillOld)
2849 {
2850 if (toFillNew)
2851 {
43eddb47 2852 core11fwd->glEnable (GL_POLYGON_OFFSET_FILL);
8d1a539c 2853 }
2854 else
2855 {
43eddb47 2856 core11fwd->glDisable (GL_POLYGON_OFFSET_FILL);
8d1a539c 2857 }
2858 }
2859
2860#if !defined(GL_ES_VERSION_2_0)
2861 const bool toLineOld = (myPolygonOffset.Mode & Aspect_POM_Line) == Aspect_POM_Line;
2862 const bool toLineNew = (theOffset.Mode & Aspect_POM_Line) == Aspect_POM_Line;
2863 if (toLineNew != toLineOld)
2864 {
2865 if (toLineNew)
2866 {
43eddb47 2867 core11fwd->glEnable (GL_POLYGON_OFFSET_LINE);
8d1a539c 2868 }
2869 else
2870 {
43eddb47 2871 core11fwd->glDisable (GL_POLYGON_OFFSET_LINE);
8d1a539c 2872 }
2873 }
2874
2875 const bool toPointOld = (myPolygonOffset.Mode & Aspect_POM_Point) == Aspect_POM_Point;
2876 const bool toPointNew = (theOffset.Mode & Aspect_POM_Point) == Aspect_POM_Point;
2877 if (toPointNew != toPointOld)
2878 {
2879 if (toPointNew)
2880 {
43eddb47 2881 core11fwd->glEnable (GL_POLYGON_OFFSET_POINT);
8d1a539c 2882 }
2883 else
2884 {
43eddb47 2885 core11fwd->glDisable (GL_POLYGON_OFFSET_POINT);
8d1a539c 2886 }
2887 }
2888#endif
2889
2890 if (myPolygonOffset.Factor != theOffset.Factor
2891 || myPolygonOffset.Units != theOffset.Units)
2892 {
43eddb47 2893 core11fwd->glPolygonOffset (theOffset.Factor, theOffset.Units);
8d1a539c 2894 }
2895 myPolygonOffset = theOffset;
2896}
2897
b40cdc2b 2898// =======================================================================
2899// function : SetCamera
2900// purpose :
2901// =======================================================================
2902void OpenGl_Context::SetCamera (const Handle(Graphic3d_Camera)& theCamera)
2903{
2904 myCamera = theCamera;
2905 if (!theCamera.IsNull())
2906 {
2907 ProjectionState.SetCurrent (theCamera->ProjectionMatrixF());
2908 WorldViewState .SetCurrent (theCamera->OrientationMatrixF());
2909 ApplyProjectionMatrix();
2910 ApplyWorldViewMatrix();
2911 }
2912}
2913
c827ea3a 2914// =======================================================================
2915// function : ApplyModelWorldMatrix
2916// purpose :
2917// =======================================================================
2918void OpenGl_Context::ApplyModelWorldMatrix()
2919{
8613985b 2920 if (myShaderManager->ModelWorldState().ModelWorldMatrix() != ModelWorldState.Current())
c827ea3a 2921 {
2922 myShaderManager->UpdateModelWorldStateTo (ModelWorldState.Current());
2923 }
2924}
2925
2926// =======================================================================
2927// function : ApplyWorldViewMatrix
2928// purpose :
2929// =======================================================================
2930void OpenGl_Context::ApplyWorldViewMatrix()
2931{
8613985b 2932 if (myShaderManager->ModelWorldState().ModelWorldMatrix() != THE_IDENTITY_MATRIX)
c827ea3a 2933 {
8613985b 2934 myShaderManager->UpdateModelWorldStateTo (THE_IDENTITY_MATRIX);
c827ea3a 2935 }
8613985b 2936 if (myShaderManager->WorldViewState().WorldViewMatrix() != WorldViewState.Current())
c827ea3a 2937 {
2938 myShaderManager->UpdateWorldViewStateTo (WorldViewState.Current());
2939 }
2940}
2941
2942// =======================================================================
2943// function : ApplyModelViewMatrix
2944// purpose :
2945// =======================================================================
2946void OpenGl_Context::ApplyModelViewMatrix()
2947{
8613985b 2948 if (myShaderManager->ModelWorldState().ModelWorldMatrix() != ModelWorldState.Current())
c827ea3a 2949 {
8613985b 2950 myShaderManager->UpdateModelWorldStateTo (ModelWorldState.Current());
c827ea3a 2951 }
8613985b 2952 if (myShaderManager->WorldViewState().WorldViewMatrix() != WorldViewState.Current())
c827ea3a 2953 {
8613985b 2954 myShaderManager->UpdateWorldViewStateTo (WorldViewState.Current());
c827ea3a 2955 }
2956}
2957
2958// =======================================================================
2959// function : ApplyProjectionMatrix
2960// purpose :
2961// =======================================================================
2962void OpenGl_Context::ApplyProjectionMatrix()
2963{
8613985b 2964 if (myShaderManager->ProjectionState().ProjectionMatrix() != ProjectionState.Current())
c827ea3a 2965 {
2966 myShaderManager->UpdateProjectionStateTo (ProjectionState.Current());
2967 }
2968}
c357e426 2969
c357e426 2970// =======================================================================
2971// function : EnableFeatures
2972// purpose :
2973// =======================================================================
2974void OpenGl_Context::EnableFeatures() const
2975{
2976 //
2977}
2978
2979// =======================================================================
2980// function : DisableFeatures
2981// purpose :
2982// =======================================================================
2983void OpenGl_Context::DisableFeatures() const
2984{
a0b49de4 2985 // Disable stuff that's likely to slow down glDrawPixels.
43eddb47 2986 core11fwd->glDisable(GL_DITHER);
2987 core11fwd->glDisable(GL_BLEND);
2988 core11fwd->glDisable(GL_DEPTH_TEST);
2989 core11fwd->glDisable(GL_STENCIL_TEST);
c357e426 2990
2991#if !defined(GL_ES_VERSION_2_0)
43eddb47 2992 if (core11ffp == NULL)
a0b49de4 2993 {
2994 return;
2995 }
2996
43eddb47 2997 core11fwd->glDisable(GL_TEXTURE_1D);
2998 core11fwd->glDisable(GL_TEXTURE_2D);
a0b49de4 2999
43eddb47 3000 core11fwd->glDisable(GL_LIGHTING);
3001 core11fwd->glDisable(GL_ALPHA_TEST);
3002 core11fwd->glDisable(GL_FOG);
3003 core11fwd->glDisable(GL_LOGIC_OP);
c357e426 3004
3005 glPixelTransferi(GL_MAP_COLOR, GL_FALSE);
3006 glPixelTransferi(GL_RED_SCALE, 1);
3007 glPixelTransferi(GL_RED_BIAS, 0);
3008 glPixelTransferi(GL_GREEN_SCALE, 1);
3009 glPixelTransferi(GL_GREEN_BIAS, 0);
3010 glPixelTransferi(GL_BLUE_SCALE, 1);
3011 glPixelTransferi(GL_BLUE_BIAS, 0);
3012 glPixelTransferi(GL_ALPHA_SCALE, 1);
3013 glPixelTransferi(GL_ALPHA_BIAS, 0);
3014
c357e426 3015 if ((myGlVerMajor >= 1) && (myGlVerMinor >= 2))
3016 {
c357e426 3017 if (CheckExtension ("GL_CONVOLUTION_1D_EXT"))
43eddb47 3018 core11fwd->glDisable(GL_CONVOLUTION_1D_EXT);
c357e426 3019
3020 if (CheckExtension ("GL_CONVOLUTION_2D_EXT"))
43eddb47 3021 core11fwd->glDisable(GL_CONVOLUTION_2D_EXT);
c357e426 3022
3023 if (CheckExtension ("GL_SEPARABLE_2D_EXT"))
43eddb47 3024 core11fwd->glDisable(GL_SEPARABLE_2D_EXT);
c357e426 3025
c357e426 3026 if (CheckExtension ("GL_SEPARABLE_2D_EXT"))
43eddb47 3027 core11fwd->glDisable(GL_HISTOGRAM_EXT);
c357e426 3028
3029 if (CheckExtension ("GL_MINMAX_EXT"))
43eddb47 3030 core11fwd->glDisable(GL_MINMAX_EXT);
c357e426 3031
c357e426 3032 if (CheckExtension ("GL_TEXTURE_3D_EXT"))
43eddb47 3033 core11fwd->glDisable(GL_TEXTURE_3D_EXT);
c357e426 3034 }
3035#endif
3036}
f88457e6 3037
31174e1a 3038// =======================================================================
3039// function : SetColorMaskRGBA
3040// purpose :
3041// =======================================================================
3042void OpenGl_Context::SetColorMaskRGBA (const NCollection_Vec4<bool>& theVal)
3043{
43eddb47 3044 core11fwd->glColorMask (theVal.r() ? GL_TRUE : GL_FALSE,
31174e1a 3045 theVal.g() ? GL_TRUE : GL_FALSE,
3046 theVal.b() ? GL_TRUE : GL_FALSE,
3047 theVal.a() ? GL_TRUE : GL_FALSE);
3048 myColorMask = theVal;
3049}
3050
f88457e6 3051// =======================================================================
3052// function : SetColorMask
3053// purpose :
3054// =======================================================================
3055bool OpenGl_Context::SetColorMask (bool theToWriteColor)
3056{
31174e1a 3057 const bool anOldValue = myColorMask.r();
3058 myColorMask.SetValues (theToWriteColor, theToWriteColor, theToWriteColor, caps->buffersOpaqueAlpha ? false : theToWriteColor);
f88457e6 3059 const GLboolean toWrite = theToWriteColor ? GL_TRUE : GL_FALSE;
43eddb47 3060 core11fwd->glColorMask (toWrite, toWrite, toWrite, myColorMask.a() ? GL_TRUE : GL_FALSE);
f88457e6 3061 return anOldValue;
3062}
c40eb6b9 3063
3064// =======================================================================
3065// function : SetSampleAlphaToCoverage
3066// purpose :
3067// =======================================================================
3068bool OpenGl_Context::SetSampleAlphaToCoverage (bool theToEnable)
3069{
2a332745 3070 bool toEnable = myAllowAlphaToCov && theToEnable;
3071 if (myAlphaToCoverage == toEnable)
c40eb6b9 3072 {
3073 return myAlphaToCoverage;
3074 }
3075
3076 if (core15fwd != NULL)
3077 {
2a332745 3078 if (toEnable)
c40eb6b9 3079 {
3080 //core15fwd->core15fwd->glSampleCoverage (1.0f, GL_FALSE);
3081 core15fwd->glEnable (GL_SAMPLE_ALPHA_TO_COVERAGE);
3082 }
3083 else
3084 {
3085 core15fwd->glDisable (GL_SAMPLE_ALPHA_TO_COVERAGE);
3086 }
3087 }
3088
3089 const bool anOldValue = myAlphaToCoverage;
2a332745 3090 myAlphaToCoverage = toEnable;
c40eb6b9 3091 return anOldValue;
3092}
bc73b006 3093
d4cefcc0 3094// =======================================================================
3095// function : GetBufferSubData
3096// purpose :
3097// =======================================================================
3098bool OpenGl_Context::GetBufferSubData (GLenum theTarget, GLintptr theOffset, GLsizeiptr theSize, void* theData)
3099{
3100 if (!hasGetBufferData)
3101 {
3102 return false;
3103 }
3104#ifdef __EMSCRIPTEN__
3105 EM_ASM_(
3106 {
3107 Module.ctx.getBufferSubData($0, $1, HEAPU8.subarray($2, $2 + $3));
3108 }, theTarget, theOffset, theData, theSize);
3109 return true;
3110#elif defined(GL_ES_VERSION_2_0)
43eddb47 3111 if (void* aData = core30->glMapBufferRange (theTarget, theOffset, theSize, GL_MAP_READ_BIT))
d4cefcc0 3112 {
3113 memcpy (theData, aData, theSize);
43eddb47 3114 core30->glUnmapBuffer (theTarget);
d4cefcc0 3115 return true;
3116 }
3117 return false;
3118#else
3119 core15fwd->glGetBufferSubData (theTarget, theOffset, theSize, theData);
3120 return true;
3121#endif
3122}
3123
bc73b006 3124// =======================================================================
3125// function : DumpJson
3126// purpose :
3127// =======================================================================
3128void OpenGl_Context::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
3129{
3130 OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
3131
3132 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myAnisoMax)
3133 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myTexClamp)
3134 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMaxTexDim)
3135 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMaxTexCombined)
3136 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMaxDumpSizeX)
3137 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMaxDumpSizeY)
3138 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMaxClipPlanes)
3139 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMaxMsaaSamples)
3140 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMaxDrawBuffers)
3141 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMaxColorAttachments)
3142 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myGlVerMajor)
3143 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myGlVerMinor)
3144 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsInitialized)
3145 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsStereoBuffers)
3146 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsGlNormalizeEnabled)
3147
3148 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myHasRayTracing)
3149 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myHasRayTracingTextures)
3150 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myHasRayTracingAdaptiveSampling)
3151 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myHasRayTracingAdaptiveSamplingAtomic)
3152
3153 for (int i = 0; i < 4; i++)
3154 {
3155 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myViewport[i])
3156 }
3157
3158 for (int i = 0; i < 4; i++)
3159 {
3160 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myViewportVirt[i])
3161 }
3162
3163 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myPointSpriteOrig)
3164 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myRenderMode)
3165 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myPolygonMode)
3166 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myPolygonOffset)
3167 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myToCullBackFaces)
3168 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myReadBuffer)
3169
3170 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myDefaultVao)
3171 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myColorMask)
3172 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myAllowAlphaToCov)
3173 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myAlphaToCoverage)
3174 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsGlDebugCtx)
3175
3176 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myResolution)
3177 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myResolutionRatio)
3178
3179 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myLineWidthScale)
3180 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myLineFeather)
3181 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myRenderScale)
3182 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myRenderScaleInv)
3183
3184 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &ModelWorldState)
3185 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &WorldViewState)
3186 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &ProjectionState)
3187}
3188
3189// =======================================================================
3190// function : DumpJsonOpenGlState
3191// purpose :
3192// =======================================================================
3193void OpenGl_Context::DumpJsonOpenGlState (Standard_OStream& theOStream, Standard_Integer)
3194{
3195 GLboolean isEnableBlend = glIsEnabled (GL_BLEND);
3196 GLboolean isEnableCullFace = glIsEnabled (GL_CULL_FACE);
3197 GLboolean isEnableDepthTest = glIsEnabled (GL_DEPTH_TEST);
3198
3199 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, isEnableBlend)
3200 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, isEnableCullFace)
3201 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, isEnableDepthTest)
3202}
3203