2828#include < cage-engine/model.h>
2929#include < cage-engine/renderObject.h>
3030#include < cage-engine/scene.h>
31+ #include < cage-engine/sceneCustomDraw.h>
3132#include < cage-engine/sceneRender.h>
3233#include < cage-engine/screenSpaceEffects.h>
3334#include < cage-engine/shader.h>
@@ -123,9 +124,12 @@ namespace cage
123124 Holder<Font> font;
124125 };
125126
127+ struct RenderCustom : private Noncopyable
128+ {};
129+
126130 struct RenderData : private Noncopyable
127131 {
128- std::variant<std::monostate, RenderModel, RenderIcon, RenderText> data;
132+ std::variant<std::monostate, RenderModel, RenderIcon, RenderText, RenderCustom > data;
129133 Mat4 model;
130134 Vec4 color = Vec4::Nan(); // linear rgb (NOT alpha-premultiplied), opacity
131135 Vec4 animation = Vec4::Nan(); // time (seconds), speed, offset (normalized), unused
@@ -166,6 +170,8 @@ namespace cage
166170 return { renderLayer, translucent, depth, +r.mesh , +r.texture , false };
167171 if constexpr (std::is_same_v<T, RenderText>)
168172 return { renderLayer, translucent, depth, +r.font , nullptr , false };
173+ if constexpr (std::is_same_v<T, RenderCustom>)
174+ return { renderLayer, translucent, depth, nullptr , nullptr , false };
169175 return {};
170176 },
171177 data);
@@ -660,6 +666,28 @@ namespace cage
660666 }
661667 }
662668
669+ void renderCustom (const RenderModeEnum renderMode, const PointerRange<const RenderData> instances) const
670+ {
671+ CAGE_ASSERT (!instances.empty ());
672+ const RenderData &rd = instances[0 ];
673+ CAGE_ASSERT (std::holds_alternative<RenderCustom>(rd.data ));
674+
675+ if (renderMode != RenderModeEnum::Color)
676+ return ;
677+
678+ for (const auto &it : instances)
679+ {
680+ const ProfilingScope profiling (" custom draw" );
681+ CAGE_ASSERT (std::holds_alternative<RenderCustom>(it.data ));
682+ CustomDrawConfig cfg;
683+ cfg.renderConfig = this ;
684+ cfg.entity = it.e ;
685+ cfg.encoder = +encoder;
686+ CAGE_ASSERT (it.e ->has <CustomDrawComponent>());
687+ it.e ->value <CustomDrawComponent>().callback (cfg);
688+ }
689+ }
690+
663691 void renderInstances (const RenderModeEnum renderMode, const PointerRange<const RenderData> instances) const
664692 {
665693 CAGE_ASSERT (!instances.empty ());
@@ -676,6 +704,8 @@ namespace cage
676704 renderIcons (renderMode, instances);
677705 if constexpr (std::is_same_v<T, RenderText>)
678706 renderTexts (renderMode, instances);
707+ if constexpr (std::is_same_v<T, RenderCustom>)
708+ renderCustom (renderMode, instances);
679709 },
680710 rd.data );
681711 }
@@ -706,6 +736,8 @@ namespace cage
706736 return { +r.mesh , +r.texture , false , d.translucent };
707737 if constexpr (std::is_same_v<T, RenderText>)
708738 return { +r.font , nullptr , false , d.translucent };
739+ if constexpr (std::is_same_v<T, RenderCustom>)
740+ return { d.e , nullptr , false , d.translucent };
709741 return {};
710742 },
711743 d.data );
@@ -886,6 +918,21 @@ namespace cage
886918 renderData.push_back (std::move (rd));
887919 }
888920
921+ void prepareCustomDraw (Entity *e, const CustomDrawComponent &cdc)
922+ {
923+ CAGE_ASSERT (cdc.callback );
924+ RenderCustom rc;
925+ RenderData rd;
926+ rd.e = e;
927+ rd.model = Mat4 (modelTransform (e));
928+ rd.color = initializeColor (e->getOrDefault <ColorComponent>());
929+ rd.renderLayer = cdc.renderLayer ;
930+ rd.translucent = true ;
931+ rd.depth = (viewProj * (rd.model * Vec4 (0 , 0 , 0 , 1 )))[2 ] * -1 ;
932+ rd.data = std::move (rc);
933+ renderData.push_back (std::move (rd));
934+ }
935+
889936 CAGE_FORCE_INLINE bool failedMask (Entity *e) const
890937 {
891938 const uint32 c = e->getOrDefault <SceneComponent>().sceneMask ;
@@ -952,6 +999,15 @@ namespace cage
952999 prepareText (e, tc);
9531000 },
9541001 +scene, false );
1002+
1003+ entitiesVisitor (
1004+ [&](Entity *e, const CustomDrawComponent &cdc)
1005+ {
1006+ if (failedMask (e))
1007+ return ;
1008+ prepareCustomDraw (e, cdc);
1009+ },
1010+ +scene, false );
9551011 }
9561012
9571013 void orderRenderData ()
0 commit comments