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