MeshLib C++ Docs
Loading...
Searching...
No Matches
MRIRenderObject.h
Go to the documentation of this file.
1#pragma once
3#include "MRPch/MRBindingMacros.h"
5#include "MRMeshFwd.h"
6#include "MRViewportId.h"
7#include "MRVector2.h"
8#include "MRVector4.h"
9#include "MRAffineXf3.h"
10#include <functional>
11#include <typeindex>
12#include <memory>
13
14namespace MR
15{
16
17enum class DepthFunction
18{
19 Never = 0,
20 Less = 1,
21 Equal = 2,
22 Greater = 4,
23 LessOrEqual = Less | Equal,
24 GreaterOrEqual = Greater | Equal,
25 NotEqual = Less | Greater,
26 Always = Less | Equal | Greater,
27 Default = 8 // usually "Less" but may differ for different object types
28};
29MR_MAKE_FLAG_OPERATORS( DepthFunction )
30
31
32struct BaseRenderParams
33{
34 const Matrix4f& viewMatrix;
35 const Matrix4f& projMatrix;
36 ViewportId viewportId; // id of the viewport
37 Vector4i viewport; // viewport x0, y0, width, height
38};
39
42struct ModelBaseRenderParams : BaseRenderParams
43{
44 const Matrix4f& modelMatrix;
45 const Plane3f& clipPlane; // viewport clip plane (it is not applied while object does not have clipping flag set)
46 DepthFunction depthFunction = DepthFunction::Default;
47};
48
50struct ModelRenderParams : ModelBaseRenderParams
51{
52 const Matrix4f* normMatrixPtr{ nullptr }; // normal matrix, only necessary for triangles rendering
53 Vector3f lightPos; // position of light source
54 TransparencyMode transparencyMode; // determines how to handle transparent models
55
56 RenderModelPassMask passMask = RenderModelPassMask::All; // Only perform rendering if `bool( passMask & desiredPass )` is true.
57};
58
60struct BasicUiRenderTask
61{
62 virtual ~BasicUiRenderTask() = default;
63
64 BasicUiRenderTask() = default;
65 BasicUiRenderTask( const BasicUiRenderTask& ) = default;
66 BasicUiRenderTask( BasicUiRenderTask&& ) = default;
67 BasicUiRenderTask& operator=( const BasicUiRenderTask& ) = default;
68 BasicUiRenderTask& operator=( BasicUiRenderTask&& ) = default;
69
71 float renderTaskDepth = 0;
72
73 enum class InteractionMask
74 {
75 mouseHover = 1 << 0,
76 mouseScroll = 1 << 1,
77 };
78 MR_MAKE_FLAG_OPERATORS_IN_CLASS( InteractionMask )
79
81 {
82 // Which interactions should be blocked by this object.
83 // This is passed along between all `renderUi()` calls in a single frame, and then the end result is used.
84 mutable InteractionMask consumedInteractions{};
85
86 // If nothing else is hovered, this returns true and writes `mouseHover` to `consumedInteractions`.
87 [[nodiscard]] bool tryConsumeMouseHover() const
88 {
89 if ( !bool( consumedInteractions & InteractionMask::mouseHover ) )
90 {
91 consumedInteractions |= InteractionMask::mouseHover;
92 return true;
93 }
94 return false;
95 }
96 };
97
100 virtual void earlyBackwardPass( const BackwardPassParams& params ) { (void)params; }
101
103 virtual void renderPass() = 0;
104};
105
106struct UiRenderParams : BaseRenderParams
107{
108 using UiTaskList = std::vector<std::shared_ptr<BasicUiRenderTask>>;
109
110 // Those are Z-sorted and then executed.
111 UiTaskList* tasks = nullptr;
112};
113
114struct UiRenderManager
115{
116 virtual ~UiRenderManager() = default;
117
118 // This is called before doing `IRenderObject::renderUi()` on even object in a viewport. Each viewport is rendered separately.
119 virtual void preRenderViewport( ViewportId viewport ) { (void)viewport; }
120 // This is called after doing `IRenderObject::renderUi()` on even object in a viewport. Each viewport is rendered separately.
121 virtual void postRenderViewport( ViewportId viewport ) { (void)viewport; }
122
123 // Returns the parameters for the `IRenderObject::earlyBackwardPass()`.
124 // This will be called exactly once per viewport, each time the UI in it is rendered.
125 virtual BasicUiRenderTask::BackwardPassParams beginBackwardPass( ViewportId viewport, UiRenderParams::UiTaskList& tasks ) { (void)viewport; (void)tasks; return {}; }
126 // After the backward pass is performed, the parameters should be passed back into this function.
127 virtual void finishBackwardPass( ViewportId viewport, const BasicUiRenderTask::BackwardPassParams& params ) { (void)viewport, (void)params; }
128};
129
130class IRenderObject
131{
132public:
133 virtual ~IRenderObject() = default;
134
135 // These functions do:
136 // 1) bind data
137 // 2) pass shaders arguments
138 // 3) draw data
139
140 // Returns true if something was rendered, or false if nothing to render.
141 virtual bool render( const ModelRenderParams& params ) = 0;
142 virtual void renderPicker( const ModelBaseRenderParams& params, unsigned geomId ) = 0;
144 virtual size_t heapBytes() const = 0;
146 virtual size_t glBytes() const = 0;
148 virtual void forceBindAll() {}
149
154 virtual void renderUi( const UiRenderParams& params ) { (void)params; }
155};
156// Those dummy definitions remove undefined references in `RenderObjectCombinator` when it calls non-overridden pure virtual methods.
157// We could check in `RenderObjectCombinator` if they're overridden or not, but it's easier to just define them.
158inline bool IRenderObject::render( const ModelRenderParams& ) { return false; }
159inline void IRenderObject::renderPicker( const ModelBaseRenderParams&, unsigned ) {}
160inline size_t IRenderObject::heapBytes() const { return 0; }
161inline size_t IRenderObject::glBytes() const { return 0; }
162
163// Combines several different `IRenderObject`s into one in a meaningful way.
164template <typename ...Bases>
165requires ( ( std::derived_from<Bases, IRenderObject> && !std::same_as<Bases, IRenderObject> ) && ... )
166class RenderObjectCombinator : public Bases...
167{
168public:
170 : Bases( object )...
171 {}
172
173 bool render( const ModelRenderParams& params ) override
174 {
175 bool ret = false;
176 // Clang 11 chokes on this if I fold from the right instead of from the left. But why?
177 (void)( ..., ( ret = Bases::render( params ) || ret ) );
178 return ret;
179 }
180 void renderPicker( const ModelBaseRenderParams& params, unsigned geomId ) override { ( Bases::renderPicker( params, geomId ), ... ); }
181 size_t heapBytes() const override { return ( std::size_t{} + ... + Bases::heapBytes() ); }
182 size_t glBytes() const override { return ( std::size_t{} + ... + Bases::glBytes() ); }
183 void forceBindAll() override { ( Bases::forceBindAll(), ... ); }
184 void renderUi( const UiRenderParams& params ) override { ( Bases::renderUi( params ), ... ); }
185};
186
187MR_BIND_IGNORE MRMESH_API std::unique_ptr<IRenderObject> createRenderObject( const VisualObject& visObj, const std::type_index& type );
188
189template<typename ObjectType>
190MR_BIND_IGNORE std::unique_ptr<IRenderObject> createRenderObject( const VisualObject& visObj )
191{
192 static_assert( std::is_base_of_v<VisualObject, std::remove_reference_t<ObjectType>>, "MR::VisualObject is not base of ObjectType" );
193 return createRenderObject( visObj, typeid( ObjectType ) );
194}
195
196using IRenderObjectConstructorLambda = std::function<std::unique_ptr<IRenderObject>( const VisualObject& )>;
197
198template<typename RenderObjType>
199MR_BIND_IGNORE IRenderObjectConstructorLambda makeRenderObjectConstructor()
200{
201 return [] ( const VisualObject& visObj ) { return std::make_unique<RenderObjType>( visObj ); };
202}
203
205{
206public:
207 MRMESH_API RegisterRenderObjectConstructor( const std::type_index& type, IRenderObjectConstructorLambda lambda );
209
210private:
211 std::type_index type_;
212};
213
214#define MR_REGISTER_RENDER_OBJECT_IMPL(objectType, .../*rendObjectType*/)\
215 static MR::RegisterRenderObjectConstructor __objectRegistrator##objectType{typeid(objectType),makeRenderObjectConstructor<__VA_ARGS__>()};
216
217}
#define MR_MAKE_FLAG_OPERATORS_IN_CLASS(T)
Definition MRFlagOperators.h:9
#define MR_MAKE_FLAG_OPERATORS(T)
Definition MRFlagOperators.h:6
#define MRMESH_API
Definition MRMeshFwd.h:80
unsafe void renderPass()
new unsafe ref float renderTaskDepth
unsafe void earlyBackwardPass(MR.BasicUiRenderTask.Const_BackwardPassParams params_)
unsafe void renderUi(MR.Const_UiRenderParams params_)
unsafe void forceBindAll()
unsafe bool render(MR.Const_ModelRenderParams params_)
unsafe void renderPicker(MR.Const_ModelBaseRenderParams params_, uint geomId)
Definition MRIRenderObject.h:43
Definition MRIRenderObject.h:51
Definition MRIRenderObject.h:205
MRMESH_API RegisterRenderObjectConstructor(const std::type_index &type, IRenderObjectConstructorLambda lambda)
Definition MRIRenderObject.h:167
size_t glBytes() const override
Definition MRIRenderObject.h:182
void renderUi(const UiRenderParams &params) override
Definition MRIRenderObject.h:184
size_t heapBytes() const override
Definition MRIRenderObject.h:181
bool render(const ModelRenderParams &params) override
Definition MRIRenderObject.h:173
void renderPicker(const ModelBaseRenderParams &params, unsigned geomId) override
Definition MRIRenderObject.h:180
RenderObjectCombinator(const VisualObject &object)
Definition MRIRenderObject.h:169
void forceBindAll() override
Definition MRIRenderObject.h:183
unsafe MR.BasicUiRenderTask.BackwardPassParams beginBackwardPass(MR.ViewportId viewport, MR.Std.Vector_StdSharedPtrMRBasicUiRenderTask tasks)
unsafe void finishBackwardPass(MR.ViewportId viewport, MR.BasicUiRenderTask.Const_BackwardPassParams params_)
unsafe void postRenderViewport(MR.ViewportId viewport)
unsafe void preRenderViewport(MR.ViewportId viewport)
Definition MRIRenderObject.h:107
Definition MRVisualObject.h:119
Definition MRCameraOrientationPlugin.h:8
MR_BIND_IGNORE IRenderObjectConstructorLambda makeRenderObjectConstructor()
Definition MRIRenderObject.h:199
MR_BIND_IGNORE MRMESH_API std::unique_ptr< IRenderObject > createRenderObject(const VisualObject &visObj, const std::type_index &type)
Definition MRIRenderObject.h:81
bool tryConsumeMouseHover() const
Definition MRIRenderObject.h:87