13 ossia::mesh_list geom;
15 using pip = QRhiGraphicsPipeline;
16 pip::Topology topology = pip::Topology::TriangleStrip;
17 pip::CullMode cullMode = pip::CullMode::None;
18 pip::FrontFace frontFace = pip::FrontFace::CW;
20 ossia::small_vector<QRhiVertexInputBinding, 2> vertexBindings;
21 ossia::small_vector<QRhiVertexInputAttribute, 2> vertexAttributes;
25 const ossia::mesh_list& g,
const ossia::geometry_filter_list_ptr& f)
31 QRhiBuffer* init_vbo(
const ossia::geometry::cpu_buffer& buf, QRhi& rhi)
const noexcept
33 const auto vtx_buf_size = buf.size;
35 = rhi.newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::VertexBuffer, vtx_buf_size);
36 mesh_buf->setName(
"Mesh::mesh_buf");
43 QRhiBuffer* init_vbo(
const ossia::geometry::gpu_buffer& buf, QRhi& rhi)
const noexcept
45 return static_cast<QRhiBuffer*
>(buf.handle);
49 init_index(
const ossia::geometry::cpu_buffer& buf, QRhi& rhi)
const noexcept
51 QRhiBuffer* idx_buf{};
52 if(
const auto idx_buf_size = buf.size; idx_buf_size > 0)
55 = rhi.newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::IndexBuffer, idx_buf_size);
56 idx_buf->setName(
"Mesh::idx_buf");
65 init_index(
const ossia::geometry::gpu_buffer& buf, QRhi& rhi)
const noexcept
67 return static_cast<QRhiBuffer*
>(buf.handle);
70 [[nodiscard]]
MeshBuffers init(QRhi& rhi)
const noexcept override
72 if(geom.meshes.empty())
74 if(geom.meshes[0].buffers.empty())
78 ret.mesh = ossia::visit(
79 [&](
auto& buf) {
return init_vbo(buf, rhi); }, geom.meshes[0].buffers[0].data);
80 if(geom.meshes[0].buffers.size() > 1)
81 ret.index = ossia::visit([&](
auto& buf) {
82 return init_index(buf, rhi);
83 }, geom.meshes[0].buffers[1].data);
88 const ossia::geometry::cpu_buffer& vtx_buf,
MeshBuffers& meshbuf,
89 QRhiResourceUpdateBatch& rb)
const noexcept
91 if(
auto sz = vtx_buf.size; sz != meshbuf.mesh->size())
93 meshbuf.mesh->destroy();
94 meshbuf.mesh->setSize(sz);
95 meshbuf.mesh->create();
97 rb.updateDynamicBuffer(meshbuf.mesh, 0, meshbuf.mesh->size(), vtx_buf.data.get());
101 const ossia::geometry::gpu_buffer& vtx_buf,
MeshBuffers& meshbuf,
102 QRhiResourceUpdateBatch& rb)
const noexcept
107 const ossia::geometry::cpu_buffer& idx_buf,
MeshBuffers& meshbuf,
108 QRhiResourceUpdateBatch& rb)
const noexcept
110 void* idx_buf_data =
nullptr;
113 if(geom.meshes[0].buffers.size() > 1)
115 if(
const auto idx_buf_size = idx_buf.size; idx_buf_size > 0)
117 idx_buf_data = idx_buf.data.get();
119 if(
auto sz = idx_buf.size; sz != meshbuf.index->size())
121 meshbuf.index->destroy();
122 meshbuf.index->setSize(sz);
123 meshbuf.index->create();
136 if(meshbuf.index && idx_buf_data)
138 rb.updateDynamicBuffer(meshbuf.index, 0, meshbuf.index->size(), idx_buf_data);
143 const ossia::geometry::gpu_buffer& idx_buf,
MeshBuffers& meshbuf,
144 QRhiResourceUpdateBatch& rb)
const noexcept
147 void update(
MeshBuffers& meshbuf, QRhiResourceUpdateBatch& rb)
const noexcept override
149 if(geom.meshes.empty())
151 if(geom.meshes[0].buffers.empty())
153 ossia::visit([&](
auto& buf) {
154 return update_vbo(buf, meshbuf, rb);
155 }, geom.meshes[0].buffers[0].data);
157 if(geom.meshes[0].buffers.size() > 1)
158 ossia::visit([&](
auto& buf) {
159 return update_index(buf, meshbuf, rb);
160 }, geom.meshes[0].buffers[1].data);
162 Flags flags()
const noexcept override
165 for(
auto& attr : vertexAttributes)
167 switch(attr.location())
191 vertexBindings.clear();
192 vertexAttributes.clear();
195 void preparePipeline(QRhiGraphicsPipeline& pip)
const noexcept override
197 if(cullMode == QRhiGraphicsPipeline::None)
199 pip.setDepthTest(
false);
200 pip.setDepthWrite(
false);
204 pip.setDepthTest(
true);
205 pip.setDepthWrite(
true);
208 pip.setTopology(this->topology);
209 pip.setCullMode(this->cullMode);
210 pip.setFrontFace(this->frontFace);
212 QRhiVertexInputLayout inputLayout;
213 inputLayout.setBindings(this->vertexBindings.begin(), this->vertexBindings.end());
214 inputLayout.setAttributes(
215 this->vertexAttributes.begin(), this->vertexAttributes.end());
216 pip.setVertexInputLayout(inputLayout);
219 void reload(
const ossia::mesh_list& ml,
const ossia::geometry_filter_list_ptr& f)
224 if(this->geom.meshes.size() == 0)
226 qDebug() <<
"Clearing geometry: ";
231 auto& g = this->geom.meshes[0];
233 vertexBindings.clear();
234 for(
auto& binding : g.bindings)
236 vertexBindings.emplace_back(
237 binding.stride, (QRhiVertexInputBinding::Classification)binding.classification,
241 vertexAttributes.clear();
242 for(
auto& attr : g.attributes)
244 vertexAttributes.emplace_back(
245 attr.binding, attr.location, (QRhiVertexInputAttribute::Format)attr.format,
249 if(g.buffers.empty())
251 qDebug() <<
"Error: empty buffer !";
255 topology = (QRhiGraphicsPipeline::Topology)g.topology;
256 cullMode = (QRhiGraphicsPipeline::CullMode)g.cull_mode;
257 frontFace = (QRhiGraphicsPipeline::FrontFace)g.front_face;
260 void draw(
const MeshBuffers& bufs, QRhiCommandBuffer& cb)
const noexcept override
262 for(
auto& g : this->geom.meshes)
264 const auto sz = g.input.size();
266 QVarLengthArray<QRhiCommandBuffer::VertexInput> bindings(sz);
269 for(
auto& in : g.input)
271 bindings[i++] = {bufs.mesh, in.offset};
274 if(g.index.buffer >= 0)
276 const auto idxFmt = g.index.format ==
decltype(g.index)::uint16
277 ? QRhiCommandBuffer::IndexUInt32
278 : QRhiCommandBuffer::IndexUInt32;
279 cb.setVertexInput(0, sz, bindings.data(), bufs.index, g.index.offset, idxFmt);
283 cb.setVertexInput(0, sz, bindings.data());
286 if(g.index.buffer > -1)
288 cb.drawIndexed(g.indices);