From 026f92845db425e79ac7e510c8dfa1f75b3e40d9 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Thu, 23 Jan 2025 17:38:50 +0100 Subject: [PATCH 01/29] [render] VertexBuffer class --- vclib/render/include/vclib/bgfx/buffers.h | 28 ++++ .../vclib/bgfx/buffers/vertex_buffer.h | 123 ++++++++++++++++++ .../bgfx/drawable/mesh/mesh_render_buffers.h | 27 ++-- 3 files changed, 161 insertions(+), 17 deletions(-) create mode 100644 vclib/render/include/vclib/bgfx/buffers.h create mode 100644 vclib/render/include/vclib/bgfx/buffers/vertex_buffer.h diff --git a/vclib/render/include/vclib/bgfx/buffers.h b/vclib/render/include/vclib/bgfx/buffers.h new file mode 100644 index 000000000..5e4d59336 --- /dev/null +++ b/vclib/render/include/vclib/bgfx/buffers.h @@ -0,0 +1,28 @@ +/***************************************************************************** + * VCLib * + * Visual Computing Library * + * * + * Copyright(C) 2021-2025 * + * Visual Computing Lab * + * ISTI - Italian National Research Council * + * * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the Mozilla Public License Version 2.0 as published * + * by the Mozilla Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * Mozilla Public License Version 2.0 * + * (https://www.mozilla.org/en-US/MPL/2.0/) for more details. * + ****************************************************************************/ + +#ifndef VCL_BGFX_BUFFERS_H +#define VCL_BGFX_BUFFERS_H + +#include "buffers/vertex_buffer.h" + +#endif // VCL_BGFX_BUFFERS_H diff --git a/vclib/render/include/vclib/bgfx/buffers/vertex_buffer.h b/vclib/render/include/vclib/bgfx/buffers/vertex_buffer.h new file mode 100644 index 000000000..f20f434e3 --- /dev/null +++ b/vclib/render/include/vclib/bgfx/buffers/vertex_buffer.h @@ -0,0 +1,123 @@ +/***************************************************************************** + * VCLib * + * Visual Computing Library * + * * + * Copyright(C) 2021-2025 * + * Visual Computing Lab * + * ISTI - Italian National Research Council * + * * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the Mozilla Public License Version 2.0 as published * + * by the Mozilla Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * Mozilla Public License Version 2.0 * + * (https://www.mozilla.org/en-US/MPL/2.0/) for more details. * + ****************************************************************************/ + +#ifndef VCL_BGFX_BUFFERS_VERTEX_BUFFER_H +#define VCL_BGFX_BUFFERS_VERTEX_BUFFER_H + +#include + +#include + +#include + +namespace vcl { + +class VertexBuffer +{ + bgfx::VertexBufferHandle mVertexBufferHandle = BGFX_INVALID_HANDLE; + +public: + VertexBuffer() = default; + + VertexBuffer(const VertexBuffer& other) = delete; + + VertexBuffer(VertexBuffer&& other) noexcept + { + mVertexBufferHandle = other.mVertexBufferHandle; + other.mVertexBufferHandle = BGFX_INVALID_HANDLE; + } + + ~VertexBuffer() + { + if (bgfx::isValid(mVertexBufferHandle)) + bgfx::destroy(mVertexBufferHandle); + } + + VertexBuffer& operator=(const VertexBuffer& other) = delete; + + VertexBuffer& operator=(VertexBuffer&& other) noexcept + { + mVertexBufferHandle = other.mVertexBufferHandle; + other.mVertexBufferHandle = BGFX_INVALID_HANDLE; + return *this; + } + + void swap(VertexBuffer& other) + { + using std::swap; + swap(mVertexBufferHandle, other.mVertexBufferHandle); + } + + friend void swap(VertexBuffer& a, VertexBuffer& b) { a.swap(b); } + + void set( + const void* bufferData, + const uint bufferSize, + bgfx::Attrib::Enum attrib, + uint numElements, + bgfx::AttribType::Enum attribType, + bgfx::ReleaseFn releaseFn = nullptr, + uint64_t flags = BGFX_BUFFER_NONE) + { + bgfx::VertexLayout layout; + layout.begin().add(attrib, numElements, attribType).end(); + + set(layout, + bgfx::makeRef( + bufferData, bufferSize * attribTypeSize(attribType), releaseFn), + flags); + } + + void set( + const bgfx::VertexLayout& layout, + const bgfx::Memory* vertices, + uint64_t flags = BGFX_BUFFER_NONE) + { + if (bgfx::isValid(mVertexBufferHandle)) + bgfx::destroy(mVertexBufferHandle); + + mVertexBufferHandle = bgfx::createVertexBuffer(vertices, layout, flags); + } + + void bind(uint stream) const + { + if (bgfx::isValid(mVertexBufferHandle)) + bgfx::setVertexBuffer(stream, mVertexBufferHandle); + } + + static int attribTypeSize(bgfx::AttribType::Enum type) + { + switch(type) + { + case bgfx::AttribType::Uint8: return 1; + case bgfx::AttribType::Uint10: return 2; + case bgfx::AttribType::Int16: return 2; + case bgfx::AttribType::Half: return 2; + case bgfx::AttribType::Float: return 4; + default: return 0; + } + } +}; + +} // namespace vcl + +#endif // VCL_BGFX_BUFFERS_VERTEX_BUFFER_H diff --git a/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h b/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h index 164f25453..37d68340f 100644 --- a/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h +++ b/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h @@ -25,6 +25,7 @@ #include "mesh_render_buffers_macros.h" +#include #include #include @@ -36,7 +37,7 @@ class MeshRenderBuffers : public vcl::MeshRenderData { using Base = vcl::MeshRenderData; - bgfx::VertexBufferHandle mVertexCoordBH = BGFX_INVALID_HANDLE; + VertexBuffer mVertexBuffer; bgfx::VertexBufferHandle mVertexNormalBH = BGFX_INVALID_HANDLE; bgfx::VertexBufferHandle mVertexColorBH = BGFX_INVALID_HANDLE; bgfx::VertexBufferHandle mVertexUVBH = BGFX_INVALID_HANDLE; @@ -85,7 +86,7 @@ class MeshRenderBuffers : public vcl::MeshRenderData { using std::swap; swap((Base&) *this, (Base&) other); - swap(mVertexCoordBH, other.mVertexCoordBH); + swap(mVertexBuffer, other.mVertexBuffer); swap(mVertexNormalBH, other.mVertexNormalBH); swap(mVertexColorBH, other.mVertexColorBH); swap(mVertexUVBH, other.mVertexUVBH); @@ -114,7 +115,7 @@ class MeshRenderBuffers : public vcl::MeshRenderData { // bgfx allows a maximum number of 4 vertex streams... - bgfx::setVertexBuffer(0, mVertexCoordBH); + mVertexBuffer.bind(0); if (bgfx::isValid(mVertexNormalBH)) { // vertex normals bgfx::setVertexBuffer(1, mVertexNormalBH); @@ -196,17 +197,12 @@ class MeshRenderBuffers : public vcl::MeshRenderData private: void createBGFXBuffers() { - // vertex buffer (positions) - bgfx::VertexLayout layout; - layout.begin() - .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float) - .end(); - - mVertexCoordBH = bgfx::createVertexBuffer( - bgfx::makeRef( - Base::vertexBufferData(), - Base::vertexBufferSize() * sizeof(float)), - layout); + mVertexBuffer.set( + Base::vertexBufferData(), + Base::vertexBufferSize(), + bgfx::Attrib::Position, + 3, + bgfx::AttribType::Float); // vertex buffer (normals) if (Base::vertexNormalBufferData()) { @@ -370,9 +366,6 @@ class MeshRenderBuffers : public vcl::MeshRenderData void destroyBGFXBuffers() { - if (bgfx::isValid(mVertexCoordBH)) - bgfx::destroy(mVertexCoordBH); - if (bgfx::isValid(mVertexNormalBH)) bgfx::destroy(mVertexNormalBH); From a068569b77109972001a63a5cbd6e437de2433b9 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Thu, 23 Jan 2025 18:11:43 +0100 Subject: [PATCH 02/29] [render] vertex normals and colors using VertexBuffer class --- .../vclib/bgfx/buffers/vertex_buffer.h | 3 +- .../bgfx/drawable/mesh/mesh_render_buffers.h | 73 ++++++------------- 2 files changed, 26 insertions(+), 50 deletions(-) diff --git a/vclib/render/include/vclib/bgfx/buffers/vertex_buffer.h b/vclib/render/include/vclib/bgfx/buffers/vertex_buffer.h index f20f434e3..4f6e0dc4b 100644 --- a/vclib/render/include/vclib/bgfx/buffers/vertex_buffer.h +++ b/vclib/render/include/vclib/bgfx/buffers/vertex_buffer.h @@ -75,11 +75,12 @@ class VertexBuffer bgfx::Attrib::Enum attrib, uint numElements, bgfx::AttribType::Enum attribType, + bool normalize = false, bgfx::ReleaseFn releaseFn = nullptr, uint64_t flags = BGFX_BUFFER_NONE) { bgfx::VertexLayout layout; - layout.begin().add(attrib, numElements, attribType).end(); + layout.begin().add(attrib, numElements, attribType, normalize).end(); set(layout, bgfx::makeRef( diff --git a/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h b/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h index 37d68340f..e87db4ea9 100644 --- a/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h +++ b/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h @@ -37,9 +37,9 @@ class MeshRenderBuffers : public vcl::MeshRenderData { using Base = vcl::MeshRenderData; - VertexBuffer mVertexBuffer; - bgfx::VertexBufferHandle mVertexNormalBH = BGFX_INVALID_HANDLE; - bgfx::VertexBufferHandle mVertexColorBH = BGFX_INVALID_HANDLE; + VertexBuffer mVertexCoordsBuffer; + VertexBuffer mVertexNormalsBuffer; + VertexBuffer mVertexColorsBuffer; bgfx::VertexBufferHandle mVertexUVBH = BGFX_INVALID_HANDLE; bgfx::VertexBufferHandle mVertexWedgeUVBH = BGFX_INVALID_HANDLE; @@ -86,9 +86,9 @@ class MeshRenderBuffers : public vcl::MeshRenderData { using std::swap; swap((Base&) *this, (Base&) other); - swap(mVertexBuffer, other.mVertexBuffer); - swap(mVertexNormalBH, other.mVertexNormalBH); - swap(mVertexColorBH, other.mVertexColorBH); + swap(mVertexCoordsBuffer, other.mVertexCoordsBuffer); + swap(mVertexNormalsBuffer, other.mVertexNormalsBuffer); + swap(mVertexColorsBuffer, other.mVertexColorsBuffer); swap(mVertexUVBH, other.mVertexUVBH); swap(mVertexWedgeUVBH, other.mVertexWedgeUVBH); swap(mTriangleIndexBH, other.mTriangleIndexBH); @@ -115,15 +115,9 @@ class MeshRenderBuffers : public vcl::MeshRenderData { // bgfx allows a maximum number of 4 vertex streams... - mVertexBuffer.bind(0); - - if (bgfx::isValid(mVertexNormalBH)) { // vertex normals - bgfx::setVertexBuffer(1, mVertexNormalBH); - } - - if (bgfx::isValid(mVertexColorBH)) { // vertex colors - bgfx::setVertexBuffer(2, mVertexColorBH); - } + mVertexCoordsBuffer.bind(0); + mVertexNormalsBuffer.bind(1); + mVertexColorsBuffer.bind(2); if (mrs.isSurfaceColorPerVertexTexcoords()) { if (bgfx::isValid(mVertexUVBH)) { // vertex UVs @@ -197,40 +191,27 @@ class MeshRenderBuffers : public vcl::MeshRenderData private: void createBGFXBuffers() { - mVertexBuffer.set( + mVertexCoordsBuffer.set( Base::vertexBufferData(), - Base::vertexBufferSize(), + Base::vertexNumber() * 3, bgfx::Attrib::Position, 3, bgfx::AttribType::Float); - // vertex buffer (normals) - if (Base::vertexNormalBufferData()) { - bgfx::VertexLayout vnlayout; - vnlayout.begin() - .add(bgfx::Attrib::Normal, 3, bgfx::AttribType::Float) - .end(); - - mVertexNormalBH = bgfx::createVertexBuffer( - bgfx::makeRef( - Base::vertexNormalBufferData(), - Base::vertexBufferSize() * sizeof(float)), - vnlayout); - } - - // vertex buffer (colors) - if (Base::vertexColorBufferData()) { - bgfx::VertexLayout vclayout; - vclayout.begin() - .add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true) - .end(); + mVertexNormalsBuffer.set( + Base::vertexNormalBufferData(), + Base::vertexNumber() * 3, + bgfx::Attrib::Normal, + 3, + bgfx::AttribType::Float); - mVertexColorBH = bgfx::createVertexBuffer( - bgfx::makeRef( - Base::vertexColorBufferData(), - Base::vertexNumber() * sizeof(uint32_t)), - vclayout); - } + mVertexColorsBuffer.set( + Base::vertexColorBufferData(), + Base::vertexNumber() * 4, + bgfx::Attrib::Color0, + 4, + bgfx::AttribType::Uint8, + true); // vertex buffer (UVs) if (Base::vertexTexCoordsBufferData()) { @@ -366,12 +347,6 @@ class MeshRenderBuffers : public vcl::MeshRenderData void destroyBGFXBuffers() { - if (bgfx::isValid(mVertexNormalBH)) - bgfx::destroy(mVertexNormalBH); - - if (bgfx::isValid(mVertexColorBH)) - bgfx::destroy(mVertexColorBH); - if (bgfx::isValid(mVertexUVBH)) bgfx::destroy(mVertexUVBH); From 095f331608aaece67271f7c5d777916a88e060a8 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Fri, 24 Jan 2025 09:46:33 +0100 Subject: [PATCH 03/29] [render] vertex uvs using VertexBuffer class --- .../bgfx/drawable/mesh/mesh_render_buffers.h | 30 ++++++------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h b/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h index e87db4ea9..3d59e025b 100644 --- a/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h +++ b/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h @@ -40,7 +40,7 @@ class MeshRenderBuffers : public vcl::MeshRenderData VertexBuffer mVertexCoordsBuffer; VertexBuffer mVertexNormalsBuffer; VertexBuffer mVertexColorsBuffer; - bgfx::VertexBufferHandle mVertexUVBH = BGFX_INVALID_HANDLE; + VertexBuffer mVertexUVBuffer; bgfx::VertexBufferHandle mVertexWedgeUVBH = BGFX_INVALID_HANDLE; bgfx::IndexBufferHandle mTriangleIndexBH = BGFX_INVALID_HANDLE; @@ -89,7 +89,7 @@ class MeshRenderBuffers : public vcl::MeshRenderData swap(mVertexCoordsBuffer, other.mVertexCoordsBuffer); swap(mVertexNormalsBuffer, other.mVertexNormalsBuffer); swap(mVertexColorsBuffer, other.mVertexColorsBuffer); - swap(mVertexUVBH, other.mVertexUVBH); + swap(mVertexUVBuffer, other.mVertexUVBuffer); swap(mVertexWedgeUVBH, other.mVertexWedgeUVBH); swap(mTriangleIndexBH, other.mTriangleIndexBH); swap(mTriangleNormalBH, other.mTriangleNormalBH); @@ -120,9 +120,7 @@ class MeshRenderBuffers : public vcl::MeshRenderData mVertexColorsBuffer.bind(2); if (mrs.isSurfaceColorPerVertexTexcoords()) { - if (bgfx::isValid(mVertexUVBH)) { // vertex UVs - bgfx::setVertexBuffer(3, mVertexUVBH); - } + mVertexUVBuffer.bind(3); } else if (mrs.isSurfaceColorPerWedgeTexcoords()) { if (bgfx::isValid(mVertexWedgeUVBH)) { // vertex wedge UVs @@ -213,19 +211,12 @@ class MeshRenderBuffers : public vcl::MeshRenderData bgfx::AttribType::Uint8, true); - // vertex buffer (UVs) - if (Base::vertexTexCoordsBufferData()) { - bgfx::VertexLayout uvlayout; - uvlayout.begin() - .add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float) - .end(); - - mVertexUVBH = bgfx::createVertexBuffer( - bgfx::makeRef( - Base::vertexTexCoordsBufferData(), - Base::vertexNumber() * 2 * sizeof(float)), - uvlayout); - } + mVertexUVBuffer.set( + Base::vertexTexCoordsBufferData(), + Base::vertexNumber() * 2, + bgfx::Attrib::TexCoord0, + 2, + bgfx::AttribType::Float); // vertex wedges buffer (duplicated vertices) if (Base::wedgeTexCoordsBufferData()) { @@ -347,9 +338,6 @@ class MeshRenderBuffers : public vcl::MeshRenderData void destroyBGFXBuffers() { - if (bgfx::isValid(mVertexUVBH)) - bgfx::destroy(mVertexUVBH); - if (bgfx::isValid(mVertexWedgeUVBH)) bgfx::destroy(mVertexWedgeUVBH); From b7e61d24665b398df2435e41bad2aca09e5fb0f6 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Fri, 24 Jan 2025 09:57:12 +0100 Subject: [PATCH 04/29] [render] wedge uvs using VertexBuffer class --- .../bgfx/drawable/mesh/mesh_render_buffers.h | 29 ++++++------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h b/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h index 3d59e025b..c833e4807 100644 --- a/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h +++ b/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h @@ -41,7 +41,7 @@ class MeshRenderBuffers : public vcl::MeshRenderData VertexBuffer mVertexNormalsBuffer; VertexBuffer mVertexColorsBuffer; VertexBuffer mVertexUVBuffer; - bgfx::VertexBufferHandle mVertexWedgeUVBH = BGFX_INVALID_HANDLE; + VertexBuffer mVertexWedgeUVBuffer; bgfx::IndexBufferHandle mTriangleIndexBH = BGFX_INVALID_HANDLE; bgfx::IndexBufferHandle mTriangleNormalBH = BGFX_INVALID_HANDLE; @@ -90,7 +90,7 @@ class MeshRenderBuffers : public vcl::MeshRenderData swap(mVertexNormalsBuffer, other.mVertexNormalsBuffer); swap(mVertexColorsBuffer, other.mVertexColorsBuffer); swap(mVertexUVBuffer, other.mVertexUVBuffer); - swap(mVertexWedgeUVBH, other.mVertexWedgeUVBH); + swap(mVertexWedgeUVBuffer, other.mVertexWedgeUVBuffer); swap(mTriangleIndexBH, other.mTriangleIndexBH); swap(mTriangleNormalBH, other.mTriangleNormalBH); swap(mTriangleColorBH, other.mTriangleColorBH); @@ -123,9 +123,7 @@ class MeshRenderBuffers : public vcl::MeshRenderData mVertexUVBuffer.bind(3); } else if (mrs.isSurfaceColorPerWedgeTexcoords()) { - if (bgfx::isValid(mVertexWedgeUVBH)) { // vertex wedge UVs - bgfx::setVertexBuffer(3, mVertexWedgeUVBH); - } + mVertexWedgeUVBuffer.bind(3); } } @@ -219,18 +217,12 @@ class MeshRenderBuffers : public vcl::MeshRenderData bgfx::AttribType::Float); // vertex wedges buffer (duplicated vertices) - if (Base::wedgeTexCoordsBufferData()) { - bgfx::VertexLayout uvlayout; - uvlayout.begin() - .add(bgfx::Attrib::TexCoord1, 2, bgfx::AttribType::Float) - .end(); - - mVertexWedgeUVBH = bgfx::createVertexBuffer( - bgfx::makeRef( - Base::wedgeTexCoordsBufferData(), - Base::vertexNumber() * 2 * sizeof(float)), - uvlayout); - } + mVertexWedgeUVBuffer.set( + Base::wedgeTexCoordsBufferData(), + Base::vertexNumber() * 2, + bgfx::Attrib::TexCoord1, + 2, + bgfx::AttribType::Float); // triangle index buffer if (Base::triangleBufferData()) { @@ -338,9 +330,6 @@ class MeshRenderBuffers : public vcl::MeshRenderData void destroyBGFXBuffers() { - if (bgfx::isValid(mVertexWedgeUVBH)) - bgfx::destroy(mVertexWedgeUVBH); - if (bgfx::isValid(mTriangleIndexBH)) bgfx::destroy(mTriangleIndexBH); From 4d2b077a95769c771b4f66bba1437a42c9b17ecb Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Fri, 24 Jan 2025 12:40:36 +0100 Subject: [PATCH 05/29] [render] IndexBuffer class, used for triangle indices --- vclib/render/include/vclib/bgfx/buffers.h | 1 + .../include/vclib/bgfx/buffers/index_buffer.h | 116 ++++++++++++++++++ .../bgfx/drawable/mesh/mesh_render_buffers.h | 18 ++- 3 files changed, 124 insertions(+), 11 deletions(-) create mode 100644 vclib/render/include/vclib/bgfx/buffers/index_buffer.h diff --git a/vclib/render/include/vclib/bgfx/buffers.h b/vclib/render/include/vclib/bgfx/buffers.h index 5e4d59336..e950f2d9e 100644 --- a/vclib/render/include/vclib/bgfx/buffers.h +++ b/vclib/render/include/vclib/bgfx/buffers.h @@ -23,6 +23,7 @@ #ifndef VCL_BGFX_BUFFERS_H #define VCL_BGFX_BUFFERS_H +#include "buffers/index_buffer.h" #include "buffers/vertex_buffer.h" #endif // VCL_BGFX_BUFFERS_H diff --git a/vclib/render/include/vclib/bgfx/buffers/index_buffer.h b/vclib/render/include/vclib/bgfx/buffers/index_buffer.h new file mode 100644 index 000000000..a5c8c3257 --- /dev/null +++ b/vclib/render/include/vclib/bgfx/buffers/index_buffer.h @@ -0,0 +1,116 @@ +/***************************************************************************** + * VCLib * + * Visual Computing Library * + * * + * Copyright(C) 2021-2025 * + * Visual Computing Lab * + * ISTI - Italian National Research Council * + * * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the Mozilla Public License Version 2.0 as published * + * by the Mozilla Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * Mozilla Public License Version 2.0 * + * (https://www.mozilla.org/en-US/MPL/2.0/) for more details. * + ****************************************************************************/ + +#ifndef VCL_BGFX_BUFFERS_INDEX_BUFFER_H +#define VCL_BGFX_BUFFERS_INDEX_BUFFER_H + +#include + +#include + +#include + +namespace vcl { + +class IndexBuffer +{ + bgfx::IndexBufferHandle mIndexBufferHandle = BGFX_INVALID_HANDLE; + +public: + IndexBuffer() = default; + + IndexBuffer(const IndexBuffer& other) = delete; + + IndexBuffer(IndexBuffer&& other) noexcept + { + mIndexBufferHandle = other.mIndexBufferHandle; + other.mIndexBufferHandle = BGFX_INVALID_HANDLE; + } + + ~IndexBuffer() + { + if (bgfx::isValid(mIndexBufferHandle)) + bgfx::destroy(mIndexBufferHandle); + } + + IndexBuffer& operator=(const IndexBuffer& other) = delete; + + IndexBuffer& operator=(IndexBuffer&& other) noexcept + { + mIndexBufferHandle = other.mIndexBufferHandle; + other.mIndexBufferHandle = BGFX_INVALID_HANDLE; + return *this; + } + + void swap(IndexBuffer& other) + { + using std::swap; + swap(mIndexBufferHandle, other.mIndexBufferHandle); + } + + friend void swap(IndexBuffer& a, IndexBuffer& b) { a.swap(b); } + + void set( + const void* bufferIndices, + const uint bufferSize, + PrimitiveType type, + uint64_t flags = BGFX_BUFFER_NONE) + { + flags |= flagsForType(type); + set(bgfx::makeRef(bufferIndices, bufferSize * sizeOf(type)), flags); + } + + void set(const bgfx::Memory* indices, uint64_t flags = BGFX_BUFFER_NONE) + { + mIndexBufferHandle = bgfx::createIndexBuffer(indices, flags); + } + + void bind() const + { + bgfx::setIndexBuffer(mIndexBufferHandle); + } + + void bindForCompute( + uint8_t stage, + bgfx::Access::Enum access = bgfx::Access::Read) + { + bgfx::setBuffer(stage, mIndexBufferHandle, access); + } + +private: + static uint64_t flagsForType(PrimitiveType type) + { + switch (type) { + case PrimitiveType::INT: + case PrimitiveType::UINT: return BGFX_BUFFER_INDEX32; + case PrimitiveType::FLOAT: + return BGFX_BUFFER_COMPUTE_FORMAT_32X1 | + BGFX_BUFFER_COMPUTE_TYPE_FLOAT; + case PrimitiveType::DOUBLE: assert(0); // not supported + default: return BGFX_BUFFER_NONE; + } + } +}; + +} // namespace vcl + +#endif // VCL_BGFX_BUFFERS_INDEX_BUFFER_H diff --git a/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h b/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h index c833e4807..bf02687e4 100644 --- a/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h +++ b/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h @@ -43,7 +43,7 @@ class MeshRenderBuffers : public vcl::MeshRenderData VertexBuffer mVertexUVBuffer; VertexBuffer mVertexWedgeUVBuffer; - bgfx::IndexBufferHandle mTriangleIndexBH = BGFX_INVALID_HANDLE; + IndexBuffer mTriangleIndexBuffer; bgfx::IndexBufferHandle mTriangleNormalBH = BGFX_INVALID_HANDLE; bgfx::IndexBufferHandle mTriangleColorBH = BGFX_INVALID_HANDLE; @@ -91,7 +91,7 @@ class MeshRenderBuffers : public vcl::MeshRenderData swap(mVertexColorsBuffer, other.mVertexColorsBuffer); swap(mVertexUVBuffer, other.mVertexUVBuffer); swap(mVertexWedgeUVBuffer, other.mVertexWedgeUVBuffer); - swap(mTriangleIndexBH, other.mTriangleIndexBH); + swap(mTriangleIndexBuffer, other.mTriangleIndexBuffer); swap(mTriangleNormalBH, other.mTriangleNormalBH); swap(mTriangleColorBH, other.mTriangleColorBH); swap(mTriangleTextureIndexBH, other.mTriangleTextureIndexBH); @@ -130,7 +130,7 @@ class MeshRenderBuffers : public vcl::MeshRenderData void bindIndexBuffers(uint indexBufferToBind = Base::TRIANGLES) const { if (indexBufferToBind == Base::TRIANGLES) { - bgfx::setIndexBuffer(mTriangleIndexBH); + mTriangleIndexBuffer.bind(); if (bgfx::isValid(mTriangleColorBH)) { // triangle colors bgfx::setBuffer( @@ -226,11 +226,10 @@ class MeshRenderBuffers : public vcl::MeshRenderData // triangle index buffer if (Base::triangleBufferData()) { - mTriangleIndexBH = bgfx::createIndexBuffer( - bgfx::makeRef( - Base::triangleBufferData(), - Base::triangleBufferSize() * sizeof(uint32_t)), - BGFX_BUFFER_INDEX32); + mTriangleIndexBuffer.set( + Base::triangleBufferData(), + Base::triangleBufferSize(), + PrimitiveType::UINT); } // triangle normal buffer @@ -330,9 +329,6 @@ class MeshRenderBuffers : public vcl::MeshRenderData void destroyBGFXBuffers() { - if (bgfx::isValid(mTriangleIndexBH)) - bgfx::destroy(mTriangleIndexBH); - if (bgfx::isValid(mTriangleNormalBH)) bgfx::destroy(mTriangleNormalBH); From aa6613ef3e7259acbb4f6187a0ad07dca3e077b3 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Fri, 24 Jan 2025 14:11:50 +0100 Subject: [PATCH 06/29] [render] triangle normals using IndexBuffer class --- .../include/vclib/bgfx/buffers/index_buffer.h | 2 +- .../bgfx/drawable/mesh/mesh_render_buffers.h | 27 ++++++------------- 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/vclib/render/include/vclib/bgfx/buffers/index_buffer.h b/vclib/render/include/vclib/bgfx/buffers/index_buffer.h index a5c8c3257..5c1c0a30c 100644 --- a/vclib/render/include/vclib/bgfx/buffers/index_buffer.h +++ b/vclib/render/include/vclib/bgfx/buffers/index_buffer.h @@ -91,7 +91,7 @@ class IndexBuffer void bindForCompute( uint8_t stage, - bgfx::Access::Enum access = bgfx::Access::Read) + bgfx::Access::Enum access = bgfx::Access::Read) const { bgfx::setBuffer(stage, mIndexBufferHandle, access); } diff --git a/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h b/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h index bf02687e4..0ea392eed 100644 --- a/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h +++ b/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h @@ -44,7 +44,7 @@ class MeshRenderBuffers : public vcl::MeshRenderData VertexBuffer mVertexWedgeUVBuffer; IndexBuffer mTriangleIndexBuffer; - bgfx::IndexBufferHandle mTriangleNormalBH = BGFX_INVALID_HANDLE; + IndexBuffer mTriangleNormalBuffer; bgfx::IndexBufferHandle mTriangleColorBH = BGFX_INVALID_HANDLE; bgfx::IndexBufferHandle mTriangleTextureIndexBH = BGFX_INVALID_HANDLE; @@ -92,7 +92,7 @@ class MeshRenderBuffers : public vcl::MeshRenderData swap(mVertexUVBuffer, other.mVertexUVBuffer); swap(mVertexWedgeUVBuffer, other.mVertexWedgeUVBuffer); swap(mTriangleIndexBuffer, other.mTriangleIndexBuffer); - swap(mTriangleNormalBH, other.mTriangleNormalBH); + swap(mTriangleNormalBuffer, other.mTriangleNormalBuffer); swap(mTriangleColorBH, other.mTriangleColorBH); swap(mTriangleTextureIndexBH, other.mTriangleTextureIndexBH); swap(mEdgeIndexBH, other.mEdgeIndexBH); @@ -139,12 +139,8 @@ class MeshRenderBuffers : public vcl::MeshRenderData bgfx::Access::Read); } - if (bgfx::isValid(mTriangleNormalBH)) { // triangle normals - bgfx::setBuffer( - VCL_MRB_PRIMITIVE_NORMAL_BUFFER, - mTriangleNormalBH, - bgfx::Access::Read); - } + mTriangleNormalBuffer.bindForCompute( + VCL_MRB_PRIMITIVE_NORMAL_BUFFER); if (bgfx::isValid(mTriangleTextureIndexBH)) { // tri texture indices bgfx::setBuffer( @@ -233,14 +229,10 @@ class MeshRenderBuffers : public vcl::MeshRenderData } // triangle normal buffer - if (Base::triangleNormalBufferData()) { - mTriangleNormalBH = bgfx::createIndexBuffer( - bgfx::makeRef( - Base::triangleNormalBufferData(), - Base::triangleNumber() * 3 * sizeof(float)), - BGFX_BUFFER_COMPUTE_FORMAT_32X1 | BGFX_BUFFER_COMPUTE_READ | - BGFX_BUFFER_COMPUTE_TYPE_FLOAT); - } + mTriangleNormalBuffer.set( + Base::triangleNormalBufferData(), + Base::triangleNumber() * 3, + PrimitiveType::FLOAT, BGFX_BUFFER_COMPUTE_READ); // triangle color buffer if (Base::triangleColorBufferData()) { @@ -329,9 +321,6 @@ class MeshRenderBuffers : public vcl::MeshRenderData void destroyBGFXBuffers() { - if (bgfx::isValid(mTriangleNormalBH)) - bgfx::destroy(mTriangleNormalBH); - if (bgfx::isValid(mTriangleColorBH)) bgfx::destroy(mTriangleColorBH); From 604c31bc441c8763d9432048bb0cd74c8e0867fa Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Fri, 24 Jan 2025 14:46:53 +0100 Subject: [PATCH 07/29] [render] triangle colors using IndexBuffer class --- .../bgfx/drawable/mesh/mesh_render_buffers.h | 28 ++++++------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h b/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h index 0ea392eed..b936ea258 100644 --- a/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h +++ b/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h @@ -45,7 +45,7 @@ class MeshRenderBuffers : public vcl::MeshRenderData IndexBuffer mTriangleIndexBuffer; IndexBuffer mTriangleNormalBuffer; - bgfx::IndexBufferHandle mTriangleColorBH = BGFX_INVALID_HANDLE; + IndexBuffer mTriangleColorBuffer; bgfx::IndexBufferHandle mTriangleTextureIndexBH = BGFX_INVALID_HANDLE; @@ -93,7 +93,7 @@ class MeshRenderBuffers : public vcl::MeshRenderData swap(mVertexWedgeUVBuffer, other.mVertexWedgeUVBuffer); swap(mTriangleIndexBuffer, other.mTriangleIndexBuffer); swap(mTriangleNormalBuffer, other.mTriangleNormalBuffer); - swap(mTriangleColorBH, other.mTriangleColorBH); + swap(mTriangleColorBuffer, other.mTriangleColorBuffer); swap(mTriangleTextureIndexBH, other.mTriangleTextureIndexBH); swap(mEdgeIndexBH, other.mEdgeIndexBH); swap(mEdgeNormalBH, other.mEdgeNormalBH); @@ -132,16 +132,12 @@ class MeshRenderBuffers : public vcl::MeshRenderData if (indexBufferToBind == Base::TRIANGLES) { mTriangleIndexBuffer.bind(); - if (bgfx::isValid(mTriangleColorBH)) { // triangle colors - bgfx::setBuffer( - VCL_MRB_PRIMITIVE_COLOR_BUFFER, - mTriangleColorBH, - bgfx::Access::Read); - } - mTriangleNormalBuffer.bindForCompute( VCL_MRB_PRIMITIVE_NORMAL_BUFFER); + mTriangleColorBuffer.bindForCompute( + VCL_MRB_PRIMITIVE_COLOR_BUFFER); + if (bgfx::isValid(mTriangleTextureIndexBH)) { // tri texture indices bgfx::setBuffer( VCL_MRB_TRIANGLE_TEXTURE_ID_BUFFER, @@ -235,13 +231,10 @@ class MeshRenderBuffers : public vcl::MeshRenderData PrimitiveType::FLOAT, BGFX_BUFFER_COMPUTE_READ); // triangle color buffer - if (Base::triangleColorBufferData()) { - mTriangleColorBH = bgfx::createIndexBuffer( - bgfx::makeRef( - Base::triangleColorBufferData(), - Base::triangleNumber() * sizeof(uint32_t)), - BGFX_BUFFER_INDEX32 | BGFX_BUFFER_COMPUTE_READ); - } + mTriangleColorBuffer.set( + Base::triangleColorBufferData(), + Base::triangleNumber(), + PrimitiveType::UINT, BGFX_BUFFER_COMPUTE_READ); // triangle wedge UV buffer if (Base::wedgeTexCoordsBufferData()) { @@ -321,9 +314,6 @@ class MeshRenderBuffers : public vcl::MeshRenderData void destroyBGFXBuffers() { - if (bgfx::isValid(mTriangleColorBH)) - bgfx::destroy(mTriangleColorBH); - if (bgfx::isValid(mTriangleTextureIndexBH)) bgfx::destroy(mTriangleTextureIndexBH); From b7b8d225599898f0f22f413087334dd49707b10f Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Fri, 24 Jan 2025 15:07:37 +0100 Subject: [PATCH 08/29] [render] setForCompute in IndexBuffer --- .../include/vclib/bgfx/buffers/index_buffer.h | 41 ++++++--- .../bgfx/drawable/mesh/mesh_render_buffers.h | 90 +++++++++++-------- 2 files changed, 83 insertions(+), 48 deletions(-) diff --git a/vclib/render/include/vclib/bgfx/buffers/index_buffer.h b/vclib/render/include/vclib/bgfx/buffers/index_buffer.h index 5c1c0a30c..b7718257b 100644 --- a/vclib/render/include/vclib/bgfx/buffers/index_buffer.h +++ b/vclib/render/include/vclib/bgfx/buffers/index_buffer.h @@ -70,12 +70,23 @@ class IndexBuffer friend void swap(IndexBuffer& a, IndexBuffer& b) { a.swap(b); } void set( + const void* bufferIndices, + const uint bufferSize, + bool is32Bit = true) + { + uint64_t flags = is32Bit ? BGFX_BUFFER_INDEX32 : BGFX_BUFFER_NONE; + uint size = is32Bit ? 4 : 2; + set(bgfx::makeRef(bufferIndices, bufferSize * size), flags); + } + + void setForCompute( const void* bufferIndices, const uint bufferSize, PrimitiveType type, - uint64_t flags = BGFX_BUFFER_NONE) + bgfx::Access::Enum access = bgfx::Access::Read) { - flags |= flagsForType(type); + uint64_t flags = flagsForType(type); + flags |= flagsForAccess(access); set(bgfx::makeRef(bufferIndices, bufferSize * sizeOf(type)), flags); } @@ -84,16 +95,16 @@ class IndexBuffer mIndexBufferHandle = bgfx::createIndexBuffer(indices, flags); } - void bind() const - { - bgfx::setIndexBuffer(mIndexBufferHandle); - } - - void bindForCompute( - uint8_t stage, + void bind( + uint stage = UINT_NULL, bgfx::Access::Enum access = bgfx::Access::Read) const { - bgfx::setBuffer(stage, mIndexBufferHandle, access); + if (stage == UINT_NULL || stage >= 255) { + bgfx::setIndexBuffer(mIndexBufferHandle); + } + else { + bgfx::setBuffer(stage, mIndexBufferHandle, access); + } } private: @@ -109,6 +120,16 @@ class IndexBuffer default: return BGFX_BUFFER_NONE; } } + + static uint64_t flagsForAccess(bgfx::Access::Enum access) + { + switch (access) { + case bgfx::Access::Read: return BGFX_BUFFER_COMPUTE_READ; + case bgfx::Access::Write: return BGFX_BUFFER_COMPUTE_WRITE; + case bgfx::Access::ReadWrite: return BGFX_BUFFER_COMPUTE_READ_WRITE; + default: return BGFX_BUFFER_NONE; + } + } }; } // namespace vcl diff --git a/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h b/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h index b936ea258..4c2ec1229 100644 --- a/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h +++ b/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h @@ -132,10 +132,10 @@ class MeshRenderBuffers : public vcl::MeshRenderData if (indexBufferToBind == Base::TRIANGLES) { mTriangleIndexBuffer.bind(); - mTriangleNormalBuffer.bindForCompute( + mTriangleNormalBuffer.bind( VCL_MRB_PRIMITIVE_NORMAL_BUFFER); - mTriangleColorBuffer.bindForCompute( + mTriangleColorBuffer.bind( VCL_MRB_PRIMITIVE_COLOR_BUFFER); if (bgfx::isValid(mTriangleTextureIndexBH)) { // tri texture indices @@ -186,55 +186,69 @@ class MeshRenderBuffers : public vcl::MeshRenderData 3, bgfx::AttribType::Float); - mVertexNormalsBuffer.set( - Base::vertexNormalBufferData(), - Base::vertexNumber() * 3, - bgfx::Attrib::Normal, - 3, - bgfx::AttribType::Float); + // vertex buffer (normals) + if (Base::vertexNormalBufferData()) { + mVertexNormalsBuffer.set( + Base::vertexNormalBufferData(), + Base::vertexNumber() * 3, + bgfx::Attrib::Normal, + 3, + bgfx::AttribType::Float); + } - mVertexColorsBuffer.set( - Base::vertexColorBufferData(), - Base::vertexNumber() * 4, - bgfx::Attrib::Color0, - 4, - bgfx::AttribType::Uint8, - true); - - mVertexUVBuffer.set( - Base::vertexTexCoordsBufferData(), - Base::vertexNumber() * 2, - bgfx::Attrib::TexCoord0, - 2, - bgfx::AttribType::Float); + // vertex buffer (colors) + if (Base::vertexColorBufferData()) { + mVertexColorsBuffer.set( + Base::vertexColorBufferData(), + Base::vertexNumber() * 4, + bgfx::Attrib::Color0, + 4, + bgfx::AttribType::Uint8, + true); + } + + // vertex buffer (UVs) + if (Base::vertexTexCoordsBufferData()) { + mVertexUVBuffer.set( + Base::vertexTexCoordsBufferData(), + Base::vertexNumber() * 2, + bgfx::Attrib::TexCoord0, + 2, + bgfx::AttribType::Float); + } // vertex wedges buffer (duplicated vertices) - mVertexWedgeUVBuffer.set( - Base::wedgeTexCoordsBufferData(), - Base::vertexNumber() * 2, - bgfx::Attrib::TexCoord1, - 2, - bgfx::AttribType::Float); + if (Base::wedgeTexCoordsBufferData()) { + mVertexWedgeUVBuffer.set( + Base::wedgeTexCoordsBufferData(), + Base::vertexNumber() * 2, + bgfx::Attrib::TexCoord1, + 2, + bgfx::AttribType::Float); + } // triangle index buffer if (Base::triangleBufferData()) { mTriangleIndexBuffer.set( Base::triangleBufferData(), - Base::triangleBufferSize(), - PrimitiveType::UINT); + Base::triangleBufferSize()); } // triangle normal buffer - mTriangleNormalBuffer.set( - Base::triangleNormalBufferData(), - Base::triangleNumber() * 3, - PrimitiveType::FLOAT, BGFX_BUFFER_COMPUTE_READ); + if (Base::triangleNormalBufferData()) { + mTriangleNormalBuffer.setForCompute( + Base::triangleNormalBufferData(), + Base::triangleNumber() * 3, + PrimitiveType::FLOAT); + } // triangle color buffer - mTriangleColorBuffer.set( - Base::triangleColorBufferData(), - Base::triangleNumber(), - PrimitiveType::UINT, BGFX_BUFFER_COMPUTE_READ); + if (Base::triangleColorBufferData()) { + mTriangleColorBuffer.setForCompute( + Base::triangleColorBufferData(), + Base::triangleNumber(), + PrimitiveType::UINT); + } // triangle wedge UV buffer if (Base::wedgeTexCoordsBufferData()) { From 053f2814ad175dc62ebfebce1fb51d1cede1b71b Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Fri, 24 Jan 2025 15:24:28 +0100 Subject: [PATCH 09/29] [render] bugfixes IndexBuffer --- .../render/include/vclib/bgfx/buffers/index_buffer.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/vclib/render/include/vclib/bgfx/buffers/index_buffer.h b/vclib/render/include/vclib/bgfx/buffers/index_buffer.h index b7718257b..0ceaa701a 100644 --- a/vclib/render/include/vclib/bgfx/buffers/index_buffer.h +++ b/vclib/render/include/vclib/bgfx/buffers/index_buffer.h @@ -99,11 +99,13 @@ class IndexBuffer uint stage = UINT_NULL, bgfx::Access::Enum access = bgfx::Access::Read) const { - if (stage == UINT_NULL || stage >= 255) { - bgfx::setIndexBuffer(mIndexBufferHandle); - } - else { - bgfx::setBuffer(stage, mIndexBufferHandle, access); + if (bgfx::isValid(mIndexBufferHandle)) { + if (stage == UINT_NULL) { + bgfx::setIndexBuffer(mIndexBufferHandle); + } + else { + bgfx::setBuffer(stage, mIndexBufferHandle, access); + } } } From bac21a29dab3a6f80b8cd328756950a50fd904e1 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Fri, 24 Jan 2025 15:26:28 +0100 Subject: [PATCH 10/29] [render] triangle texture indices using IndexBuffer class --- .../bgfx/drawable/mesh/mesh_render_buffers.h | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h b/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h index 4c2ec1229..076e1412b 100644 --- a/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h +++ b/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h @@ -47,7 +47,7 @@ class MeshRenderBuffers : public vcl::MeshRenderData IndexBuffer mTriangleNormalBuffer; IndexBuffer mTriangleColorBuffer; - bgfx::IndexBufferHandle mTriangleTextureIndexBH = BGFX_INVALID_HANDLE; + IndexBuffer mTriangleTextureIndexBuffer; bgfx::IndexBufferHandle mEdgeIndexBH = BGFX_INVALID_HANDLE; bgfx::IndexBufferHandle mEdgeNormalBH = BGFX_INVALID_HANDLE; @@ -94,7 +94,7 @@ class MeshRenderBuffers : public vcl::MeshRenderData swap(mTriangleIndexBuffer, other.mTriangleIndexBuffer); swap(mTriangleNormalBuffer, other.mTriangleNormalBuffer); swap(mTriangleColorBuffer, other.mTriangleColorBuffer); - swap(mTriangleTextureIndexBH, other.mTriangleTextureIndexBH); + swap(mTriangleTextureIndexBuffer, other.mTriangleTextureIndexBuffer); swap(mEdgeIndexBH, other.mEdgeIndexBH); swap(mEdgeNormalBH, other.mEdgeNormalBH); swap(mEdgeColorBH, other.mEdgeColorBH); @@ -138,12 +138,8 @@ class MeshRenderBuffers : public vcl::MeshRenderData mTriangleColorBuffer.bind( VCL_MRB_PRIMITIVE_COLOR_BUFFER); - if (bgfx::isValid(mTriangleTextureIndexBH)) { // tri texture indices - bgfx::setBuffer( - VCL_MRB_TRIANGLE_TEXTURE_ID_BUFFER, - mTriangleTextureIndexBH, - bgfx::Access::Read); - } + mTriangleTextureIndexBuffer.bind( + VCL_MRB_TRIANGLE_TEXTURE_ID_BUFFER); } else if (indexBufferToBind == Base::EDGES) { bgfx::setIndexBuffer(mEdgeIndexBH); @@ -254,11 +250,10 @@ class MeshRenderBuffers : public vcl::MeshRenderData if (Base::wedgeTexCoordsBufferData()) { assert(Base::wedgeTextureIDsBufferData()); - mTriangleTextureIndexBH = bgfx::createIndexBuffer( - bgfx::makeRef( - Base::wedgeTextureIDsBufferData(), - Base::triangleNumber() * sizeof(uint32_t)), - BGFX_BUFFER_INDEX32 | BGFX_BUFFER_COMPUTE_READ); + mTriangleTextureIndexBuffer.setForCompute( + Base::wedgeTextureIDsBufferData(), + Base::triangleNumber(), + PrimitiveType::UINT); } // edge index buffer @@ -328,9 +323,6 @@ class MeshRenderBuffers : public vcl::MeshRenderData void destroyBGFXBuffers() { - if (bgfx::isValid(mTriangleTextureIndexBH)) - bgfx::destroy(mTriangleTextureIndexBH); - if (bgfx::isValid(mEdgeIndexBH)) bgfx::destroy(mEdgeIndexBH); From bfc7ea775472bf3f6e3da82b4784f1d935483478 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Fri, 24 Jan 2025 15:45:14 +0100 Subject: [PATCH 11/29] [render] edge indices using IndexBuffer class --- .../bgfx/drawable/mesh/mesh_render_buffers.h | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h b/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h index 076e1412b..17b26a484 100644 --- a/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h +++ b/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h @@ -49,7 +49,7 @@ class MeshRenderBuffers : public vcl::MeshRenderData IndexBuffer mTriangleTextureIndexBuffer; - bgfx::IndexBufferHandle mEdgeIndexBH = BGFX_INVALID_HANDLE; + IndexBuffer mEdgeIndexBuffer; bgfx::IndexBufferHandle mEdgeNormalBH = BGFX_INVALID_HANDLE; bgfx::IndexBufferHandle mEdgeColorBH = BGFX_INVALID_HANDLE; @@ -95,7 +95,7 @@ class MeshRenderBuffers : public vcl::MeshRenderData swap(mTriangleNormalBuffer, other.mTriangleNormalBuffer); swap(mTriangleColorBuffer, other.mTriangleColorBuffer); swap(mTriangleTextureIndexBuffer, other.mTriangleTextureIndexBuffer); - swap(mEdgeIndexBH, other.mEdgeIndexBH); + swap(mEdgeIndexBuffer, other.mEdgeIndexBuffer); swap(mEdgeNormalBH, other.mEdgeNormalBH); swap(mEdgeColorBH, other.mEdgeColorBH); swap(mWireframeIndexBH, other.mWireframeIndexBH); @@ -142,7 +142,7 @@ class MeshRenderBuffers : public vcl::MeshRenderData VCL_MRB_TRIANGLE_TEXTURE_ID_BUFFER); } else if (indexBufferToBind == Base::EDGES) { - bgfx::setIndexBuffer(mEdgeIndexBH); + mEdgeIndexBuffer.bind(); if (bgfx::isValid(mEdgeColorBH)) { // edge colors bgfx::setBuffer( @@ -258,11 +258,8 @@ class MeshRenderBuffers : public vcl::MeshRenderData // edge index buffer if (Base::edgeBufferData()) { - mEdgeIndexBH = bgfx::createIndexBuffer( - bgfx::makeRef( - Base::edgeBufferData(), - Base::edgeBufferSize() * sizeof(uint32_t)), - BGFX_BUFFER_INDEX32); + mEdgeIndexBuffer.set( + Base::edgeBufferData(), Base::edgeBufferSize()); } // edge normal buffer @@ -323,9 +320,6 @@ class MeshRenderBuffers : public vcl::MeshRenderData void destroyBGFXBuffers() { - if (bgfx::isValid(mEdgeIndexBH)) - bgfx::destroy(mEdgeIndexBH); - if (bgfx::isValid(mEdgeNormalBH)) bgfx::destroy(mEdgeNormalBH); From bfe59c388c52fb3bd34009d96d07f86309afe904 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Fri, 24 Jan 2025 16:00:13 +0100 Subject: [PATCH 12/29] [render] edge normals and colors using IndexBuffer class --- .../bgfx/drawable/mesh/mesh_render_buffers.h | 49 ++++++------------- 1 file changed, 16 insertions(+), 33 deletions(-) diff --git a/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h b/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h index 17b26a484..9d62d309e 100644 --- a/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h +++ b/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h @@ -50,8 +50,8 @@ class MeshRenderBuffers : public vcl::MeshRenderData IndexBuffer mTriangleTextureIndexBuffer; IndexBuffer mEdgeIndexBuffer; - bgfx::IndexBufferHandle mEdgeNormalBH = BGFX_INVALID_HANDLE; - bgfx::IndexBufferHandle mEdgeColorBH = BGFX_INVALID_HANDLE; + IndexBuffer mEdgeNormalBuffer; + IndexBuffer mEdgeColorBuffer; bgfx::IndexBufferHandle mWireframeIndexBH = BGFX_INVALID_HANDLE; @@ -96,8 +96,8 @@ class MeshRenderBuffers : public vcl::MeshRenderData swap(mTriangleColorBuffer, other.mTriangleColorBuffer); swap(mTriangleTextureIndexBuffer, other.mTriangleTextureIndexBuffer); swap(mEdgeIndexBuffer, other.mEdgeIndexBuffer); - swap(mEdgeNormalBH, other.mEdgeNormalBH); - swap(mEdgeColorBH, other.mEdgeColorBH); + swap(mEdgeNormalBuffer, other.mEdgeNormalBuffer); + swap(mEdgeColorBuffer, other.mEdgeColorBuffer); swap(mWireframeIndexBH, other.mWireframeIndexBH); swap(mTexturesH, other.mTexturesH); } @@ -144,19 +144,11 @@ class MeshRenderBuffers : public vcl::MeshRenderData else if (indexBufferToBind == Base::EDGES) { mEdgeIndexBuffer.bind(); - if (bgfx::isValid(mEdgeColorBH)) { // edge colors - bgfx::setBuffer( - VCL_MRB_PRIMITIVE_COLOR_BUFFER, - mEdgeColorBH, - bgfx::Access::Read); - } + mEdgeNormalBuffer.bind( + VCL_MRB_PRIMITIVE_NORMAL_BUFFER); - if (bgfx::isValid(mEdgeNormalBH)) { // edge normals - bgfx::setBuffer( - VCL_MRB_PRIMITIVE_NORMAL_BUFFER, - mEdgeNormalBH, - bgfx::Access::Read); - } + mEdgeColorBuffer.bind( + VCL_MRB_PRIMITIVE_COLOR_BUFFER); } else if (indexBufferToBind == Base::WIREFRAME) { bgfx::setIndexBuffer(mWireframeIndexBH); @@ -264,21 +256,18 @@ class MeshRenderBuffers : public vcl::MeshRenderData // edge normal buffer if (Base::edgeNormalBufferData()) { - mEdgeNormalBH = bgfx::createIndexBuffer( - bgfx::makeRef( - Base::edgeNormalBufferData(), - Base::edgeNumber() * 3 * sizeof(float)), - BGFX_BUFFER_COMPUTE_FORMAT_32X1 | BGFX_BUFFER_COMPUTE_READ | - BGFX_BUFFER_COMPUTE_TYPE_FLOAT); + mEdgeNormalBuffer.setForCompute( + Base::edgeNormalBufferData(), + Base::edgeNumber() * 3, + PrimitiveType::FLOAT); } // edge color buffer if (Base::edgeColorBufferData()) { - mEdgeColorBH = bgfx::createIndexBuffer( - bgfx::makeRef( - Base::edgeColorBufferData(), - Base::edgeNumber() * sizeof(uint32_t)), - BGFX_BUFFER_INDEX32 | BGFX_BUFFER_COMPUTE_READ); + mEdgeColorBuffer.setForCompute( + Base::edgeColorBufferData(), + Base::edgeNumber(), + PrimitiveType::UINT); } // wireframe index buffer @@ -320,12 +309,6 @@ class MeshRenderBuffers : public vcl::MeshRenderData void destroyBGFXBuffers() { - if (bgfx::isValid(mEdgeNormalBH)) - bgfx::destroy(mEdgeNormalBH); - - if (bgfx::isValid(mEdgeColorBH)) - bgfx::destroy(mEdgeColorBH); - if (bgfx::isValid(mWireframeIndexBH)) bgfx::destroy(mWireframeIndexBH); From f59d572d8adabde39bd939f1404104a2d4433f66 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Fri, 24 Jan 2025 16:34:05 +0100 Subject: [PATCH 13/29] [render] VertexBuffer can be used in compute shaders --- .../vclib/bgfx/buffers/vertex_buffer.h | 90 ++++++++++++++----- .../bgfx/drawable/mesh/mesh_render_buffers.h | 10 +-- 2 files changed, 73 insertions(+), 27 deletions(-) diff --git a/vclib/render/include/vclib/bgfx/buffers/vertex_buffer.h b/vclib/render/include/vclib/bgfx/buffers/vertex_buffer.h index 4f6e0dc4b..f04ab2116 100644 --- a/vclib/render/include/vclib/bgfx/buffers/vertex_buffer.h +++ b/vclib/render/include/vclib/bgfx/buffers/vertex_buffer.h @@ -34,6 +34,7 @@ namespace vcl { class VertexBuffer { bgfx::VertexBufferHandle mVertexBufferHandle = BGFX_INVALID_HANDLE; + bool mCompute = false; public: VertexBuffer() = default; @@ -43,6 +44,7 @@ class VertexBuffer VertexBuffer(VertexBuffer&& other) noexcept { mVertexBufferHandle = other.mVertexBufferHandle; + mCompute = other.mCompute; other.mVertexBufferHandle = BGFX_INVALID_HANDLE; } @@ -57,6 +59,7 @@ class VertexBuffer VertexBuffer& operator=(VertexBuffer&& other) noexcept { mVertexBufferHandle = other.mVertexBufferHandle; + mCompute = other.mCompute; other.mVertexBufferHandle = BGFX_INVALID_HANDLE; return *this; } @@ -65,56 +68,99 @@ class VertexBuffer { using std::swap; swap(mVertexBufferHandle, other.mVertexBufferHandle); + swap(mCompute, other.mCompute); } friend void swap(VertexBuffer& a, VertexBuffer& b) { a.swap(b); } void set( - const void* bufferData, - const uint bufferSize, - bgfx::Attrib::Enum attrib, - uint numElements, - bgfx::AttribType::Enum attribType, - bool normalize = false, - bgfx::ReleaseFn releaseFn = nullptr, - uint64_t flags = BGFX_BUFFER_NONE) + const void* bufferData, + const uint bufferSize, + bgfx::Attrib::Enum attrib, + uint numElements, + PrimitiveType type, + bool normalize = false, + bgfx::ReleaseFn releaseFn = nullptr) { bgfx::VertexLayout layout; - layout.begin().add(attrib, numElements, attribType, normalize).end(); + layout.begin().add(attrib, numElements, attribType(type), normalize).end(); set(layout, bgfx::makeRef( - bufferData, bufferSize * attribTypeSize(attribType), releaseFn), + bufferData, + bufferSize * sizeOf(type), + releaseFn)); + } + + void setForCompute( + const void* bufferData, + const uint bufferSize, + bgfx::Attrib::Enum attrib, + uint numElements, + PrimitiveType type, + bool normalize = false, + bgfx::Access::Enum access = bgfx::Access::Read, + bgfx::ReleaseFn releaseFn = nullptr) + { + uint64_t flags = flagsForAccess(access); + + bgfx::VertexLayout layout; + layout.begin() + .add(attrib, numElements, attribType(type), normalize) + .end(); + + set(layout, + bgfx::makeRef( + bufferData, bufferSize * sizeOf(type), releaseFn), + true, flags); } void set( const bgfx::VertexLayout& layout, const bgfx::Memory* vertices, + bool compute = false, uint64_t flags = BGFX_BUFFER_NONE) { if (bgfx::isValid(mVertexBufferHandle)) bgfx::destroy(mVertexBufferHandle); mVertexBufferHandle = bgfx::createVertexBuffer(vertices, layout, flags); + mCompute = compute; } - void bind(uint stream) const + void bind(uint stream, bgfx::Access::Enum access = bgfx::Access::Read) const { - if (bgfx::isValid(mVertexBufferHandle)) - bgfx::setVertexBuffer(stream, mVertexBufferHandle); + if (bgfx::isValid(mVertexBufferHandle)) { + if (!mCompute) + bgfx::setVertexBuffer(stream, mVertexBufferHandle); + else + bgfx::setBuffer(stream, mVertexBufferHandle, access); + } + } + +private: + static uint64_t flagsForAccess(bgfx::Access::Enum access) + { + switch (access) { + case bgfx::Access::Read: return BGFX_BUFFER_COMPUTE_READ; + case bgfx::Access::Write: return BGFX_BUFFER_COMPUTE_WRITE; + case bgfx::Access::ReadWrite: return BGFX_BUFFER_COMPUTE_READ_WRITE; + default: return BGFX_BUFFER_NONE; + } } - static int attribTypeSize(bgfx::AttribType::Enum type) + static bgfx::AttribType::Enum attribType(PrimitiveType type) { - switch(type) - { - case bgfx::AttribType::Uint8: return 1; - case bgfx::AttribType::Uint10: return 2; - case bgfx::AttribType::Int16: return 2; - case bgfx::AttribType::Half: return 2; - case bgfx::AttribType::Float: return 4; - default: return 0; + switch (type) { + case PrimitiveType::CHAR: + case PrimitiveType::UCHAR: return bgfx::AttribType::Uint8; + case PrimitiveType::SHORT: + case PrimitiveType::USHORT: return bgfx::AttribType::Int16; + case PrimitiveType::FLOAT: return bgfx::AttribType::Float; + default: + assert(0); // not supported + return bgfx::AttribType::Count; } } }; diff --git a/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h b/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h index 9d62d309e..59b87c3ad 100644 --- a/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h +++ b/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h @@ -172,7 +172,7 @@ class MeshRenderBuffers : public vcl::MeshRenderData Base::vertexNumber() * 3, bgfx::Attrib::Position, 3, - bgfx::AttribType::Float); + PrimitiveType::FLOAT); // vertex buffer (normals) if (Base::vertexNormalBufferData()) { @@ -181,7 +181,7 @@ class MeshRenderBuffers : public vcl::MeshRenderData Base::vertexNumber() * 3, bgfx::Attrib::Normal, 3, - bgfx::AttribType::Float); + PrimitiveType::FLOAT); } // vertex buffer (colors) @@ -191,7 +191,7 @@ class MeshRenderBuffers : public vcl::MeshRenderData Base::vertexNumber() * 4, bgfx::Attrib::Color0, 4, - bgfx::AttribType::Uint8, + PrimitiveType::UCHAR, true); } @@ -202,7 +202,7 @@ class MeshRenderBuffers : public vcl::MeshRenderData Base::vertexNumber() * 2, bgfx::Attrib::TexCoord0, 2, - bgfx::AttribType::Float); + PrimitiveType::FLOAT); } // vertex wedges buffer (duplicated vertices) @@ -212,7 +212,7 @@ class MeshRenderBuffers : public vcl::MeshRenderData Base::vertexNumber() * 2, bgfx::Attrib::TexCoord1, 2, - bgfx::AttribType::Float); + PrimitiveType::FLOAT); } // triangle index buffer From 6f9507c7d73385e28618a0f4515b0beaf867a3e3 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Fri, 24 Jan 2025 16:45:53 +0100 Subject: [PATCH 14/29] [render] IndexBuffer can be set with releaseFn --- .../include/vclib/bgfx/buffers/index_buffer.h | 15 +++++++++------ .../bgfx/drawable/mesh/mesh_render_buffers.h | 3 +++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/vclib/render/include/vclib/bgfx/buffers/index_buffer.h b/vclib/render/include/vclib/bgfx/buffers/index_buffer.h index 0ceaa701a..69165f996 100644 --- a/vclib/render/include/vclib/bgfx/buffers/index_buffer.h +++ b/vclib/render/include/vclib/bgfx/buffers/index_buffer.h @@ -70,24 +70,27 @@ class IndexBuffer friend void swap(IndexBuffer& a, IndexBuffer& b) { a.swap(b); } void set( - const void* bufferIndices, - const uint bufferSize, - bool is32Bit = true) + const void* bufferIndices, + const uint bufferSize, + bool is32Bit = true, + bgfx::ReleaseFn releaseFn = nullptr) { uint64_t flags = is32Bit ? BGFX_BUFFER_INDEX32 : BGFX_BUFFER_NONE; uint size = is32Bit ? 4 : 2; - set(bgfx::makeRef(bufferIndices, bufferSize * size), flags); + set(bgfx::makeRef(bufferIndices, bufferSize * size, releaseFn), flags); } void setForCompute( const void* bufferIndices, const uint bufferSize, PrimitiveType type, - bgfx::Access::Enum access = bgfx::Access::Read) + bgfx::Access::Enum access = bgfx::Access::Read, + bgfx::ReleaseFn releaseFn = nullptr) { uint64_t flags = flagsForType(type); flags |= flagsForAccess(access); - set(bgfx::makeRef(bufferIndices, bufferSize * sizeOf(type)), flags); + set(bgfx::makeRef(bufferIndices, bufferSize * sizeOf(type), releaseFn), + flags); } void set(const bgfx::Memory* indices, uint64_t flags = BGFX_BUFFER_NONE) diff --git a/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h b/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h index 59b87c3ad..01871f034 100644 --- a/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h +++ b/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h @@ -49,12 +49,15 @@ class MeshRenderBuffers : public vcl::MeshRenderData IndexBuffer mTriangleTextureIndexBuffer; + // TODO: manage wireframe with proper lines IndexBuffer mEdgeIndexBuffer; IndexBuffer mEdgeNormalBuffer; IndexBuffer mEdgeColorBuffer; + // TODO: manage wireframe with proper lines bgfx::IndexBufferHandle mWireframeIndexBH = BGFX_INVALID_HANDLE; + // TODO: manage with a TextureUnit class std::vector> mTexturesH; public: From 060474c5f4b34c3f4e456533c5e8451b6d99b6e6 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Fri, 24 Jan 2025 17:37:13 +0100 Subject: [PATCH 15/29] [algorithms] create axis algorithm --- .../include/vclib/algorithms/mesh/create.h | 1 + .../vclib/algorithms/mesh/create/axis.h | 129 ++++++++++++++++++ vclib/core/todo.md | 1 + .../vclib/bgfx/drawable/drawable_axis.h | 8 +- .../src/vclib/bgfx/drawable/drawable_axis.cpp | 60 +------- 5 files changed, 142 insertions(+), 57 deletions(-) create mode 100644 vclib/core/include/vclib/algorithms/mesh/create/axis.h diff --git a/vclib/core/include/vclib/algorithms/mesh/create.h b/vclib/core/include/vclib/algorithms/mesh/create.h index cd4a41d6b..b406c4f84 100644 --- a/vclib/core/include/vclib/algorithms/mesh/create.h +++ b/vclib/core/include/vclib/algorithms/mesh/create.h @@ -23,6 +23,7 @@ #ifndef VCL_ALGORITHMS_MESH_CREATE_H #define VCL_ALGORITHMS_MESH_CREATE_H +#include "create/axis.h" #include "create/cone.h" #include "create/dodecahedron.h" #include "create/hexahedron.h" diff --git a/vclib/core/include/vclib/algorithms/mesh/create/axis.h b/vclib/core/include/vclib/algorithms/mesh/create/axis.h new file mode 100644 index 000000000..fd5d5dc52 --- /dev/null +++ b/vclib/core/include/vclib/algorithms/mesh/create/axis.h @@ -0,0 +1,129 @@ +/***************************************************************************** + * VCLib * + * Visual Computing Library * + * * + * Copyright(C) 2021-2025 * + * Visual Computing Lab * + * ISTI - Italian National Research Council * + * * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the Mozilla Public License Version 2.0 as published * + * by the Mozilla Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * Mozilla Public License Version 2.0 * + * (https://www.mozilla.org/en-US/MPL/2.0/) for more details. * + ****************************************************************************/ + +#ifndef VCL_ALGORITHMS_MESH_CREATE_AXIS_H +#define VCL_ALGORITHMS_MESH_CREATE_AXIS_H + +#include "cone.h" +#include "sphere.h" + +namespace vcl { + +namespace detail { + +template +MeshType createAxisCylinder(double unitLength, bool fromOrigin = false) +{ + const double cylLength = fromOrigin ? unitLength : unitLength * 2; + const double cylRadius = cylLength * 0.0025; + + const double coneRadius = cylRadius * 10; + const double coneLength = cylLength * 0.1; + + const double firstSphereRadius = unitLength * 0.02; + const double commonSphereRadius = unitLength * 0.008; + + MeshType cylinder = + vcl::createCylinder(cylRadius, cylLength); + + if (fromOrigin) { + vcl::translate(cylinder, vcl::Point3d(0, unitLength * 0.5, 0)); + } + + vcl::updatePerVertexNormals(cylinder); + + return cylinder; +} + +template +MeshType createAxisConeSpheres(double unitLength, bool fromOrigin = false) +{ + const double cylLength = fromOrigin ? unitLength : unitLength * 2; + const double cylRadius = cylLength * 0.0025; + + const double coneRadius = cylRadius * 10; + const double coneLength = cylLength * 0.1; + + const double firstSphereRadius = unitLength * 0.02; + const double commonSphereRadius = unitLength * 0.008; + + MeshType coneSpheres = + vcl::createCone(coneRadius, 0, coneLength); + double transl = unitLength + (coneLength * 0.5); + vcl::translate(coneSpheres, vcl::Point3d(0, transl, 0)); + + if (!fromOrigin) { + vcl::Sphered s(vcl::Point3d(0, -1, 0), firstSphereRadius); + MeshType sp = vcl::createSphere(s); + coneSpheres.append(sp); + } + + for (uint i = 0; i < 9; ++i) { + const double step = unitLength * 0.1; + const double x = step + i * step; + vcl::Sphered s(vcl::Point3d(0, x, 0), commonSphereRadius); + MeshType sp = vcl::createSphere(s); + coneSpheres.append(sp); + if (!fromOrigin) { + s.center().y() = -x; + sp = vcl::createSphere(s); + coneSpheres.append(sp); + } + } + + const double rad = fromOrigin ? firstSphereRadius : commonSphereRadius; + vcl::Sphered s = vcl::Sphered(vcl::Point3d(0, 0, 0), rad); + MeshType sp = vcl::createSphere(s); + coneSpheres.append(sp); + + vcl::updatePerVertexNormals(coneSpheres); + + return coneSpheres; +} + +} // namespace detail + +template +std::pair createAxisDisjoint( + double unitLength = 1, + bool fromOrigin = false) +{ + return std::make_pair( + detail::createAxisCylinder(unitLength, fromOrigin), + detail::createAxisConeSpheres(unitLength, fromOrigin)); +} + +template +MeshType createAxis(double unitLength = 1, bool fromOrigin = false) +{ + MeshType axis = + detail::createAxisCylinder(unitLength, fromOrigin); + + axis.append( + detail::createAxisConeSpheres(unitLength, fromOrigin)); + + return axis; +} + +} // namespace vcl + +#endif // VCL_ALGORITHMS_MESH_CREATE_AXIS_H diff --git a/vclib/core/todo.md b/vclib/core/todo.md index fee9d2a52..1db8ca8fc 100644 --- a/vclib/core/todo.md +++ b/vclib/core/todo.md @@ -23,6 +23,7 @@ - Components: - [ ] references to elements should be available using ELEM_ID - Mesh: + - [ ] append() should also take a rvalue reference and move it - [ ] manage clean() for all components of mesh, not only element containers - Utils: - [ ] MeshInfo should not use its own enums for elements and components diff --git a/vclib/render/include/vclib/bgfx/drawable/drawable_axis.h b/vclib/render/include/vclib/bgfx/drawable/drawable_axis.h index 2f81bfba7..ef16d8c2e 100644 --- a/vclib/render/include/vclib/bgfx/drawable/drawable_axis.h +++ b/vclib/render/include/vclib/bgfx/drawable/drawable_axis.h @@ -26,6 +26,7 @@ #include "mesh/mesh_render_buffers.h" #include "uniforms/drawable_axis_uniforms.h" +#include #include #include #include @@ -38,6 +39,9 @@ namespace vcl { class DrawableAxis : public DrawableObject { + inline static const std::pair AXIS_MESHES = + vcl::createAxisDisjoint(); + bool mVisible = false; const vcl::Color mColors[3] = { @@ -59,7 +63,7 @@ class DrawableAxis : public DrawableObject mutable DrawableAxisUniforms mUniforms; public: - DrawableAxis(double size = 1, bool fromOrigin = false); + DrawableAxis(double size = 1); ~DrawableAxis() = default; @@ -83,7 +87,7 @@ class DrawableAxis : public DrawableObject private: void updateMatrices(double size); - void createAxis(bool fromOrigin); + void createAxis(); }; } // namespace vcl diff --git a/vclib/render/src/vclib/bgfx/drawable/drawable_axis.cpp b/vclib/render/src/vclib/bgfx/drawable/drawable_axis.cpp index 107fab938..399895105 100644 --- a/vclib/render/src/vclib/bgfx/drawable/drawable_axis.cpp +++ b/vclib/render/src/vclib/bgfx/drawable/drawable_axis.cpp @@ -26,9 +26,9 @@ namespace vcl { -DrawableAxis::DrawableAxis(double size, bool fromOrigin) +DrawableAxis::DrawableAxis(double size) { - createAxis(fromOrigin); + createAxis(); updateMatrices(size); } @@ -83,65 +83,15 @@ void DrawableAxis::updateMatrices(double size) mMatrices[2](3, 3) = 1; } -void DrawableAxis::createAxis(bool fromOrigin) +void DrawableAxis::createAxis() { - const double unitLength = 1.0; - - const double cylLength = fromOrigin ? unitLength : unitLength * 2; - const double cylRadius = cylLength * 0.0025; - - const double coneRadius = cylRadius * 10; - const double coneLength = cylLength * 0.1; - - const double firstSphereRadius = unitLength * 0.02; - const double commonSphereRadius = unitLength * 0.008; - - vcl::TriMesh cylinder = - vcl::createCylinder(cylRadius, cylLength); - if (fromOrigin) { - vcl::translate(cylinder, vcl::Point3d(0, unitLength * 0.5, 0)); - } - - vcl::updatePerVertexNormals(cylinder); - - vcl::TriMesh rest = - vcl::createCone(coneRadius, 0, coneLength); - double transl = unitLength + (coneLength * 0.5); - vcl::translate(rest, vcl::Point3d(0, transl, 0)); - - if (!fromOrigin) { - vcl::Sphered s(vcl::Point3d(0, -1, 0), firstSphereRadius); - vcl::TriMesh sp = vcl::createSphere(s); - rest.append(sp); - } - - for (uint i = 0; i < 9; ++i) { - const double step = unitLength * 0.1; - const double x = step + i * step; - vcl::Sphered s(vcl::Point3d(0, x, 0), commonSphereRadius); - vcl::TriMesh sp = vcl::createSphere(s); - rest.append(sp); - if (!fromOrigin) { - s.center().y() = -x; - sp = vcl::createSphere(s); - rest.append(sp); - } - } - - const double rad = fromOrigin ? firstSphereRadius : commonSphereRadius; - vcl::Sphered s = vcl::Sphered(vcl::Point3d(0, 0, 0), rad); - vcl::TriMesh sp = vcl::createSphere(s); - rest.append(sp); - - vcl::updatePerVertexNormals(rest); - mArrowBuffers[0] = MeshRenderBuffers( - cylinder, + AXIS_MESHES.first, MeshRenderBuffers::VERT_NORMALS | MeshRenderBuffers::TRIANGLES); mArrowBuffers[1] = MeshRenderBuffers( - rest, + AXIS_MESHES.second, MeshRenderBuffers::VERT_NORMALS | MeshRenderBuffers::TRIANGLES); } From 043b1442d764cb8d595637a38cde3f818ac9694a Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Fri, 24 Jan 2025 17:46:43 +0100 Subject: [PATCH 16/29] [render] DrawableDirectionalLight uses VertexBuffer --- .../drawable/drawable_directional_light.h | 3 ++- .../drawable/drawable_directional_light.cpp | 22 +++++++------------ 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/vclib/render/include/vclib/bgfx/drawable/drawable_directional_light.h b/vclib/render/include/vclib/bgfx/drawable/drawable_directional_light.h index 62e79bd1a..92b8b9831 100644 --- a/vclib/render/include/vclib/bgfx/drawable/drawable_directional_light.h +++ b/vclib/render/include/vclib/bgfx/drawable/drawable_directional_light.h @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -44,7 +45,7 @@ class DrawableDirectionalLight : public DrawableObject std::vector mVertices; // vertices of the drawn lines vcl::Color mColor = vcl::Color::Yellow; // color of the lines - bgfx::VertexBufferHandle mVertexCoordBH = BGFX_INVALID_HANDLE; + VertexBuffer mVertexCoordBuffer; DrawableDirectionalLightUniforms mUniform; diff --git a/vclib/render/src/vclib/bgfx/drawable/drawable_directional_light.cpp b/vclib/render/src/vclib/bgfx/drawable/drawable_directional_light.cpp index 1904b3f81..9f7639098 100644 --- a/vclib/render/src/vclib/bgfx/drawable/drawable_directional_light.cpp +++ b/vclib/render/src/vclib/bgfx/drawable/drawable_directional_light.cpp @@ -76,9 +76,6 @@ DrawableDirectionalLight::DrawableDirectionalLight( DrawableDirectionalLight::~DrawableDirectionalLight() { - if (bgfx::isValid(mVertexCoordBH)) { - bgfx::destroy(mVertexCoordBH); - } } DrawableDirectionalLight& DrawableDirectionalLight::operator=( @@ -97,7 +94,7 @@ void DrawableDirectionalLight::swap(DrawableDirectionalLight& other) swap(mUniform, other.mUniform); swap(mProgram, other.mProgram); swap(mTransform, other.mTransform); - swap(mVertexCoordBH, other.mVertexCoordBH); + swap(mVertexCoordBuffer, other.mVertexCoordBuffer); } void DrawableDirectionalLight::updateRotation(const Matrix44f& rot) @@ -124,7 +121,7 @@ void DrawableDirectionalLight::draw(uint viewId) const mUniform.bind(); - bgfx::setVertexBuffer(0, mVertexCoordBH); + mVertexCoordBuffer.bind(0); bgfx::submit(viewId, mProgram); } @@ -143,15 +140,12 @@ std::shared_ptr DrawableDirectionalLight::clone() const void DrawableDirectionalLight::createVertexBuffer() { - // vertex buffer (positions) - bgfx::VertexLayout layout; - layout.begin() - .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float) - .end(); - - mVertexCoordBH = bgfx::createVertexBuffer( - bgfx::makeRef(mVertices.data(), mVertices.size() * sizeof(float)), - layout); + mVertexCoordBuffer.set( + mVertices.data(), + mVertices.size(), + bgfx::Attrib::Position, + 3, + PrimitiveType::FLOAT); } } // namespace vcl From bd08717b68d84e4feab88cfb03f0e18c71b836f0 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Sat, 25 Jan 2025 01:08:33 +0000 Subject: [PATCH 17/29] [clang-format] Committing clang-format changes --- examples/render/common/default_viewer.h | 2 +- .../vclib/algorithms/mesh/create/axis.h | 14 ++++++-------- vclib/core/include/vclib/types/base.h | 18 +++++++++--------- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/examples/render/common/default_viewer.h b/examples/render/common/default_viewer.h index 34c4cc784..58929602d 100644 --- a/examples/render/common/default_viewer.h +++ b/examples/render/common/default_viewer.h @@ -54,7 +54,7 @@ auto defaultViewer() #ifdef VCLIB_RENDER_EXAMPLES_WITH_QT return vcl::qt::MeshViewer(); #elif VCLIB_RENDER_EXAMPLES_WITH_GLFW - return vcl::glfw::ViewerWindow ; + return vcl::glfw::ViewerWindow; #endif } diff --git a/vclib/core/include/vclib/algorithms/mesh/create/axis.h b/vclib/core/include/vclib/algorithms/mesh/create/axis.h index fd5d5dc52..2420db543 100644 --- a/vclib/core/include/vclib/algorithms/mesh/create/axis.h +++ b/vclib/core/include/vclib/algorithms/mesh/create/axis.h @@ -42,8 +42,7 @@ MeshType createAxisCylinder(double unitLength, bool fromOrigin = false) const double firstSphereRadius = unitLength * 0.02; const double commonSphereRadius = unitLength * 0.008; - MeshType cylinder = - vcl::createCylinder(cylRadius, cylLength); + MeshType cylinder = vcl::createCylinder(cylRadius, cylLength); if (fromOrigin) { vcl::translate(cylinder, vcl::Point3d(0, unitLength * 0.5, 0)); @@ -66,14 +65,13 @@ MeshType createAxisConeSpheres(double unitLength, bool fromOrigin = false) const double firstSphereRadius = unitLength * 0.02; const double commonSphereRadius = unitLength * 0.008; - MeshType coneSpheres = - vcl::createCone(coneRadius, 0, coneLength); - double transl = unitLength + (coneLength * 0.5); + MeshType coneSpheres = vcl::createCone(coneRadius, 0, coneLength); + double transl = unitLength + (coneLength * 0.5); vcl::translate(coneSpheres, vcl::Point3d(0, transl, 0)); if (!fromOrigin) { vcl::Sphered s(vcl::Point3d(0, -1, 0), firstSphereRadius); - MeshType sp = vcl::createSphere(s); + MeshType sp = vcl::createSphere(s); coneSpheres.append(sp); } @@ -81,7 +79,7 @@ MeshType createAxisConeSpheres(double unitLength, bool fromOrigin = false) const double step = unitLength * 0.1; const double x = step + i * step; vcl::Sphered s(vcl::Point3d(0, x, 0), commonSphereRadius); - MeshType sp = vcl::createSphere(s); + MeshType sp = vcl::createSphere(s); coneSpheres.append(sp); if (!fromOrigin) { s.center().y() = -x; @@ -92,7 +90,7 @@ MeshType createAxisConeSpheres(double unitLength, bool fromOrigin = false) const double rad = fromOrigin ? firstSphereRadius : commonSphereRadius; vcl::Sphered s = vcl::Sphered(vcl::Point3d(0, 0, 0), rad); - MeshType sp = vcl::createSphere(s); + MeshType sp = vcl::createSphere(s); coneSpheres.append(sp); vcl::updatePerVertexNormals(coneSpheres); diff --git a/vclib/core/include/vclib/types/base.h b/vclib/core/include/vclib/types/base.h index a40bcb302..21832d8d0 100644 --- a/vclib/core/include/vclib/types/base.h +++ b/vclib/core/include/vclib/types/base.h @@ -84,15 +84,15 @@ enum class MatrixStorageType { ROW_MAJOR, COLUMN_MAJOR }; constexpr int sizeOf(PrimitiveType type) noexcept { switch (type) { - case PrimitiveType::CHAR: return sizeof(char); - case PrimitiveType::UCHAR: return sizeof(unsigned char); - case PrimitiveType::SHORT: return sizeof(int16_t); - case PrimitiveType::USHORT: return sizeof(uint16_t); - case PrimitiveType::INT: return sizeof(int32_t); - case PrimitiveType::UINT: return sizeof(uint32_t); - case PrimitiveType::FLOAT: return sizeof(float); - case PrimitiveType::DOUBLE: return sizeof(double); - default: return 0; + case PrimitiveType::CHAR: return sizeof(char); + case PrimitiveType::UCHAR: return sizeof(unsigned char); + case PrimitiveType::SHORT: return sizeof(int16_t); + case PrimitiveType::USHORT: return sizeof(uint16_t); + case PrimitiveType::INT: return sizeof(int32_t); + case PrimitiveType::UINT: return sizeof(uint32_t); + case PrimitiveType::FLOAT: return sizeof(float); + case PrimitiveType::DOUBLE: return sizeof(double); + default: return 0; } } From 2b85ab4bfd88d12718976f55984a846b7e0c1dd0 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Sat, 25 Jan 2025 10:01:07 +0100 Subject: [PATCH 18/29] [render] move transform in drawable trackball --- .../include/vclib/bgfx/drawable/drawable_trackball.h | 6 ++++-- .../render/drawable/trackball/trackball_render_data.h | 6 ------ .../src/vclib/bgfx/drawable/drawable_trackball.cpp | 7 ++++++- .../drawable/trackball/trackball_render_data.cpp | 10 ---------- 4 files changed, 10 insertions(+), 19 deletions(-) diff --git a/vclib/render/include/vclib/bgfx/drawable/drawable_trackball.h b/vclib/render/include/vclib/bgfx/drawable/drawable_trackball.h index 93f7cac43..cda02606d 100644 --- a/vclib/render/include/vclib/bgfx/drawable/drawable_trackball.h +++ b/vclib/render/include/vclib/bgfx/drawable/drawable_trackball.h @@ -48,9 +48,9 @@ class DrawableTrackBall : public DrawableObject, protected TrackballRenderData DrawableTrackballUniforms mUniforms; -public: - using TrackballRenderData::setTransform; + vcl::Matrix44f mTransform = vcl::Matrix44f::Identity(); +public: // TODO: manage copy and swap DrawableTrackBall(); @@ -58,6 +58,8 @@ class DrawableTrackBall : public DrawableObject, protected TrackballRenderData void updateDragging(bool isDragging); + void setTransform(const vcl::Matrix44f& mtx); + // DrawableObject interface void draw(uint viewId) const override; diff --git a/vclib/render/include/vclib/render/drawable/trackball/trackball_render_data.h b/vclib/render/include/vclib/render/drawable/trackball/trackball_render_data.h index bdcb583ce..544f466db 100644 --- a/vclib/render/include/vclib/render/drawable/trackball/trackball_render_data.h +++ b/vclib/render/include/vclib/render/drawable/trackball/trackball_render_data.h @@ -33,8 +33,6 @@ class TrackballRenderData std::vector mVertices; std::vector mEdges; - vcl::Matrix44f mTransform = vcl::Matrix44f::Identity(); - public: TrackballRenderData(uint pointsPerCircle = 64); @@ -45,10 +43,6 @@ class TrackballRenderData const float* vertexBufferData() const; const uint16_t* edgeBufferData() const; - - const float* transformData() const; - - void setTransform(const vcl::Matrix44f& mtx); }; } // namespace vcl diff --git a/vclib/render/src/vclib/bgfx/drawable/drawable_trackball.cpp b/vclib/render/src/vclib/bgfx/drawable/drawable_trackball.cpp index 134b4de12..251e0e94f 100644 --- a/vclib/render/src/vclib/bgfx/drawable/drawable_trackball.cpp +++ b/vclib/render/src/vclib/bgfx/drawable/drawable_trackball.cpp @@ -46,6 +46,11 @@ void DrawableTrackBall::updateDragging(bool isDragging) mUniforms.setDragging(isDragging); } +void DrawableTrackBall::setTransform(const Matrix44f& mtx) +{ + mTransform = mtx; +} + void DrawableTrackBall::draw(uint viewId) const { if (isVisible()) { @@ -58,7 +63,7 @@ void DrawableTrackBall::draw(uint viewId) const bgfx::setVertexBuffer(0, mVertexCoordBH); bgfx::setIndexBuffer(mEdgeIndexBH); - bgfx::setTransform(transformData()); + bgfx::setTransform(mTransform.data()); mUniforms.bind(); diff --git a/vclib/render/src/vclib/render/drawable/trackball/trackball_render_data.cpp b/vclib/render/src/vclib/render/drawable/trackball/trackball_render_data.cpp index 6c73cad9a..8f40c4832 100644 --- a/vclib/render/src/vclib/render/drawable/trackball/trackball_render_data.cpp +++ b/vclib/render/src/vclib/render/drawable/trackball/trackball_render_data.cpp @@ -82,14 +82,4 @@ const uint16_t* TrackballRenderData::edgeBufferData() const return mEdges.data(); } -const float* TrackballRenderData::transformData() const -{ - return mTransform.data(); -} - -void TrackballRenderData::setTransform(const Matrix44f& mtx) -{ - mTransform = mtx; -} - } // namespace vcl From 86ec9904cc3e09b485b9262513ffc4ceafac1498 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Sat, 25 Jan 2025 10:30:07 +0100 Subject: [PATCH 19/29] [algorithms] createTrackBall function --- vclib/core/include/vclib/algorithms/core.h | 1 + .../include/vclib/algorithms/core/create.h} | 72 ++++++++++--------- .../vclib/bgfx/drawable/drawable_trackball.h | 8 ++- .../trackball/trackball_render_data.h | 50 ------------- .../bgfx/drawable/drawable_trackball.cpp | 13 ++-- 5 files changed, 52 insertions(+), 92 deletions(-) rename vclib/{render/src/vclib/render/drawable/trackball/trackball_render_data.cpp => core/include/vclib/algorithms/core/create.h} (56%) delete mode 100644 vclib/render/include/vclib/render/drawable/trackball/trackball_render_data.h diff --git a/vclib/core/include/vclib/algorithms/core.h b/vclib/core/include/vclib/algorithms/core.h index 88527ad36..0a909f440 100644 --- a/vclib/core/include/vclib/algorithms/core.h +++ b/vclib/core/include/vclib/algorithms/core.h @@ -25,6 +25,7 @@ #include "core/bounding_box.h" #include "core/box.h" +#include "core/create.h" #include "core/distance.h" #include "core/fitting.h" #include "core/intersection.h" diff --git a/vclib/render/src/vclib/render/drawable/trackball/trackball_render_data.cpp b/vclib/core/include/vclib/algorithms/core/create.h similarity index 56% rename from vclib/render/src/vclib/render/drawable/trackball/trackball_render_data.cpp rename to vclib/core/include/vclib/algorithms/core/create.h index 8f40c4832..8749514dd 100644 --- a/vclib/render/src/vclib/render/drawable/trackball/trackball_render_data.cpp +++ b/vclib/core/include/vclib/algorithms/core/create.h @@ -20,66 +20,68 @@ * (https://www.mozilla.org/en-US/MPL/2.0/) for more details. * ****************************************************************************/ -#include +#ifndef VCL_ALGORITHMS_CORE_CREATE_H +#define VCL_ALGORITHMS_CORE_CREATE_H -#include -#include +#include "polygon/create.h" namespace vcl { -TrackballRenderData::TrackballRenderData(uint pointsPerCircle) +/** + * @brief Returns a pair of vectors containing the vertices and edges of a 3D + * Trackball, composed of three circles in the x, y, and z planes. + * + * @tparam ScalarType: the type of scalar used for the 3D vertices. + * @tparam UintType: the type of integer used for the edge indices. + * + * @param[in] scale: the scale of the trackball. + * @param[in] pointsPerCircle: the number of points per circle. + * @return a pair of vectors containing the vertices and edges of the trackball. + */ +template +std::pair>, std::vector> +createTrackBall(ScalarType scale = 1.0, uint pointsPerCircle = 64) { - vcl::Polygon2f circle = - vcl::createCircle(pointsPerCircle, 1.0f); + using PointType = vcl::Point3; - mVertices.reserve(pointsPerCircle * 3); + std::vector vertices; + std::vector edges; + + vcl::Polygon2 circle = + vcl::createCircle>(pointsPerCircle, 1.0); + + vertices.reserve(pointsPerCircle * 3); // x uint first = 0; for (uint i = 0; i < circle.size(); ++i) { const auto& p = circle.point(i); - mVertices.push_back(vcl::Point3f(0, p.x(), p.y())); - mEdges.push_back(i + first); - mEdges.push_back((i + 1) % circle.size() + first); + vertices.push_back(PointType(0, p.x(), p.y())); + edges.push_back(i + first); + edges.push_back((i + 1) % circle.size() + first); } // y first = circle.size(); for (uint i = 0; i < circle.size(); ++i) { const auto& p = circle.point(i); - mVertices.push_back(vcl::Point3f(p.x(), 0, p.y())); - mEdges.push_back(i + first); - mEdges.push_back((i + 1) % circle.size() + first); + vertices.push_back(PointType(p.x(), 0, p.y())); + edges.push_back(i + first); + edges.push_back((i + 1) % circle.size() + first); } // z first = 2 * circle.size(); for (uint i = 0; i < circle.size(); ++i) { const auto& p = circle.point(i); - mVertices.push_back(vcl::Point3f(p.x(), p.y(), 0)); - mEdges.push_back(i + first); - mEdges.push_back((i + 1) % circle.size() + first); + vertices.push_back(PointType(p.x(), p.y(), 0)); + edges.push_back(i + first); + edges.push_back((i + 1) % circle.size() + first); } -} - -uint TrackballRenderData::vertexNumber() const -{ - return mVertices.size(); -} - -uint TrackballRenderData::edgeNumber() const -{ - return mEdges.size(); -} -const float* TrackballRenderData::vertexBufferData() const -{ - return mVertices.front().data(); -} - -const uint16_t* TrackballRenderData::edgeBufferData() const -{ - return mEdges.data(); + return std::make_pair(std::move(vertices), std::move(edges)); } } // namespace vcl + +#endif // VCL_ALGORITHMS_CORE_CREATE_H diff --git a/vclib/render/include/vclib/bgfx/drawable/drawable_trackball.h b/vclib/render/include/vclib/bgfx/drawable/drawable_trackball.h index cda02606d..6e023d4eb 100644 --- a/vclib/render/include/vclib/bgfx/drawable/drawable_trackball.h +++ b/vclib/render/include/vclib/bgfx/drawable/drawable_trackball.h @@ -25,16 +25,20 @@ #include "uniforms/drawable_trackball_uniforms.h" +#include #include -#include #include #include namespace vcl { -class DrawableTrackBall : public DrawableObject, protected TrackballRenderData +class DrawableTrackBall : public DrawableObject { + inline static const uint N_POINTS = 128; + inline static const auto TRACKBALL_DATA = + createTrackBall(1.0, N_POINTS); + bool mVisible = true; bgfx::VertexBufferHandle mVertexCoordBH = BGFX_INVALID_HANDLE; diff --git a/vclib/render/include/vclib/render/drawable/trackball/trackball_render_data.h b/vclib/render/include/vclib/render/drawable/trackball/trackball_render_data.h deleted file mode 100644 index 544f466db..000000000 --- a/vclib/render/include/vclib/render/drawable/trackball/trackball_render_data.h +++ /dev/null @@ -1,50 +0,0 @@ -/***************************************************************************** - * VCLib * - * Visual Computing Library * - * * - * Copyright(C) 2021-2025 * - * Visual Computing Lab * - * ISTI - Italian National Research Council * - * * - * All rights reserved. * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the Mozilla Public License Version 2.0 as published * - * by the Mozilla Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * Mozilla Public License Version 2.0 * - * (https://www.mozilla.org/en-US/MPL/2.0/) for more details. * - ****************************************************************************/ - -#ifndef VCL_RENDER_DRAWABLE_TRACKBALL_TRACKBALL_RENDER_DATA_H -#define VCL_RENDER_DRAWABLE_TRACKBALL_TRACKBALL_RENDER_DATA_H - -#include -#include - -namespace vcl { - -class TrackballRenderData -{ - std::vector mVertices; - std::vector mEdges; - -public: - TrackballRenderData(uint pointsPerCircle = 64); - - uint vertexNumber() const; - - uint edgeNumber() const; - - const float* vertexBufferData() const; - - const uint16_t* edgeBufferData() const; -}; - -} // namespace vcl - -#endif // VCL_RENDER_DRAWABLE_TRACKBALL_TRACKBALL_RENDER_DATA_H diff --git a/vclib/render/src/vclib/bgfx/drawable/drawable_trackball.cpp b/vclib/render/src/vclib/bgfx/drawable/drawable_trackball.cpp index 251e0e94f..da266e949 100644 --- a/vclib/render/src/vclib/bgfx/drawable/drawable_trackball.cpp +++ b/vclib/render/src/vclib/bgfx/drawable/drawable_trackball.cpp @@ -27,9 +27,9 @@ namespace vcl { -DrawableTrackBall::DrawableTrackBall() : TrackballRenderData(128) +DrawableTrackBall::DrawableTrackBall() { - mUniforms.setNumberOfVerticesPerAxis(128); + mUniforms.setNumberOfVerticesPerAxis(N_POINTS); createBuffers(); } @@ -81,11 +81,14 @@ void DrawableTrackBall::createBuffers() .end(); mVertexCoordBH = bgfx::createVertexBuffer( - bgfx::makeRef(vertexBufferData(), vertexNumber() * 3 * sizeof(float)), + bgfx::makeRef( + TRACKBALL_DATA.first.data(), + TRACKBALL_DATA.first.size() * 3 * sizeof(float)), layout); - mEdgeIndexBH = bgfx::createIndexBuffer( - bgfx::makeRef(edgeBufferData(), edgeNumber() * sizeof(uint16_t))); + mEdgeIndexBH = bgfx::createIndexBuffer(bgfx::makeRef( + TRACKBALL_DATA.second.data(), + TRACKBALL_DATA.second.size() * sizeof(uint16_t))); } } // namespace vcl From fb9df4998da0fecd5da837b0c7f6e40a8f2cb818 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Sat, 25 Jan 2025 14:10:13 +0100 Subject: [PATCH 20/29] [render] DrawableTrackBall just in header --- .../vclib/bgfx/drawable/drawable_trackball.h | 57 +++++++++-- .../bgfx/drawable/drawable_trackball.cpp | 94 ------------------- 2 files changed, 49 insertions(+), 102 deletions(-) delete mode 100644 vclib/render/src/vclib/bgfx/drawable/drawable_trackball.cpp diff --git a/vclib/render/include/vclib/bgfx/drawable/drawable_trackball.h b/vclib/render/include/vclib/bgfx/drawable/drawable_trackball.h index 6e023d4eb..3ce77056d 100644 --- a/vclib/render/include/vclib/bgfx/drawable/drawable_trackball.h +++ b/vclib/render/include/vclib/bgfx/drawable/drawable_trackball.h @@ -26,6 +26,7 @@ #include "uniforms/drawable_trackball_uniforms.h" #include +#include #include #include @@ -35,7 +36,7 @@ namespace vcl { class DrawableTrackBall : public DrawableObject { - inline static const uint N_POINTS = 128; + inline static const uint N_POINTS = 128; inline static const auto TRACKBALL_DATA = createTrackBall(1.0, N_POINTS); @@ -55,18 +56,41 @@ class DrawableTrackBall : public DrawableObject vcl::Matrix44f mTransform = vcl::Matrix44f::Identity(); public: - // TODO: manage copy and swap - DrawableTrackBall(); + DrawableTrackBall() + { + mUniforms.setNumberOfVerticesPerAxis(N_POINTS); + + createBuffers(); + } - ~DrawableTrackBall(); + ~DrawableTrackBall() = default; - void updateDragging(bool isDragging); + void updateDragging(bool isDragging) { mUniforms.setDragging(isDragging); } - void setTransform(const vcl::Matrix44f& mtx); + void setTransform(const vcl::Matrix44f& mtx) { mTransform = mtx; } // DrawableObject interface - void draw(uint viewId) const override; + void draw(uint viewId) const override + { + if (isVisible()) { + if (bgfx::isValid(mProgram)) { + bgfx::setState( + 0 | BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_Z | + BGFX_STATE_DEPTH_TEST_LESS | BGFX_STATE_PT_LINES | + BGFX_STATE_BLEND_NORMAL); + + bgfx::setVertexBuffer(0, mVertexCoordBH); + bgfx::setIndexBuffer(mEdgeIndexBH); + + bgfx::setTransform(mTransform.data()); + + mUniforms.bind(); + + bgfx::submit(viewId, mProgram); + } + } + } Box3d boundingBox() const override { return Box3d(); } @@ -80,7 +104,24 @@ class DrawableTrackBall : public DrawableObject void setVisibility(bool vis) override { mVisible = vis; } private: - void createBuffers(); + void createBuffers() + { + // vertex buffer + bgfx::VertexLayout layout; + layout.begin() + .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float) + .end(); + + mVertexCoordBH = bgfx::createVertexBuffer( + bgfx::makeRef( + TRACKBALL_DATA.first.data(), + TRACKBALL_DATA.first.size() * 3 * sizeof(float)), + layout); + + mEdgeIndexBH = bgfx::createIndexBuffer(bgfx::makeRef( + TRACKBALL_DATA.second.data(), + TRACKBALL_DATA.second.size() * sizeof(uint16_t))); + } }; } // namespace vcl diff --git a/vclib/render/src/vclib/bgfx/drawable/drawable_trackball.cpp b/vclib/render/src/vclib/bgfx/drawable/drawable_trackball.cpp deleted file mode 100644 index da266e949..000000000 --- a/vclib/render/src/vclib/bgfx/drawable/drawable_trackball.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/***************************************************************************** - * VCLib * - * Visual Computing Library * - * * - * Copyright(C) 2021-2025 * - * Visual Computing Lab * - * ISTI - Italian National Research Council * - * * - * All rights reserved. * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the Mozilla Public License Version 2.0 as published * - * by the Mozilla Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * Mozilla Public License Version 2.0 * - * (https://www.mozilla.org/en-US/MPL/2.0/) for more details. * - ****************************************************************************/ - -#include - -#include -#include - -namespace vcl { - -DrawableTrackBall::DrawableTrackBall() -{ - mUniforms.setNumberOfVerticesPerAxis(N_POINTS); - - createBuffers(); -} - -DrawableTrackBall::~DrawableTrackBall() -{ - if (bgfx::isValid(mVertexCoordBH)) { - bgfx::destroy(mVertexCoordBH); - } -} - -void DrawableTrackBall::updateDragging(bool isDragging) -{ - mUniforms.setDragging(isDragging); -} - -void DrawableTrackBall::setTransform(const Matrix44f& mtx) -{ - mTransform = mtx; -} - -void DrawableTrackBall::draw(uint viewId) const -{ - if (isVisible()) { - if (bgfx::isValid(mProgram)) { - bgfx::setState( - 0 | BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_Z | - BGFX_STATE_DEPTH_TEST_LESS | BGFX_STATE_PT_LINES | - BGFX_STATE_BLEND_NORMAL); - - bgfx::setVertexBuffer(0, mVertexCoordBH); - bgfx::setIndexBuffer(mEdgeIndexBH); - - bgfx::setTransform(mTransform.data()); - - mUniforms.bind(); - - bgfx::submit(viewId, mProgram); - } - } -} - -void DrawableTrackBall::createBuffers() -{ - // vertex buffer - bgfx::VertexLayout layout; - layout.begin() - .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float) - .end(); - - mVertexCoordBH = bgfx::createVertexBuffer( - bgfx::makeRef( - TRACKBALL_DATA.first.data(), - TRACKBALL_DATA.first.size() * 3 * sizeof(float)), - layout); - - mEdgeIndexBH = bgfx::createIndexBuffer(bgfx::makeRef( - TRACKBALL_DATA.second.data(), - TRACKBALL_DATA.second.size() * sizeof(uint16_t))); -} - -} // namespace vcl From aab5f24947b413097acbbe3deaec058de8e91759 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Sat, 25 Jan 2025 14:31:12 +0100 Subject: [PATCH 21/29] [render] DrawableTrackball uses VertexBuffer --- .../vclib/bgfx/drawable/drawable_trackball.h | 79 ++++++++++++++----- 1 file changed, 61 insertions(+), 18 deletions(-) diff --git a/vclib/render/include/vclib/bgfx/drawable/drawable_trackball.h b/vclib/render/include/vclib/bgfx/drawable/drawable_trackball.h index 3ce77056d..1b481844f 100644 --- a/vclib/render/include/vclib/bgfx/drawable/drawable_trackball.h +++ b/vclib/render/include/vclib/bgfx/drawable/drawable_trackball.h @@ -26,6 +26,7 @@ #include "uniforms/drawable_trackball_uniforms.h" #include +#include #include #include #include @@ -42,8 +43,8 @@ class DrawableTrackBall : public DrawableObject bool mVisible = true; - bgfx::VertexBufferHandle mVertexCoordBH = BGFX_INVALID_HANDLE; - bgfx::IndexBufferHandle mEdgeIndexBH = BGFX_INVALID_HANDLE; + VertexBuffer mVertexCoordsBuffer; + IndexBuffer mEdgeIndexBuffer; // TODO: can we be sure that this is called after the context initialization // triggered by a window? @@ -63,12 +64,58 @@ class DrawableTrackBall : public DrawableObject createBuffers(); } + DrawableTrackBall(const DrawableTrackBall& other) : + mVisible(other.mVisible), + mProgram(other.mProgram), + mUniforms(other.mUniforms), + mTransform(other.mTransform) + { + // copy all the members that can be copied, and then re-create the + // buffers + createBuffers(); + } + + // default move constructor - buffers can be moved + DrawableTrackBall(DrawableTrackBall&& other) = default; + + // default destructor - buffers are destroyed by their destructor ~DrawableTrackBall() = default; + /** + * @brief Swap the content of this object with another DrawableTrackBall + * object. + * + * @param[in] other: the other DrawableTrackBall object. + */ + void swap(DrawableTrackBall& other) + { + using std::swap; + swap(mVisible, other.mVisible); + swap(mVertexCoordsBuffer, other.mVertexCoordsBuffer); + swap(mEdgeIndexBuffer, other.mEdgeIndexBuffer); + swap(mProgram, other.mProgram); + swap(mUniforms, other.mUniforms); + swap(mTransform, other.mTransform); + } + + friend void swap(DrawableTrackBall& a, DrawableTrackBall& b) { a.swap(b); } + + /** + * @brief Update the dragging status of the trackball. + * @param[in] isDragging: true if the trackball is being dragged, false + * otherwise. + */ void updateDragging(bool isDragging) { mUniforms.setDragging(isDragging); } void setTransform(const vcl::Matrix44f& mtx) { mTransform = mtx; } + // copy and swap idiom + DrawableTrackBall& operator=(DrawableTrackBall other) + { + swap(other); + return *this; + } + // DrawableObject interface void draw(uint viewId) const override @@ -80,8 +127,8 @@ class DrawableTrackBall : public DrawableObject BGFX_STATE_DEPTH_TEST_LESS | BGFX_STATE_PT_LINES | BGFX_STATE_BLEND_NORMAL); - bgfx::setVertexBuffer(0, mVertexCoordBH); - bgfx::setIndexBuffer(mEdgeIndexBH); + mVertexCoordsBuffer.bind(0); + mEdgeIndexBuffer.bind(); bgfx::setTransform(mTransform.data()); @@ -107,20 +154,16 @@ class DrawableTrackBall : public DrawableObject void createBuffers() { // vertex buffer - bgfx::VertexLayout layout; - layout.begin() - .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float) - .end(); - - mVertexCoordBH = bgfx::createVertexBuffer( - bgfx::makeRef( - TRACKBALL_DATA.first.data(), - TRACKBALL_DATA.first.size() * 3 * sizeof(float)), - layout); - - mEdgeIndexBH = bgfx::createIndexBuffer(bgfx::makeRef( - TRACKBALL_DATA.second.data(), - TRACKBALL_DATA.second.size() * sizeof(uint16_t))); + mVertexCoordsBuffer.set( + TRACKBALL_DATA.first.data(), + TRACKBALL_DATA.first.size() * 3, + bgfx::Attrib::Position, + 3, + PrimitiveType::FLOAT); + + // edge index buffer + mEdgeIndexBuffer.set( + TRACKBALL_DATA.second.data(), TRACKBALL_DATA.second.size(), false); } }; From 1939666f231a97d9ad93835d04c0d0f226ad80f4 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Sat, 25 Jan 2025 15:16:28 +0100 Subject: [PATCH 22/29] [render] documentation for VertexBuffer and IndexBuffer classes --- .../include/vclib/bgfx/buffers/index_buffer.h | 124 +++++++++++++++++- .../vclib/bgfx/buffers/vertex_buffer.h | 121 +++++++++++++++-- 2 files changed, 231 insertions(+), 14 deletions(-) diff --git a/vclib/render/include/vclib/bgfx/buffers/index_buffer.h b/vclib/render/include/vclib/bgfx/buffers/index_buffer.h index 69165f996..5db4849ce 100644 --- a/vclib/render/include/vclib/bgfx/buffers/index_buffer.h +++ b/vclib/render/include/vclib/bgfx/buffers/index_buffer.h @@ -31,44 +31,117 @@ namespace vcl { +/** + * @brief The IndexBuffer manages the lifetime of a bgfx::IndexBufferHandle. + * + * It provides an interface to set the index buffer data and bind it to the + * rendering pipeline. The index buffer can be used for rendering or for + * compute shaders. + * + * @note An IndexBuffer can be moved but not copied (a copy would require to + * create a new bgfx::IndexBufferHandle, that can be done only having access + * to the data). Any class that contains an IndexBuffer should implement the + * copy constructor and the copy assignment operator. + */ class IndexBuffer { bgfx::IndexBufferHandle mIndexBufferHandle = BGFX_INVALID_HANDLE; + bool mCompute = false; public: + /** + * @brief Empty constructor. + * + * It creates an invalid IndexBuffer object. + */ IndexBuffer() = default; + // Copying an IndexBuffer is not allowed IndexBuffer(const IndexBuffer& other) = delete; + /** + * @brief Move constructor. + * + * The other IndexBuffer is left in an invalid state. + * + * @param[in] other: the other IndexBuffer object. + */ IndexBuffer(IndexBuffer&& other) noexcept { - mIndexBufferHandle = other.mIndexBufferHandle; - other.mIndexBufferHandle = BGFX_INVALID_HANDLE; + swap(other); } + /** + * @brief Destructor. + * + * It destroys the bgfx::IndexBufferHandle. + */ ~IndexBuffer() { if (bgfx::isValid(mIndexBufferHandle)) bgfx::destroy(mIndexBufferHandle); } + // Copying a IndexBuffer is not allowed IndexBuffer& operator=(const IndexBuffer& other) = delete; + /** + * @brief Move assignment operator. + * + * The other IndexBuffer is left in an invalid state. + * + * @param[in] other: the other IndexBuffer object. + * @return a reference to this object. + */ IndexBuffer& operator=(IndexBuffer&& other) noexcept { - mIndexBufferHandle = other.mIndexBufferHandle; - other.mIndexBufferHandle = BGFX_INVALID_HANDLE; + swap(other); return *this; } + /** + * @brief Swap the content of this object with another IndexBuffer object. + * + * @param[in] other: the other IndexBuffer object. + */ void swap(IndexBuffer& other) { using std::swap; swap(mIndexBufferHandle, other.mIndexBufferHandle); + swap(mCompute, other.mCompute); } friend void swap(IndexBuffer& a, IndexBuffer& b) { a.swap(b); } + /** + * @brief Check if the IndexBuffer is valid. + * + * @return true if the IndexBuffer is valid, false otherwise. + */ + bool isValid() const { return bgfx::isValid(mIndexBufferHandle); } + + /** + * @brief Check if the IndexBuffer is used for compute shaders. + * + * @return true if the IndexBuffer is used for compute shaders, false + * otherwise. + */ + bool isCompute() const { return mCompute; } + + /** + * @brief Set the index buffer data. + * + * @note The data must be available for two bgfx::frame calls, then it is + * safe to release the data. If you cannot guarantee this, you must provide + * a release function that will be called automatically when the data is no + * longer needed. + * + * @param[in] bufferIndices: the data to be copied in the index buffer. + * @param[in] bufferSize: the size of the bufferIndices. + * @param[in] is32Bit: if true, the bufferIndices are 32-bit integers. + * @param[in] releaseFn: the release function to be called when the data is + * no longer needed. + */ void set( const void* bufferIndices, const uint bufferSize, @@ -77,9 +150,26 @@ class IndexBuffer { uint64_t flags = is32Bit ? BGFX_BUFFER_INDEX32 : BGFX_BUFFER_NONE; uint size = is32Bit ? 4 : 2; - set(bgfx::makeRef(bufferIndices, bufferSize * size, releaseFn), flags); + set(bgfx::makeRef(bufferIndices, bufferSize * size, releaseFn), + false, + flags); } + /** + * @brief Set the index buffer data for compute shaders. + * + * @note The data must be available for two bgfx::frame calls, then it is + * safe to release the data. If you cannot guarantee this, you must provide + * a release function that will be called automatically when the data is no + * longer needed. + * + * @param[in] bufferIndices: the data to be copied in the index buffer. + * @param[in] bufferSize: the size of the bufferIndices. + * @param[in] type: the type of the elements. + * @param[in] access: the access type for the buffer. + * @param[in] releaseFn: the release function to be called when the data is + * no longer needed. + */ void setForCompute( const void* bufferIndices, const uint bufferSize, @@ -90,14 +180,36 @@ class IndexBuffer uint64_t flags = flagsForType(type); flags |= flagsForAccess(access); set(bgfx::makeRef(bufferIndices, bufferSize * sizeOf(type), releaseFn), + true, flags); } - void set(const bgfx::Memory* indices, uint64_t flags = BGFX_BUFFER_NONE) + /** + * @brief Set the index buffer data. + * + * @param[in] indices: the memory containing the data. + * @param[in] compute: if true, the buffer is used for compute shaders. + * @param[in] flags: the flags for the buffer. + */ + void set( + const bgfx::Memory* indices, + bool compute = false, + uint64_t flags = BGFX_BUFFER_NONE) { mIndexBufferHandle = bgfx::createIndexBuffer(indices, flags); + mCompute = compute; } + /** + * @brief Bind the index buffer to the rendering pipeline. + * + * If the stage is not specified, the index buffer is bound to the rendering + * pipeline. Otherwise, it is bound to the compute shader with the specified + * stage and the given access type (Read, Write, ReadWrite). + * + * @param[in] stage: the stage to which the buffer is bound. + * @param[in] access: the access type for the buffer. + */ void bind( uint stage = UINT_NULL, bgfx::Access::Enum access = bgfx::Access::Read) const diff --git a/vclib/render/include/vclib/bgfx/buffers/vertex_buffer.h b/vclib/render/include/vclib/bgfx/buffers/vertex_buffer.h index f04ab2116..1df93b9b9 100644 --- a/vclib/render/include/vclib/bgfx/buffers/vertex_buffer.h +++ b/vclib/render/include/vclib/bgfx/buffers/vertex_buffer.h @@ -31,39 +31,79 @@ namespace vcl { +/** + * @brief The VertexBuffer manages the lifetime of a bgfx::VertexBufferHandle. + * + * It provides an interface to set the vertex buffer data and bind it to the + * rendering pipeline. The vertex buffer can be used for rendering or for + * compute shaders. + * + * @note A VertexBuffer can be moved but not copied (a copy would require to + * create a new bgfx::VertexBufferHandle, that can be done only having access + * to the data). Any class that contains a VertexBuffer should implement the + * copy constructor and the copy assignment operator. + */ class VertexBuffer { bgfx::VertexBufferHandle mVertexBufferHandle = BGFX_INVALID_HANDLE; bool mCompute = false; public: + /** + * @brief Empty constructor. + * + * It creates an invalid VertexBuffer object. + */ VertexBuffer() = default; + // Copying a VertexBuffer is not allowed VertexBuffer(const VertexBuffer& other) = delete; + /** + * @brief Move constructor. + * + * The other VertexBuffer is left in an invalid state. + * + * @param[in] other: the other VertexBuffer object. + */ VertexBuffer(VertexBuffer&& other) noexcept { - mVertexBufferHandle = other.mVertexBufferHandle; - mCompute = other.mCompute; - other.mVertexBufferHandle = BGFX_INVALID_HANDLE; + swap(other); } + /** + * @brief Destructor. + * + * If the VertexBuffer is valid, the bgfx::VertexBufferHandle is destroyed. + */ ~VertexBuffer() { if (bgfx::isValid(mVertexBufferHandle)) bgfx::destroy(mVertexBufferHandle); } + // Copying a VertexBuffer is not allowed VertexBuffer& operator=(const VertexBuffer& other) = delete; + /** + * @brief Move assignment operator. + * + * The other VertexBuffer is left in an invalid state. + * + * @param[in] other: the other VertexBuffer object. + * @return a reference to this object. + */ VertexBuffer& operator=(VertexBuffer&& other) noexcept { - mVertexBufferHandle = other.mVertexBufferHandle; - mCompute = other.mCompute; - other.mVertexBufferHandle = BGFX_INVALID_HANDLE; + swap(other); return *this; } + /** + * @brief Swap the content of this object with another VertexBuffer object. + * + * @param[in] other: the other VertexBuffer object. + */ void swap(VertexBuffer& other) { using std::swap; @@ -73,6 +113,38 @@ class VertexBuffer friend void swap(VertexBuffer& a, VertexBuffer& b) { a.swap(b); } + /** + * @brief Check if the VertexBuffer is valid. + * + * @return true if the VertexBuffer is valid, false otherwise. + */ + bool isValid() const { return bgfx::isValid(mVertexBufferHandle); } + + /** + * @brief Check if the VertexBuffer is used for compute shaders. + * + * @return true if the VertexBuffer is used for compute shaders, false + * otherwise. + */ + bool isCompute() const { return mCompute; } + + /** + * @brief Set the vertex buffer data for rendering. + * + * @note The data must be available for two bgfx::frame calls, then it is + * safe to release the data. If you cannot guarantee this, you must provide + * a release function that will be called automatically when the data is no + * longer needed. + * + * @param[in] bufferData: the data to be copied in the vertex buffer. + * @param[in] bufferSize: the size of the bufferData. + * @param[in] attrib: the attribute to which the data refers. + * @param[in] numElements: the number of elements for each vertex. + * @param[in] type: the type of the elements. + * @param[in] normalize: if true, the data is normalized. + * @param[in] releaseFn: the release function to be called when the data is + * no longer needed. + */ void set( const void* bufferData, const uint bufferSize, @@ -92,6 +164,24 @@ class VertexBuffer releaseFn)); } + /** + * @brief Set the vertex buffer data for compute shaders. + * + * @note The data must be available for two bgfx::frame calls, then it is + * safe to release the data. If you cannot guarantee this, you must provide + * a release function that will be called automatically when the data is no + * longer needed. + * + * @param[in] bufferData: the data to be copied in the vertex buffer. + * @param[in] bufferSize: the size of the bufferData. + * @param[in] attrib: the attribute to which the data refers. + * @param[in] numElements: the number of elements for each vertex. + * @param[in] type: the type of the elements. + * @param[in] normalize: if true, the data is normalized. + * @param[in] access: the access type for the buffer. + * @param[in] releaseFn: the release function to be called when the data is + * no longer needed. + */ void setForCompute( const void* bufferData, const uint bufferSize, @@ -116,19 +206,34 @@ class VertexBuffer flags); } + /** + * @brief Set the vertex buffer data. + * + * @param[in] layout: the vertex layout. + * @param[in] data: the memory containing the data. + * @param[in] compute: if true, the buffer is used for compute shaders. + * @param[in] flags: the flags for the buffer. + */ void set( const bgfx::VertexLayout& layout, - const bgfx::Memory* vertices, + const bgfx::Memory* data, bool compute = false, uint64_t flags = BGFX_BUFFER_NONE) { if (bgfx::isValid(mVertexBufferHandle)) bgfx::destroy(mVertexBufferHandle); - mVertexBufferHandle = bgfx::createVertexBuffer(vertices, layout, flags); + mVertexBufferHandle = bgfx::createVertexBuffer(data, layout, flags); mCompute = compute; } + /** + * @brief Bind the vertex buffer to the rendering pipeline. + * + * @param[in] stream: the stream (or stage, in case of compute) to which the + * vertex buffer is bound. + * @param[in] access: the access type for the buffer (only for compute). + */ void bind(uint stream, bgfx::Access::Enum access = bgfx::Access::Read) const { if (bgfx::isValid(mVertexBufferHandle)) { From eb8721e7ad729e46c9f884d349d149830097b0a9 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Sun, 26 Jan 2025 01:14:20 +0000 Subject: [PATCH 23/29] [clang-format] Committing clang-format changes --- .../include/vclib/bgfx/buffers/index_buffer.h | 21 +++++++-------- .../vclib/bgfx/buffers/vertex_buffer.h | 27 ++++++++----------- .../vclib/bgfx/drawable/drawable_trackball.h | 8 +++--- .../bgfx/drawable/mesh/mesh_render_buffers.h | 15 ++++------- 4 files changed, 28 insertions(+), 43 deletions(-) diff --git a/vclib/render/include/vclib/bgfx/buffers/index_buffer.h b/vclib/render/include/vclib/bgfx/buffers/index_buffer.h index 5db4849ce..64b242dd6 100644 --- a/vclib/render/include/vclib/bgfx/buffers/index_buffer.h +++ b/vclib/render/include/vclib/bgfx/buffers/index_buffer.h @@ -46,7 +46,7 @@ namespace vcl { class IndexBuffer { bgfx::IndexBufferHandle mIndexBufferHandle = BGFX_INVALID_HANDLE; - bool mCompute = false; + bool mCompute = false; public: /** @@ -66,10 +66,7 @@ class IndexBuffer * * @param[in] other: the other IndexBuffer object. */ - IndexBuffer(IndexBuffer&& other) noexcept - { - swap(other); - } + IndexBuffer(IndexBuffer&& other) noexcept { swap(other); } /** * @brief Destructor. @@ -149,7 +146,7 @@ class IndexBuffer bgfx::ReleaseFn releaseFn = nullptr) { uint64_t flags = is32Bit ? BGFX_BUFFER_INDEX32 : BGFX_BUFFER_NONE; - uint size = is32Bit ? 4 : 2; + uint size = is32Bit ? 4 : 2; set(bgfx::makeRef(bufferIndices, bufferSize * size, releaseFn), false, flags); @@ -171,11 +168,11 @@ class IndexBuffer * no longer needed. */ void setForCompute( - const void* bufferIndices, - const uint bufferSize, - PrimitiveType type, - bgfx::Access::Enum access = bgfx::Access::Read, - bgfx::ReleaseFn releaseFn = nullptr) + const void* bufferIndices, + const uint bufferSize, + PrimitiveType type, + bgfx::Access::Enum access = bgfx::Access::Read, + bgfx::ReleaseFn releaseFn = nullptr) { uint64_t flags = flagsForType(type); flags |= flagsForAccess(access); @@ -197,7 +194,7 @@ class IndexBuffer uint64_t flags = BGFX_BUFFER_NONE) { mIndexBufferHandle = bgfx::createIndexBuffer(indices, flags); - mCompute = compute; + mCompute = compute; } /** diff --git a/vclib/render/include/vclib/bgfx/buffers/vertex_buffer.h b/vclib/render/include/vclib/bgfx/buffers/vertex_buffer.h index 1df93b9b9..051c959ac 100644 --- a/vclib/render/include/vclib/bgfx/buffers/vertex_buffer.h +++ b/vclib/render/include/vclib/bgfx/buffers/vertex_buffer.h @@ -46,7 +46,7 @@ namespace vcl { class VertexBuffer { bgfx::VertexBufferHandle mVertexBufferHandle = BGFX_INVALID_HANDLE; - bool mCompute = false; + bool mCompute = false; public: /** @@ -66,10 +66,7 @@ class VertexBuffer * * @param[in] other: the other VertexBuffer object. */ - VertexBuffer(VertexBuffer&& other) noexcept - { - swap(other); - } + VertexBuffer(VertexBuffer&& other) noexcept { swap(other); } /** * @brief Destructor. @@ -155,13 +152,12 @@ class VertexBuffer bgfx::ReleaseFn releaseFn = nullptr) { bgfx::VertexLayout layout; - layout.begin().add(attrib, numElements, attribType(type), normalize).end(); + layout.begin() + .add(attrib, numElements, attribType(type), normalize) + .end(); set(layout, - bgfx::makeRef( - bufferData, - bufferSize * sizeOf(type), - releaseFn)); + bgfx::makeRef(bufferData, bufferSize * sizeOf(type), releaseFn)); } /** @@ -200,8 +196,7 @@ class VertexBuffer .end(); set(layout, - bgfx::makeRef( - bufferData, bufferSize * sizeOf(type), releaseFn), + bgfx::makeRef(bufferData, bufferSize * sizeOf(type), releaseFn), true, flags); } @@ -216,15 +211,15 @@ class VertexBuffer */ void set( const bgfx::VertexLayout& layout, - const bgfx::Memory* data, - bool compute = false, - uint64_t flags = BGFX_BUFFER_NONE) + const bgfx::Memory* data, + bool compute = false, + uint64_t flags = BGFX_BUFFER_NONE) { if (bgfx::isValid(mVertexBufferHandle)) bgfx::destroy(mVertexBufferHandle); mVertexBufferHandle = bgfx::createVertexBuffer(data, layout, flags); - mCompute = compute; + mCompute = compute; } /** diff --git a/vclib/render/include/vclib/bgfx/drawable/drawable_trackball.h b/vclib/render/include/vclib/bgfx/drawable/drawable_trackball.h index 1b481844f..792d16767 100644 --- a/vclib/render/include/vclib/bgfx/drawable/drawable_trackball.h +++ b/vclib/render/include/vclib/bgfx/drawable/drawable_trackball.h @@ -44,7 +44,7 @@ class DrawableTrackBall : public DrawableObject bool mVisible = true; VertexBuffer mVertexCoordsBuffer; - IndexBuffer mEdgeIndexBuffer; + IndexBuffer mEdgeIndexBuffer; // TODO: can we be sure that this is called after the context initialization // triggered by a window? @@ -65,10 +65,8 @@ class DrawableTrackBall : public DrawableObject } DrawableTrackBall(const DrawableTrackBall& other) : - mVisible(other.mVisible), - mProgram(other.mProgram), - mUniforms(other.mUniforms), - mTransform(other.mTransform) + mVisible(other.mVisible), mProgram(other.mProgram), + mUniforms(other.mUniforms), mTransform(other.mTransform) { // copy all the members that can be copied, and then re-create the // buffers diff --git a/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h b/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h index 01871f034..2c910ed25 100644 --- a/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h +++ b/vclib/render/include/vclib/bgfx/drawable/mesh/mesh_render_buffers.h @@ -135,11 +135,9 @@ class MeshRenderBuffers : public vcl::MeshRenderData if (indexBufferToBind == Base::TRIANGLES) { mTriangleIndexBuffer.bind(); - mTriangleNormalBuffer.bind( - VCL_MRB_PRIMITIVE_NORMAL_BUFFER); + mTriangleNormalBuffer.bind(VCL_MRB_PRIMITIVE_NORMAL_BUFFER); - mTriangleColorBuffer.bind( - VCL_MRB_PRIMITIVE_COLOR_BUFFER); + mTriangleColorBuffer.bind(VCL_MRB_PRIMITIVE_COLOR_BUFFER); mTriangleTextureIndexBuffer.bind( VCL_MRB_TRIANGLE_TEXTURE_ID_BUFFER); @@ -147,11 +145,9 @@ class MeshRenderBuffers : public vcl::MeshRenderData else if (indexBufferToBind == Base::EDGES) { mEdgeIndexBuffer.bind(); - mEdgeNormalBuffer.bind( - VCL_MRB_PRIMITIVE_NORMAL_BUFFER); + mEdgeNormalBuffer.bind(VCL_MRB_PRIMITIVE_NORMAL_BUFFER); - mEdgeColorBuffer.bind( - VCL_MRB_PRIMITIVE_COLOR_BUFFER); + mEdgeColorBuffer.bind(VCL_MRB_PRIMITIVE_COLOR_BUFFER); } else if (indexBufferToBind == Base::WIREFRAME) { bgfx::setIndexBuffer(mWireframeIndexBH); @@ -221,8 +217,7 @@ class MeshRenderBuffers : public vcl::MeshRenderData // triangle index buffer if (Base::triangleBufferData()) { mTriangleIndexBuffer.set( - Base::triangleBufferData(), - Base::triangleBufferSize()); + Base::triangleBufferData(), Base::triangleBufferSize()); } // triangle normal buffer From d6baab533152f579ee301f2b07a061f57c55f01f Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Sun, 26 Jan 2025 10:21:28 +0100 Subject: [PATCH 24/29] [mesh] wedge texture index is stored in a ushort (was short) --- .../vclib/concepts/mesh/components/wedge_tex_coords.h | 4 ++-- .../include/vclib/mesh/components/wedge_tex_coords.h | 10 +++++----- vclib/core/include/vclib/types/base.h | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/vclib/core/include/vclib/concepts/mesh/components/wedge_tex_coords.h b/vclib/core/include/vclib/concepts/mesh/components/wedge_tex_coords.h index 59bec8ebf..9b1d59efc 100644 --- a/vclib/core/include/vclib/concepts/mesh/components/wedge_tex_coords.h +++ b/vclib/core/include/vclib/concepts/mesh/components/wedge_tex_coords.h @@ -61,7 +61,7 @@ concept HasWedgeTexCoords = requires ( { obj.wedgeTexCoord(uint()) } -> TexCoordConcept; { obj.wedgeTexCoordMod(int()) } -> TexCoordConcept; - { obj.textureIndex() } -> std::convertible_to; + { obj.textureIndex() } -> std::convertible_to; { obj.wedgeTexCoordBegin() } -> InputIterator; { obj.wedgeTexCoordEnd() } -> InputIterator; @@ -73,7 +73,7 @@ concept HasWedgeTexCoords = requires ( { obj.setWedgeTexCoord(uint(), t) } -> std::same_as; { obj.setWedgeTexCoords(vec) } -> std::same_as; - { obj.textureIndex() } -> std::same_as; + { obj.textureIndex() } -> std::same_as; { obj.wedgeTexCoordBegin() } -> OutputIterator; { obj.wedgeTexCoordEnd() } -> OutputIterator; diff --git a/vclib/core/include/vclib/mesh/components/wedge_tex_coords.h b/vclib/core/include/vclib/mesh/components/wedge_tex_coords.h index 1c542fd25..4930e8af0 100644 --- a/vclib/core/include/vclib/mesh/components/wedge_tex_coords.h +++ b/vclib/core/include/vclib/mesh/components/wedge_tex_coords.h @@ -52,7 +52,7 @@ namespace vcl::comp { * * @code{.cpp} * auto t = f.wedgeTexCoord(0); - * short tid = f.textureIndex(); + * ushort tid = f.textureIndex(); * @endcode * * @note This component is *Tied To Vertex Number*: it means that the size of @@ -85,7 +85,7 @@ class WedgeTexCoords : CompId::WEDGE_TEX_COORDS, vcl::TexCoord, N, - short, + ushort, ParentElemType, !std::is_same_v, OPT, @@ -96,7 +96,7 @@ class WedgeTexCoords : CompId::WEDGE_TEX_COORDS, vcl::TexCoord, N, - short, + ushort, ParentElemType, !std::is_same_v, OPT, @@ -225,7 +225,7 @@ class WedgeTexCoords : * * @return A reference to the texture index. */ - short& textureIndex() { return Base::additionalData(); } + ushort& textureIndex() { return Base::additionalData(); } /** * @brief Returns the texture index used to identify the texture on which @@ -233,7 +233,7 @@ class WedgeTexCoords : * * @return The texture index. */ - short textureIndex() const { return Base::additionalData(); } + ushort textureIndex() const { return Base::additionalData(); } /* Iterator Member functions */ diff --git a/vclib/core/include/vclib/types/base.h b/vclib/core/include/vclib/types/base.h index 21832d8d0..6337a3ff3 100644 --- a/vclib/core/include/vclib/types/base.h +++ b/vclib/core/include/vclib/types/base.h @@ -32,8 +32,8 @@ namespace vcl { // Define some basic types, for convenience -using uint = unsigned int; -using ushort = unsigned short; +using uint = uint32_t; +using ushort = uint16_t; /** * @brief The UINT_NULL value represent a null value of uint that is the maximum From ef5b58764e3b1e99c07b17a5703f364bff640ad0 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Sun, 26 Jan 2025 11:12:45 +0100 Subject: [PATCH 25/29] [space] TexCoord inherits from Point2 --- .../core/include/vclib/space/core/tex_coord.h | 74 +++++++------------ 1 file changed, 27 insertions(+), 47 deletions(-) diff --git a/vclib/core/include/vclib/space/core/tex_coord.h b/vclib/core/include/vclib/space/core/tex_coord.h index bd71b648d..f02e2da82 100644 --- a/vclib/core/include/vclib/space/core/tex_coord.h +++ b/vclib/core/include/vclib/space/core/tex_coord.h @@ -27,54 +27,49 @@ namespace vcl { +/** + * @brief The TexCoord class represents a 2-dimensional texture coordinate + * containing two scalar values. + * + * The TexCoord class template represents a 2-dimensional texture coordinate + * containing two scalar values. The scalar type of the texture coordinates is a + * template parameter of the class. + * + * The class is a specialization of the Point2 class template, where the two + * components of the texture coordinate are named `u` and `v`. The class adds + * setter member functions for setting the `u` and `v` components of the texture + * coordinate, with an additional assert that the values are in the range [0, + * 1]. + * + * @tparam Scalar: The scalar type of the texture coordinate components. + * + * @ingroup space_core + */ template -class TexCoord +class TexCoord : public Point2 { - template - friend class TexCoord; - - Point2 mCoord; - + using Base = Point2; public: - using ScalarType = Scalar; - - TexCoord() = default; - - TexCoord(const Scalar& s1, const Scalar& s2) : mCoord(s1, s2) {} - - TexCoord(const Point2& p) : mCoord(p) {} - - template - auto cast() const - { - if constexpr (std::is_same::value) { - return *this; - } - else { - TexCoord tmp; - tmp.mCoord = mCoord.template cast(); - return tmp; - } - } + using Base::Base; - Scalar u() const { return mCoord.x(); } + Scalar u() const { return Base::x(); } - Scalar v() const { return mCoord.y(); } + Scalar v() const { return Base::y(); } - Scalar& u() { return mCoord.x(); } + Scalar& u() { return Base::x(); } - Scalar& v() { return mCoord.y(); } + Scalar& v() { return Base::y(); } void setU(Scalar s) { assert(s >= 0 && s <= 1); - mCoord.x() = s; + Base::x() = s; } void setV(Scalar s) { assert(s >= 0 && s <= 1); - mCoord.y() = s; + Base::y() = s; } void set(Scalar u, Scalar v) @@ -82,21 +77,6 @@ class TexCoord setU(u); setV(v); } - - void serialize(std::ostream& os) const { mCoord.serialize(os); } - - void deserialize(std::istream& is) { mCoord.deserialize(is); } - - // operators - Scalar& operator()(uint i) { return mCoord[i]; } - - const Scalar& operator()(uint i) const { return mCoord[i]; } - - Scalar& operator[](uint i) { return mCoord[i]; } - - const Scalar& operator[](uint i) const { return mCoord[i]; } - - bool operator==(const TexCoord& t1) const = default; }; /* Specialization Aliases */ From 62838cc81ba68bbe97f2f1c1bc0095d772023475 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Sun, 26 Jan 2025 16:00:04 +0100 Subject: [PATCH 26/29] [algorithms] countVerticesToDuplicateByWedgeTexCoords function --- assets/example_meshes/cube_textured.ply | 33 ++++ tests/core/002-mesh-topology/main.cpp | 27 ++++ .../vclib/algorithms/mesh/stat/topology.h | 146 ++++++++++++++++++ 3 files changed, 206 insertions(+) create mode 100644 assets/example_meshes/cube_textured.ply diff --git a/assets/example_meshes/cube_textured.ply b/assets/example_meshes/cube_textured.ply new file mode 100644 index 000000000..64c67da56 --- /dev/null +++ b/assets/example_meshes/cube_textured.ply @@ -0,0 +1,33 @@ +ply +format ascii 1.0 +comment TextureFile TextureDouble_A.png +comment TextureFile TextureDouble_B.png +element vertex 8 +property float x +property float y +property float z +element face 12 +property list uchar int vertex_indices +property list uchar float texcoord +property int texnumber +end_header +0 0 0 +1 0 0 +0 1 0 +1 1 0 +0 0 1 +1 0 1 +0 1 1 +1 1 1 +3 2 1 0 6 0.5 1 0 0.5 0.5 0.5 1 +3 1 2 3 6 0 0.5 0.5 1 0 1 1 +3 4 2 0 6 0.5 0 1 0.5 0.5 0.5 1 +3 2 4 6 6 1 0.5 0.5 0 1 0 1 +3 1 4 0 6 0 0.5 0.5 0 0.5 0.5 1 +3 4 1 5 6 0.5 0 0 0.5 0 0 1 +3 6 5 7 6 0 0.5 0.5 0 0.5 0.5 0 +3 5 6 4 6 0.5 0 0 0.5 0 0 0 +3 3 6 7 6 0.5 1 0 0.5 0.5 0.5 0 +3 6 3 2 6 0 0.5 0.5 1 0 1 0 +3 5 3 7 6 0.5 0 1 0.5 0.5 0.5 0 +3 3 5 1 6 1 0.5 0.5 0 1 0 0 diff --git a/tests/core/002-mesh-topology/main.cpp b/tests/core/002-mesh-topology/main.cpp index 4e9998f15..3b9886712 100644 --- a/tests/core/002-mesh-topology/main.cpp +++ b/tests/core/002-mesh-topology/main.cpp @@ -746,3 +746,30 @@ TEMPLATE_TEST_CASE( REQUIRE(pm.face(5).adjFace(3) == &pm.face(3)); } } + +TEMPLATE_TEST_CASE( + "Wedge Driven Vertex Duplication", + "", + vcl::TriMesh, + vcl::TriMeshf, + vcl::TriMeshIndexed, + vcl::TriMeshIndexedf) +{ + using TriMesh = TestType; + + TriMesh tm1 = + vcl::loadPly(VCLIB_EXAMPLE_MESHES_PATH "/TextureDouble.ply"); + + THEN("Test the number of vertices to duplicate") + { + REQUIRE(vcl::countVerticesToDuplicateByWedgeTexCoords(tm1) == 0); + } + + TriMesh tm2 = + vcl::loadPly(VCLIB_EXAMPLE_MESHES_PATH "/cube_textured.ply"); + + THEN("Test the number of vertices to duplicate") + { + REQUIRE(vcl::countVerticesToDuplicateByWedgeTexCoords(tm2) == 8); + } +} diff --git a/vclib/core/include/vclib/algorithms/mesh/stat/topology.h b/vclib/core/include/vclib/algorithms/mesh/stat/topology.h index 2bc5b28d1..df9de5246 100644 --- a/vclib/core/include/vclib/algorithms/mesh/stat/topology.h +++ b/vclib/core/include/vclib/algorithms/mesh/stat/topology.h @@ -24,6 +24,9 @@ #define VCL_ALGORITHMS_MESH_STAT_TOPOLOGY_H #include +#include + +#include namespace vcl { @@ -68,6 +71,25 @@ void setReferencedVertices( (setReferencedVertices(mesh, refs, nRefs), ...); } +// struct to store the information of the wedge texcoords +template +struct WedgeTexCoordsInfo { + WedgeTexCoordType texCoord; + ushort texCoordIndex; + + bool operator<(const WedgeTexCoordsInfo& other) const + { + if (texCoordIndex == other.texCoordIndex) { + return texCoord < other.texCoord; + } + return texCoordIndex < other.texCoordIndex; + } +}; + +static inline std::list dummyUintList; +static inline std::list>> dummyListOfLists; +static inline std::vector> dummyVectorOfPairs; + } // namespace detail /** @@ -204,6 +226,130 @@ Container referencedVertices( return refVertices; } +/** + * @brief This function counts the number of vertices that must be duplicated in + * a mesh to have a unique texcoord per vertex, by checking the texcoords of the + * wedges of the mesh faces. + * + * The function returns the number of vertices that must be duplicated (i.e., + * added to the mesh) to have a unique texcoord per vertex. The function also + * returns a vector that tells, for each vertex, the pair face/wedge index in + * the face that must be kept for the vertex, the list of vertices to duplicate, + * and the list of faces that must be reassigned to the duplicated vertices. + * + * @param[in] mesh: The input mesh. It must satisfy the FaceMeshConcept and must + * have per-face wedge texcoords. + * @param[out] vertWedgeMap: A vector that tells, for each vertex, the pair + * face/wedge index in the face that must be kept for the vertex (it allows to + * index the texcoords of the vertex). + * @param[out] vertsToDuplicate: a list of vertices that must be duplicated + * (each element of the list is the index of the vertex to duplicate). + * @param[out] facesToReassign: a list of lists of pairs face/wedge index in the + * face that must be reassigned to the duplicated vertices (each list of pairs + * is the list of faces that must be reassigned to the corresponding duplicated + * vertex). The list contains a list for each vertex to duplicate. + * @return The number of vertices that must be duplicated. + */ +template +uint countVerticesToDuplicateByWedgeTexCoords( + const MeshType& mesh, + std::vector> vertWedgeMap = + detail::dummyVectorOfPairs, + std::list& vertsToDuplicate = detail::dummyUintList, + std::list>>& facesToReassign = + detail::dummyListOfLists) +{ + vcl::requirePerFaceWedgeTexCoords(mesh); + + using WedgeTexCoordType = MeshType::FaceType::WedgeTexCoordType; + using WedgeTexCoordsInfo = detail::WedgeTexCoordsInfo; + + // list of faces that reference a wedge texcoord, with the index of the + // vertex in the face + using FaceList = std::list>; + + vertWedgeMap.resize(mesh.vertexContainerSize()); + vertsToDuplicate.clear(); + facesToReassign.clear(); + + uint count = 0; + + // for each vertex, I'll store a map of WedgeTexCoordsInfo + // each element of the map represent a unique wedge texcoord(the texcoord + // itself and the index of the texcoord), and for each element it maps a + // list of faces that reference the texcoord + std::vector> wedges( + mesh.vertexContainerSize()); + + for(const auto& f : mesh.faces()) { + for(uint i = 0; i < f.vertexNumber(); ++i) { + uint vi = f.vertexIndex(i); + + // check if the i-th wedge texcoord of the face already exists + WedgeTexCoordsInfo wi = {f.wedgeTexCoord(i), f.textureIndex()}; + auto it = wedges[vi].find(wi); + if(it == wedges[vi].end()) { // if it doesn't exist, add it + // if there was already a texcoord for the vertex, it means that + // the vertex will be duplicated + if (!wedges[vi].empty()) { + count++; + } + wedges[vi][wi].emplace_back(f.index(), i); + } + else { + // if it exists, add the face to the list of faces that + // reference the texcoord + it->second.emplace_back(f.index(), i); + } + } + } + + // for each vertex, check if there are multiple texcoords + // note: here we will modify the maps for convenience: at the end of this + // loop, the info will be contained in the two lists vertsToDuplicate and + // facesToReassign (the wedges vector of map will be inconsistent) + for (uint vi = 0; auto& map : wedges) { + if (map.size() > 1) { + // there are multiple texcoords for the vertex vi, so it will be + // duplicated + + // remove from the map the element having the higher number of + // faces referencing the texcoord (we do this to reassign the less + // number of faces) + auto it = std::max_element( + map.begin(), + map.end(), + [](const auto& a, const auto& b) { + return a.second.size() < b.second.size(); + }); + // store the reference of the texcoord to keep (pair face/vertex + // index in the face) + vertWedgeMap[vi] = it->second.front(); + map.erase(it); + + // store the vertex to duplicate, and the faces to reassign + for (auto& [wi, fl] : map) { + vertsToDuplicate.push_back(vi); + facesToReassign.push_back(std::move(fl)); + } + + } + else { + if (map.size() == 1) { + // there is only one texcoord for the vertex vi, so store its + // reference (pair face/vertex index in the face) + vertWedgeMap[vi] = map.begin()->second.front(); + } + else { // the vertex was unreferenced + vertWedgeMap[vi] = {UINT_NULL, UINT_NULL}; + } + } + ++vi; + } + + return count; +} + } // namespace vcl #endif // VCL_ALGORITHMS_MESH_STAT_TOPOLOGY_H From bc63f8df241b27e230090fee471dcb87f0c7efd9 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Sun, 26 Jan 2025 16:10:55 +0100 Subject: [PATCH 27/29] [space] TexCoord inherits Point operators --- vclib/core/include/vclib/concepts/space/point.h | 12 +++++++----- vclib/core/include/vclib/space/core/point.h | 3 ++- vclib/core/include/vclib/space/core/tex_coord.h | 10 ++++++++++ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/vclib/core/include/vclib/concepts/space/point.h b/vclib/core/include/vclib/concepts/space/point.h index cf6e8f7fb..3d0575c7f 100644 --- a/vclib/core/include/vclib/concepts/space/point.h +++ b/vclib/core/include/vclib/concepts/space/point.h @@ -38,12 +38,14 @@ namespace vcl { */ template concept PointConcept = requires ( - T&& obj, - typename RemoveRef::ScalarType s, - typename RemoveRef::ScalarType& sR, - typename RemoveRef::Base& baseObjR) { + T&& obj, + typename RemoveRef::ScalarType s, + typename RemoveRef::ScalarType& sR, + typename RemoveRef::BaseMatrixType& baseObjR) { + // inner types typename RemoveRef::ScalarType; - typename RemoveRef::Base; + typename RemoveRef::BaseMatrixType; + obj.DIM; RemoveRef(); diff --git a/vclib/core/include/vclib/space/core/point.h b/vclib/core/include/vclib/space/core/point.h index d8dcd4b14..df305f395 100644 --- a/vclib/core/include/vclib/space/core/point.h +++ b/vclib/core/include/vclib/space/core/point.h @@ -56,8 +56,9 @@ namespace vcl { template class Point : public Eigen::Matrix { -public: using Base = Eigen::Matrix; +public: + using BaseMatrixType = Base; // inherit Base operators using Base::operator+; diff --git a/vclib/core/include/vclib/space/core/tex_coord.h b/vclib/core/include/vclib/space/core/tex_coord.h index f02e2da82..c3cf5f454 100644 --- a/vclib/core/include/vclib/space/core/tex_coord.h +++ b/vclib/core/include/vclib/space/core/tex_coord.h @@ -52,6 +52,16 @@ class TexCoord : public Point2 public: using Base::Base; + // inherit Base operators + using Base::operator+; + using Base::operator-; + using Base::operator*; + using Base::operator/; + using Base::operator+=; + using Base::operator-=; + using Base::operator*=; + using Base::operator/=; + Scalar u() const { return Base::x(); } Scalar v() const { return Base::y(); } From 8616f9b9860915d0cce107693c9e80482648b002 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Sun, 26 Jan 2025 16:21:45 +0100 Subject: [PATCH 28/29] Revert "[space] TexCoord inherits from Point2" This reverts commit ef5b58764e3b1e99c07b17a5703f364bff640ad0. --- .../include/vclib/concepts/space/tex_coord.h | 2 +- .../core/include/vclib/space/core/tex_coord.h | 65 ++++++++++++++----- 2 files changed, 48 insertions(+), 19 deletions(-) diff --git a/vclib/core/include/vclib/concepts/space/tex_coord.h b/vclib/core/include/vclib/concepts/space/tex_coord.h index 763dc3b7f..a3ad425ed 100644 --- a/vclib/core/include/vclib/concepts/space/tex_coord.h +++ b/vclib/core/include/vclib/concepts/space/tex_coord.h @@ -46,7 +46,7 @@ concept TexCoordConcept = requires ( { obj.u() } -> std::convertible_to; { obj.v() } -> std::convertible_to; - { obj == obj } -> std::same_as; + { obj <=> obj } -> std::convertible_to; { obj(uint()) } -> std::convertible_to; { obj[uint()] } -> std::convertible_to; diff --git a/vclib/core/include/vclib/space/core/tex_coord.h b/vclib/core/include/vclib/space/core/tex_coord.h index c3cf5f454..c4907a65a 100644 --- a/vclib/core/include/vclib/space/core/tex_coord.h +++ b/vclib/core/include/vclib/space/core/tex_coord.h @@ -45,41 +45,55 @@ namespace vcl { * * @ingroup space_core */ +// TODO: TexCoord should inherit from Point2 template -class TexCoord : public Point2 +class TexCoord { - using Base = Point2; + template + friend class TexCoord; + + Point2 mCoord; + public: - using Base::Base; + using ScalarType = Scalar; + + TexCoord() = default; + + TexCoord(const Scalar& s1, const Scalar& s2) : mCoord(s1, s2) {} - // inherit Base operators - using Base::operator+; - using Base::operator-; - using Base::operator*; - using Base::operator/; - using Base::operator+=; - using Base::operator-=; - using Base::operator*=; - using Base::operator/=; + TexCoord(const Point2& p) : mCoord(p) {} + + template + auto cast() const + { + if constexpr (std::is_same::value) { + return *this; + } + else { + TexCoord tmp; + tmp.mCoord = mCoord.template cast(); + return tmp; + } + } - Scalar u() const { return Base::x(); } + Scalar u() const { return mCoord.x(); } - Scalar v() const { return Base::y(); } + Scalar v() const { return mCoord.y(); } - Scalar& u() { return Base::x(); } + Scalar& u() { return mCoord.x(); } - Scalar& v() { return Base::y(); } + Scalar& v() { return mCoord.y(); } void setU(Scalar s) { assert(s >= 0 && s <= 1); - Base::x() = s; + mCoord.x() = s; } void setV(Scalar s) { assert(s >= 0 && s <= 1); - Base::y() = s; + mCoord.y() = s; } void set(Scalar u, Scalar v) @@ -87,6 +101,21 @@ class TexCoord : public Point2 setU(u); setV(v); } + + void serialize(std::ostream& os) const { mCoord.serialize(os); } + + void deserialize(std::istream& is) { mCoord.deserialize(is); } + + // operators + Scalar& operator()(uint i) { return mCoord[i]; } + + const Scalar& operator()(uint i) const { return mCoord[i]; } + + Scalar& operator[](uint i) { return mCoord[i]; } + + const Scalar& operator[](uint i) const { return mCoord[i]; } + + auto operator<=>(const TexCoord& t1) const = default; }; /* Specialization Aliases */ From 7c1415f6f7fde81302424b1db7441b2e60303a08 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Mon, 27 Jan 2025 01:13:19 +0000 Subject: [PATCH 29/29] [clang-format] Committing clang-format changes --- .../vclib/algorithms/mesh/stat/topology.h | 24 +++++++++---------- vclib/core/include/vclib/space/core/point.h | 1 + 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/vclib/core/include/vclib/algorithms/mesh/stat/topology.h b/vclib/core/include/vclib/algorithms/mesh/stat/topology.h index df9de5246..1724563fb 100644 --- a/vclib/core/include/vclib/algorithms/mesh/stat/topology.h +++ b/vclib/core/include/vclib/algorithms/mesh/stat/topology.h @@ -73,9 +73,10 @@ void setReferencedVertices( // struct to store the information of the wedge texcoords template -struct WedgeTexCoordsInfo { +struct WedgeTexCoordsInfo +{ WedgeTexCoordType texCoord; - ushort texCoordIndex; + ushort texCoordIndex; bool operator<(const WedgeTexCoordsInfo& other) const { @@ -86,9 +87,9 @@ struct WedgeTexCoordsInfo { } }; -static inline std::list dummyUintList; +static inline std::list dummyUintList; static inline std::list>> dummyListOfLists; -static inline std::vector> dummyVectorOfPairs; +static inline std::vector> dummyVectorOfPairs; } // namespace detail @@ -261,7 +262,7 @@ uint countVerticesToDuplicateByWedgeTexCoords( { vcl::requirePerFaceWedgeTexCoords(mesh); - using WedgeTexCoordType = MeshType::FaceType::WedgeTexCoordType; + using WedgeTexCoordType = MeshType::FaceType::WedgeTexCoordType; using WedgeTexCoordsInfo = detail::WedgeTexCoordsInfo; // list of faces that reference a wedge texcoord, with the index of the @@ -281,14 +282,14 @@ uint countVerticesToDuplicateByWedgeTexCoords( std::vector> wedges( mesh.vertexContainerSize()); - for(const auto& f : mesh.faces()) { - for(uint i = 0; i < f.vertexNumber(); ++i) { + for (const auto& f : mesh.faces()) { + for (uint i = 0; i < f.vertexNumber(); ++i) { uint vi = f.vertexIndex(i); // check if the i-th wedge texcoord of the face already exists WedgeTexCoordsInfo wi = {f.wedgeTexCoord(i), f.textureIndex()}; - auto it = wedges[vi].find(wi); - if(it == wedges[vi].end()) { // if it doesn't exist, add it + auto it = wedges[vi].find(wi); + if (it == wedges[vi].end()) { // if it doesn't exist, add it // if there was already a texcoord for the vertex, it means that // the vertex will be duplicated if (!wedges[vi].empty()) { @@ -317,9 +318,7 @@ uint countVerticesToDuplicateByWedgeTexCoords( // faces referencing the texcoord (we do this to reassign the less // number of faces) auto it = std::max_element( - map.begin(), - map.end(), - [](const auto& a, const auto& b) { + map.begin(), map.end(), [](const auto& a, const auto& b) { return a.second.size() < b.second.size(); }); // store the reference of the texcoord to keep (pair face/vertex @@ -332,7 +331,6 @@ uint countVerticesToDuplicateByWedgeTexCoords( vertsToDuplicate.push_back(vi); facesToReassign.push_back(std::move(fl)); } - } else { if (map.size() == 1) { diff --git a/vclib/core/include/vclib/space/core/point.h b/vclib/core/include/vclib/space/core/point.h index df305f395..5831c4651 100644 --- a/vclib/core/include/vclib/space/core/point.h +++ b/vclib/core/include/vclib/space/core/point.h @@ -57,6 +57,7 @@ template class Point : public Eigen::Matrix { using Base = Eigen::Matrix; + public: using BaseMatrixType = Base;