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