4#include <Crousti/GfxNode.hpp>
9template <
typename Node_T>
11 avnd::texture_input_introspection<Node_T>::size == 0
12 && avnd::texture_output_introspection<Node_T>::size > 0)
13struct GfxRenderer<Node_T>
final :
score::gfx::GenericNodeRenderer
15 using texture_outputs = avnd::texture_output_introspection<Node_T>;
16 std::shared_ptr<Node_T> state;
18 ossia::time_value m_last_time{-1};
20 const GfxNode<Node_T>& node() const noexcept
22 return static_cast<const GfxNode<Node_T>&
>(score::gfx::NodeRenderer::node);
25 GfxRenderer(
const GfxNode<Node_T>& p)
26 :
score::gfx::GenericNodeRenderer{p}
27 , state{
std::make_shared<Node_T>()}
29 prepareNewState<Node_T>(state, p);
38 template <
typename Tex>
42 auto& rhi = *renderer.
state.rhi;
44 if(size.width() > 0 && size.height() > 0)
46 texture = rhi.newTexture(
47 gpp::qrhi::textureFormat<Tex>(), size, 1, QRhiTexture::Flag{});
52 auto sampler = rhi.newSampler(
53 QRhiSampler::Linear, QRhiSampler::Linear, QRhiSampler::None,
54 QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge);
57 this->m_samplers.push_back({sampler, texture});
60 template <avnd::cpu_texture Tex>
63 auto& [sampler, texture] = this->m_samplers[k];
66 auto sz = texture->pixelSize();
67 if(cpu_tex.width == sz.width() && cpu_tex.height == sz.height())
72 if(cpu_tex.width > 0 && cpu_tex.height > 0)
74 QRhiTexture* oldtex = texture;
75 QRhiTexture* newtex = renderer.
state.rhi->newTexture(
76 gpp::qrhi::textureFormat<Tex>(), QSize{cpu_tex.width, cpu_tex.height}, 1,
79 for(
auto& [edge, pass] : this->m_p)
81 score::gfx::replaceTexture(*pass.srb, sampler, newtex);
86 oldtex->deleteLater();
93 for(
auto& [edge, pass] : this->m_p)
95 score::gfx::replaceTexture(*pass.srb, sampler, &renderer.emptyTexture());
101 void uploadOutputTexture(
103 QRhiResourceUpdateBatch* res)
107 if(
auto texture = updateTexture(renderer, k, cpu_tex))
111 QRhiTextureSubresourceUploadDescription sd(cpu_tex.bytes, cpu_tex.bytesize());
112 QRhiTextureUploadDescription desc{QRhiTextureUploadEntry{0, 0, sd}};
114 res->uploadTexture(texture, desc);
117 cpu_tex.changed =
false;
125 auto& parent = node();
126 if constexpr(
requires { state->prepare(); })
128 parent.processControlIn(
129 *
this, *state, m_last_message, parent.last_message, parent.m_ctx);
134 this->defaultMeshInit(renderer, mesh, res);
135 this->processUBOInit(renderer);
138 std::tie(this->m_vertexS, this->m_fragmentS)
142 avnd::cpu_texture_output_introspection<Node_T>::for_all(
143 avnd::get_outputs<Node_T>(*state), [&](
auto& t) {
144 createOutput(renderer, t.texture, QSize{t.texture.width, t.texture.height});
147 this->defaultPassesInit(renderer, mesh);
154 this->defaultUBOUpdate(renderer, res);
160 for(
auto& [sampl, texture] : this->m_samplers)
163 texture->deleteLater();
167 this->defaultRelease(r);
170 void runInitialPasses(
174 auto& parent = node();
176 if(parent.last_message.token.date == m_last_time)
180 m_last_time = parent.last_message.token.date;
182 parent.processControlIn(
183 *
this, *state, m_last_message, parent.last_message, parent.m_ctx);
190 avnd::cpu_texture_output_introspection<Node_T>::for_all(
191 avnd::get_outputs<Node_T>(*state), [&](
auto& t) {
192 uploadOutputTexture(renderer, k, t.texture, res);
196 commands.resourceUpdate(res);
197 res = renderer.
state.rhi->nextResourceUpdateBatch();
200 parent.processControlOut(*this->state);
204template <
typename Node_T>
205 requires(avnd::texture_input_introspection<Node_T>::size == 0
206 && avnd::texture_output_introspection<Node_T>::size > 0)
207struct GfxNode<Node_T>
final
212 , GpuNodeElements<Node_T>
217 std::weak_ptr<Execution::ExecutionCommandQueue> q, Gfx::exec_controls ctls,
219 : CustomGfxNodeBase{ctx}
220 , GpuControlOuts{
std::move(q),
std::move(ctls)}
221 , processModel{element}
225 initGfxPorts<Node_T>(
this, this->input, this->output);
231 return new GfxRenderer<Node_T>{*
this};
Definition score-plugin-avnd/Crousti/ProcessModel.hpp:79
Renderer for a given node.
Definition NodeRenderer.hpp:11
List of nodes to be rendered to an output.
Definition RenderList.hpp:19
const score::gfx::Mesh & defaultTriangle() const noexcept
A triangle mesh correct for this API.
Definition RenderList.cpp:305
RenderState & state
RenderState corresponding to this RenderList.
Definition RenderList.hpp:89
QRhiTexture & emptyTexture() const noexcept
Texture to use when a texture is missing.
Definition RenderList.hpp:112
Definition Factories.hpp:19
std::pair< QShader, QShader > makeShaders(const RenderState &v, QString vert, QString frag)
Get a pair of compiled vertex / fragment shaders from GLSL 4.5 sources.
Definition score-plugin-gfx/Gfx/Graph/Utils.cpp:390
Base toolkit upon which the software is built.
Definition Application.cpp:97
Definition DocumentContext.hpp:18
Connection between two score::gfx::Port.
Definition score-plugin-gfx/Gfx/Graph/Utils.hpp:66
Definition score-plugin-gfx/Gfx/Graph/Node.hpp:50
Port of a score::gfx::Node.
Definition score-plugin-gfx/Gfx/Graph/Utils.hpp:48
Useful abstraction for storing all the data related to a render target.
Definition score-plugin-gfx/Gfx/Graph/Utils.hpp:111