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