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);