Loading...
Searching...
No Matches
BackgroundNode.hpp
1#pragma once
2
3#include <Gfx/GfxParameter.hpp>
4#include <Gfx/Graph/RenderList.hpp>
5#include <Gfx/Graph/Window.hpp>
6#include <Gfx/InvertYRenderer.hpp>
7#include <Gfx/Settings/Model.hpp>
8
9namespace score::gfx
10{
12{
13 explicit BackgroundNode()
14 {
15 input.push_back(new Port{this, {}, Types::Image, {}});
16 auto& ctx = score::GUIAppContext();
17 auto& settings = ctx.settings<Gfx::Settings::Model>();
18 double settings_rate = settings.getRate();
19 if(settings_rate <= 0.)
20 settings_rate = 60.;
21 m_conf = {.manualRenderingRate = 1000. / settings_rate};
22 }
23
24 virtual ~BackgroundNode() { }
25
26 void startRendering() override { }
27 void render() override
28 {
29 auto renderer = m_renderer.lock();
30 if(renderer && m_renderState)
31 {
32 if(renderer->renderers.size() > 1)
33 {
34 auto rhi = m_renderState->rhi;
35 QRhiCommandBuffer* cb{};
36 if(rhi->beginOffscreenFrame(&cb) != QRhi::FrameOpSuccess)
37 return;
38
39 renderer->render(*cb);
40 rhi->endOffscreenFrame();
41 }
42 else
43 {
44 shared_readback->data.clear();
45 shared_readback->pixelSize = {};
46 }
47 }
48 }
49 void onRendererChange() override { }
50 bool canRender() const override { return true; }
51 void stopRendering() override { }
52
53 void setRenderer(std::shared_ptr<RenderList> r) override { m_renderer = r; }
54 RenderList* renderer() const override { return m_renderer.lock().get(); }
55
56 void createOutput(score::gfx::OutputConfiguration conf) override
57 {
58 m_onResize = conf.onResize;
59
60 QSize newSz = m_renderSize;
61 if(newSz.width() <= 0 || newSz.height() <= 0)
62 newSz = m_size;
63 if(newSz.width() <= 0 || newSz.height() <= 0)
64 newSz = QSize{1024, 1024};
65
66 m_renderState = score::gfx::createRenderState(conf.graphicsApi, newSz, nullptr);
67 m_renderState->outputSize = m_renderState->renderSize;
68
69 auto rhi = m_renderState->rhi;
70 m_texture = rhi->newTexture(
71 QRhiTexture::RGBA8, m_renderState->renderSize, 1,
72 QRhiTexture::RenderTarget | QRhiTexture::UsedAsTransferSource);
73 m_texture->create();
74
75 m_depthBuffer = rhi->newRenderBuffer(
76 QRhiRenderBuffer::DepthStencil, m_renderState->renderSize, 1);
77 m_depthBuffer->create();
78
79 QRhiTextureRenderTargetDescription desc;
80 desc.setColorAttachments({QRhiColorAttachment(m_texture)});
81
82 desc.setDepthStencilBuffer(m_depthBuffer);
83 m_renderTarget = rhi->newTextureRenderTarget(desc);
84 m_renderState->renderPassDescriptor
85 = m_renderTarget->newCompatibleRenderPassDescriptor();
86 m_renderTarget->setRenderPassDescriptor(m_renderState->renderPassDescriptor);
87 m_renderTarget->create();
88
89 conf.onReady();
90 }
91
92 void destroyOutput() override
93 {
94 if(m_renderState)
95 {
96 delete m_renderTarget;
97 m_renderTarget = nullptr;
98
99 delete m_depthBuffer;
100 m_depthBuffer = nullptr;
101
102 delete m_texture;
103 m_texture = nullptr;
104
105 delete m_renderState->renderPassDescriptor;
106 m_renderState->renderPassDescriptor = nullptr;
107
108 m_renderState->destroy();
109 m_renderState.reset();
110 }
111 }
112 void updateGraphicsAPI(GraphicsApi) override { }
113
114 void setSize(QSize newSz)
115 {
116 if(m_size != newSz)
117 {
118 m_size = newSz;
119 resize();
120 }
121 }
122 void setRenderSize(QSize newSz)
123 {
124 if(m_renderSize != newSz)
125 {
126 m_renderSize = newSz;
127 resize();
128 }
129 }
130
131 void resize()
132 {
133 QSize newSz = m_renderSize;
134 if(newSz.width() <= 0 || newSz.height() <= 0)
135 newSz = m_size;
136 if(newSz.width() <= 0 || newSz.height() <= 0)
137 newSz = QSize{1024, 1024};
138
139 if(m_renderState)
140 {
141 m_renderState->renderSize = newSz;
142 m_renderState->outputSize = newSz;
143
144 auto rhi = m_renderState->rhi;
145
146 m_renderTarget->destroy();
147 m_texture->destroy();
148 m_texture->setPixelSize(newSz);
149 m_texture->create();
150
151 if(m_depthBuffer)
152 m_depthBuffer->destroy();
153 else
154 m_depthBuffer = rhi->newRenderBuffer(QRhiRenderBuffer::DepthStencil, newSz);
155 m_depthBuffer->setPixelSize(newSz);
156 m_depthBuffer->create();
157
158 delete m_renderTarget;
159 delete m_renderState->renderPassDescriptor;
160
161 QRhiTextureRenderTargetDescription desc;
162 desc.setColorAttachments({QRhiColorAttachment(m_texture)});
163 desc.setDepthStencilBuffer(m_depthBuffer);
164 m_renderTarget = rhi->newTextureRenderTarget(desc);
165 m_renderState->renderPassDescriptor
166 = m_renderTarget->newCompatibleRenderPassDescriptor();
167 m_renderTarget->setRenderPassDescriptor(m_renderState->renderPassDescriptor);
168 m_renderTarget->create();
169 }
170
171 if(m_onResize)
172 m_onResize();
173 }
174
175 std::shared_ptr<RenderState> renderState() const override { return m_renderState; }
176
178 {
180 .texture = m_texture,
181 .renderPass = m_renderState->renderPassDescriptor,
182 .renderTarget = m_renderTarget};
183 return new Gfx::InvertYRenderer{
184 *this, rt, const_cast<QRhiReadbackResult&>(*shared_readback)};
185 }
186
187 OutputNode::Configuration configuration() const noexcept override { return m_conf; }
188
189 std::shared_ptr<QRhiReadbackResult> shared_readback;
190
191private:
192 Configuration m_conf;
193
194 std::weak_ptr<score::gfx::RenderList> m_renderer{};
195 QRhiTexture* m_texture{};
196 QRhiRenderBuffer* m_depthBuffer{};
197 QRhiTextureRenderTarget* m_renderTarget{};
198 std::shared_ptr<score::gfx::RenderState> m_renderState{};
199
200 std::function<void()> m_onResize;
201 QSize m_size{1024, 1024};
202 QSize m_renderSize{};
203};
204}
Definition InvertYRenderer.hpp:10
Definition score-plugin-gfx/Gfx/Settings/Model.hpp:41
std::vector< Port * > input
Input ports of that node.
Definition score-plugin-gfx/Gfx/Graph/Node.hpp:103
Base class for sink nodes (QWindow, spout, syphon, NDI output, ...)
Definition OutputNode.hpp:31
Definition OutputNode.hpp:18
List of nodes to be rendered to an output.
Definition RenderList.hpp:19
std::vector< score::gfx::NodeRenderer * > renderers
Renderers - one per node.
Definition RenderList.hpp:117
void render(QRhiCommandBuffer &commands, bool force=false)
Render every node in order.
Definition RenderList.cpp:501
Graphics rendering pipeline for ossia score.
Definition Filter/PreviewWidget.hpp:12
GraphicsApi
Available graphics APIs to use.
Definition RenderState.hpp:22
Definition BackgroundNode.hpp:12
score::gfx::OutputNodeRenderer * createRenderer(RenderList &r) const noexcept override
Create a renderer in a given context for this node.
Definition BackgroundNode.hpp:177
Definition OutputNode.hpp:11
Definition OutputNode.hpp:61
Port of a score::gfx::Node.
Definition score-plugin-gfx/Gfx/Graph/Utils.hpp:54
Useful abstraction for storing all the data related to a render target.
Definition score-plugin-gfx/Gfx/Graph/Utils.hpp:122