Visual Computing Library  devel
Loading...
Searching...
No Matches
lines.h
1/*****************************************************************************
2 * VCLib *
3 * Visual Computing Library *
4 * *
5 * Copyright(C) 2021-2026 *
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_BGFX_PRIMITIVES_LINES_H
24#define VCL_BGFX_PRIMITIVES_LINES_H
25
26#include <vclib/bgfx/primitives/lines/cpu_generated_lines.h>
27#include <vclib/bgfx/primitives/lines/primitive_lines.h>
28#include <vclib/bgfx/uniform.h>
29
30#include <vclib/base.h>
31#include <vclib/space/core.h>
32
33#include <variant>
34
35#include <bgfx/bgfx.h>
36
37namespace vcl {
38
39// TODO: add shading per-line (flat, per-line normal) (?)
55class Lines
56{
57public:
58 enum class ColorToUse {
59 PER_VERTEX, // Select color form vertex color
60 PER_EDGE, // Select color from edge buffer color
61 GENERAL // Use general color in uniform data
62 };
63
64 enum class ImplementationType {
65 PRIMITIVE = 0, // Use bgfx primitive lines (not implemented)
66 CPU_GENERATED = 1, // Buffers pre-generated in CPU
67
68 // TODO: uncomment when they will be implemented
69 // GPU_GENERATED, // Buffers pre-generated in GPU with computes
70 // CPU_INSTANCING, // Using Instancing with buffers generated in CPU
71 // GPU_INSTANCING, // Using Instancing with buffer generated in GPU
72 // // computes
73 // TEXTURE_INSTANCING, // Using Instancing with textures generated in
74 // GPU computes
75
76 COUNT
77 };
78
79private:
80 float mThickness = 5.0f;
81
82 // TODO: shading should become a enum with options: PER_VERTEX, PER_EDGE,
83 // NONE
84 // PER_EDGE means that we use a buffer of normals for each edge
85 bool mShadingPerVertexCapability = false; // true if normals provided
86 bool mShadingPerVertex = false;
87
88 BitSet8 mColorCapability = {false, false, true}; // general color only
89 ColorToUse mColorToUse = ColorToUse::GENERAL;
90 Color mGeneralColor = Color::ColorABGR::LightGray;
91
92 ImplementationType mType = ImplementationType::COUNT;
93
94 std::variant<detail::PrimitiveLines, detail::CPUGeneratedLines>
95 mLinesImplementation;
96
97 static inline Uniform sSettingUH;
98
99public:
112 Lines(ImplementationType type = ImplementationType::COUNT)
113 {
114 if (type == ImplementationType::COUNT)
115 type = defaultImplementationType(false);
116 setImplementationType(type);
117 };
118
150 const std::vector<float>& vertCoords,
151 const std::vector<float>& vertNormals,
152 const std::vector<uint>& vertColors,
153 const std::vector<uint>& lineColors,
154 float thickness = 5.0f,
155 bool shadingPerVertex = false,
156 ColorToUse colorToUse = ColorToUse::GENERAL,
157 ImplementationType type = ImplementationType::COUNT) :
158 mThickness(thickness)
159 {
163 }
164
197 const std::vector<float>& vertCoords,
198 const std::vector<uint>& lineIndices,
199 const std::vector<float>& vertNormals,
200 const std::vector<uint>& vertColors,
201 const std::vector<uint>& lineColors,
202 float thickness = 5.0f,
203 bool shadingPerVertex = false,
204 ColorToUse colorToUse = ColorToUse::GENERAL,
205 ImplementationType type = ImplementationType::COUNT) :
206 mThickness(thickness)
207 {
208 setPoints(
212 }
213
238 const std::vector<float>& vertCoords,
239 const std::vector<float>& vertNormals,
240 const std::vector<uint>& vertColors,
241 const std::vector<uint>& lineColors,
242 ImplementationType type = ImplementationType::COUNT)
243 {
244 using enum ImplementationType;
245 using namespace detail;
246
247 if (type == COUNT)
248 type = defaultImplementationType(true);
249 setImplementationType(type);
250
251 switch (mType) {
252 case PRIMITIVE: // always supported
253 std::get<PrimitiveLines>(mLinesImplementation)
255 break;
256
257 case CPU_GENERATED: // always supported
258 std::get<CPUGeneratedLines>(mLinesImplementation)
260 break;
261 default: break;
262 }
263 updateShadingCapability(vertNormals);
264 updateColorCapability(vertColors, lineColors);
265 }
266
292 const std::vector<float>& vertCoords,
293 const std::vector<uint>& lineIndices,
294 const std::vector<float>& vertNormals,
295 const std::vector<uint>& vertColors,
296 const std::vector<uint>& lineColors,
297 ImplementationType type = ImplementationType::COUNT)
298 {
299 using enum ImplementationType;
300 using namespace detail;
301
302 if (type == COUNT)
303 type = defaultImplementationType(true);
304 setImplementationType(type);
305
306 switch (mType) {
307 case PRIMITIVE: // always supported
308 std::get<PrimitiveLines>(mLinesImplementation)
309 .setPoints(
314 lineColors);
315 break;
316
317 case CPU_GENERATED: // always supported
318 std::get<CPUGeneratedLines>(mLinesImplementation)
319 .setPoints(
324 lineColors);
325 break;
326 default: break;
327 }
328 updateShadingCapability(vertNormals);
329 updateColorCapability(vertColors, lineColors);
330 }
331
336 float thickness() const { return mThickness; }
337
343 float& thickness() { return mThickness; }
344
350 bool shadingPerVertex() const { return mShadingPerVertex; }
351
356 ColorToUse colorToUse() const { return mColorToUse; }
357
363 Color generalColor() const { return mGeneralColor; }
364
372 Color& generalColor() { return mGeneralColor; }
373
380 ImplementationType implementationType() const { return mType; }
381
393 {
394 if (!mShadingPerVertexCapability && perVertex) {
395 throw std::runtime_error(
396 "Lines::setShading(): shading per vertex not supported by the "
397 "current buffers.");
398 }
399 else {
400 mShadingPerVertex = perVertex;
401 }
402 }
403
412 void setColorToUse(ColorToUse color)
413 {
414 if (!mColorCapability[toUnderlying(color)]) {
415 throw std::runtime_error(
416 "Lines::setColorToUse(): color option not supported by the "
417 "current buffers.");
418 }
419 else {
420 mColorToUse = color;
421 }
422 }
423
428 void draw(uint viewId) const
429 {
430 using enum ImplementationType;
431 using namespace detail;
432
433 bindSettingsUniform();
434 if (mType == PRIMITIVE)
435 std::get<PrimitiveLines>(mLinesImplementation).draw(viewId);
436
437 if (mType == CPU_GENERATED)
438 std::get<CPUGeneratedLines>(mLinesImplementation).draw(viewId);
439 }
440
441private:
449 ImplementationType defaultImplementationType(
450 bool cpuMemPointsProvided) const
451 {
452 using enum ImplementationType;
453
455 return CPU_GENERATED;
456 else
457 return PRIMITIVE;
458 }
459
460 bool setImplementationType(ImplementationType type)
461 {
462 using enum ImplementationType;
463
464 if (mType == type)
465 return false; // no change
466
467 // TODO: check whether caps allow the new implementation type
468 // then set the implementation and the type
469 switch (type) {
470 case PRIMITIVE: // always supported
471 mLinesImplementation = detail::PrimitiveLines();
472 mType = type;
473 return true;
474
475 case CPU_GENERATED: // always supported
476 mLinesImplementation = detail::CPUGeneratedLines();
477 mType = type;
478 return true;
479
480 default: return false; // not supported
481 }
482 }
483
484 void updateShadingCapability(const std::vector<float>& vertNormals)
485 {
486 mShadingPerVertexCapability = !vertNormals.empty();
487 if (!mShadingPerVertexCapability)
488 mShadingPerVertex = false;
489 }
490
491 void updateColorCapability(
492 const std::vector<uint>& vertColors,
493 const std::vector<uint>& lineColors)
494 {
495 using enum ColorToUse;
496
497 mColorCapability[toUnderlying(PER_VERTEX)] = !vertColors.empty();
498 mColorCapability[toUnderlying(PER_EDGE)] = !lineColors.empty();
499
500 if (!mColorCapability[toUnderlying(mColorToUse)])
501 mColorToUse = GENERAL;
502 }
503
504 void bindSettingsUniform() const
505 {
506 // lazy initialization
507 // to avoid creating uniforms before bgfx is initialized
508 if (!sSettingUH.isValid())
509 sSettingUH = Uniform("u_settings", bgfx::UniformType::Vec4);
510
511 float data[] = {
512 mThickness,
513 static_cast<float>(mColorToUse),
514 std::bit_cast<float>(mGeneralColor.abgr()),
515 static_cast<float>(mShadingPerVertex)};
516 sSettingUH.bind(data);
517 }
518};
519
520} // namespace vcl
521
522#endif // VCL_BGFX_PRIMITIVES_LINES_H
The Color class represents a 32 bit color.
Definition color.h:48
The Lines class provides an abstraction for rendering 3D lines with variable thickness and different ...
Definition lines.h:56
ImplementationType implementationType() const
Returns the current implementation type that is used to render the lines.
Definition lines.h:380
void setPoints(const std::vector< float > &vertCoords, const std::vector< uint > &lineIndices, const std::vector< float > &vertNormals, const std::vector< uint > &vertColors, const std::vector< uint > &lineColors, ImplementationType type=ImplementationType::COUNT)
Sets the points of the lines.
Definition lines.h:291
ColorToUse colorToUse() const
Returns the color that is used to render the lines.
Definition lines.h:356
void draw(uint viewId) const
Draws in the given view the lines with the current settings.
Definition lines.h:428
ImplementationType defaultImplementationType(bool cpuMemPointsProvided) const
Returns the default supported implementation type that can be used, depending on the capabilities of ...
Definition lines.h:449
Lines(const std::vector< float > &vertCoords, const std::vector< float > &vertNormals, const std::vector< uint > &vertColors, const std::vector< uint > &lineColors, float thickness=5.0f, bool shadingPerVertex=false, ColorToUse colorToUse=ColorToUse::GENERAL, ImplementationType type=ImplementationType::COUNT)
Creates a Lines object with given points and parameters.
Definition lines.h:149
Color & generalColor()
Returns a reference to the general color that is used to render the lines when colorToUse() is set to...
Definition lines.h:372
void setColorToUse(ColorToUse color)
Sets which color to use for rendering the lines.
Definition lines.h:412
Lines(const std::vector< float > &vertCoords, const std::vector< uint > &lineIndices, const std::vector< float > &vertNormals, const std::vector< uint > &vertColors, const std::vector< uint > &lineColors, float thickness=5.0f, bool shadingPerVertex=false, ColorToUse colorToUse=ColorToUse::GENERAL, ImplementationType type=ImplementationType::COUNT)
Creates a Lines object with given points and parameters.
Definition lines.h:196
Lines(ImplementationType type=ImplementationType::COUNT)
Creates a Lines object with default parameters and without points.
Definition lines.h:112
float thickness() const
Returns the thickness of the lines (in pixels).
Definition lines.h:336
float & thickness()
Returns a reference to the thickness of the lines (in pixels). This allows to modify the thickness di...
Definition lines.h:343
bool shadingPerVertex() const
Returns true if shading is computed per vertex using vertex normals, false if no shading is applied.
Definition lines.h:350
Color generalColor() const
Returns the general color that is used to render the lines when colorToUse() is set to ColorToUse::GE...
Definition lines.h:363
void setPoints(const std::vector< float > &vertCoords, const std::vector< float > &vertNormals, const std::vector< uint > &vertColors, const std::vector< uint > &lineColors, ImplementationType type=ImplementationType::COUNT)
Sets the points of the lines.
Definition lines.h:237
void setShading(bool perVertex)
Sets wether to use per vertex shading (using vertex normals) or not.
Definition lines.h:392
A class representing a line segment in n-dimensional space. The class is parameterized by a PointConc...
Definition segment.h:41
The Uniform class wraps a bgfx::UniformHandle and provides a simple interface to set the uniform data...
Definition uniform.h:43
void bind(const void *data) const
Sets the uniform data for the current shader program.
Definition uniform.h:165
bool isValid() const
Checks if the Uniform is valid (i.e., if it has a valid bgfx::UniformHandle).
Definition uniform.h:129