partial move
parent
8705a1d4e1
commit
e8ad56187e
|
@ -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/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>
|
|
@ -4,18 +4,23 @@
|
||||||
<mapping directory="" vcs="Git" />
|
<mapping directory="" vcs="Git" />
|
||||||
<mapping directory="$PROJECT_DIR$/cmake-build-debug-addrsan/_deps/freetype-src" vcs="Git" />
|
<mapping directory="$PROJECT_DIR$/cmake-build-debug-addrsan/_deps/freetype-src" vcs="Git" />
|
||||||
<mapping directory="$PROJECT_DIR$/cmake-build-debug-addrsan/_deps/freetype-src/subprojects/dlg" vcs="Git" />
|
<mapping directory="$PROJECT_DIR$/cmake-build-debug-addrsan/_deps/freetype-src/subprojects/dlg" vcs="Git" />
|
||||||
|
<mapping directory="$PROJECT_DIR$/cmake-build-debug-addrsan/_deps/glfw3-src" vcs="Git" />
|
||||||
<mapping directory="$PROJECT_DIR$/cmake-build-debug-addrsan/_deps/imgui-src" vcs="Git" />
|
<mapping directory="$PROJECT_DIR$/cmake-build-debug-addrsan/_deps/imgui-src" vcs="Git" />
|
||||||
<mapping directory="$PROJECT_DIR$/cmake-build-debug/_deps/freetype-src" vcs="Git" />
|
<mapping directory="$PROJECT_DIR$/cmake-build-debug/_deps/freetype-src" vcs="Git" />
|
||||||
<mapping directory="$PROJECT_DIR$/cmake-build-debug/_deps/freetype-src/subprojects/dlg" vcs="Git" />
|
<mapping directory="$PROJECT_DIR$/cmake-build-debug/_deps/freetype-src/subprojects/dlg" vcs="Git" />
|
||||||
|
<mapping directory="$PROJECT_DIR$/cmake-build-debug/_deps/glfw3-src" vcs="Git" />
|
||||||
<mapping directory="$PROJECT_DIR$/cmake-build-debug/_deps/imgui-src" vcs="Git" />
|
<mapping directory="$PROJECT_DIR$/cmake-build-debug/_deps/imgui-src" vcs="Git" />
|
||||||
<mapping directory="$PROJECT_DIR$/cmake-build-release/_deps/freetype-src" vcs="Git" />
|
<mapping directory="$PROJECT_DIR$/cmake-build-release/_deps/freetype-src" vcs="Git" />
|
||||||
<mapping directory="$PROJECT_DIR$/cmake-build-release/_deps/freetype-src/subprojects/dlg" vcs="Git" />
|
<mapping directory="$PROJECT_DIR$/cmake-build-release/_deps/freetype-src/subprojects/dlg" vcs="Git" />
|
||||||
|
<mapping directory="$PROJECT_DIR$/cmake-build-release/_deps/glfw3-src" vcs="Git" />
|
||||||
<mapping directory="$PROJECT_DIR$/cmake-build-release/_deps/imgui-src" vcs="Git" />
|
<mapping directory="$PROJECT_DIR$/cmake-build-release/_deps/imgui-src" vcs="Git" />
|
||||||
<mapping directory="$PROJECT_DIR$/cmake-build-relwithdebinfo-addrsan/_deps/freetype-src" vcs="Git" />
|
<mapping directory="$PROJECT_DIR$/cmake-build-relwithdebinfo-addrsan/_deps/freetype-src" vcs="Git" />
|
||||||
<mapping directory="$PROJECT_DIR$/cmake-build-relwithdebinfo-addrsan/_deps/freetype-src/subprojects/dlg" vcs="Git" />
|
<mapping directory="$PROJECT_DIR$/cmake-build-relwithdebinfo-addrsan/_deps/freetype-src/subprojects/dlg" vcs="Git" />
|
||||||
|
<mapping directory="$PROJECT_DIR$/cmake-build-relwithdebinfo-addrsan/_deps/glfw3-src" vcs="Git" />
|
||||||
<mapping directory="$PROJECT_DIR$/cmake-build-relwithdebinfo-addrsan/_deps/imgui-src" vcs="Git" />
|
<mapping directory="$PROJECT_DIR$/cmake-build-relwithdebinfo-addrsan/_deps/imgui-src" vcs="Git" />
|
||||||
<mapping directory="$PROJECT_DIR$/cmake-build-relwithdebinfo/_deps/freetype-src" vcs="Git" />
|
<mapping directory="$PROJECT_DIR$/cmake-build-relwithdebinfo/_deps/freetype-src" vcs="Git" />
|
||||||
<mapping directory="$PROJECT_DIR$/cmake-build-relwithdebinfo/_deps/freetype-src/subprojects/dlg" vcs="Git" />
|
<mapping directory="$PROJECT_DIR$/cmake-build-relwithdebinfo/_deps/freetype-src/subprojects/dlg" vcs="Git" />
|
||||||
|
<mapping directory="$PROJECT_DIR$/cmake-build-relwithdebinfo/_deps/glfw3-src" vcs="Git" />
|
||||||
<mapping directory="$PROJECT_DIR$/cmake-build-relwithdebinfo/_deps/imgui-src" vcs="Git" />
|
<mapping directory="$PROJECT_DIR$/cmake-build-relwithdebinfo/_deps/imgui-src" vcs="Git" />
|
||||||
<mapping directory="$PROJECT_DIR$/lib/blt-with-graphics" vcs="Git" />
|
<mapping directory="$PROJECT_DIR$/lib/blt-with-graphics" vcs="Git" />
|
||||||
<mapping directory="$PROJECT_DIR$/lib/blt-with-graphics/libraries/BLT" vcs="Git" />
|
<mapping directory="$PROJECT_DIR$/lib/blt-with-graphics/libraries/BLT" vcs="Git" />
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
cmake_minimum_required(VERSION 3.25)
|
cmake_minimum_required(VERSION 3.25)
|
||||||
project(gpu-particles VERSION 0.0.15)
|
project(gpu-particles VERSION 0.0.16)
|
||||||
|
|
||||||
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)
|
||||||
|
|
|
@ -49,6 +49,7 @@ pkgs.mkShell
|
||||||
libGL
|
libGL
|
||||||
libGL.dev
|
libGL.dev
|
||||||
glfw
|
glfw
|
||||||
|
libbacktrace
|
||||||
];
|
];
|
||||||
LD_LIBRARY_PATH="/run/opengl-driver/lib:/run/opengl-driver-32/lib";
|
LD_LIBRARY_PATH="/run/opengl-driver/lib:/run/opengl-driver-32/lib";
|
||||||
}
|
}
|
||||||
|
|
188
include/vao.h
188
include/vao.h
|
@ -1,188 +0,0 @@
|
||||||
#pragma once
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2024 Brett Terpstra
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 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
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BLT_GFX_VAO_H
|
|
||||||
#define BLT_GFX_VAO_H
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <vbo.h>
|
|
||||||
#include <blt/std/hashmap.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;
|
|
||||||
std::optional<hashset_t<u32>> attribute_numbers;
|
|
||||||
|
|
||||||
[[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:
|
|
||||||
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:
|
|
||||||
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;
|
|
||||||
bool attributed = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
class vao_context_t
|
|
||||||
{
|
|
||||||
friend vao_vbo_context_t;
|
|
||||||
friend unique_vao_t;
|
|
||||||
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& 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)
|
|
||||||
{
|
|
||||||
glGenVertexArrays(1, &*vaoID);
|
|
||||||
}
|
|
||||||
|
|
||||||
unique_vao_t(const unique_vao_t&) = delete;
|
|
||||||
|
|
||||||
unique_vao_t& operator=(const unique_vao_t&) = delete;
|
|
||||||
|
|
||||||
unique_vao_t(unique_vao_t&& other) noexcept: vaoID(std::exchange(other.vaoID, std::nullopt))
|
|
||||||
{}
|
|
||||||
|
|
||||||
unique_vao_t& operator=(unique_vao_t&& other) noexcept
|
|
||||||
{
|
|
||||||
vaoID = std::exchange(other.vaoID, vaoID);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
detail::vao_context_t bind();
|
|
||||||
|
|
||||||
[[nodiscard]] std::optional<ref<unique_vbo_t>> get_attribute(const u32 attribute) const
|
|
||||||
{
|
|
||||||
for (const auto& vbo_obj : vbo_list)
|
|
||||||
{
|
|
||||||
if (const auto attrs = vbo_obj.attribute_numbers)
|
|
||||||
{
|
|
||||||
if (attrs->contains(attribute))
|
|
||||||
return *vbo_obj.vbo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] std::optional<ref<unique_vbo_t>> get_buffer_type(const GLuint buffer_type) const
|
|
||||||
{
|
|
||||||
for (const auto& vbo_obj : vbo_list)
|
|
||||||
{
|
|
||||||
if (vbo_obj.vbo->get_buffer_type() == buffer_type)
|
|
||||||
return *vbo_obj.vbo;
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] std::optional<ref<unique_vbo_t>> get_element() const
|
|
||||||
{
|
|
||||||
for (const auto& vbo_obj : vbo_list)
|
|
||||||
{
|
|
||||||
if (vbo_obj.is_element())
|
|
||||||
return *vbo_obj.vbo;
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
~unique_vao_t()
|
|
||||||
{
|
|
||||||
if (vaoID)
|
|
||||||
glDeleteVertexArrays(1, &*vaoID);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::optional<GLuint> vaoID;
|
|
||||||
std::vector<detail::vao_vbo_storage_t> vbo_list;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //BLT_GFX_VAO_H
|
|
216
include/vbo.h
216
include/vbo.h
|
@ -1,216 +0,0 @@
|
||||||
#pragma once
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2024 Brett Terpstra
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 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
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BLT_GFX_VBO_H
|
|
||||||
#define BLT_GFX_VBO_H
|
|
||||||
|
|
||||||
#include <vbo.h>
|
|
||||||
#include <vbo.h>
|
|
||||||
#include <vbo.h>
|
|
||||||
#include <blt/gfx/gl_includes.h>
|
|
||||||
|
|
||||||
namespace blt::gfx
|
|
||||||
{
|
|
||||||
class unique_vbo_t;
|
|
||||||
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* So long as this class is called from vbo.bind(), it is always valid to chain any internal functions.
|
|
||||||
* This system is designed to be foolproof, so don't get too clever
|
|
||||||
*/
|
|
||||||
class vbo_context_t
|
|
||||||
{
|
|
||||||
friend unique_vbo_t;
|
|
||||||
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)
|
|
||||||
*
|
|
||||||
* It is very unlikely that you need this method!
|
|
||||||
*/
|
|
||||||
vbo_context_t& bind();
|
|
||||||
|
|
||||||
vbo_context_t& unbind();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reserves a chunk of GPU memory for future use
|
|
||||||
*/
|
|
||||||
vbo_context_t& resize(GLsizeiptr size, GLint mem_type);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reserves a chunk of GPU memory for future use
|
|
||||||
*/
|
|
||||||
vbo_context_t& resize(const size_t size, const GLint mem_type)
|
|
||||||
{
|
|
||||||
return resize(static_cast<GLsizeiptr>(size), mem_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Uploads a chunk of memory to the GPU. If the existing VBO has enough space, the memory will be reused.
|
|
||||||
*/
|
|
||||||
vbo_context_t& upload(size_t size, const void* ptr, GLint mem_type);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Uploads a chunk of memory to the GPU. If the existing VBO has enough space, the memory will be reused.
|
|
||||||
*/
|
|
||||||
template <typename T, std::enable_if_t<!std::is_same_v<T, void>, bool> = true>
|
|
||||||
vbo_context_t& upload(const size_t size, T* ptr, const GLint mem_type)
|
|
||||||
{
|
|
||||||
return upload(size, static_cast<void*>(ptr), mem_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates an internal segment of the VBO. This function will never reallocate.
|
|
||||||
*/
|
|
||||||
vbo_context_t& update(size_t offset, size_t size, const void* ptr);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates an internal segment of the VBO. This function will never reallocate.
|
|
||||||
*/
|
|
||||||
template <typename T, std::enable_if_t<!std::is_same_v<T, void>, bool> = true>
|
|
||||||
vbo_context_t& update(const size_t offset, const size_t size, T* ptr)
|
|
||||||
{
|
|
||||||
return update(offset, size, static_cast<void*>(ptr));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
[[nodiscard]] bool is_bound() const;
|
|
||||||
|
|
||||||
explicit vbo_context_t(unique_vbo_t& vbo): vbo(vbo)
|
|
||||||
{
|
|
||||||
bind();
|
|
||||||
}
|
|
||||||
|
|
||||||
unique_vbo_t& vbo;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
class unique_vbo_t
|
|
||||||
{
|
|
||||||
friend class detail::vbo_context_t;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit unique_vbo_t(const GLuint type): vboID(0), buffer_type(type)
|
|
||||||
{
|
|
||||||
glGenBuffers(1, &*vboID);
|
|
||||||
}
|
|
||||||
|
|
||||||
unique_vbo_t(const unique_vbo_t&) = delete;
|
|
||||||
|
|
||||||
unique_vbo_t& operator=(const unique_vbo_t&) = delete;
|
|
||||||
|
|
||||||
unique_vbo_t(unique_vbo_t&& other) noexcept: vboID(std::exchange(other.vboID, std::nullopt)), buffer_type(other.buffer_type),
|
|
||||||
size(other.size), memory_type(other.memory_type)
|
|
||||||
{}
|
|
||||||
|
|
||||||
unique_vbo_t& operator=(unique_vbo_t&& other) noexcept
|
|
||||||
{
|
|
||||||
vboID = std::exchange(other.vboID, vboID);
|
|
||||||
buffer_type = std::exchange(other.buffer_type, buffer_type);
|
|
||||||
size = std::exchange(other.size, size);
|
|
||||||
memory_type = std::exchange(other.memory_type, memory_type);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Changes the internal buffer type of this VBO
|
|
||||||
*/
|
|
||||||
GLuint change_type(const GLuint type)
|
|
||||||
{
|
|
||||||
return std::exchange(this->buffer_type, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function binds the VBO to the current buffer_type slot and returns an object which allows you to modify or use this VBO.
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
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)
|
|
||||||
glDeleteBuffers(1, &*vboID);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::optional<GLuint> vboID;
|
|
||||||
GLuint buffer_type;
|
|
||||||
GLsizeiptr size = 0;
|
|
||||||
GLint memory_type = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class unique_ssbo_t : public unique_vbo_t
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
unique_ssbo_t(): unique_vbo_t{GL_SHADER_STORAGE_BUFFER}
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
class unique_ebo_t : public unique_vbo_t
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
unique_ebo_t(): unique_vbo_t{GL_ELEMENT_ARRAY_BUFFER}
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
class unique_ubo_t : public unique_vbo_t
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit unique_ubo_t(const i32 location): unique_vbo_t{GL_UNIFORM_BUFFER}
|
|
||||||
{set_location(location);}
|
|
||||||
|
|
||||||
void set_location(i32 new_location);
|
|
||||||
|
|
||||||
[[nodiscard]] i32 get_location() const
|
|
||||||
{
|
|
||||||
return location;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
i32 location = 0;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //BLT_GFX_VBO_H
|
|
16
src/main.cpp
16
src/main.cpp
|
@ -14,16 +14,16 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
#include <imgui.h>
|
||||||
|
#include <blt/gfx/vao.h>
|
||||||
|
#include <blt/gfx/vbo.h>
|
||||||
#include <blt/gfx/window.h>
|
#include <blt/gfx/window.h>
|
||||||
#include "blt/gfx/renderer/resource_manager.h"
|
|
||||||
#include "blt/gfx/renderer/batch_2d_renderer.h"
|
|
||||||
#include "blt/gfx/renderer/camera.h"
|
|
||||||
#include <blt/std/random.h>
|
#include <blt/std/random.h>
|
||||||
#include <vao.h>
|
|
||||||
#include <vbo.h>
|
|
||||||
#include <shaders/particle.frag>
|
#include <shaders/particle.frag>
|
||||||
#include <shaders/particle.vert>
|
#include <shaders/particle.vert>
|
||||||
#include <imgui.h>
|
#include "blt/gfx/renderer/batch_2d_renderer.h"
|
||||||
|
#include "blt/gfx/renderer/camera.h"
|
||||||
|
#include "blt/gfx/renderer/resource_manager.h"
|
||||||
|
|
||||||
constexpr blt::size_t PARTICLE_COUNT = 8192;
|
constexpr blt::size_t PARTICLE_COUNT = 8192;
|
||||||
|
|
||||||
|
@ -70,10 +70,9 @@ public:
|
||||||
unique_ebo_t alive_particles_ebo;
|
unique_ebo_t alive_particles_ebo;
|
||||||
alive_particles_ebo.bind().upload(sizeof(blt::u32) * alive_particles.size(), alive_particles.data(), GL_DYNAMIC_DRAW);
|
alive_particles_ebo.bind().upload(sizeof(blt::u32) * alive_particles.size(), alive_particles.data(), GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
auto vao_ctx = particle_vao.bind();
|
const auto vao_ctx = particle_vao.configure();
|
||||||
vao_ctx.attach_vbo(std::move(particle_vbo)).attribute_ptr(0, 2, GL_FLOAT, sizeof(particle_t), 0);
|
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));
|
vao_ctx.attach_vbo(std::move(alive_particles_ebo));
|
||||||
vao_ctx.unbind();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void render()
|
void render()
|
||||||
|
@ -84,7 +83,6 @@ public:
|
||||||
particle_shader->setInt("tex1", 0);
|
particle_shader->setInt("tex1", 0);
|
||||||
particle_shader->setInt("tex2", 1);
|
particle_shader->setInt("tex2", 1);
|
||||||
particle_vao.bind();
|
particle_vao.bind();
|
||||||
// particle_vao.get_element()->get().bind();
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
resources.get("silly").value()->bind();
|
resources.get("silly").value()->bind();
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
|
93
src/vao.cpp
93
src/vao.cpp
|
@ -1,93 +0,0 @@
|
||||||
/*
|
|
||||||
* <Short Description>
|
|
||||||
* Copyright (C) 2025 Brett Terpstra
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 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
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* 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 ENSURE_CONTEXT_BOUND BLT_CONTRACT(glfwGetCurrentContext() != nullptr, "Expected active OpenGL context!")
|
|
||||||
|
|
||||||
#if blt_debug_has_flag(BLT_DEBUG_CONTRACTS)
|
|
||||||
GLuint bound_vao_id = 0;
|
|
||||||
#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 (!vbo.attribute_numbers)
|
|
||||||
vbo.attribute_numbers = hashset_t<u32>();
|
|
||||||
if (!vbo.attribute_numbers->contains(attribute_number))
|
|
||||||
vbo.attribute_numbers->insert(attribute_number);
|
|
||||||
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()
|
|
||||||
{
|
|
||||||
ENSURE_CONTEXT_BOUND;
|
|
||||||
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
|
|
||||||
{
|
|
||||||
ENSURE_CONTEXT_BOUND;
|
|
||||||
glBindVertexArray(0);
|
|
||||||
bound_vao_id = 0;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
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(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()
|
|
||||||
{
|
|
||||||
ENSURE_CONTEXT_BOUND;
|
|
||||||
return detail::vao_context_t{*this};
|
|
||||||
}
|
|
||||||
}
|
|
103
src/vbo.cpp
103
src/vbo.cpp
|
@ -1,103 +0,0 @@
|
||||||
/*
|
|
||||||
* <Short Description>
|
|
||||||
* Copyright (C) 2025 Brett Terpstra
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 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
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#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 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);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
vbo.memory_type = mem_type;
|
|
||||||
glBufferData(vbo.buffer_type, vbo.size, ptr, mem_type);
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
update(0, size, ptr);
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
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()
|
|
||||||
{
|
|
||||||
BLT_CONTRACT(glfwGetCurrentContext() != nullptr, "Expected active OpenGL context!");
|
|
||||||
return detail::vbo_context_t{*this};
|
|
||||||
}
|
|
||||||
|
|
||||||
void unique_ubo_t::set_location(const i32 new_location)
|
|
||||||
{
|
|
||||||
BLT_CONTRACT(native_handle().has_value(), "Expected UBO to have an associated buffer! (You are probably calling this on a moved-from value)");
|
|
||||||
location = new_location;
|
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, location, *native_handle());
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue