forked from Open-Cascade-SAS/OCCT
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathOpenGl_Context.hxx
More file actions
1211 lines (1009 loc) · 58.8 KB
/
Copy pathOpenGl_Context.hxx
File metadata and controls
1211 lines (1009 loc) · 58.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// Created on: 2012-01-26
// Created by: Kirill GAVRILOV
// Copyright (c) 2012-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef OpenGl_Context_HeaderFile
#define OpenGl_Context_HeaderFile
#include <Aspect_Drawable.hxx>
#include <Aspect_Display.hxx>
#include <Aspect_GraphicsLibrary.hxx>
#include <Aspect_RenderingContext.hxx>
#include <Graphic3d_DiagnosticInfo.hxx>
#include <Message.hxx>
#include <OpenGl_Caps.hxx>
#include <OpenGl_LineAttributes.hxx>
#include <OpenGl_Material.hxx>
#include <OpenGl_MatrixState.hxx>
#include <OpenGl_Vec.hxx>
#include <OpenGl_Resource.hxx>
#include <OpenGl_TextureSet.hxx>
#include <Standard_Transient.hxx>
#include <TCollection_AsciiString.hxx>
#include <NCollection_IndexedDataMap.hxx>
#include <TColStd_PackedMapOfInteger.hxx>
#include <OpenGl_Clipping.hxx>
#include <NCollection_Shared.hxx>
#include <memory>
//! Forward declarations
#if defined(__APPLE__)
#import <TargetConditionals.h>
#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
#ifdef __OBJC__
@class EAGLContext;
#else
struct EAGLContext;
#endif
#else
#ifdef __OBJC__
@class NSOpenGLContext;
#else
struct NSOpenGLContext;
#endif
#endif
#endif
struct OpenGl_GlFunctions;
struct OpenGl_ArbTBO;
struct OpenGl_ArbIns;
struct OpenGl_ArbDbg;
struct OpenGl_ArbFBO;
struct OpenGl_ArbFBOBlit;
struct OpenGl_ArbSamplerObject;
struct OpenGl_ArbTexBindless;
struct OpenGl_ExtGS;
struct OpenGl_GlCore11Fwd;
struct OpenGl_GlCore11;
struct OpenGl_GlCore12;
struct OpenGl_GlCore13;
struct OpenGl_GlCore14;
struct OpenGl_GlCore15;
struct OpenGl_GlCore20;
struct OpenGl_GlCore21;
struct OpenGl_GlCore30;
struct OpenGl_GlCore31;
struct OpenGl_GlCore32;
struct OpenGl_GlCore33;
struct OpenGl_GlCore40;
struct OpenGl_GlCore41;
struct OpenGl_GlCore42;
struct OpenGl_GlCore43;
struct OpenGl_GlCore44;
struct OpenGl_GlCore45;
struct OpenGl_GlCore46;
class Graphic3d_Camera;
class Graphic3d_PresentationAttributes;
class OpenGl_Aspects;
class OpenGl_FrameBuffer;
class OpenGl_ShaderProgram;
class OpenGl_ShaderManager;
class OpenGl_FrameStats;
enum OpenGl_FeatureFlag
{
OpenGl_FeatureNotAvailable = 0, //!< Feature is not supported by OpenGl implementation.
OpenGl_FeatureInExtensions = 1, //!< Feature is supported as extension.
OpenGl_FeatureInCore = 2 //!< Feature is supported as part of core profile.
};
//! This class generalize access to the GL context and available extensions.
//!
//! Functions related to specific OpenGL version or extension are grouped into structures which can
//! be accessed as fields of this class. The most simple way to check that required functionality is
//! available - is NULL check for the group:
//! @code
//! if (myContext->core20 != NULL)
//! {
//! myGlProgram = myContext->core20->glCreateProgram();
//! .. do more stuff ..
//! }
//! else
//! {
//! .. compatibility with outdated configurations ..
//! }
//! @endcode
//!
//! Current implementation provide access to OpenGL core functionality up to 4.6 version (core12,
//! core13, core14, etc.) as well as several extensions (arbTBO, arbFBO, etc.).
//!
//! OpenGL context might be initialized in Core Profile. In this case deprecated functionality
//! become unavailable. To select which core** function set should be used in specific case:
//! - Determine the minimal OpenGL version required for implemented functionality and use it to
//! access all functions.
//! For example, if algorithm requires OpenGL 2.1+, it is better to write core20fwd->glEnable()
//! rather than core11fwd->glEnable() for uniformity.
//! - Validate minimal requirements at initialization/creation time and omit checks within code
//! where algorithm should be already initialized.
//! Properly escape code incompatible with Core Profile. The simplest way to check Core Profile
//! is "if (core11ffp == NULL)".
//!
//! Simplified extensions classification:
//! - prefixed with NV, AMD, ATI are vendor-specific (however may be provided by other vendors in
//! some cases);
//! - prefixed with EXT are accepted by 2+ vendors;
//! - prefixed with ARB are accepted by Architecture Review Board and are candidates
//! for inclusion into GL core functionality.
//! Some functionality can be represented in several extensions simultaneously.
//! In this case developer should be careful because different specification may differ
//! in aspects (like enumeration values and error-handling).
//!
//! Notice that some systems provide mechanisms to simultaneously incorporate with GL contexts with
//! different capabilities. For this reason OpenGl_Context should be initialized and used for each
//! GL context independently.
//!
//! Matrices of OpenGl transformations:
//! model -> world -> view -> projection
//! These matrices might be changed for local transformation, transform persistent using direct
//! access to current matrix of ModelWorldState, WorldViewState and ProjectionState After, these
//! matrices should be applied using ApplyModelWorldMatrix, ApplyWorldViewMatrix,
//! ApplyModelViewMatrix or ApplyProjectionMatrix.
class OpenGl_Context : public Standard_Transient
{
DEFINE_STANDARD_RTTIEXT(OpenGl_Context, Standard_Transient)
friend class OpenGl_Window;
friend struct OpenGl_GlFunctions;
public:
typedef NCollection_Shared<
NCollection_DataMap<TCollection_AsciiString, occ::handle<OpenGl_Resource>>>
OpenGl_ResourcesMap;
//! Function for getting power of to number larger or equal to input number.
//! @param theNumber number to 'power of two'
//! @param theThreshold upper threshold
//! @return power of two number
inline static int GetPowerOfTwo(const int theNumber, const int theThreshold)
{
for (int p2 = 2; p2 <= theThreshold; p2 <<= 1)
{
if (theNumber <= p2)
{
return p2;
}
}
return theThreshold;
}
//! Format GL constant as hex value 0xABCD.
Standard_EXPORT static TCollection_AsciiString FormatGlEnumHex(int theGlEnum);
//! Format pointer as hex value 0xABCD.
Standard_EXPORT static TCollection_AsciiString FormatPointer(const void* thePtr);
//! Format size value.
Standard_EXPORT static TCollection_AsciiString FormatSize(size_t theSize);
//! Return text description of GL error.
Standard_EXPORT static TCollection_AsciiString FormatGlError(int theGlError);
public:
//! Empty constructor. You should call Init() to perform initialization with bound GL context.
Standard_EXPORT OpenGl_Context(const occ::handle<OpenGl_Caps>& theCaps = nullptr);
//! Destructor.
Standard_EXPORT ~OpenGl_Context() override;
//! Release all resources, including shared ones
Standard_EXPORT void forcedRelease();
//! Share GL context resources.
//! theShareCtx - handle to context to retrieve handles to shared resources.
Standard_EXPORT void Share(const occ::handle<OpenGl_Context>& theShareCtx);
//! Initialize class from currently bound OpenGL context. Method should be called only once.
//! @return false if no GL context is bound to the current thread
Standard_EXPORT bool Init(const bool theIsCoreProfile = false);
//! @return true if this context is valid (has been initialized)
inline bool IsValid() const { return myIsInitialized; }
//! Initialize class from specified surface and rendering context. Method should be called only
//! once. The meaning of parameters is platform-specific.
//!
//! EGL:
//! @code
//! occ::handle<Aspect_Window> theAspWin;
//! EGLSurface theEglSurf = eglCreateWindowSurface (theEglDisp, anEglConfig,
//! (EGLNativeWindowType )theAspWin->NativeHandle(), NULL); EGLDisplay theEglDisp =
//! eglGetDisplay (EGL_DEFAULT_DISPLAY); EGLContext theEglCtx = eglCreateContext ((EGLDisplay
//! )theEglDisp, anEglConfig, EGL_NO_CONTEXT, anEglCtxAttribs); occ::handle<OpenGl_Context>
//! aGlCtx = new OpenGl_Context(); aGlCtx->Init ((Aspect_Drawable )theEglSurf, (Aspect_Display
//! )theEglDisp, (Aspect_RenderingContext )theEglCtx);
//! @endcode
//!
//! Windows (Win32):
//! @code
//! occ::handle<WNT_Window> theAspWin;
//! HWND theWindow = (HWND )theAspWin->NativeHandle();
//! HDC theDevCtx = GetDC(theWindow);
//! HGLRC theGContext = wglCreateContext (theDevCtx);
//! occ::handle<OpenGl_Context> aGlCtx = new OpenGl_Context();
//! aGlCtx->Init ((Aspect_Drawable )theWindow, (Aspect_Display )theDevCtx,
//! (Aspect_RenderingContext )theGContext);
//! @endcode
//!
//! Linux (Xlib):
//! @code
//! occ::handle<Xw_Window> theAspWin;
//! Window theXWindow = (Window )theAspWin->NativeHandle();
//! Display* theXDisp = (Display* )theAspWin->DisplayConnection()->GetDisplayAspect();
//! GLXContext theGlxCtx = glXCreateContext (theXDisp, aVis.get(), NULL, GL_TRUE);
//! occ::handle<OpenGl_Context> aGlCtx = new OpenGl_Context();
//! aGlCtx->Init ((Aspect_Drawable )theXWindow, (Aspect_Display )theXDisp,
//! (Aspect_RenderingContext )theGlxCtx);
//! @endcode
//!
//! @param[in] theSurface surface / window (EGLSurface | HWND | GLXDrawable/Window)
//! @param[in] theDisplay display or device context (EGLDisplay | HDC | Display*)
//! @param[in] theContext rendering context (EGLContext | HGLRC | GLXContext |
//! EAGLContext* | NSOpenGLContext*)
//! @param[in] theIsCoreProfile flag indicating that passed GL rendering context has been created
//! with Core Profile
//! @return false if OpenGL context can not be bound to specified surface
Standard_EXPORT bool Init(const Aspect_Drawable theSurface,
const Aspect_Display theDisplay,
const Aspect_RenderingContext theContext,
const bool theIsCoreProfile = false);
//! Return window handle currently bound to this OpenGL context (EGLSurface | HWND | GLXDrawable).
Aspect_Drawable Window() const { return myWindow; }
//! Return display / window device context (EGLDisplay | HDC | Display*).
Aspect_Display GetDisplay() const { return myDisplay; }
//! Return rendering context (EGLContext | HGLRC | GLXContext | EAGLContext* | NSOpenGLContext*).
Aspect_RenderingContext RenderingContext() const { return myGContext; }
#if defined(__APPLE__) && !defined(HAVE_XLIB)
#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
//! Initialize class from specified OpenGL ES context (EAGLContext). Method should be called only
//! once.
bool Init(EAGLContext* theGContext, const bool theIsCoreProfile = false)
{
return Init((Aspect_Drawable)0,
(Aspect_Display) nullptr,
(Aspect_RenderingContext)theGContext,
theIsCoreProfile);
}
#else
//! Initialize class from specified OpenGL context (NSOpenGLContext). Method should be called only
//! once.
bool Init(NSOpenGLContext* theGContext, const bool theIsCoreProfile = false)
{
return Init((Aspect_Drawable)0,
(Aspect_Display) nullptr,
(Aspect_RenderingContext)theGContext,
theIsCoreProfile);
}
#endif
#endif
//! Read OpenGL version information from active context.
Standard_EXPORT static void ReadGlVersion(int& theGlVerMajor, int& theGlVerMinor);
//! Check if theExtName extension is supported by active GL context.
Standard_EXPORT bool CheckExtension(const char* theExtName) const;
//! Check if theExtName extension is in extensions string.
Standard_EXPORT static bool CheckExtension(const char* theExtString, const char* theExtName);
//! Auxiliary template to retrieve GL function pointer.
//! Pointer to function retrieved from library is statically casted
//! to requested type - there no way to check real signature of exported function.
//! The context should be bound before call.
//! @param[out] theLastFailFuncName set to theFuncName in case of failure, unmodified on success
//! @param[in] theFuncName function name to find
//! @param[out] theFuncPtr retrieved function pointer
//! @return TRUE on success
template <typename FuncType_t>
bool FindProcVerbose(const char*& theLastFailFuncName,
const char* theFuncName,
FuncType_t& theFuncPtr)
{
theFuncPtr = (FuncType_t)findProc(theFuncName);
if (theFuncPtr == nullptr)
{
theLastFailFuncName = theFuncName;
return false;
}
return true;
}
//! Auxiliary template to retrieve GL function pointer.
//! Same as FindProcVerbose() but without auxiliary last function name argument.
template <typename FuncType_t>
bool FindProc(const char* theFuncName, FuncType_t& theFuncPtr)
{
theFuncPtr = (FuncType_t)findProc(theFuncName);
return (theFuncPtr != nullptr);
}
//! Return active graphics library.
Aspect_GraphicsLibrary GraphicsLibrary() const { return myGapi; }
//! @return true if detected GL version is greater or equal to requested one.
inline bool IsGlGreaterEqual(const int theVerMajor, const int theVerMinor) const
{
return (myGlVerMajor > theVerMajor)
|| (myGlVerMajor == theVerMajor && myGlVerMinor >= theVerMinor);
}
//! Return cached GL version major number.
int VersionMajor() const { return myGlVerMajor; }
//! Return cached GL version minor number.
int VersionMinor() const { return myGlVerMinor; }
//! Access entire map of loaded OpenGL functions.
const OpenGl_GlFunctions* Functions() const { return myFuncs.get(); }
//! Clean up errors stack for this GL context (glGetError() in loop).
//! @return true if some error has been cleared
Standard_EXPORT bool ResetErrors(const bool theToPrintErrors = false);
//! This method uses system-dependent API to retrieve information
//! about GL context bound to the current thread.
//! @return true if current thread is bound to this GL context
Standard_EXPORT bool IsCurrent() const;
//! Activates current context.
//! Class should be initialized with appropriate info.
Standard_EXPORT bool MakeCurrent();
//! Swap front/back buffers for this GL context (should be activated before!).
Standard_EXPORT void SwapBuffers();
//! Setup swap interval (VSync).
Standard_EXPORT bool SetSwapInterval(const int theInterval);
//! Return true if active mode is GL_RENDER (cached state)
Standard_EXPORT bool IsRender() const;
//! Return true if active mode is GL_FEEDBACK (cached state)
Standard_EXPORT bool IsFeedback() const;
//! This function retrieves information from GL about free GPU memory that is:
//! - OS-dependent. On some OS it is per-process and on others - for entire system.
//! - Vendor-dependent. Currently available only on NVIDIA and AMD/ATi drivers only.
//! - Numbers meaning may vary.
//! You should use this info only for diagnostics purposes.
//! @return free GPU dedicated memory in bytes.
Standard_EXPORT size_t AvailableMemory() const;
//! This function retrieves information from GL about GPU memory
//! and contains more vendor-specific values than AvailableMemory().
Standard_EXPORT TCollection_AsciiString MemoryInfo() const;
//! This function retrieves information from GL about GPU memory.
Standard_EXPORT void MemoryInfo(
NCollection_IndexedDataMap<TCollection_AsciiString, TCollection_AsciiString>& theDict) const;
//! Fill in the dictionary with OpenGL info.
//! Should be called with bound context.
Standard_EXPORT void DiagnosticInformation(
NCollection_IndexedDataMap<TCollection_AsciiString, TCollection_AsciiString>& theDict,
Graphic3d_DiagnosticInfo theFlags) const;
//! Fetches information about window buffer pixel format.
Standard_EXPORT void WindowBufferBits(NCollection_Vec4<int>& theColorBits,
NCollection_Vec2<int>& theDepthStencilBits) const;
//! Access shared resource by its name.
//! @param theKey - unique identifier;
//! @return handle to shared resource or NULL.
Standard_EXPORT const occ::handle<OpenGl_Resource>& GetResource(
const TCollection_AsciiString& theKey) const;
//! Access shared resource by its name.
//! @param theKey - unique identifier;
//! @param theValue - handle to fill;
//! @return true if resource was shared.
template <typename TheHandleType>
bool GetResource(const TCollection_AsciiString& theKey, TheHandleType& theValue) const
{
const occ::handle<OpenGl_Resource>& aResource = GetResource(theKey);
if (aResource.IsNull())
{
return false;
}
theValue = TheHandleType::DownCast(aResource);
return !theValue.IsNull();
}
//! Register shared resource.
//! Notice that after registration caller shouldn't release it by himself -
//! it will be automatically released on context destruction.
//! @param theKey - unique identifier, shouldn't be empty;
//! @param theResource - new resource to register, shouldn't be NULL.
Standard_EXPORT bool ShareResource(const TCollection_AsciiString& theKey,
const occ::handle<OpenGl_Resource>& theResource);
//! Release shared resource.
//! If there are more than one reference to this resource
//! (also used by some other existing object) then call will be ignored.
//! This means that current object itself should nullify handle before this call.
//! Notice that this is unrecommended operation at all and should be used
//! only in case of fat resources to release memory for other needs.
//! @param theKey unique identifier
//! @param theToDelay postpone release until next redraw call
Standard_EXPORT void ReleaseResource(const TCollection_AsciiString& theKey,
const bool theToDelay = false);
//! Append resource to queue for delayed clean up.
//! Resources in this queue will be released at next redraw call.
template <class T>
void DelayedRelease(occ::handle<T>& theResource)
{
myUnusedResources->Prepend(theResource);
theResource.Nullify();
}
//! Clean up the delayed release queue.
Standard_EXPORT void ReleaseDelayed();
//! Return map of shared resources.
const OpenGl_ResourcesMap& SharedResources() const { return *mySharedResources; }
//! @return tool for management of clippings within this context.
inline OpenGl_Clipping& ChangeClipping() { return myClippingState; }
//! @return tool for management of clippings within this context.
inline const OpenGl_Clipping& Clipping() const { return myClippingState; }
//! @return tool for management of shader programs within this context.
inline const occ::handle<OpenGl_ShaderManager>& ShaderManager() const { return myShaderManager; }
public:
//! Either GL_CLAMP_TO_EDGE (1.2+) or GL_CLAMP (1.1).
int TextureWrapClamp() const { return myTexClamp; }
//! @return true if texture parameters GL_TEXTURE_BASE_LEVEL/GL_TEXTURE_MAX_LEVEL are supported.
bool HasTextureBaseLevel() const
{
return myGapi == Aspect_GraphicsLibrary_OpenGLES ? IsGlGreaterEqual(3, 0)
: IsGlGreaterEqual(1, 2);
}
//! Return map of supported texture formats.
const occ::handle<Image_SupportedFormats>& SupportedTextureFormats() const
{
return mySupportedFormats;
}
//! @return maximum degree of anisotropy texture filter
int MaxDegreeOfAnisotropy() const { return myAnisoMax; }
//! @return value for GL_MAX_TEXTURE_SIZE
int MaxTextureSize() const { return myMaxTexDim; }
//! @return value for GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
int MaxCombinedTextureUnits() const { return myMaxTexCombined; }
//! This method returns the multi-texture limit for obsolete fixed-function pipeline.
//! Use MaxCombinedTextureUnits() instead for limits for using programmable pipeline.
//! @return value for GL_MAX_TEXTURE_UNITS
int MaxTextureUnitsFFP() const { return myMaxTexUnitsFFP; }
//! Return texture unit to be used for sprites (Graphic3d_TextureUnit_PointSprite by default).
Graphic3d_TextureUnit SpriteTextureUnit() const { return mySpriteTexUnit; }
//! @return true if MSAA textures are supported.
bool HasTextureMultisampling() const { return myHasMsaaTextures; }
//! @return value for GL_MAX_SAMPLES
int MaxMsaaSamples() const { return myMaxMsaaSamples; }
//! @return maximum FBO width for image dump
int MaxDumpSizeX() const { return myMaxDumpSizeX; }
//! @return maximum FBO height for image dump
int MaxDumpSizeY() const { return myMaxDumpSizeY; }
//! @return value for GL_MAX_DRAW_BUFFERS
int MaxDrawBuffers() const { return myMaxDrawBuffers; }
//! @return value for GL_MAX_COLOR_ATTACHMENTS
int MaxColorAttachments() const { return myMaxColorAttachments; }
//! Get maximum number of clip planes supported by OpenGl.
//! This value is implementation dependent. At least 6
//! planes should be supported by OpenGl (see specs).
//! @return value for GL_MAX_CLIP_PLANES
int MaxClipPlanes() const { return myMaxClipPlanes; }
//! @return TRUE if ray tracing mode is supported
bool HasRayTracing() const { return myHasRayTracing; }
//! @return TRUE if textures in ray tracing mode are supported
bool HasRayTracingTextures() const { return myHasRayTracingTextures; }
//! @return TRUE if adaptive screen sampling in ray tracing mode is supported
bool HasRayTracingAdaptiveSampling() const { return myHasRayTracingAdaptiveSampling; }
//! @return TRUE if atomic adaptive screen sampling in ray tracing mode is supported
bool HasRayTracingAdaptiveSamplingAtomic() const { return myHasRayTracingAdaptiveSamplingAtomic; }
//! Returns TRUE if sRGB rendering is supported.
bool HasSRGB() const { return hasTexSRGB && hasFboSRGB; }
//! Returns TRUE if sRGB rendering is supported and permitted.
bool ToRenderSRGB() const { return HasSRGB() && !caps->sRGBDisable && !caps->ffpEnable; }
//! Returns TRUE if window/surface buffer is sRGB-ready.
//!
//! When offscreen FBOs are created in sRGB, but window is not sRGB-ready,
//! blitting into window should be done with manual gamma correction.
//!
//! In desktop OpenGL, window buffer can be considered as sRGB-ready by default,
//! even when application has NOT requested sRGB-ready pixel format,
//! and rendering is managed via GL_FRAMEBUFFER_SRGB state.
//!
//! In OpenGL ES, sRGB-ready window surface should be explicitly requested on construction,
//! and cannot be disabled/enabled without GL_EXT_sRGB_write_control extension afterwards
//! (GL_FRAMEBUFFER_SRGB can be considered as always tuned ON).
bool IsWindowSRGB() const { return myIsSRgbWindow; }
//! Overrides if window/surface buffer is sRGB-ready or not (initialized with the context).
void SetWindowSRGB(bool theIsSRgb) { myIsSRgbWindow = theIsSRgb; }
//! Returns TRUE if window/surface buffer has deep color (10bit per component / 30bit RGB) or
//! better precision.
bool IsWindowDeepColor() const { return myIsWindowDeepColor; }
//! Convert Quantity_ColorRGBA into vec4
//! with conversion or no conversion into non-linear sRGB
//! basing on ToRenderSRGB() flag.
NCollection_Vec4<float> Vec4FromQuantityColor(const NCollection_Vec4<float>& theColor) const
{
return myIsSRgbActive ? Vec4LinearFromQuantityColor(theColor)
: Vec4sRGBFromQuantityColor(theColor);
}
//! Convert Quantity_ColorRGBA into vec4.
//! Quantity_Color is expected to be linear RGB, hence conversion is NOT required
const NCollection_Vec4<float>& Vec4LinearFromQuantityColor(
const NCollection_Vec4<float>& theColor) const
{
return theColor;
}
//! Convert Quantity_ColorRGBA (linear RGB) into non-linear sRGB vec4.
NCollection_Vec4<float> Vec4sRGBFromQuantityColor(const NCollection_Vec4<float>& theColor) const
{
return Quantity_ColorRGBA::Convert_LinearRGB_To_sRGB(theColor);
}
//! Returns TRUE if PBR shading model is supported.
//! Basically, feature requires OpenGL 3.0+ / OpenGL ES 3.0+ hardware; more precisely:
//! - Graphics hardware with moderate capabilities for compiling long enough GLSL program.
//! - FBO (e.g. for baking environment).
//! - Multi-texturing with >= 4 units (LUT and IBL textures).
//! - GL_RG32F texture format (arbTexRG + arbTexFloat)
//! - Cubemap texture lookup textureCubeLod()/textureLod() with LOD index within Fragment Shader,
//! which requires GLSL OpenGL 3.0+ / OpenGL ES 3.0+ or OpenGL 2.1 + GL_EXT_gpu_shader4
//! extension.
bool HasPBR() const { return myHasPBR; }
//! Returns texture unit where Environment Lookup Table is expected to be bound, or 0 if PBR is
//! unavailable.
Graphic3d_TextureUnit PBREnvLUTTexUnit() const { return myPBREnvLUTTexUnit; }
//! Returns texture unit where Diffuse (irradiance) IBL map's spherical harmonics coefficients is
//! expected to be bound, or 0 if PBR is unavailable.
Graphic3d_TextureUnit PBRDiffIBLMapSHTexUnit() const { return myPBRDiffIBLMapSHTexUnit; }
//! Returns texture unit where Specular IBL map is expected to be bound, or 0 if PBR is
//! unavailable.
Graphic3d_TextureUnit PBRSpecIBLMapTexUnit() const { return myPBRSpecIBLMapTexUnit; }
//! Returns texture unit where shadow map is expected to be bound, or 0 if unavailable.
Graphic3d_TextureUnit ShadowMapTexUnit() const { return myShadowMapTexUnit; }
//! Returns texture unit for occDepthPeelingDepth within enabled Depth Peeling.
Graphic3d_TextureUnit DepthPeelingDepthTexUnit() const { return myDepthPeelingDepthTexUnit; }
//! Returns texture unit for occDepthPeelingFrontColor within enabled Depth Peeling.
Graphic3d_TextureUnit DepthPeelingFrontColorTexUnit() const
{
return myDepthPeelingFrontColorTexUnit;
}
//! Returns true if VBO is supported and permitted.
inline bool ToUseVbo() const { return core15fwd != nullptr && !caps->vboDisable; }
//! @return cached state of GL_NORMALIZE.
bool IsGlNormalizeEnabled() const { return myIsGlNormalizeEnabled; }
//! Sets GL_NORMALIZE enabled or disabled.
//! @return old value of the flag
Standard_EXPORT bool SetGlNormalizeEnabled(bool isEnabled);
//! @return cached state of polygon rasterization mode (glPolygonMode()).
int PolygonMode() const { return myPolygonMode; }
//! Sets polygon rasterization mode (glPolygonMode() function).
//! @return old value of the rasterization mode.
Standard_EXPORT int SetPolygonMode(const int theMode);
//! @return cached enabled state of polygon hatching rasterization.
bool IsPolygonHatchEnabled() const { return myHatchIsEnabled; }
//! Sets enabled state of polygon hatching rasterization
//! without affecting currently selected hatching pattern.
//! @return previous state of polygon hatching mode.
Standard_EXPORT bool SetPolygonHatchEnabled(const bool theIsEnabled);
//! @return cached state of polygon hatch type.
int PolygonHatchStyle() const { return myActiveHatchType; }
//! Sets polygon hatch pattern.
//! Zero-index value is a default alias for solid filling.
//! @param theStyle type of hatch supported by base implementation of
//! OpenGl_LineAttributes (Aspect_HatchStyle) or the type supported by custom
//! implementation derived from OpenGl_LineAttributes class.
//! @return old type of hatch.
Standard_EXPORT int SetPolygonHatchStyle(const occ::handle<Graphic3d_HatchStyle>& theStyle);
//! Sets and applies current polygon offset.
Standard_EXPORT void SetPolygonOffset(const Graphic3d_PolygonOffset& theOffset);
//! Returns currently applied polygon offset parameters.
const Graphic3d_PolygonOffset& PolygonOffset() const { return myPolygonOffset; }
//! Returns camera object.
const occ::handle<Graphic3d_Camera>& Camera() const { return myCamera; }
//! Sets camera object to the context and update matrices.
Standard_EXPORT void SetCamera(const occ::handle<Graphic3d_Camera>& theCamera);
//! Applies matrix into shader manager stored in ModelWorldState to OpenGl.
//! In "model -> world -> view -> projection" it performs:
//! model -> world
Standard_EXPORT void ApplyModelWorldMatrix();
//! Applies matrix stored in WorldViewState to OpenGl.
//! In "model -> world -> view -> projection" it performs:
//! model -> world -> view,
//! where model -> world is identical matrix
Standard_EXPORT void ApplyWorldViewMatrix();
//! Applies combination of matrices stored in ModelWorldState and WorldViewState to OpenGl.
//! In "model -> world -> view -> projection" it performs:
//! model -> world -> view
Standard_EXPORT void ApplyModelViewMatrix();
//! Applies matrix stored in ProjectionState to OpenGl.
//! In "model -> world -> view -> projection" it performs:
//! view -> projection
Standard_EXPORT void ApplyProjectionMatrix();
public:
//! @return messenger instance
inline const occ::handle<Message_Messenger>& Messenger() const
{
return ::Message::DefaultMessenger();
}
//! Callback for GL_ARB_debug_output extension
//! @param theSource message source within GL_DEBUG_SOURCE_ enumeration
//! @param theType message type within GL_DEBUG_TYPE_ enumeration
//! @param theId message ID within source
//! @param theSeverity message severity within GL_DEBUG_SEVERITY_ enumeration
//! @param theMessage the message itself
Standard_EXPORT void PushMessage(const unsigned int theSource,
const unsigned int theType,
const unsigned int theId,
const unsigned int theSeverity,
const TCollection_ExtendedString& theMessage);
//! Adds a filter for messages with theId and theSource (GL_DEBUG_SOURCE_)
Standard_EXPORT bool ExcludeMessage(const unsigned int theSource, const unsigned int theId);
//! Removes a filter for messages with theId and theSource (GL_DEBUG_SOURCE_)
Standard_EXPORT bool IncludeMessage(const unsigned int theSource, const unsigned int theId);
//! @return true if OpenGl context supports left and right rendering buffers.
bool HasStereoBuffers() const { return myIsStereoBuffers; }
public: //! @name methods to alter or retrieve current state
//! Return structure holding frame statistics.
const occ::handle<OpenGl_FrameStats>& FrameStats() const { return myFrameStats; }
//! Set structure holding frame statistics.
//! This call makes sense only if application defines OpenGl_FrameStats sub-class.
void SetFrameStats(const occ::handle<OpenGl_FrameStats>& theStats) { myFrameStats = theStats; }
//! Return cached viewport definition (x, y, width, height).
const int* Viewport() const { return myViewport; }
//! Resize the viewport (alias for glViewport).
//! @param theRect viewport definition (x, y, width, height)
Standard_EXPORT void ResizeViewport(const int theRect[4]);
//! Return virtual viewport definition (x, y, width, height).
const int* VirtualViewport() const { return myViewportVirt; }
//! Return active read buffer.
int ReadBuffer() { return myReadBuffer; }
//! Switch read buffer, wrapper for ::glReadBuffer().
Standard_EXPORT void SetReadBuffer(const int theReadBuffer);
//! Return active draw buffer attached to a render target referred by index (layout location).
int DrawBuffer(int theIndex = 0) const
{
return theIndex >= myDrawBuffers.Lower() && theIndex <= myDrawBuffers.Upper()
? myDrawBuffers.Value(theIndex)
: 0; // GL_NONE
}
//! Switch draw buffer, wrapper for ::glDrawBuffer().
Standard_EXPORT void SetDrawBuffer(const int theDrawBuffer);
//! Switch draw buffer, wrapper for ::glDrawBuffers (GLsizei, const GLenum*).
Standard_EXPORT void SetDrawBuffers(const int theNb, const int* theDrawBuffers);
//! Switch read/draw buffers.
void SetReadDrawBuffer(const int theBuffer)
{
SetReadBuffer(theBuffer);
SetDrawBuffer(theBuffer);
}
//! Returns cached GL_FRAMEBUFFER_SRGB state.
//! If TRUE, GLSL program is expected to write linear RGB color.
//! Otherwise, GLSL program might need manually converting result color into sRGB color space.
bool IsFrameBufferSRGB() const { return myIsSRgbActive; }
//! Enables/disables GL_FRAMEBUFFER_SRGB flag.
//! This flag can be set to:
//! - TRUE when writing into offscreen FBO (always expected to be in sRGB or RGBF formats).
//! - TRUE when writing into sRGB-ready window buffer (might require choosing proper pixel format
//! on window creation).
//! - FALSE if sRGB rendering is not supported or sRGB-not-ready window buffer is used for
//! drawing.
//! @param[in] theIsFbo flag indicating writing into offscreen FBO (always expected sRGB-ready
//! when sRGB FBO is supported)
//! or into window buffer (FALSE, sRGB-readiness might vary).
//! @param[in] theIsFboSRgb flag indicating off-screen FBO is sRGB-ready
Standard_EXPORT void SetFrameBufferSRGB(bool theIsFbo, bool theIsFboSRgb = true);
//! Return cached flag indicating writing into color buffer is enabled or disabled (glColorMask).
const NCollection_Vec4<bool>& ColorMaskRGBA() const { return myColorMask; }
//! Enable/disable writing into color buffer (wrapper for glColorMask).
Standard_EXPORT void SetColorMaskRGBA(const NCollection_Vec4<bool>& theToWriteColor);
//! Return cached flag indicating writing into color buffer is enabled or disabled (glColorMask).
bool ColorMask() const { return myColorMask.r(); }
//! Enable/disable writing into color buffer (wrapper for glColorMask).
//! Alpha component writes will be disabled unconditionally in case of caps->buffersOpaqueAlpha.
Standard_EXPORT bool SetColorMask(bool theToWriteColor);
//! Return TRUE if GL_SAMPLE_ALPHA_TO_COVERAGE usage is allowed.
bool AllowSampleAlphaToCoverage() const { return myAllowAlphaToCov; }
//! Allow GL_SAMPLE_ALPHA_TO_COVERAGE usage.
void SetAllowSampleAlphaToCoverage(bool theToEnable) { myAllowAlphaToCov = theToEnable; }
//! Return GL_SAMPLE_ALPHA_TO_COVERAGE state.
bool SampleAlphaToCoverage() const { return myAlphaToCoverage; }
//! Enable/disable GL_SAMPLE_ALPHA_TO_COVERAGE.
Standard_EXPORT bool SetSampleAlphaToCoverage(bool theToEnable);
//! Return back face culling state.
Graphic3d_TypeOfBackfacingModel FaceCulling() const { return myFaceCulling; }
//! Enable or disable back face culling (glEnable (GL_CULL_FACE)).
Standard_EXPORT void SetFaceCulling(Graphic3d_TypeOfBackfacingModel theMode);
//! Return back face culling state.
bool ToCullBackFaces() const
{
return myFaceCulling == Graphic3d_TypeOfBackfacingModel_BackCulled;
}
//! Enable or disable back face culling (glCullFace() + glEnable(GL_CULL_FACE)).
void SetCullBackFaces(bool theToEnable)
{
SetFaceCulling(theToEnable ? Graphic3d_TypeOfBackfacingModel_BackCulled
: Graphic3d_TypeOfBackfacingModel_DoubleSided);
}
//! Fetch OpenGl context state. This class tracks value of several OpenGl
//! state variables. Consulting the cached values is quicker than
//! doing the same via OpenGl API. Call this method if any of the controlled
//! OpenGl state variables has a possibility of being out-of-date.
Standard_EXPORT void FetchState();
//! @return active textures
const occ::handle<OpenGl_TextureSet>& ActiveTextures() const { return myActiveTextures; }
//! Bind specified texture set to current context taking into account active GLSL program.
Standard_DEPRECATED("BindTextures() with explicit GLSL program should be used instead")
occ::handle<OpenGl_TextureSet> BindTextures(const occ::handle<OpenGl_TextureSet>& theTextures)
{
return BindTextures(theTextures, myActiveProgram);
}
//! Bind specified texture set to current context, or unbind previous one when NULL specified.
//! @param[in] theTextures texture set to bind
//! @param[in] theProgram program attributes; when not NULL,
//! mock textures will be bound to texture units expected by GLSL program,
//! but undefined by texture set
//! @return previous texture set
Standard_EXPORT occ::handle<OpenGl_TextureSet> BindTextures(
const occ::handle<OpenGl_TextureSet>& theTextures,
const occ::handle<OpenGl_ShaderProgram>& theProgram);
//! @return active GLSL program
const occ::handle<OpenGl_ShaderProgram>& ActiveProgram() const { return myActiveProgram; }
//! Bind specified program to current context,
//! or unbind previous one when NULL specified.
//! @return true if some program is bound to context
Standard_EXPORT bool BindProgram(const occ::handle<OpenGl_ShaderProgram>& theProgram);
//! Setup current shading material.
Standard_EXPORT void SetShadingMaterial(
const OpenGl_Aspects* theAspect,
const occ::handle<Graphic3d_PresentationAttributes>& theHighlight);
//! Checks if transparency is required for the given aspect and highlight style.
Standard_EXPORT static bool CheckIsTransparent(
const OpenGl_Aspects* theAspect,
const occ::handle<Graphic3d_PresentationAttributes>& theHighlight,
float& theAlphaFront,
float& theAlphaBack);
//! Checks if transparency is required for the given aspect and highlight style.
static bool CheckIsTransparent(const OpenGl_Aspects* theAspect,
const occ::handle<Graphic3d_PresentationAttributes>& theHighlight)
{
float anAlphaFront = 1.0f, anAlphaBack = 1.0f;
return CheckIsTransparent(theAspect, theHighlight, anAlphaFront, anAlphaBack);
}
//! Setup current color.
Standard_EXPORT void SetColor4fv(const NCollection_Vec4<float>& theColor);
//! Setup type of line.
Standard_EXPORT void SetTypeOfLine(const Aspect_TypeOfLine theType, const float theFactor = 1.0f);
//! Setup stipple line pattern with 1.0f factor; wrapper for glLineStipple().
void SetLineStipple(const uint16_t thePattern) { SetLineStipple(1.0f, thePattern); }
//! Setup type of line; wrapper for glLineStipple().
Standard_EXPORT void SetLineStipple(const float theFactor, const uint16_t thePattern);
//! Setup width of line.
Standard_EXPORT void SetLineWidth(const float theWidth);
//! Setup point size.
Standard_EXPORT void SetPointSize(const float theSize);
//! Setup point sprite origin using GL_POINT_SPRITE_COORD_ORIGIN state:
//! - GL_UPPER_LEFT when GLSL program is active;
//! flipping should be handled in GLSL program for compatibility with OpenGL ES
//! - GL_LOWER_LEFT for FFP
Standard_EXPORT void SetPointSpriteOrigin();
//! Setup texture matrix to active GLSL program or to FFP global state using glMatrixMode
//! (GL_TEXTURE).
//! @param[in] theParams texture parameters
//! @param[in] theIsTopDown texture top-down flag
Standard_EXPORT void SetTextureMatrix(const occ::handle<Graphic3d_TextureParams>& theParams,
const bool theIsTopDown);
//! Bind default Vertex Array Object
Standard_EXPORT void BindDefaultVao();
//! Default Frame Buffer Object.
const occ::handle<OpenGl_FrameBuffer>& DefaultFrameBuffer() const { return myDefaultFbo; }
//! Setup new Default Frame Buffer Object and return previously set.
//! This call doesn't change Active FBO!
Standard_EXPORT occ::handle<OpenGl_FrameBuffer> SetDefaultFrameBuffer(
const occ::handle<OpenGl_FrameBuffer>& theFbo);
//! Return debug context initialization state.
bool IsDebugContext() const { return myIsGlDebugCtx; }
Standard_EXPORT void EnableFeatures() const;
Standard_EXPORT void DisableFeatures() const;
//! Return resolution for rendering text.
unsigned int Resolution() const { return myResolution; }
//! Resolution scale factor (rendered resolution to standard resolution).
//! This scaling factor for parameters like text size to be properly displayed on device (screen /
//! printer).
float ResolutionRatio() const { return myResolutionRatio; }
//! Rendering scale factor (rendering viewport height to real window buffer height).
float RenderScale() const { return myRenderScale; }
//! Return TRUE if rendering scale factor is not 1.
bool HasRenderScale() const { return std::abs(myRenderScale - 1.0f) > 0.0001f; }
//! Rendering scale factor (inverted value).
float RenderScaleInv() const { return myRenderScaleInv; }
//! Return scale factor for line width.
float LineWidthScale() const { return myLineWidthScale; }
//! Set resolution ratio.
//! Note that this method rounds @theRatio to nearest integer.
void SetResolution(unsigned int theResolution, float theRatio, float theScale)
{
myResolution = (unsigned int)(theScale * theResolution + 0.5f);
myRenderScale = theScale;
myRenderScaleInv = 1.0f / theScale;
SetResolutionRatio(theRatio * theScale);
}
//! Set resolution ratio.
//! Note that this method rounds @theRatio to nearest integer.
void SetResolutionRatio(const float theRatio)
{
myResolutionRatio = theRatio;
myLineWidthScale = (std::max)(1.0f, std::floor(theRatio + 0.5f));
}
//! Return line feater width in pixels.
float LineFeather() const { return myLineFeather; }
//! Set line feater width.
void SetLineFeather(float theValue) { myLineFeather = theValue; }
//! Wrapper over glGetBufferSubData(), implemented as:
//! - OpenGL 1.5+ (desktop) via glGetBufferSubData();
//! - OpenGL ES 3.0+ via glMapBufferRange();
//! - WebGL 2.0+ via gl.getBufferSubData().
//! @param[in] theTarget target buffer to map {GLenum}
//! @param[in] theOffset offset to the beginning of sub-data {GLintptr}
//! @param[in] theSize number of bytes to read {GLsizeiptr}
//! @param[out] theData destination pointer to fill
//! @return FALSE if functionality is unavailable
Standard_EXPORT bool GetBufferSubData(unsigned int theTarget,
intptr_t theOffset,
intptr_t theSize,
void* theData);
//! Return Graphics Driver's vendor.
const TCollection_AsciiString& Vendor() const { return myVendor; }
//! Dumps the content of me into the stream
Standard_EXPORT void DumpJson(Standard_OStream& theOStream, int theDepth = -1) const;
//! Dumps the content of openGL state into the stream