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