From 765382738becbb1895be203a7ddd5c4a19cb9ea5 Mon Sep 17 00:00:00 2001 From: Kai Blaschke Date: Tue, 30 Sep 2025 23:13:27 +0200 Subject: [PATCH] Add Doxygen documentation, plus a few small fixes. --- .../MilkdropPreset/FinalComposite.hpp | 8 +- .../MilkdropPreset/PerPixelMesh.hpp | 12 +- src/libprojectM/Renderer/BlendMode.hpp | 89 +++----- src/libprojectM/Renderer/Color.hpp | 4 + src/libprojectM/Renderer/Mesh.cpp | 8 +- src/libprojectM/Renderer/Mesh.hpp | 200 ++++++++++++++++-- src/libprojectM/Renderer/Point.hpp | 4 + src/libprojectM/Renderer/TextureUV.hpp | 4 + src/libprojectM/Renderer/VertexArray.hpp | 16 ++ src/libprojectM/Renderer/VertexBuffer.hpp | 113 +++++++++- .../Renderer/VertexBufferUsage.hpp | 26 ++- src/libprojectM/Renderer/VertexIndexArray.cpp | 6 + src/libprojectM/Renderer/VertexIndexArray.hpp | 99 ++++++++- 13 files changed, 489 insertions(+), 100 deletions(-) diff --git a/src/libprojectM/MilkdropPreset/FinalComposite.hpp b/src/libprojectM/MilkdropPreset/FinalComposite.hpp index 8bbf9706b..970144770 100644 --- a/src/libprojectM/MilkdropPreset/FinalComposite.hpp +++ b/src/libprojectM/MilkdropPreset/FinalComposite.hpp @@ -87,15 +87,15 @@ private: static constexpr int vertexCount{compositeGridWidth * compositeGridHeight}; static constexpr int indexCount{(compositeGridWidth - 2) * (compositeGridHeight - 2) * 6}; - Renderer::Mesh m_compositeMesh; //!< The composite shader mesh. - Renderer::VertexBuffer m_radiusAngle; //!< Additional vertex attribute array for radius and angle. + Renderer::Mesh m_compositeMesh; //!< The composite shader mesh. + Renderer::VertexBuffer m_radiusAngle{Renderer::VertexBufferUsage::StreamDraw}; //!< Additional vertex attribute array for radius and angle. int m_viewportWidth{}; //!< Last known viewport width. int m_viewportHeight{}; //!< Last known viewport height. std::unique_ptr m_compositeShader; //!< The composite shader. Either preset-defined or empty. - std::unique_ptr m_videoEcho; //!< Video echo effect. Used if no composite shader is loaded and video echo is enabled. - std::unique_ptr m_filters; //!< Color post-processing filters. Used if no composite shader is loaded. + std::unique_ptr m_videoEcho; //!< Video echo effect. Used if no composite shader is loaded and video echo is enabled. + std::unique_ptr m_filters; //!< Color post-processing filters. Used if no composite shader is loaded. }; } // namespace MilkdropPreset diff --git a/src/libprojectM/MilkdropPreset/PerPixelMesh.hpp b/src/libprojectM/MilkdropPreset/PerPixelMesh.hpp index 609053204..f9a51c02b 100644 --- a/src/libprojectM/MilkdropPreset/PerPixelMesh.hpp +++ b/src/libprojectM/MilkdropPreset/PerPixelMesh.hpp @@ -122,12 +122,12 @@ private: int m_viewportWidth{}; //!< Last known viewport width. int m_viewportHeight{}; //!< Last known viewport height. - Renderer::Mesh m_warpMesh; //!< The Warp effect mesh - Renderer::VertexBuffer m_radiusAngleBuffer; //!< Vertex attribute buffer for radius and angle values. - Renderer::VertexBuffer m_zoomRotWarpBuffer; //!< Vertex attribute buffer for zoom, roation and warp values. - Renderer::VertexBuffer m_centerBuffer; //!< Vertex attribute buffer for center coordinate values. - Renderer::VertexBuffer m_distanceBuffer; //!< Vertex attribute buffer for distance values. - Renderer::VertexBuffer m_stretchBuffer; //!< Vertex attribute buffer for stretch values. + Renderer::Mesh m_warpMesh; //!< The Warp effect mesh + Renderer::VertexBuffer m_radiusAngleBuffer{Renderer::VertexBufferUsage::StreamDraw}; //!< Vertex attribute buffer for radius and angle values. + Renderer::VertexBuffer m_zoomRotWarpBuffer{Renderer::VertexBufferUsage::StreamDraw}; //!< Vertex attribute buffer for zoom, roation and warp values. + Renderer::VertexBuffer m_centerBuffer{Renderer::VertexBufferUsage::StreamDraw}; //!< Vertex attribute buffer for center coordinate values. + Renderer::VertexBuffer m_distanceBuffer{Renderer::VertexBufferUsage::StreamDraw}; //!< Vertex attribute buffer for distance values. + Renderer::VertexBuffer m_stretchBuffer{Renderer::VertexBufferUsage::StreamDraw}; //!< Vertex attribute buffer for stretch values. std::weak_ptr m_perPixelMeshShader; //!< Special shader which calculates the per-pixel UV coordinates. std::unique_ptr m_warpShader; //!< The warp shader. Either preset-defined or a default shader. diff --git a/src/libprojectM/Renderer/BlendMode.hpp b/src/libprojectM/Renderer/BlendMode.hpp index 33d40923d..222b6f0d8 100644 --- a/src/libprojectM/Renderer/BlendMode.hpp +++ b/src/libprojectM/Renderer/BlendMode.hpp @@ -5,9 +5,16 @@ namespace libprojectM { namespace Renderer { +/** + * A simple wrapper class around OpenGL's blend mode functionality. + */ class BlendMode { public: + /** + * Available blend functions. + * @see https://registry.khronos.org/OpenGL-Refpages/gl4/html/glBlendFunc.xhtml + */ enum class Function : int { Zero, @@ -33,67 +40,35 @@ public: BlendMode() = delete; - static void Set(bool enable, Function srcFunc, Function dstFunc) - { - SetBlendActive(enable); - SetBlendFunction(srcFunc, dstFunc); - } + /** + * @brief Enables or disables blending and sets the blend functions. + * A convenience wrapper around BlendMode::SetBlendActive() and BlendMode::SetBlendFunction(). + * @param enable If true, blending is enabled, otherwise disabled. + * @param srcFunc The blend function to determine the source color. + * @param dstFunc the blend function to determine the destination color. + */ + static void Set(bool enable, Function srcFunc, Function dstFunc); - static void SetBlendActive(bool enable) - { - if (enable) - { - glEnable(GL_BLEND); - } - else - { - glDisable(GL_BLEND); - } - } + /** + * Enables or disables blending. + * @param enable If true, blending is enabled, otherwise disabled. + */ + static void SetBlendActive(bool enable); - static void SetBlendFunction(Function srcFunc, Function dstFunc) - { - glBlendFunc(FunctionToGL(srcFunc), FunctionToGL(dstFunc)); - } + /** + * Sets the blend functions. + * @param srcFunc The blend function to determine the source color. + * @param dstFunc the blend function to determine the destination color. + */ + static void SetBlendFunction(Function srcFunc, Function dstFunc); private: - static GLuint FunctionToGL(Function func) - { - switch (func) - { - case Function::Zero: - return GL_ZERO; - case Function::One: - default: - return GL_ONE; - case Function::SourceColor: - return GL_SRC_COLOR; - case Function::OneMinusSourceColor: - return GL_ONE_MINUS_SRC_COLOR; - case Function::DestinationColor: - return GL_DST_COLOR; - case Function::OneMinusDestinationColor: - return GL_ONE_MINUS_DST_COLOR; - case Function::SourceAlpha: - return GL_SRC_ALPHA; - case Function::OneMinusSourceAlpha: - return GL_ONE_MINUS_SRC_ALPHA; - case Function::DestinationAlpha: - return GL_DST_ALPHA; - case Function::OneMinusDestinationAlpha: - return GL_ONE_MINUS_DST_ALPHA; - case Function::ConstantColor: - return GL_CONSTANT_COLOR; - case Function::OneMinusConstantColor: - return GL_ONE_MINUS_CONSTANT_COLOR; - case Function::ConstantAlpha: - return GL_CONSTANT_ALPHA; - case Function::OneMinusConstantAlpha: - return GL_ONE_MINUS_CONSTANT_ALPHA; - case Function::SourceAlphaSaturate: - return GL_SRC_ALPHA_SATURATE; - } - } + /** + * Translates the Function enum values into OpenGL constants. + * @param func The blend function to translate. + * @return the OpenGL constant for the given blend function. + */ + static GLuint FunctionToGL(Function func); }; } // namespace Renderer diff --git a/src/libprojectM/Renderer/Color.hpp b/src/libprojectM/Renderer/Color.hpp index 87c8e388b..aaf10057b 100644 --- a/src/libprojectM/Renderer/Color.hpp +++ b/src/libprojectM/Renderer/Color.hpp @@ -162,6 +162,10 @@ public: Modulo(col.A())); } + /** + * @brief Initializes the attribute array pointer for this storage type. + * @param attributeIndex the attribute index to use. + */ static void InitializeAttributePointer(uint32_t attributeIndex) { glVertexAttribPointer(attributeIndex, sizeof(Color) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(Color), nullptr); diff --git a/src/libprojectM/Renderer/Mesh.cpp b/src/libprojectM/Renderer/Mesh.cpp index 83236a106..78a6f23be 100644 --- a/src/libprojectM/Renderer/Mesh.cpp +++ b/src/libprojectM/Renderer/Mesh.cpp @@ -12,16 +12,18 @@ Mesh::Mesh(VertexBufferUsage usage) : m_vertices(usage) , m_colors(usage) , m_textureUVs(usage) + , m_indices(usage) { Initialize(); } Mesh::Mesh(VertexBufferUsage usage, bool useColor, bool useTextureUVs) - : m_vertices(usage) + : m_useColorAttributes(useColor) + , m_useUVAttributes(useTextureUVs) + , m_vertices(usage) , m_colors(usage) , m_textureUVs(usage) - , m_useColorAttributes(useColor) - , m_useUVAttributes(useTextureUVs) + , m_indices(usage) { Initialize(); } diff --git a/src/libprojectM/Renderer/Mesh.hpp b/src/libprojectM/Renderer/Mesh.hpp index c18d89c87..fc9a5cedf 100644 --- a/src/libprojectM/Renderer/Mesh.hpp +++ b/src/libprojectM/Renderer/Mesh.hpp @@ -11,7 +11,6 @@ #include #include -#include namespace libprojectM { namespace Renderer { @@ -25,148 +24,325 @@ namespace Renderer { * - 0: Vertex position (2 elements, X/Y) * - 1: Color (4 elements, R/G/B/A) * - 2: U/V coordinate (2 elements, U/V) + * + * Attribute data is stored in individual buffers. When setting the buffers via their Set() methods, + * the user has to make sure that all buffers have at least the same length as the main vertex buffer. + * + * Keep in mind that only 8 attribute arrays are guaranteed to be supported by the OpenGL spec. + * + * The Mesh class always uses vertex indices to render, using glDrawElements. If the index buffer is + * empty on the first draw call, it will be populated with a 1:1 mapping of the vertex buffer. If + * the vertex count changes, the caller has to make sure that the index array is updated accordingly. + * + * @note When using this class, attributes indices 1 and 2 will be toggled according to the + * attribute enable flags. When using additional vertex arrays, make sure to start with index 3. */ class Mesh { public: enum class PrimitiveType : uint8_t { - Points, - Lines, - LineStrip, - LineLoop, - Triangles, - TriangleStrip, - TriangleFan + Points, //!< Renders each vertex as a single texel. + Lines, //!< Renders individual lines, one for each 2 vertices. + LineStrip, //!< Renders all vertices as a continuous line. + LineLoop, //!< Renders all vertices as a continuous line, plus an additional line from the last to first vertex. + Triangles, //!< Renders vertices as individual triangles, with three vertices/indices making up one triangle. + TriangleStrip, //!< Renders vertices as a continuous strip of triangles, where 2 vertices are shared between each old and new triangle. + TriangleFan //!< Renders a fan of triangles, with the first vertex being used as the first vertex of all rendered triangles. }; + /** + * Constructor. Creates the mesh with a default rendering mode of PrimitiveType::Lines. + */ Mesh(); + /** + * Constructor. Creates the mesh with a default rendering mode of PrimitiveType::Lines. + * Allows setting the buffer usage hint for the internal buffers. + * @param usage The buffer usage hint. + */ explicit Mesh(VertexBufferUsage usage); + /** + * Constructor. Creates the mesh with a default rendering mode of PrimitiveType::Lines. + * Allows setting the buffer usage hint for the internal buffers and to specify the use + * or color and texture coordinate attribute arrays. + * @param usage The buffer usage hint. + * @param useColor If true, the color attribute array will be enabled by default. + * @param useTextureUVs If true, the texture coordinate attribute array will be enabled by default. + */ Mesh(VertexBufferUsage usage, bool useColor, bool useTextureUVs); + /** + * Default destructor. + */ virtual ~Mesh() = default; + /** + * Returns the currently set primitive type which is rendered when calling Draw(). + * @return The currently set primitive type. + */ auto RenderPrimitiveType() const -> PrimitiveType { return m_primitiveType; } + /** + * Sets the primitive type to render when calling Draw(). + * @param primitiveType The new primitive type to render. + */ void SetRenderPrimitiveType(PrimitiveType primitiveType) { m_primitiveType = primitiveType; } + /** + * Returns the current number of vertices in the vertex buffer. + * @return The number of vertices in the vertex buffer. + */ auto VertexCount() const -> uint32_t { return m_vertices.Size(); } + /** + * @brief Sets the size of all attribute buffers to the given count. + * Only buffers enabled at the time of the call are resized to save memory. If a buffer is + * enabled after calling this function, either resize it manually or call this function again. + * @param vertexCount The new vertex count. + */ void SetVertexCount(uint32_t vertexCount); + /** + * Returns a constant reference to the vertex position buffer. + * @return A constant reference to the internal vertex (position) buffer. + */ auto Vertices() const -> const VertexBuffer& { return m_vertices; } + /** + * Returns a reference to the vertex position buffer. + * @return A writeable reference to the internal vertex (position) buffer. + */ auto Vertices() -> VertexBuffer& { return m_vertices; } + /** + * Returns a Point instance with the position of a vertex at the given index. + * @throws std::out_of_range thrown if the index is out of range. + * @param index The index of the vertex position to retrieve. + * @return A constant reference to the vertex position at the given index. + */ auto Vertex(uint32_t index) const -> const Point& { return m_vertices[index]; } + /** + * Returns a Point instance with the position of a vertex at the given index. + * @throws std::out_of_range thrown if the index is out of range. + * @param index The index of the vertex position to retrieve. + * @return A writeable reference to the vertex position at the given index. + */ auto Vertex(uint32_t index) -> Point& { return m_vertices[index]; } + /** + * Set a given vertex index to a new value. + * @param index The index of the vertex to set. + * @param vertex The new data to set at the given index. + */ void SetVertex(uint32_t index, const Point& vertex) { m_vertices[index] = vertex; } + /** + * Returns a constant reference to the internal color buffer. + * @return A constant reference to the internal color buffer. + */ auto Colors() const -> const VertexBuffer& { return m_colors; } + /** + * Returns a reference to the internal color buffer. + * @return A writeable reference to the internal color buffer. + */ auto Colors() -> VertexBuffer& { return m_colors; } + /** + * Returns a Color instance with the RGBA color of a vertex at the given index. + * @throws std::out_of_range thrown if the index is out of range. + * @param index The index of the vertex color to retrieve. + * @return A constant reference to the vertex color at the given index. + */ auto Color(uint32_t index) const -> const Color& { return m_colors[index]; } + /** + * Returns a Color instance with the RGBA color of a vertex at the given index. + * @throws std::out_of_range thrown if the index is out of range. + * @param index The index of the vertex color to retrieve. + * @return A writeable reference to the vertex color at the given index. + */ auto Color(uint32_t index) -> class Color& { return m_colors[index]; } + /** + * Returns whether the color attribute array (index 1) is enabled. + * @return true if the color attribute array is enabled, false if not. + */ auto UseColor() const -> bool { return m_useColorAttributes; } + /** + * @brief Enables or disables the use of the color attribute array (index 1). + * When enabling the array, the color buffer is resized to the size of the position buffer. + * When disabling the array, the color buffer is cleared. + * @note Disabling the color attribute array does NOT free any previously allocated GPU buffer memory. + * @param useColor true to enable the color attribute array, false to disable it. + */ void SetUseColor(bool useColor); - void SetColor(uint32_t index, const class Color& vertex) + /** + * Set a given index to a new color value. + * @param index The index of the vertex color to set. + * @param color The new color data to set at the given index. + */ + void SetColor(uint32_t index, const class Color& color) { - m_colors[index] = vertex; + m_colors[index] = color; } + /** + * Returns a constant reference to the internal texture coordinates buffer. + * @return A constant reference to the internal texture coordinates buffer. + */ auto UVs() const -> const VertexBuffer& { return m_textureUVs; } + /** + * Returns a reference to the internal texture coordinates buffer. + * @return A writeable reference to the internal texture coordinates buffer. + */ auto UVs() -> VertexBuffer& { return m_textureUVs; } + /** + * Returns a TextureUV instance with the texture coordinates of a vertex at the given index. + * @throws std::out_of_range thrown if the index is out of range. + * @param index The index of the vertex texture coordinates to retrieve. + * @return A constant reference to the vertex texture coordinates at the given index. + */ auto UV(uint32_t index) const -> const TextureUV& { return m_textureUVs[index]; } + /** + * Returns a TextureUV instance with the texture coordinates of a vertex at the given index. + * @throws std::out_of_range thrown if the index is out of range. + * @param index The index of the vertex texture coordinates to retrieve. + * @return A writeable reference to the vertex texture coordinates at the given index. + */ auto UV(uint32_t index) -> TextureUV& { return m_textureUVs[index]; } - void SetUV(uint32_t index, const TextureUV& vertex) + /** + * Set a given index to new texture coordinates. + * @param index The index of the vertex texture coordinates to set. + * @param uvs The new texture coordinates data to set at the given index. + */ + void SetUV(uint32_t index, const TextureUV& uvs) { - m_textureUVs[index] = vertex; + m_textureUVs[index] = uvs; } + /** + * Returns whether the texture coordinates attribute array (index 2) is enabled. + * @return true if the texture coordinates attribute array is enabled, false if not. + */ auto UseUV() const -> bool { return m_useUVAttributes; } + /** + * @brief Enables or disables the use of the texture coordinates attribute array (index 2). + * When enabling the array, the texture coordinates buffer is resized to the size of the position buffer. + * When disabling the array, the texture coordinates buffer is cleared. + * @note Disabling the texture coordinates attribute array does NOT free any previously allocated GPU buffer memory. + * @param useUV true to enable the texture coordinates attribute array, false to disable it. + */ void SetUseUV(bool useUV); + /** + * Returns a reference to the vertex index buffer. + * @return A writeable reference to the vertex index buffer. + */ auto Indices() -> VertexIndexArray&; + /** + * Returns a constant reference to the vertex index buffer. + * @return A constant reference to the vertex index buffer. + */ auto Indices() const -> const VertexIndexArray&; + /** + * Binds the vertex array object used to store the mesh vertex data. + */ void Bind() const; + /** + * Binds the default vertex array object with ID 0. + */ static void Unbind(); + /** + * @brief Updates the data all enabled buffers, sending it to the GPU. + * Calling this method is required to render any changed vertex data. As long + * as Update() is not called, Draw() will always draw the same geometry. + * @note This method binds the vertex array object and all buffers and leaves them bound. + */ void Update(); + /** + * @brief Draws the current geometry stored in the GPU. + * If this method is called with an empty vertex index buffer, the index buffer is filled with + * a continuous 1:1 mapping to the vertex position buffer. + * @note Before calling this method, the caller has to ensure that all buffers have the correct + * length and were properly uploaded to the GPU by calling Update(). + * @note This method binds and unbinds the stored vertex array object. + */ void Draw(); private: + /** + * Binds the internal buffers to the vertex array object and initializes the array pointers. + */ void Initialize(); PrimitiveType m_primitiveType{PrimitiveType::Lines}; //!< Mesh render primitive type. diff --git a/src/libprojectM/Renderer/Point.hpp b/src/libprojectM/Renderer/Point.hpp index 68aa61332..7d3c07482 100644 --- a/src/libprojectM/Renderer/Point.hpp +++ b/src/libprojectM/Renderer/Point.hpp @@ -60,6 +60,10 @@ public: m_y = y; } + /** + * @brief Initializes the attribute array pointer for this storage type. + * @param attributeIndex the attribute index to use. + */ static void InitializeAttributePointer(uint32_t attributeIndex) { glVertexAttribPointer(attributeIndex, sizeof(Point) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(Point), nullptr); diff --git a/src/libprojectM/Renderer/TextureUV.hpp b/src/libprojectM/Renderer/TextureUV.hpp index 292b6e751..677188ef9 100644 --- a/src/libprojectM/Renderer/TextureUV.hpp +++ b/src/libprojectM/Renderer/TextureUV.hpp @@ -60,6 +60,10 @@ public: m_v = v; } + /** + * @brief Initializes the attribute array pointer for this storage type. + * @param attributeIndex the attribute index to use. + */ static void InitializeAttributePointer(uint32_t attributeIndex) { glVertexAttribPointer(attributeIndex, sizeof(TextureUV) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(TextureUV), nullptr); diff --git a/src/libprojectM/Renderer/VertexArray.hpp b/src/libprojectM/Renderer/VertexArray.hpp index ad507c809..997690b2f 100644 --- a/src/libprojectM/Renderer/VertexArray.hpp +++ b/src/libprojectM/Renderer/VertexArray.hpp @@ -8,25 +8,41 @@ namespace libprojectM { namespace Renderer { +/** + * @brief Wraps a vertex array object. + * Creates, destroys and binds a single VAO. + */ class VertexArray { public: + /** + * Constructor. Creates a new VAO. + */ VertexArray() { glGenVertexArrays(1, &m_vaoID); } + /** + * Destructor. Deletes the stored VAO. + */ virtual ~VertexArray() { glDeleteVertexArrays(1, &m_vaoID); m_vaoID = 0; } + /** + * Binds the stored VAO. + */ void Bind() const { glBindVertexArray(m_vaoID); } + /** + * Binds the default VAO with ID 0. + */ static void Unbind() { glBindVertexArray(0); diff --git a/src/libprojectM/Renderer/VertexBuffer.hpp b/src/libprojectM/Renderer/VertexBuffer.hpp index 472bd7221..ef6a62fe8 100644 --- a/src/libprojectM/Renderer/VertexBuffer.hpp +++ b/src/libprojectM/Renderer/VertexBuffer.hpp @@ -10,58 +10,161 @@ namespace libprojectM { namespace Renderer { +/** + * @brief Wraps a vertex buffer object and manages its data. + * + * The templated storage class must meet a few requirements: + * - It must only contain 1 to 4 members of a single type allowed by the OpenGL specification. + * - It must implement a function with the following signature to initialize the attribute pointer: + * static void InitializeAttributePointer(uint32_t attributeIndex) + * - It must be default-constructible. + * + * @tparam VT The data storage type for this buffer. + */ template class VertexBuffer { public: + /** + * Constructor. Creates an empty buffer with the default usage hint. + */ VertexBuffer(); + /** + * Constructor. Creates an empty buffer with a specific usage hint. + * @param usage The usage hint for this buffer. + */ explicit VertexBuffer(VertexBufferUsage usage); + /** + * Destructor. Deletes the GPU buffer. + */ virtual ~VertexBuffer(); + /** + * Binds the stored vertex buffer object. + */ void Bind() const; + /** + * Binds the default vertex buffer object with ID 0. + */ static void Unbind(); + /** + * Initializes the attribute array pointer for this buffer. + * @param attributeIndex The index to use for the attributes stored in this buffer. + */ void InitializeAttributePointer(uint32_t attributeIndex) const; + /** + * Enables or disabled the use of the given attribute array index. + * @param attributeIndex The index to enable or disable. + * @param enable true to enable the given attribute array index, false to disable. + */ static void SetEnableAttributeArray(uint32_t attributeIndex, bool enable); + /** + * Return a reference to the internal vector storing the buffer's elements. + * @return A writeable reference to the internal buffer vector. + */ auto Get() -> std::vector&; + /** + * Return a constant reference to the internal vector storing the buffer's elements. + * @return A constant reference to the internal buffer vector. + */ auto Get() const -> const std::vector&; + /** + * @brief Replaces the buffer with the given contents. + * All elements are copied. To reduce overhead with large buffers, use the Get() method instead + * and then move-assign the vector to the returned reference. + * @param buffer The new buffer contents. + */ void Set(const std::vector& buffer); + /** + * Returns a reference to a single stored vertex attrobute data object at the given index. + * @throws std::out_of_range Thrown if the given index is outside the vector's boundaries. + * @param index The index for the vertex attribute data to return. + * @return A writeable reference to a single attribute object for the given index. + */ auto Vertex(size_t index) -> VT&; + /** + * Returns a reference to a single stored vertex attrobute data object at the given index. + * @throws std::out_of_range Thrown if the given index is outside the vector's boundaries. + * @param index The index for the vertex attribute data to return. + * @return A constant reference to a single attribute object for the given index. + */ auto Vertex(size_t index) const -> const VT&; + /** + * Assigns new data to the given index. + * @throws std::out_of_range Thrown if the given index is outside the vector's boundaries. + * @param index The index of the vertex attribute data to assign. + * @param vertex The new data to assign to the given index. + */ void SetVertex(size_t index, const VT& vertex); + /** + * Queries if the buffer is empty. + * @return true if the buffer is empty, false if the buffer contains at least one element. + */ auto Empty() const -> bool; + /** + * Returns the number of stored elements in this buffer. + * @return The number of stored elements in this buffer. + */ auto Size() const -> size_t; + /** + * @brief Changes the buffer size to the given value. + * If the buffer size is increased, new elements at the end are default-constructed. + * @param size The new size of the buffer. + */ void Resize(size_t size); + /** + * @brief Changes the buffer size to the given value. + * If the buffer size is increased, new elements at the end are copied from the given element in elem. + * @param size The new size of the buffer. + * @param elem An element to copy for newly added entries. + */ void Resize(size_t size, const VT& elem); - + /** + * @brief Uploads the current buffer contents to the GPU. + * This method won't change the GPU buffer if the buffer is empty. + * @note This method binds the stored vertex buffer object and leaves it bound. + */ void Update(); + /** + * @brief A shorthand notation to access individual buffer elements. + * @throws std::out_of_range Thrown if the given index is outside the buffer index bounds. + * @param index The index of the vertex attribute to access. + * @return A writeable reference to the vertex attribute data at the given index. + */ auto operator[](size_t index) -> VT&; + /** + * @brief A shorthand notation to access individual buffer elements. + * @throws std::out_of_range Thrown if the given index is outside the buffer index bounds. + * @param index The index of the vertex attribute to access. + * @return A constant reference to the vertex attribute data at the given index. + */ auto operator[](size_t index) const -> const VT&; private: - GLuint m_vboID{}; - size_t m_vboSize{}; + GLuint m_vboID{}; //!< The ID of the OpenGL vertex buffer object. + size_t m_vboSize{}; //!< Stores the last number if items uploaded to the GPU. - VertexBufferUsage m_vboUsage{VertexBufferUsage::StaticDraw}; + VertexBufferUsage m_vboUsage{VertexBufferUsage::StaticDraw}; //!< The buffer usage hint. - std::vector m_vertices; + std::vector m_vertices; //!< The local copy of the vertex buffer data. }; template diff --git a/src/libprojectM/Renderer/VertexBufferUsage.hpp b/src/libprojectM/Renderer/VertexBufferUsage.hpp index 9cf5d2131..4dc01755b 100644 --- a/src/libprojectM/Renderer/VertexBufferUsage.hpp +++ b/src/libprojectM/Renderer/VertexBufferUsage.hpp @@ -5,19 +5,27 @@ namespace libprojectM { namespace Renderer { +/** + * An enum with available buffer usage hints. + */ enum class VertexBufferUsage : char { - StreamDraw, - StreamRead, - StreamCopy, - StaticDraw, - StaticRead, - StaticCopy, - DynamicDraw, - DynamicRead, - DynamicCopy + StreamDraw, //!< The data store contents will be modified once and used at most a few times for drawing. + StreamRead, //!< The data store contents will be modified once and used at most a few times for reading data from GL. + StreamCopy, //!< The data store contents will be modified once and used at most a few times for both drawing and reading data from GL. + StaticDraw, //!< The data store contents will be modified once and used many times for drawing. + StaticRead, //!< The data store contents will be modified once and used many times for reading data from GL. + StaticCopy, //!< The data store contents will be modified once and used many times for both drawing and reading data from GL. + DynamicDraw, //!< The data store contents will be modified repeatedly and used many times for drawing. + DynamicRead, //!< The data store contents will be modified repeatedly and used many times for reading data from GL. + DynamicCopy //!< The data store contents will be modified repeatedly and used many times for both drawing and reading data from GL. }; +/** + * Translates values from the VertexBufferUsage enumeration to OpenGL constants. + * @param usage The usage hint to translate to an OpenGL constant. + * @return The OpenGL constant for the given usage hint enum value. + */ auto VertexBufferUsageToGL(VertexBufferUsage usage) -> GLuint; } // namespace Renderer diff --git a/src/libprojectM/Renderer/VertexIndexArray.cpp b/src/libprojectM/Renderer/VertexIndexArray.cpp index b3104d54d..382b80147 100644 --- a/src/libprojectM/Renderer/VertexIndexArray.cpp +++ b/src/libprojectM/Renderer/VertexIndexArray.cpp @@ -8,6 +8,12 @@ VertexIndexArray::VertexIndexArray() glGenBuffers(1, &m_veabID); } +VertexIndexArray::VertexIndexArray(VertexBufferUsage usage) + : m_vboUsage(usage) +{ + glGenBuffers(1, &m_veabID); +} + VertexIndexArray::~VertexIndexArray() { glDeleteBuffers(1, &m_veabID); diff --git a/src/libprojectM/Renderer/VertexIndexArray.hpp b/src/libprojectM/Renderer/VertexIndexArray.hpp index c129f5ebe..f3f60f7ae 100644 --- a/src/libprojectM/Renderer/VertexIndexArray.hpp +++ b/src/libprojectM/Renderer/VertexIndexArray.hpp @@ -8,52 +8,143 @@ namespace libprojectM { namespace Renderer { +/** + * Wraps a vertex element array buffer, containing vertex indices for drawing. + */ class VertexIndexArray { public: + /** + * Constructor. Creates an empty index buffer with the default usage hint. + */ VertexIndexArray(); + /** + * Constructor. Creates an empty index buffer with the specified usage hint. + */ + VertexIndexArray(VertexBufferUsage usage); + + /** + * Destructor. Deleted the index buffer. + */ virtual ~VertexIndexArray(); + /** + * Binds the stored index buffer. + */ void Bind() const; + /** + * Binds the default index buffer with ID 0. + */ static void Unbind(); + /** + * Return a reference to the internal vector storing the buffer's elements. + * @return A writeable reference to the internal buffer vector. + */ auto Get() -> std::vector&; + /** + * Return a constant reference to the internal vector storing the buffer's elements. + * @return A constant reference to the internal buffer vector. + */ auto Get() const -> const std::vector&; + /** + * @brief Replaces the index buffer with the given contents. + * All elements are copied. To reduce overhead with large buffers, use the Get() method instead + * and then move-assign the vector to the returned reference. + * @param buffer The new index buffer contents. + */ void Set(const std::vector& buffer); + /** + * Returns a reference to a single value at the given index in the buffer. + * @throws std::out_of_range Thrown if the given index is outside the vector's boundaries. + * @param index The index for the vertex index value to return. + * @return A writeable reference to a value for the given index. + */ auto VertexIndex(size_t index) -> uint32_t; + /** + * Returns a reference to a single value at the given index in the buffer. + * @throws std::out_of_range Thrown if the given index is outside the vector's boundaries. + * @param index The index for the vertex index value to return. + * @return A constant reference to a value for the given index. + */ auto VertexIndex(size_t index) const -> uint32_t; + /** + * Assigns a new index value to the given index. + * @throws std::out_of_range Thrown if the given index is outside the vector's boundaries. + * @param index The index of the vertex index value to assign. + * @param value The new index value to assign to the given index. + */ void SetVertexIndex(size_t index, uint32_t value); + /** + * Queries if the buffer is empty. + * @return true if the buffer is empty, false if the buffer contains at least one element. + */ auto Empty() const -> bool; + /** + * Returns the number of stored elements in this buffer. + * @return The number of stored elements in this buffer. + */ auto Size() const -> size_t; + /** + * @brief Changes the buffer size to the given value. + * If the buffer size is increased, new elements at the end are set to 0. + * @param size The new size of the index buffer. + */ void Resize(size_t size); + /** + * @brief Changes the buffer size to the given value. + * If the buffer size is increased, new elements at the end are copied from the given value. + * @param size The new size of the index buffer. + * @param value A value to copy for newly added entries. + */ void Resize(size_t size, uint32_t value); + /** + * @brief Fills the buffer with values from 0 to size() - 1. + * This is useful if each vertex is only drawn once, in the order as stored in the vertex buffer. + */ void MakeContinuous(); + /** + * Uploads the current index buffer contents to the GPU. + * @note this functions binds the index buffer object and leaves it bound. + */ void Update(); + /** + * @brief A shorthand notation to access individual buffer elements. + * @throws std::out_of_range Thrown if the given index is outside the buffer index bounds. + * @param index The index of the vertex index value to access. + * @return A writeable reference to the vertex index value at the given index. + */ auto operator[](size_t index) -> uint32_t&; + /** + * @brief A shorthand notation to access individual buffer elements. + * @throws std::out_of_range Thrown if the given index is outside the buffer index bounds. + * @param index The index of the vertex index value to access. + * @return A constant reference to the vertex index value at the given index. + */ auto operator[](size_t index) const -> uint32_t; private: - GLuint m_veabID{}; - size_t m_veabSize{}; + GLuint m_veabID{}; //!< The ID of the OpenGL vertex element array buffer object. + size_t m_veabSize{}; //!< Stores the last number if items uploaded to the GPU. - VertexBufferUsage m_vboUsage{VertexBufferUsage::StaticDraw}; + VertexBufferUsage m_vboUsage{VertexBufferUsage::StaticDraw}; //!< The buffer usage hint. - std::vector m_indices; + std::vector m_indices; //!< The local copy of the vertex index buffer data. }; } // namespace Renderer