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