continuing work on vbos
parent
c002f3fcaa
commit
b1bf0a58f6
|
@ -283,8 +283,11 @@
|
|||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_CAST_EXPRESSION_PARENTHESES/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/TOPLEVEL_FUNCTION_DECLARATION_RETURN_TYPE_STYLE/@EntryValue" value="ON_SINGLE_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/TOPLEVEL_FUNCTION_DEFINITION_RETURN_TYPE_STYLE/@EntryValue" value="ON_SINGLE_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BRACED_INIT_LIST_STYLE/@EntryValue" value="CHOP_IF_LONG" type="string" />
|
||||
<option name="/Default/CodeStyle/CppIncludeDirective/SortIncludeDirectives/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CppIncludeDirective/UseAngleBracketsInsteadOfQuotes/@EntryValue" value="WhenPossible" type="string" />
|
||||
<option name="/Default/CodeStyle/CppIncludeDirective/UseRelativePaths/@EntryValue" value="Never" type="string" />
|
||||
<option name="/Default/CodeStyle/Generate/=CppDefinitions/@KeyIndexDefined" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/Generate/=CppDefinitions/Options/=GenerateInlineDefinitions/@EntryIndexedValue" value="False" type="string" />
|
||||
</component>
|
||||
</project>
|
|
@ -1,5 +1,5 @@
|
|||
cmake_minimum_required(VERSION 3.25)
|
||||
project(gpu-particles VERSION 0.0.11)
|
||||
project(gpu-particles VERSION 0.0.12)
|
||||
|
||||
option(ENABLE_ADDRSAN "Enable the address sanitizer" OFF)
|
||||
option(ENABLE_UBSAN "Enable the ub sanitizer" OFF)
|
||||
|
|
|
@ -19,13 +19,72 @@
|
|||
#ifndef BLT_GFX_VAO_H
|
||||
#define BLT_GFX_VAO_H
|
||||
|
||||
#include <memory>
|
||||
#include <vbo.h>
|
||||
#include <blt/std/vector.h>
|
||||
|
||||
namespace blt::gfx
|
||||
{
|
||||
class unique_vao_t;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct vao_vbo_storage_t
|
||||
{
|
||||
std::unique_ptr<unique_vbo_t> vbo;
|
||||
u32 attribute_number = 0;
|
||||
|
||||
[[nodiscard]] bool is_element() const
|
||||
{
|
||||
return vbo->get_buffer_type() == GL_ELEMENT_ARRAY_BUFFER;
|
||||
}
|
||||
|
||||
explicit vao_vbo_storage_t(unique_vbo_t&& vbo): vbo(std::make_unique<unique_vbo_t>(std::move(vbo)))
|
||||
{}
|
||||
};
|
||||
|
||||
class vao_vbo_context_t
|
||||
{
|
||||
friend class vao_context_t;
|
||||
public:
|
||||
|
||||
private:
|
||||
vao_vbo_context_t(unique_vao_t& vao, vao_vbo_storage_t& vbo): vbo(vbo), vao(vao)
|
||||
{}
|
||||
|
||||
vao_vbo_storage_t& vbo;
|
||||
unique_vao_t& vao;
|
||||
};
|
||||
|
||||
class vao_context_t
|
||||
{
|
||||
friend vao_vbo_context_t;
|
||||
friend class unique_vao_t;
|
||||
|
||||
public:
|
||||
vao_context_t& bind();
|
||||
|
||||
vao_context_t& unbind();
|
||||
|
||||
vao_vbo_context_t attach_vbo(unique_vbo_t&& vbo) const;
|
||||
|
||||
private:
|
||||
[[nodiscard]] bool is_bound() const;
|
||||
|
||||
explicit vao_context_t(unique_vao_t& vao): vao(vao)
|
||||
{
|
||||
bind();
|
||||
}
|
||||
|
||||
unique_vao_t& vao;
|
||||
};
|
||||
}
|
||||
|
||||
class unique_vao_t
|
||||
{
|
||||
friend detail::vao_vbo_context_t;
|
||||
friend detail::vao_context_t;
|
||||
|
||||
public:
|
||||
unique_vao_t(): vaoID(0)
|
||||
{
|
||||
|
@ -45,6 +104,8 @@ namespace blt::gfx
|
|||
return *this;
|
||||
}
|
||||
|
||||
detail::vao_context_t bind();
|
||||
|
||||
~unique_vao_t()
|
||||
{
|
||||
if (vaoID)
|
||||
|
@ -53,8 +114,8 @@ namespace blt::gfx
|
|||
|
||||
private:
|
||||
std::optional<GLuint> vaoID;
|
||||
std::vector<detail::vao_vbo_storage_t> vbo_list;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //BLT_GFX_VAO_H
|
||||
|
|
|
@ -36,12 +36,8 @@ namespace blt::gfx
|
|||
*/
|
||||
class vbo_context_t
|
||||
{
|
||||
friend unique_vbo_t;
|
||||
public:
|
||||
explicit vbo_context_t(unique_vbo_t& vbo): vbo(vbo)
|
||||
{
|
||||
bind();
|
||||
}
|
||||
|
||||
/**
|
||||
* By default, the VBO is bound when this class is constructed (this class should only be constructed through the VBO bind() method)
|
||||
*
|
||||
|
@ -93,6 +89,13 @@ namespace blt::gfx
|
|||
}
|
||||
|
||||
private:
|
||||
[[nodiscard]] bool is_bound() const;
|
||||
|
||||
explicit vbo_context_t(unique_vbo_t& vbo): vbo(vbo)
|
||||
{
|
||||
bind();
|
||||
}
|
||||
|
||||
unique_vbo_t& vbo;
|
||||
};
|
||||
}
|
||||
|
@ -137,14 +140,31 @@ namespace blt::gfx
|
|||
* This allows you to use the VBO without worrying about whether an operation is valid in this context.
|
||||
* As so long as you use this object in line, or without binding other VBOs to the same buffer_type
|
||||
* (violating the contracts this function attempts to create) then all functions on the associated object are valid to call.
|
||||
*
|
||||
* You can enable the flag BLT_DEBUG_CONTRACTS which will validate VBO bind state making most of ^ irrelevant
|
||||
*/
|
||||
[[nodiscard]] detail::vbo_context_t bind();
|
||||
detail::vbo_context_t bind();
|
||||
|
||||
[[nodiscard]] auto native_handle() const
|
||||
{
|
||||
return vboID;
|
||||
}
|
||||
|
||||
[[nodiscard]] GLsizeiptr get_size() const
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
[[nodiscard]] GLint get_memory_type() const
|
||||
{
|
||||
return memory_type;
|
||||
}
|
||||
|
||||
[[nodiscard]] GLuint get_buffer_type() const
|
||||
{
|
||||
return buffer_type;
|
||||
}
|
||||
|
||||
~unique_vbo_t()
|
||||
{
|
||||
if (vboID)
|
||||
|
|
45
src/vao.cpp
45
src/vao.cpp
|
@ -16,8 +16,51 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <vao.h>
|
||||
#include <blt/gfx/window.h>
|
||||
#include <blt/std/assert.h>
|
||||
#include <blt/std/hashmap.h>
|
||||
|
||||
namespace blt::gfx
|
||||
{
|
||||
#define BLT_DEBUG_LEVEL BLT_DEBUG_CONTRACTS
|
||||
|
||||
}
|
||||
#if blt_debug_has_flag(BLT_DEBUG_CONTRACTS)
|
||||
GLuint bound_vao_id;
|
||||
#endif
|
||||
|
||||
detail::vao_context_t& detail::vao_context_t::bind()
|
||||
{
|
||||
BLT_CONTRACT(vao.vaoID, "Expected VAO to have an associated VAO ID!");
|
||||
glBindVertexArray(*vao.vaoID);
|
||||
bound_vao_id = *vao.vaoID;
|
||||
return *this;
|
||||
}
|
||||
|
||||
detail::vao_context_t& detail::vao_context_t::unbind() // NOLINT
|
||||
{
|
||||
glBindVertexArray(0);
|
||||
bound_vao_id = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
detail::vao_vbo_context_t detail::vao_context_t::attach_vbo(unique_vbo_t&& vbo) const
|
||||
{
|
||||
BLT_CONTRACT(vao.vaoID, "Expected VAO to have an associated VAO ID!");
|
||||
BLT_CONTRACT(is_bound(), "Expected VAO to be bound before attaching VBO! (If you are using this API correctly, this has been done for you!)");
|
||||
|
||||
auto& vbo_storage = vao.vbo_list.emplace_back(std::move(vbo));
|
||||
vbo_storage.vbo->bind();
|
||||
return vao_vbo_context_t{vao, vbo_storage};
|
||||
}
|
||||
|
||||
bool detail::vao_context_t::is_bound() const
|
||||
{
|
||||
return *vao.vaoID == bound_vao_id;
|
||||
}
|
||||
|
||||
detail::vao_context_t unique_vao_t::bind()
|
||||
{
|
||||
BLT_CONTRACT(glfwGetCurrentContext() != nullptr, "Expected active OpenGL context!");
|
||||
return detail::vao_context_t{*this};
|
||||
}
|
||||
}
|
||||
|
|
25
src/vbo.cpp
25
src/vbo.cpp
|
@ -18,26 +18,38 @@
|
|||
#include <vbo.h>
|
||||
#include <blt/gfx/window.h>
|
||||
#include <blt/std/assert.h>
|
||||
#include <blt/std/hashmap.h>
|
||||
|
||||
namespace blt::gfx
|
||||
{
|
||||
#if blt_debug_has_flag(BLT_DEBUG_CONTRACTS)
|
||||
static hashmap_t<GLuint, GLuint> bound_vbo_ids;
|
||||
#endif
|
||||
|
||||
namespace detail
|
||||
{
|
||||
vbo_context_t& vbo_context_t::bind()
|
||||
{
|
||||
BLT_CONTRACT(vbo.vboID, "Expected VBO to have an assoicated VBO ID!");
|
||||
BLT_CONTRACT(vbo.vboID, "Expected VBO to have an associated VBO ID!");
|
||||
glBindBuffer(vbo.buffer_type, *vbo.vboID);
|
||||
#if blt_debug_has_flag(BLT_DEBUG_CONTRACTS)
|
||||
bound_vbo_ids[vbo.buffer_type] = *vbo.vboID;
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
vbo_context_t& vbo_context_t::unbind()
|
||||
{
|
||||
glBindBuffer(vbo.buffer_type, 0);
|
||||
#if blt_debug_has_flag(BLT_DEBUG_CONTRACTS)
|
||||
bound_vbo_ids[vbo.buffer_type] = 0;
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
vbo_context_t& vbo_context_t::resize(const GLsizeiptr size, const GLint mem_type)
|
||||
{
|
||||
BLT_CONTRACT(is_bound(), "Expected VBO to be bound before resizing!");
|
||||
vbo.size = size;
|
||||
vbo.memory_type = mem_type;
|
||||
glBufferData(vbo.buffer_type, size, nullptr, mem_type);
|
||||
|
@ -46,6 +58,7 @@ namespace blt::gfx
|
|||
|
||||
vbo_context_t& vbo_context_t::upload(const size_t size, const void* ptr, const GLint mem_type)
|
||||
{
|
||||
BLT_CONTRACT(is_bound(), "Expected VBO to be bound before uploading!");
|
||||
if (mem_type != vbo.memory_type || static_cast<size_t>(vbo.size) < size)
|
||||
{
|
||||
vbo.size = static_cast<GLsizeiptr>(size);
|
||||
|
@ -60,9 +73,19 @@ namespace blt::gfx
|
|||
|
||||
vbo_context_t& vbo_context_t::update(const size_t offset, const size_t size, const void* ptr)
|
||||
{
|
||||
BLT_CONTRACT(is_bound(), "Expected VBO to be bound before updating!");
|
||||
glBufferSubData(vbo.buffer_type, static_cast<GLsizeiptr>(offset), static_cast<GLsizeiptr>(size), ptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool vbo_context_t::is_bound() const
|
||||
{
|
||||
#if blt_debug_has_flag(BLT_DEBUG_CONTRACTS)
|
||||
return bound_vbo_ids[vbo.buffer_type] == *vbo.vboID;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
detail::vbo_context_t unique_vbo_t::bind()
|
||||
|
|
Loading…
Reference in New Issue