158 lines
4.2 KiB
C++
158 lines
4.2 KiB
C++
/**
|
|
This file is a part of our_dick
|
|
Copyright (C) 2022 rexy712
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef OUR_DICK_GRAPHICS_OGL_UBO_HPP
|
|
#define OUR_DICK_GRAPHICS_OGL_UBO_HPP
|
|
|
|
#include "gl_include.hpp"
|
|
|
|
#include <rml/mat.hpp>
|
|
#include <rml/vec.hpp>
|
|
|
|
#include <type_traits> //a lot of stuff
|
|
|
|
#include "buffer_map.hpp"
|
|
|
|
namespace gfx::ogl{
|
|
|
|
namespace detail{
|
|
template<class T>
|
|
struct is_bounded_array{
|
|
static constexpr bool value = false;
|
|
};
|
|
template<class T, size_t I>
|
|
struct is_bounded_array<T[I]>{
|
|
static constexpr bool value = true;
|
|
};
|
|
|
|
template<class T>
|
|
struct is_valid_uniform_scalar{
|
|
static constexpr bool value = std::is_same_v<T,GLint> ||
|
|
std::is_same_v<T,GLuint> ||
|
|
std::is_same_v<T,bool> ||
|
|
std::is_same_v<T,GLfloat> ||
|
|
std::is_same_v<T,GLdouble>;
|
|
};
|
|
template<class T>
|
|
struct is_valid_uniform_matrix{
|
|
template<class U, size_t R, size_t C>
|
|
static constexpr bool test(rml::matrix_base<U,R,C>*){
|
|
return is_valid_uniform_scalar<typename T::value_type>::value && T::Columns <= 4 && T::Rows <= 4;
|
|
}
|
|
static constexpr bool test(void*){
|
|
return false;
|
|
}
|
|
static constexpr bool value = test(static_cast<std::decay_t<T>*>(nullptr));
|
|
};
|
|
template<class T>
|
|
struct is_valid_uniform_type{
|
|
static constexpr bool value = is_valid_uniform_scalar<T>::value || is_valid_uniform_matrix<T>::value || is_bounded_array<T>::value;
|
|
};
|
|
template<size_t I, class Type, class... Types>
|
|
struct get_type{
|
|
using type = typename get_type<I-1, Types...>::type;
|
|
};
|
|
template<class Type, class... Types>
|
|
struct get_type<0, Type, Types...>{
|
|
using type = Type;
|
|
};
|
|
template<class... Types>
|
|
struct get_type<0,bool,Types...>{
|
|
using type = int;
|
|
};
|
|
|
|
template<size_t I, class... Types>
|
|
using get_type_t = typename get_type<I, Types...>::type;
|
|
|
|
|
|
template<class T>
|
|
constexpr size_t get_alignment_of_(void);
|
|
template<class T>
|
|
constexpr size_t get_alignment_multiple_(void);
|
|
template<class T>
|
|
constexpr size_t size_of_(void);
|
|
}
|
|
|
|
|
|
//Class for a uniform buffer object
|
|
//automatically sets alignments for std140 uniform blocks
|
|
template<class... Types>
|
|
class ubo
|
|
{
|
|
private:
|
|
static_assert((detail::is_valid_uniform_type<Types>::value && ...));
|
|
|
|
public:
|
|
static constexpr size_t num_elements = sizeof...(Types);
|
|
|
|
template<size_t I>
|
|
using type_of = detail::get_type_t<I, Types...>;
|
|
|
|
private:
|
|
GLuint m_buffer = 0;
|
|
|
|
public:
|
|
ubo(buffer::usage usage = buffer::usage::DYNAMIC_DRAW);
|
|
ubo(const ubo&);
|
|
ubo(ubo&&);
|
|
~ubo(void);
|
|
|
|
ubo& operator=(const ubo&);
|
|
ubo& operator=(ubo&&);
|
|
|
|
|
|
//raw modify the data (NOT A GOOD IDEA)
|
|
scoped_buffer_map<void> map(buffer::maptype m);
|
|
void buffer(const void* data, size_t datasize, size_t start);
|
|
void initialize(unsigned char value = 0);
|
|
|
|
//Safely modify the data to comply with GLSL std140 layout
|
|
template<size_t I>
|
|
auto get(void);
|
|
template<size_t I, class T>
|
|
void set(T&& t);
|
|
|
|
//Direct access to opengl handle
|
|
GLuint raw(void)const;
|
|
|
|
size_t get_size(void)const;
|
|
size_t get_cap(void)const;
|
|
buffer::usage get_usage(void)const;
|
|
|
|
//Bind to uniform block binding location
|
|
void bind(size_t index)const;
|
|
private:
|
|
template<size_t I>
|
|
static constexpr size_t get_offset_of_(void);
|
|
template<size_t I>
|
|
static constexpr size_t get_alignment_of_(void);
|
|
static constexpr size_t get_total_size_(void);
|
|
|
|
public:
|
|
template<size_t I>
|
|
static constexpr size_t offset_of = get_offset_of_<I>();
|
|
template<size_t I>
|
|
static constexpr size_t alignment_of = get_alignment_of_<I>();
|
|
};
|
|
|
|
}
|
|
|
|
#include "ubo.tpp"
|
|
|
|
#endif
|