Visual Computing Library  devel
Loading...
Searching...
No Matches
mesh_render_vectors.h
1/*****************************************************************************
2 * VCLib *
3 * Visual Computing Library *
4 * *
5 * Copyright(C) 2021-2025 *
6 * Visual Computing Lab *
7 * ISTI - Italian National Research Council *
8 * *
9 * All rights reserved. *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the Mozilla Public License Version 2.0 as published *
13 * by the Mozilla Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * Mozilla Public License Version 2.0 *
20 * (https://www.mozilla.org/en-US/MPL/2.0/) for more details. *
21 ****************************************************************************/
22
23#ifndef VCL_OPENGL2_DRAWABLE_MESH_MESH_RENDER_VECTORS_H
24#define VCL_OPENGL2_DRAWABLE_MESH_MESH_RENDER_VECTORS_H
25
26#include <vclib/algorithms/core.h>
27#include <vclib/algorithms/mesh.h>
28#include <vclib/io.h>
29#include <vclib/mesh.h>
30#include <vclib/space/complex.h>
31#include <vclib/space/core.h>
32
33#include <vclib/render/drawable/mesh/mesh_render_data.h>
34#include <vclib/render/drawable/mesh/mesh_render_info.h>
35
36namespace vcl {
37
38template<MeshConcept Mesh>
39class MeshRenderVectors : public MeshRenderData<MeshRenderVectors<Mesh>>
40{
41 using MeshType = Mesh;
43 using MRI = MeshRenderInfo;
44
45 friend Base;
46
47 std::vector<float> mVerts;
48 std::vector<float> mVNormals;
49 std::vector<uint32_t> mVColors;
50 std::vector<float> mVTexCoords;
51 std::vector<float> mWTexCoords;
52
53 std::vector<uint32_t> mTris;
54 std::vector<float> mTNormals;
55 std::vector<uint32_t> mTColors;
56 std::vector<uint32_t> mVTexIds;
57 std::vector<uint32_t> mWTexIds;
58
59 std::vector<uint32_t> mEdges;
60 std::vector<float> mENormals;
61 std::vector<uint32_t> mEColors;
62
63 std::vector<uint32_t> mWireframe;
64
65 std::vector<vcl::Image> mTextures;
66
67 std::array<float, 4> mMeshColor = {0.5, 0.5, 0.5, 1};
68
69public:
70 MeshRenderVectors() = default;
71
73 const MeshType& mesh,
74 MRI::BuffersBitSet buffersToFill = MRI::BUFFERS_ALL) :
76 {
77 Base::update(mesh, buffersToFill);
78 }
79
80 void swap(MeshRenderVectors& other)
81 {
82 using std::swap;
83 Base::swap(other);
84 swap(mVerts, other.mVerts);
85 swap(mVNormals, other.mVNormals);
86 swap(mVColors, other.mVColors);
87 swap(mVTexCoords, other.mVTexCoords);
88 swap(mWTexCoords, other.mWTexCoords);
89 swap(mTris, other.mTris);
90 swap(mTNormals, other.mTNormals);
91 swap(mTColors, other.mTColors);
92 swap(mVTexIds, other.mVTexIds);
93 swap(mWTexIds, other.mWTexIds);
94 swap(mEdges, other.mEdges);
95 swap(mENormals, other.mENormals);
96 swap(mEColors, other.mEColors);
97 swap(mWireframe, other.mWireframe);
98 swap(mTextures, other.mTextures);
99 swap(mMeshColor, other.mMeshColor);
100 }
101
102 uint vertexNumber() const { return mVerts.size() / 3; }
103
104 uint triangleNumber() const { return mTris.size() / 3; }
105
106 uint edgeNumber() const { return mEdges.size() / 2; }
107
108 uint wireframeEdgeNumber() const { return mWireframe.size() / 2; }
109
110 uint textureNumber() const { return mTextures.size(); }
111
112 vcl::Point2i textureSize(uint ti) const
113 {
114 return vcl::Point2i(mTextures[ti].width(), mTextures[ti].height());
115 }
116
117 const float* vertexBufferData() const
118 {
119 if (mVerts.empty())
120 return nullptr;
121 return mVerts.data();
122 }
123
124 uint vertexBufferSize() const { return mVerts.size(); }
125
126 const uint32_t* triangleBufferData() const
127 {
128 if (mTris.empty())
129 return nullptr;
130 return mTris.data();
131 }
132
133 uint triangleBufferSize() const { return mTris.size(); }
134
135 const uint32_t* edgeBufferData() const
136 {
137 if (mEdges.empty())
138 return nullptr;
139 return mEdges.data();
140 }
141
142 uint edgeBufferSize() const { return mEdges.size(); }
143
144 const uint32_t* wireframeBufferData() const
145 {
146 if (mWireframe.empty())
147 return nullptr;
148 return mWireframe.data();
149 }
150
151 uint wireframeBufferSize() const { return mWireframe.size(); }
152
153 const float* vertexNormalBufferData() const
154 {
155 if (mVNormals.empty())
156 return nullptr;
157 return mVNormals.data();
158 }
159
160 const uint32_t* vertexColorBufferData() const
161 {
162 if (mVColors.empty())
163 return nullptr;
164 return mVColors.data();
165 }
166
167 const float* triangleNormalBufferData() const
168 {
169 if (mTNormals.empty())
170 return nullptr;
171 return mTNormals.data();
172 }
173
174 const uint32_t* triangleColorBufferData() const
175 {
176 if (mTColors.empty())
177 return nullptr;
178 return mTColors.data();
179 }
180
181 const float* vertexTexCoordsBufferData() const
182 {
183 if (mVTexCoords.empty())
184 return nullptr;
185 return mVTexCoords.data();
186 }
187
188 const uint32_t* vertexTextureIDsBufferData() const
189 {
190 if (mVTexIds.empty())
191 return nullptr;
192 return mVTexIds.data();
193 }
194
195 const float* wedgeTexCoordsBufferData() const
196 {
197 if (mWTexCoords.empty())
198 return nullptr;
199 return mWTexCoords.data();
200 }
201
202 const uint32_t* wedgeTextureIDsBufferData() const
203 {
204 if (mWTexIds.empty())
205 return nullptr;
206 return mWTexIds.data();
207 }
208
209 const float* edgeNormalBufferData() const
210 {
211 if (mENormals.empty())
212 return nullptr;
213 return mENormals.data();
214 }
215
216 const uint32_t* edgeColorBufferData() const
217 {
218 if (mEColors.empty())
219 return nullptr;
220 return mEColors.data();
221 }
222
223 const float* meshColorBufferData() const { return mMeshColor.data(); }
224
225 const unsigned char* textureBufferData(uint ti) const
226 {
227 return mTextures[ti].data();
228 }
229
230private:
231 void setVertexPositionsBuffer(const MeshType& mesh) // override
232 {
233 uint nv = Base::numVerts();
234
235 mVerts.resize(nv * 3);
236
237 Base::fillVertexPositions(mesh, mVerts.data());
238 }
239
240 void setVertexNormalsBuffer(const MeshType& mesh) // override
241 {
242 uint nv = Base::numVerts();
243
244 mVNormals.resize(nv * 3);
245
246 Base::fillVertexNormals(mesh, mVNormals.data());
247 }
248
249 void setVertexColorsBuffer(const MeshType& mesh) // override
250 {
251 uint nv = Base::numVerts();
252
253 mVColors.resize(nv);
254
255 Base::fillVertexColors(mesh, mVColors.data(), Color::Format::ABGR);
256 }
257
258 void setVertexTexCoordsBuffer(const MeshType& mesh) // override
259 {
260 uint nv = Base::numVerts();
261
262 mVTexCoords.resize(nv * 2);
263
264 Base::fillVertexTexCoords(mesh, mVTexCoords.data());
265 }
266
267 void setWedgeTexCoordsBuffer(const MeshType& mesh) // override
268 {
269 uint nv = Base::numVerts();
270
271 mWTexCoords.resize(nv * 2);
272
273 Base::fillWedgeTexCoords(mesh, mWTexCoords.data());
274 }
275
276 void setTriangleIndicesBuffer(const MeshType& mesh) // override
277 {
278 uint nt = Base::numTris();
279
280 mTris.resize(nt * 3);
281
282 Base::fillTriangleIndices(mesh, mTris.data());
283 }
284
285 void setTriangleNormalsBuffer(const MeshType& mesh) // override
286 {
287 uint nt = Base::numTris();
288
289 mTNormals.resize(nt * 3);
290
291 Base::fillTriangleNormals(mesh, mTNormals.data());
292 }
293
294 void setTriangleColorsBuffer(const MeshType& mesh) // override
295 {
296 uint nt = Base::numTris();
297
298 mTColors.resize(nt);
299
300 Base::fillTriangleColors(mesh, mTColors.data(), Color::Format::ABGR);
301 }
302
303 void setVertexMaterialIndicesBuffer(const MeshType& mesh) // override
304 {
305 if (vcl::isPerVertexMaterialIndexAvailable(mesh)) {
306 uint nt = Base::numTris();
307
308 mVTexIds.resize(nt);
309
310 Base::fillVertexMaterialIndices(mesh, mVTexIds.data());
311 }
312 }
313
314 void setFaceMaterialIndicesBuffer(const MeshType& mesh) // override
315 {
316 uint nt = Base::numTris();
317
318 mWTexIds.resize(nt);
319
320 Base::fillFaceMaterialIndices(mesh, mWTexIds.data());
321 }
322
323 void setEdgeIndicesBuffer(const MeshType& mesh) // override
324 {
325 uint ne = Base::numEdges();
326
327 mEdges.resize(ne * 2);
328
329 Base::fillEdgeIndices(mesh, mEdges.data());
330 }
331
332 void setEdgeNormalsBuffer(const MeshType& mesh) // override
333 {
334 uint ne = Base::numEdges();
335
336 mENormals.resize(ne * 3);
337
338 Base::fillEdgeNormals(mesh, mENormals.data());
339 }
340
341 void setEdgeColorsBuffer(const MeshType& mesh) // override
342 {
343 uint ne = Base::numEdges();
344
345 mEColors.resize(ne);
346
347 Base::fillEdgeColors(mesh, mEColors.data(), Color::Format::ABGR);
348 }
349
350 void setWireframeIndicesBuffer(const MeshType& mesh) // override
351 {
352 const uint nw = Base::numWireframeLines();
353
354 mWireframe.resize(nw * 2);
355
356 Base::fillWireframeIndices(mesh, mWireframe.data());
357 }
358
359 void setTextures(const MeshType& mesh) // override
360 {
361 mTextures.clear();
362
363 if constexpr (vcl::HasMaterials<MeshType>) {
364 mTextures.reserve(mesh.materialsNumber());
365 for (uint i = 0; i < mesh.materialsNumber(); ++i) {
366 const auto& texture =
367 mesh.material(i).baseColorTextureDescriptor();
368
369 vcl::Image txt = mesh.textureImage(texture.path());
370
371 if (txt.isNull()) {
372 if (!texture.path().empty()) {
373 try {
374 txt = vcl::loadImage(
375 mesh.meshBasePath() + texture.path());
376 }
377 catch (...) {
378 // do nothing
379 }
380 }
381 }
382
383 if (txt.isNull()) {
385 }
386 txt.mirror();
387 mTextures.push_back(txt);
388 }
389 }
390 }
391
392 void setMeshUniforms(const MeshType& m) // override
393 {
394 if constexpr (vcl::HasColor<MeshType>) {
395 mMeshColor[0] = m.color().redF();
396 mMeshColor[1] = m.color().greenF();
397 mMeshColor[2] = m.color().blueF();
398 mMeshColor[3] = m.color().alphaF();
399 }
400 }
401};
402
403} // namespace vcl
404
405#endif // VCL_OPENGL2_DRAWABLE_MESH_MESH_RENDER_VECTORS_H
The BitSet class allows to treat an integral type as an array of booleans of a guaranteed size.
Definition bit_set.h:52
A class representing a box in N-dimensional space.
Definition box.h:46
PointT size() const
Computes the size of the box.
Definition box.h:267
bool isNull() const
Checks whether the box is null or not.
Definition box.h:133
A class for representing and manipulating 2D images.
Definition image.h:48
The MeshRenderData class provides a common interface to automatically update the buffers used to rend...
Definition mesh_render_data.h:81
The MeshRenderInfo class is a collection of rendering settings for a Mesh.
Definition mesh_render_info.h:61
Definition mesh_render_vectors.h:40
The Mesh class represents a generic 3D mesh. A mesh is composed of a generic number of containers of ...
Definition mesh.h:68
The Point class represents an N-dimensional point containing N scalar values.
Definition point.h:55
Concept that is evaluated true if a Mesh has the Color component.
Definition mesh_requirements.h:62
Concept that is evaluated true if a Mesh has the Materials component.
Definition mesh_requirements.h:88
Image createCheckBoardImage(uint imageSize, uint checkNum=8)
Create a checkboard image.
Definition create.h:109
Point2< int > Point2i
A convenience alias for a 2-dimensional Point with integer components.
Definition point.h:707