vbo and vao
parent
b1bf0a58f6
commit
67785f465e
|
@ -283,11 +283,8 @@
|
||||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_CAST_EXPRESSION_PARENTHESES/@EntryValue" value="true" type="bool" />
|
<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_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/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/SortIncludeDirectives/@EntryValue" value="true" type="bool" />
|
||||||
<option name="/Default/CodeStyle/CppIncludeDirective/UseAngleBracketsInsteadOfQuotes/@EntryValue" value="WhenPossible" type="string" />
|
<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/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>
|
</component>
|
||||||
</project>
|
</project>
|
|
@ -1,5 +1,5 @@
|
||||||
cmake_minimum_required(VERSION 3.25)
|
cmake_minimum_required(VERSION 3.25)
|
||||||
project(gpu-particles VERSION 0.0.12)
|
project(gpu-particles VERSION 0.0.13)
|
||||||
|
|
||||||
option(ENABLE_ADDRSAN "Enable the address sanitizer" OFF)
|
option(ENABLE_ADDRSAN "Enable the address sanitizer" OFF)
|
||||||
option(ENABLE_UBSAN "Enable the ub sanitizer" OFF)
|
option(ENABLE_UBSAN "Enable the ub sanitizer" OFF)
|
||||||
|
|
|
@ -32,7 +32,7 @@ namespace blt::gfx
|
||||||
struct vao_vbo_storage_t
|
struct vao_vbo_storage_t
|
||||||
{
|
{
|
||||||
std::unique_ptr<unique_vbo_t> vbo;
|
std::unique_ptr<unique_vbo_t> vbo;
|
||||||
u32 attribute_number = 0;
|
std::optional<std::vector<u32>> attribute_numbers;
|
||||||
|
|
||||||
[[nodiscard]] bool is_element() const
|
[[nodiscard]] bool is_element() const
|
||||||
{
|
{
|
||||||
|
@ -47,21 +47,55 @@ namespace blt::gfx
|
||||||
{
|
{
|
||||||
friend class vao_context_t;
|
friend class vao_context_t;
|
||||||
public:
|
public:
|
||||||
|
vao_vbo_context_t(const vao_vbo_context_t& copy) = delete;
|
||||||
|
vao_vbo_context_t(vao_vbo_context_t&& move) = delete;
|
||||||
|
vao_vbo_context_t& operator=(const vao_vbo_context_t& copy) = delete;
|
||||||
|
vao_vbo_context_t& operator=(vao_vbo_context_t&& move) = delete;
|
||||||
|
/**
|
||||||
|
* This function takes ownership of the underlying VBO (GPU side). It will be freed when the basic vertex array is deleted
|
||||||
|
* @param attribute_number attribute number to bind to
|
||||||
|
* @param coordinate_size size of the data (number of elements, not the number of bytes)
|
||||||
|
* @param type GL_TYPE type of data
|
||||||
|
* @param stride how many bytes this data takes (for the entire per-vertex data structure) 0 will assume packed data
|
||||||
|
* This is in effect how many bytes until the next block of data
|
||||||
|
* @param offset offset into the data structure to where the data is stored
|
||||||
|
*/
|
||||||
|
vao_vbo_context_t& attribute_ptr(int attribute_number, int coordinate_size, GLenum type, int stride, long offset);
|
||||||
|
|
||||||
|
vao_vbo_context_t& silence()
|
||||||
|
{
|
||||||
|
attributed = true;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Useless function, but if it makes you feel better, feel free to use it.
|
||||||
|
*/
|
||||||
|
vao_vbo_context_t& as_element()
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~vao_vbo_context_t();
|
||||||
private:
|
private:
|
||||||
vao_vbo_context_t(unique_vao_t& vao, vao_vbo_storage_t& vbo): vbo(vbo), vao(vao)
|
vao_vbo_context_t(unique_vao_t& vao, vao_vbo_storage_t& vbo): vbo(vbo), vao(vao)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
vao_vbo_storage_t& vbo;
|
vao_vbo_storage_t& vbo;
|
||||||
unique_vao_t& vao;
|
unique_vao_t& vao;
|
||||||
|
bool attributed = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class vao_context_t
|
class vao_context_t
|
||||||
{
|
{
|
||||||
friend vao_vbo_context_t;
|
friend vao_vbo_context_t;
|
||||||
friend class unique_vao_t;
|
friend unique_vao_t;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
vao_context_t(const vao_context_t& copy) = delete;
|
||||||
|
vao_context_t(vao_context_t&& move) = delete;
|
||||||
|
vao_context_t& operator=(const vao_context_t& copy) = delete;
|
||||||
|
vao_context_t& operator=(vao_context_t&& move) = delete;
|
||||||
|
|
||||||
vao_context_t& bind();
|
vao_context_t& bind();
|
||||||
|
|
||||||
vao_context_t& unbind();
|
vao_context_t& unbind();
|
||||||
|
|
|
@ -38,6 +38,10 @@ namespace blt::gfx
|
||||||
{
|
{
|
||||||
friend unique_vbo_t;
|
friend unique_vbo_t;
|
||||||
public:
|
public:
|
||||||
|
vbo_context_t(const vbo_context_t& copy) = delete;
|
||||||
|
vbo_context_t(vbo_context_t&& move) = delete;
|
||||||
|
vbo_context_t& operator=(const vbo_context_t& copy) = delete;
|
||||||
|
vbo_context_t& operator=(vbo_context_t&& move) = delete;
|
||||||
/**
|
/**
|
||||||
* By default, the VBO is bound when this class is constructed (this class should only be constructed through the VBO bind() method)
|
* By default, the VBO is bound when this class is constructed (this class should only be constructed through the VBO bind() method)
|
||||||
*
|
*
|
||||||
|
|
24
src/main.cpp
24
src/main.cpp
|
@ -24,7 +24,6 @@
|
||||||
#include <shaders/particle.frag>
|
#include <shaders/particle.frag>
|
||||||
#include <shaders/particle.vert>
|
#include <shaders/particle.vert>
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
#include <blt/std/ranges.h>
|
|
||||||
|
|
||||||
constexpr blt::size_t PARTICLE_COUNT = 8192;
|
constexpr blt::size_t PARTICLE_COUNT = 8192;
|
||||||
|
|
||||||
|
@ -48,9 +47,7 @@ struct particle_t
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<blt::gfx::vertex_array_t> particle_vao;
|
std::optional<blt::gfx::unique_vao_t> particle_vao;
|
||||||
std::unique_ptr<blt::gfx::vertex_buffer_t> particle_vbo;
|
|
||||||
std::unique_ptr<blt::gfx::element_buffer_t> alive_particles_ebo;
|
|
||||||
std::unique_ptr<blt::gfx::shader_t> particle_shader;
|
std::unique_ptr<blt::gfx::shader_t> particle_shader;
|
||||||
|
|
||||||
std::vector<blt::u32> alive_particles;
|
std::vector<blt::u32> alive_particles;
|
||||||
|
@ -69,17 +66,16 @@ void init(const blt::gfx::window_data&)
|
||||||
alive_particles.push_back(i);
|
alive_particles.push_back(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
particle_vbo = std::make_unique<vertex_buffer_t>();
|
unique_vbo_t particle_vbo(GL_ARRAY_BUFFER);
|
||||||
particle_vbo->create(GL_ARRAY_BUFFER);
|
particle_vbo.bind().upload(sizeof(particle_t) * particles.size(), particles.data(), GL_DYNAMIC_DRAW);
|
||||||
particle_vbo->allocate(sizeof(particle_t) * particles.size(), GL_DYNAMIC_DRAW, particles.data());
|
|
||||||
|
|
||||||
alive_particles_ebo = std::make_unique<element_buffer_t>();
|
unique_ebo_t alive_particles_ebo;
|
||||||
alive_particles_ebo->create();
|
alive_particles_ebo.bind().upload(sizeof(blt::u32) * alive_particles.size(), alive_particles.data(), GL_DYNAMIC_DRAW);
|
||||||
alive_particles_ebo->allocate(sizeof(blt::u32) * alive_particles.size(), GL_DYNAMIC_DRAW, alive_particles.data());
|
|
||||||
|
|
||||||
particle_vao = std::make_unique<vertex_array_t>();
|
particle_vao = unique_vao_t();
|
||||||
particle_vao->bindVBO(*particle_vbo, 0, 2, GL_FLOAT, sizeof(particle_t), 0);
|
const auto vao_ctx = particle_vao->bind();
|
||||||
particle_vao->bindElement(*alive_particles_ebo);
|
vao_ctx.attach_vbo(std::move(particle_vbo)).attribute_ptr(0, 2, GL_FLOAT, sizeof(particle_t), 0);
|
||||||
|
vao_ctx.attach_vbo(std::move(alive_particles_ebo));
|
||||||
|
|
||||||
global_matrices.create_internals();
|
global_matrices.create_internals();
|
||||||
resources.load_resources();
|
resources.load_resources();
|
||||||
|
@ -99,6 +95,8 @@ void update(const blt::gfx::window_data& data)
|
||||||
|
|
||||||
void destroy(const blt::gfx::window_data&)
|
void destroy(const blt::gfx::window_data&)
|
||||||
{
|
{
|
||||||
|
particle_vao.reset();
|
||||||
|
particle_shader.reset();
|
||||||
global_matrices.cleanup();
|
global_matrices.cleanup();
|
||||||
resources.cleanup();
|
resources.cleanup();
|
||||||
renderer_2d.cleanup();
|
renderer_2d.cleanup();
|
||||||
|
|
38
src/vao.cpp
38
src/vao.cpp
|
@ -22,14 +22,45 @@
|
||||||
|
|
||||||
namespace blt::gfx
|
namespace blt::gfx
|
||||||
{
|
{
|
||||||
#define BLT_DEBUG_LEVEL BLT_DEBUG_CONTRACTS
|
#define ENSURE_CONTEXT_BOUND BLT_CONTRACT(glfwGetCurrentContext() != nullptr, "Expected active OpenGL context!")
|
||||||
|
|
||||||
#if blt_debug_has_flag(BLT_DEBUG_CONTRACTS)
|
#if blt_debug_has_flag(BLT_DEBUG_CONTRACTS)
|
||||||
GLuint bound_vao_id;
|
GLuint bound_vao_id;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
detail::vao_vbo_context_t& detail::vao_vbo_context_t::attribute_ptr(const int attribute_number, const int coordinate_size, const GLenum type,
|
||||||
|
const int stride, const long offset)
|
||||||
|
{
|
||||||
|
if (auto& vec = vbo.attribute_numbers)
|
||||||
|
{
|
||||||
|
for (const auto& v : *vec)
|
||||||
|
{
|
||||||
|
if (static_cast<i32>(v) == attribute_number)
|
||||||
|
goto use;
|
||||||
|
}
|
||||||
|
vec->push_back(attribute_number);
|
||||||
|
}
|
||||||
|
use:
|
||||||
|
glEnableVertexAttribArray(attribute_number);
|
||||||
|
glVertexAttribPointer(attribute_number, coordinate_size, type, GL_FALSE, stride < 0 ? 0 : stride, reinterpret_cast<void*>(offset));
|
||||||
|
attributed = true;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
detail::vao_vbo_context_t::~vao_vbo_context_t()
|
||||||
|
{
|
||||||
|
#if blt_debug_has_flag(BLT_DEBUG_CONTRACTS)
|
||||||
|
if (!(vbo.is_element() || attributed))
|
||||||
|
{
|
||||||
|
BLT_WARN("VBO is not an element array buffer or been assigned to an attribute, are you sure this is what you want?");
|
||||||
|
BLT_WARN("You can silence this warning by calling .silence()");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
detail::vao_context_t& detail::vao_context_t::bind()
|
detail::vao_context_t& detail::vao_context_t::bind()
|
||||||
{
|
{
|
||||||
|
ENSURE_CONTEXT_BOUND;
|
||||||
BLT_CONTRACT(vao.vaoID, "Expected VAO to have an associated VAO ID!");
|
BLT_CONTRACT(vao.vaoID, "Expected VAO to have an associated VAO ID!");
|
||||||
glBindVertexArray(*vao.vaoID);
|
glBindVertexArray(*vao.vaoID);
|
||||||
bound_vao_id = *vao.vaoID;
|
bound_vao_id = *vao.vaoID;
|
||||||
|
@ -45,6 +76,7 @@ namespace blt::gfx
|
||||||
|
|
||||||
detail::vao_vbo_context_t detail::vao_context_t::attach_vbo(unique_vbo_t&& vbo) const
|
detail::vao_vbo_context_t detail::vao_context_t::attach_vbo(unique_vbo_t&& vbo) const
|
||||||
{
|
{
|
||||||
|
ENSURE_CONTEXT_BOUND;
|
||||||
BLT_CONTRACT(vao.vaoID, "Expected VAO to have an associated VAO ID!");
|
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!)");
|
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!)");
|
||||||
|
|
||||||
|
@ -60,7 +92,7 @@ namespace blt::gfx
|
||||||
|
|
||||||
detail::vao_context_t unique_vao_t::bind()
|
detail::vao_context_t unique_vao_t::bind()
|
||||||
{
|
{
|
||||||
BLT_CONTRACT(glfwGetCurrentContext() != nullptr, "Expected active OpenGL context!");
|
ENSURE_CONTEXT_BOUND;
|
||||||
return detail::vao_context_t{*this};
|
return detail::vao_context_t{*this};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue