Integrate some wip changes into pause_state

This commit is contained in:
rexy712 2022-02-18 16:57:14 -08:00
parent 0cc6c7fff6
commit f2fa02336b
57 changed files with 891 additions and 601 deletions

View File

@ -45,42 +45,64 @@
#ifdef OUR_DICK_ENABLE_DEBUG_OUTPUT
#define OUR_DICK_DEBUG_NULL_STATEMENT do{;}while(0)
#include <cstdio>
#include "util/source_location.hpp"
#define debug_print_impl(loc, ...) do{ std::fprintf(stderr, "%s:%s:%d: ", loc.file_name(), loc.function_name(), loc.line()); std::fprintf(stderr, __VA_ARGS__); }while(0)
#define debug_print_impl(location, ...) do{ auto loc = location; std::fprintf(stderr, "%s:%s:%d: ", loc.file_name(), loc.function_name(), loc.line()); std::fprintf(stderr, __VA_ARGS__); }while(0)
#define debug_print(...) debug_print_impl(util::source_location::current(), __VA_ARGS__)
#ifdef OUR_DICK_ENABLE_DEBUG_VERBOSE_OUTPUT
#define debug_print_verbose(...) debug_print(__VA_ARGS__)
#else
#define debug_print_verbose(...)
#endif
#ifdef OUR_DICK_ENABLE_COLOR_DEBUG
#define OUR_DICK_DEBUG_PRINT_RED "\033[38;5;9m"
#define OUR_DICK_DEBUG_PRINT_YELLOW "\033[38;5;11m"
#define OUR_DICK_DEBUG_PRINT_GREEN "\033[38;5;2m"
#define OUR_DICK_DEBUG_PRINT_BLUE "\033[38;5;12m"
#define OUR_DICK_DEBUG_PRINT_CLEAR "\033[0m"
#define debug_print_color_base(color, ...) do{ std::fprintf(stderr, color); debug_print(__VA_ARGS__); std::fprintf(stderr, OUR_DICK_DEBUG_PRINT_CLEAR); }while(0)
#define debug_print_warn(...) debug_print_color_base(OUR_DICK_DEBUG_PRINT_YELLOW, __VA_ARGS__)
#define debug_print_error(...) debug_print_color_base(OUR_DICK_DEBUG_PRINT_RED, __VA_ARGS__)
#define debug_print_succ(...) debug_print_color_base(OUR_DICK_DEBUG_PRINT_GREEN, __VA_ARGS__)
#define debug_print_info(...) debug_print_color_base(OUR_DICK_DEBUG_PRINT_BLUE, __VA_ARGS__)
#else
#define debug_print_error(...) debug_print(__VA_ARGS__)
#define debug_print_warn(...) debug_print(__VA_ARGS__)
#define debug_print_succ(...) debug_print(__VA_ARGS__)
#define debug_print_info(...) debug_print(__VA_ARGS__)
#endif
#ifdef OUR_DICK_ENABLE_DEBUG_VERBOSE_OUTPUT
#define debug_print_verbose(...) debug_print(__VA_ARGS__)
#define debug_print_verbose_warn(...) debug_print_warn(__VA_ARGS__)
#define debug_print_verbose_error(...) debug_print_error(__VA_ARGS__)
#define debug_print_verbose_succ(...) debug_print_succ(__VA_ARGS__)
#define debug_print_verbose_info(...) debug_print_info(__VA_ARGS__)
#else
#define debug_print_verbose(...) OUR_DICK_DEBUG_NULL_STATEMENT
#define debug_print_verbose_warn(...) OUR_DICK_DEBUG_NULL_STATEMENT
#define debug_print_verbose_error(...) OUR_DICK_DEBUG_NULL_STATEMENT
#define debug_print_verbose_succ(...) OUR_DICK_DEBUG_NULL_STATEMENT
#define debug_print_verbose_info(...) OUR_DICK_DEBUG_NULL_STATEMENT
#endif
#else
#define OUR_DICK_DEBUG_NULL_STATEMENT
#define debug_print(...) OUR_DICK_DEBUG_NULL_STATEMENT
#define debug_print_error(...) OUR_DICK_DEBUG_NULL_STATEMENT
#define debug_print_warn(...) OUR_DICK_DEBUG_NULL_STATEMENT
#define debug_print_succ(...) OUR_DICK_DEBUG_NULL_STATEMENT
#define debug_print_info(...) OUR_DICK_DEBUG_NULL_STATEMENT
#define debug_print_verbose(...) OUR_DICK_DEBUG_NULL_STATEMENT
#define debug_print_verbose_warn(...) OUR_DICK_DEBUG_NULL_STATEMENT
#define debug_print_verbose_error(...) OUR_DICK_DEBUG_NULL_STATEMENT
#define debug_print_verbose_succ(...) OUR_DICK_DEBUG_NULL_STATEMENT
#define debug_print_verbose_info(...) OUR_DICK_DEBUG_NULL_STATEMENT
#endif
#ifdef OUR_DICK_ENABLE_DEBUG_VERBOSE_OUTPUT
#include <typeinfo>
#endif
#include "util/demangle.hpp"
#endif

View File

@ -24,6 +24,7 @@
#include "gfx/ogl/window.hpp"
#include "input.hpp"
#include "math/vec.hpp"
#include "wip/renderer.hpp"
#include <queue>
@ -33,6 +34,7 @@ namespace egn{
{
protected:
gfx::ogl::window m_window;
wip::gfx::renderer m_renderer;
game_state_manager m_states_manager;
std::queue<input_event> m_event_queue;
double m_last_time;
@ -52,8 +54,8 @@ namespace egn{
void on_notify(const game_state_event& e)override;
gfx::resource_manager& gfx_resource_manager(void);
const gfx::resource_manager& gfx_resource_manager(void)const;
wip::gfx::renderer& renderer(void);
const wip::gfx::renderer& renderer(void)const;
void push_state(std::unique_ptr<game_state_iface>&&);
void pop_state(void);

View File

@ -22,6 +22,8 @@
#include "observable.hpp"
#include "input.hpp"
#include "wip/renderer.hpp"
#include <stack>
#include <memory>
#include <queue>
@ -71,6 +73,9 @@ namespace egn{
game_state_iface& operator=(const game_state_iface&) = default;
game_state_iface& operator=(game_state_iface&&) = default;
wip::gfx::renderer& renderer(void);
const wip::gfx::renderer& renderer(void)const;
public:
virtual ~game_state_iface(void) = default;

View File

@ -27,39 +27,51 @@
namespace gfx::ogl{
//Class representing a framebuffer object
class fbo
{
private:
GLuint m_buffer;
math::vec4f m_vp_coords;
math::vec4f m_vp_coords; //Opengl doesn't associate viewports with framebuffers, so i do
public:
//Construct an object representing the default 'root' framebuffer
fbo(void);
//build a framebuffer object with given attachments of textures or render buffers
template<typename... Args>
explicit fbo(Args&&... args);
explicit fbo(util::no_initialize_t);
fbo(const fbo&) = delete;
fbo(const fbo&) = delete; //TODO
fbo(fbo&& f);
~fbo(void);
fbo& operator=(const fbo&) = delete;
fbo& operator=(fbo&& f);
//Direct access to opengl handle
GLuint raw(void)const;
//Remove attached textures or renderbuffers
bool detach(GLenum point);
//Add a new texture or renderbuffer attachment
bool attach(const texture& tex, GLenum point);
bool attach(const rbo& r, GLenum point);
//Clear individual fields
void clear_color_buffer(const math::vec4f& color = {0.0f, 0.0f, 0.0f, 1.0f});
void clear_depth_buffer(GLfloat value = 1.0f);
void clear_stencil_buffer(GLint value = 0);
//Clear fields as by glClear
void clear(GLbitfield mask);
//Assign this framebuffer's viewport
void set_viewport(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2);
//Activate this framebuffer's viewport. Calls glViewport
void apply_viewport(void)const;
const math::vec4f& get_viewport(void)const;
//Set this as the active framebuffer
bool bind(void)const;
private:
template<typename... Args>

View File

@ -23,6 +23,7 @@
namespace gfx::ogl{
//Class representing a renderbuffer object
class rbo
{
private:
@ -41,9 +42,12 @@ namespace gfx::ogl{
rbo& operator=(const rbo& r) = delete;
rbo& operator=(rbo&& r);
//Raw access to opengl handle
GLuint raw(void)const;
//Set this as the active renderbuffer
void bind(void)const;
//Reset to default renderbuffer binding
void unbind(void)const;
void resize(GLsizei w, GLsizei h);

View File

@ -117,7 +117,6 @@ namespace gfx::ogl{
//Texture
void set(const texture&, GLuint tex_unit = 0);
void set(const texture_array& t, GLuint tex_unit = 0);
void set(const weak_texture&, GLuint tex_unit = 0);
//Float vectors
void set(const vec2f&);

View File

@ -25,31 +25,6 @@
namespace gfx::ogl{
class texture;
class weak_texture
{
private:
GLuint m_texture;
public:
weak_texture(GLuint tex);
weak_texture(const texture& tex);
weak_texture(const weak_texture&) = default;
weak_texture(weak_texture&&) = default;
~weak_texture(void) = default;
weak_texture& operator=(const weak_texture&) = default;
weak_texture& operator=(weak_texture&&) = default;
GLuint raw(void)const;
GLsizei get_width(void)const;
GLsizei get_height(void)const;
void bind(GLuint target = GL_TEXTURE_2D)const;
void bind_unit(GLuint tunit)const;
};
//class representing an opengl 2D texture
class texture_base
{
@ -153,14 +128,13 @@ namespace gfx::ogl{
//bind to given texture unit and load into given program uniform location
void bind_unit(GLuint tunit)const;
weak_texture create_handle(void)const;
private:
bool create_texture_storage_(void);
};
class texture_array;
//Represents a single layer of a texture_array
class texture_slice
{
private:

View File

@ -89,6 +89,8 @@ namespace gfx::ogl{
}
//Class for a uniform buffer object
//automatically sets alignments for std140 uniform blocks
template<class... Types>
class ubo
{
@ -125,12 +127,14 @@ namespace gfx::ogl{
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>

View File

@ -25,6 +25,8 @@
#include <array>
#include <cstring> //memcpy, memset
#include "config.hpp"
namespace gfx::ogl{
template<class... Types>
@ -107,12 +109,14 @@ namespace gfx::ogl{
template<class... Types>
void ubo<Types...>::buffer(const void* data, size_t datasize, size_t start){
debug_print_warn("Manually editing values of ubo!\n");
if(start > get_size())
return;
glNamedBufferSubData(m_buffer, start, std::min(datasize, get_size() - start), data);
}
template<class... Types>
void ubo<Types...>::initialize(unsigned char value){
debug_print_warn("Manually editing values of ubo!\n");
const size_t size = get_size();
auto m = map(buffer::maptype::WRITE);
if(!m){

View File

@ -23,8 +23,6 @@
#include "../init.hpp"
#include "math/math.hpp"
#include "util/init_constants.hpp"
#include "fbo.hpp"
#include "../resource_manager.hpp"
namespace gfx::ogl{
@ -45,8 +43,6 @@ namespace gfx::ogl{
private:
GLFWwindow* m_window = nullptr;
glfw_system m_glfw_handle;
fbo m_root_fbo{util::no_initialize};
resource_manager m_resources;
char* m_title = nullptr;
int m_antialias_level = 0;
int m_refresh_rate = GLFW_DONT_CARE;
@ -73,12 +69,6 @@ namespace gfx::ogl{
void destroy(void);
resource_manager& resource_man(void);
const resource_manager& resource_man(void)const;
fbo& framebuffer(void);
const fbo& framebuffer(void)const;
void set_size(const math::vec2i&);
void set_size(int w, int h);
void set_width(int w);

View File

@ -27,6 +27,8 @@
#include "util/deferred.hpp"
#include "config.hpp"
namespace gfx{
template<class T>
@ -71,8 +73,21 @@ namespace gfx{
template<class T>
template<class... Args>
auto resource_container<T>::emplace_value(const char* key, Args&&... args) -> std::pair<node,bool>{
#ifdef OUR_DICK_ENABLE_DEBUG_VERBOSE_OUTPUT
//print out construction to check if things only get built once
//must enable rtti for typeid() which is disabled by default in the makefile
//add -frtti in the DEBUG_CXXFLAGS variable
if(node n = get_value(key);!n){
debug_print_verbose("Constructing new %s in container\n", ::util::demangle(typeid(T).name()).c_str());
auto p = m_map.emplace(key, util::deferred_function(std::make_shared<T,Args&&...>, std::forward<Args>(args)...));
return {(*p.first).second, p.second};
}else{
return {n, false};
}
#else
auto p = m_map.try_emplace(key, util::deferred_function(std::make_shared<T,Args&&...>, std::forward<Args>(args)...));
return {(*p.first).second, p.second};
#endif
}
template<class T>
auto resource_container<T>::get_value(const char* key) -> node{

View File

@ -1,97 +0,0 @@
/**
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_RESOURCE_MANAGER_HPP
#define OUR_DICK_GRAPHICS_RESOURCE_MANAGER_HPP
#include "resource_container.hpp"
#include "ogl/texture.hpp"
#include "ogl/shader_program.hpp"
#include "egn/font.hpp"
#include <utility> //forward
namespace gfx{
class resource_manager
{
public:
template<class T>
using container_type = resource_container<T>;
private:
container_type<ogl::texture> m_textures;
container_type<egn::font_atlas> m_fonts;
container_type<ogl::texture_array> m_texture_arrays;
container_type<ogl::shader_program> m_shaders;
public:
resource_manager(void) = default;
resource_manager(const resource_manager&) = default;
resource_manager(resource_manager&&) = default;
~resource_manager(void) = default;
resource_manager& operator=(const resource_manager&) = default;
resource_manager& operator=(resource_manager&&) = default;
bool has_texture_array(const char* key)const;
template<class... Args>
auto emplace_texture_array(const char* key, Args&&... args);
container_type<ogl::texture_array>::node get_texture_array(const char* file);
bool erase_texture_array(const char* key);
bool has_texture(const char* key)const;
template<class... Args>
auto emplace_texture(const char* key, Args&&... args);
container_type<ogl::texture>::node get_texture(const char* file);
bool erase_texture(const char* key);
bool has_font(const char* key)const;
template<class... Args>
auto emplace_font(const char* key, Args&&... args);
container_type<egn::font_atlas>::node get_font(const char* file);
bool erase_font(const char* key);
bool has_shader(const char* key)const;
template<class... Args>
auto emplace_shader(const char* key, Args&&... args);
container_type<ogl::shader_program>::node get_shader(const char* key);
bool erase_shader(const char* key);
};
template<class... Args>
auto resource_manager::emplace_texture_array(const char* key, Args&&... args){
return m_texture_arrays.emplace_value(key, std::forward<Args>(args)...);
}
template<class... Args>
auto resource_manager::emplace_texture(const char* key, Args&&... args){
return m_textures.emplace_value(key, std::forward<Args>(args)...);
}
template<class... Args>
auto resource_manager::emplace_font(const char* key, Args&&... args){
return m_fonts.emplace_value(key, std::forward<Args>(args)...);
}
template<class... Args>
auto resource_manager::emplace_shader(const char* key, Args&&... args){
return m_shaders.emplace_value(key, std::forward<Args>(args)...);
}
}
#endif

View File

@ -29,7 +29,7 @@
namespace math{
//Common stuff shared by all types of matrices
template<typename T, size_t R, size_t C>
template<class T, size_t R, size_t C>
class matrix_base
{
static_assert(C > 0, "Cannot have 0 columns matrix");
@ -61,19 +61,19 @@ namespace math{
//Value initializing constructors
constexpr explicit matrix_base(value_type v);
template<typename... Args, std::enable_if_t<(std::is_convertible_v<Args,T> && ...),int> = 0>
template<class... Args, std::enable_if_t<(std::is_convertible_v<Args,T> && ...),int> = 0>
constexpr matrix_base(Args&&... args);
//Copying constructors
constexpr matrix_base(const matrix_base&) = default;
constexpr matrix_base(matrix_base&&) = default;
template<typename U>
template<class U>
constexpr matrix_base(const matrix_base<U,Columns,Rows>& m);
~matrix_base(void) = default;
constexpr matrix_base& operator=(const matrix_base&) = default;
constexpr matrix_base& operator=(matrix_base&&) = default;
template<typename U, size_t TR, size_t TC>
template<class U, size_t TR, size_t TC>
constexpr matrix_base& operator=(const matrix_base<U,TR,TC>& m);
//Getters/Setters
@ -95,7 +95,7 @@ namespace math{
};
//Non square matrices
template<typename T, size_t R, size_t C>
template<class T, size_t R, size_t C>
class matrix : public matrix_base<T,R,C>
{
private:
@ -113,7 +113,7 @@ namespace math{
template<size_t TR, size_t TC, std::enable_if_t<TR <= R && TC <= C,int> = 0>
constexpr matrix(const matrix_base<value_type,TR,TC>& other);
template<typename U>
template<class U>
constexpr matrix(const matrix<U,R,C>& other);
constexpr matrix(const matrix&) = default;
constexpr matrix(matrix&&) = default;
@ -122,12 +122,12 @@ namespace math{
//Assignement
constexpr matrix& operator=(const matrix&) = default;
constexpr matrix& operator=(matrix&&) = default;
template<typename U>
template<class U>
constexpr matrix& operator=(const matrix<U,R,C>& m);
};
//Square matrices
template<typename T, size_t R>
template<class T, size_t R>
class matrix<T,R,R> : public matrix_base<T,R,R>
{
private:
@ -148,14 +148,14 @@ namespace math{
constexpr explicit matrix(detail::id_initialize_t);
template<size_t TR, size_t TC, std::enable_if_t<TR <= R && TC <= R,int> = 0>
constexpr matrix(const matrix_base<value_type,TR,TC>& other);
template<typename U>
template<class U>
constexpr matrix(const matrix<U,R,R>& other);
~matrix(void) = default;
//Assignement
constexpr matrix& operator=(const matrix&) = default;
constexpr matrix& operator=(matrix&&) = default;
template<typename U>
template<class U>
constexpr matrix& operator=(const matrix<U,R,R>& m);
//square matrix arithmetic operations
@ -165,37 +165,11 @@ namespace math{
constexpr matrix inverse(void)const;
};
template<typename T, size_t R>
constexpr T determinate(const matrix<T,R,R>& m);
template<typename T, size_t R>
constexpr matrix<T,R,R> inverse(const matrix<T,R,R>& m);
template<typename T>
matrix<T,2,2> rotation2d_pure(T angle);
template<typename T>
constexpr matrix<T,2,2> rotation2d_pure(T sin, T cos);
template<typename T>
constexpr matrix<T,2,2> scale2d(T x, T y);
template<typename T>
matrix<T,3,3> rotation2d(T angle);
template<typename T>
constexpr matrix<T,3,3> rotation2d(T sin, T cos);
template<typename T>
matrix<T,3,3> rotation2d(T x, T y, T z);
template<typename T>
constexpr matrix<T,4,4> rotation3d(T angle_x, T angle_y, T angle_z);
template<typename T>
constexpr matrix<T,4,4> translation3d(T x, T y, T z);
template<typename T>
constexpr matrix<T,4,4> scale3d(T x, T y, T z);
namespace detail{
template<typename T>
template<class T>
struct is_matrix_helper {
template<typename U, size_t R, size_t C>
template<class U, size_t R, size_t C>
static std::true_type test(matrix_base<U,R,C>*);
static std::false_type test(void*);
@ -205,65 +179,92 @@ namespace math{
}
//Determine if a given list of tyes are all matrix types
template<typename... Ms>
template<class... Ms>
struct is_matrix {
static constexpr bool value = (detail::is_matrix_helper<Ms>::value && ...);
};
template<class T>
concept Matrix = is_matrix<T>::value;
namespace detail{
template<class T, class U>
concept Compatible_Scalar = requires(T&& t, U&& u){
requires !is_matrix<T>::value;
requires std::is_convertible_v<decltype(u * t),std::decay_t<T>>;
requires std::is_convertible_v<decltype(u / t),std::decay_t<T>>;
requires std::is_convertible_v<decltype(u + t),std::decay_t<T>>;
requires std::is_convertible_v<decltype(u - t),std::decay_t<T>>;
u * t;
u / t;
u + t;
u - t;
};
template<typename M1, typename M2>
struct are_same_size_matrix {
using l = std::decay_t<M1>;
using r = std::decay_t<M2>;
static constexpr bool value = is_matrix<M1,M2>::value && l::Columns == r::Columns && l::Rows == r::Rows;
};
template<typename... Ms>
using enable_if_matrix = std::enable_if_t<is_matrix<Ms...>::value,int>;
template<typename M1, typename M2>
using enable_if_eq_matrix = std::enable_if_t<are_same_size_matrix<M1,M2>::value,int>;
}
template<class T, size_t R>
constexpr T determinate(const matrix<T,R,R>& m);
template<class T, size_t R>
constexpr matrix<T,R,R> inverse(const matrix<T,R,R>& m);
template<class T>
matrix<T,2,2> rotation2d_pure(T angle);
template<class T>
constexpr matrix<T,2,2> rotation2d_pure(T sin, T cos);
template<class T>
constexpr matrix<T,2,2> scale2d(T x, T y);
template<class T>
matrix<T,3,3> rotation2d(T angle);
template<class T>
constexpr matrix<T,3,3> rotation2d(T sin, T cos);
template<class T>
matrix<T,3,3> rotation2d(T x, T y, T z);
template<class T>
constexpr matrix<T,4,4> rotation3d(T angle_x, T angle_y, T angle_z);
template<class T>
constexpr matrix<T,4,4> translation3d(T x, T y, T z);
template<class T>
constexpr matrix<T,4,4> scale3d(T x, T y, T z);
//Logic operators
template<typename T, typename U, size_t R, size_t C>
template<class T, class U, size_t R, size_t C>
constexpr bool operator==(const matrix_base<T,R,C>& left, const matrix_base<U,R,C> right);
template<typename T, typename U, size_t R, size_t C>
template<class T, class U, size_t R, size_t C>
constexpr bool operator!=(const matrix_base<T,R,C>& left, const matrix_base<U,R,C> right);
//Arithmetic operators
template<typename T, typename U, size_t R1, size_t C1, size_t R2>
template<class T, class U, size_t R1, size_t C1, size_t R2>
constexpr auto operator*(const matrix<T,R1,C1>& left, const matrix<U,C1,R2>& right);
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int> = 0>
template<class T, class U, size_t C, size_t R> requires Compatible_Scalar<U,T>
constexpr auto operator*(const matrix<T,R,C>& left, U&& right);
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int> = 0>
template<class T, class U, size_t C, size_t R> requires Compatible_Scalar<U,T>
constexpr auto operator*(U&& left, const matrix<T,R,C>& right);
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int> = 0>
template<class T, class U, size_t C, size_t R> requires Compatible_Scalar<U,T>
constexpr auto operator/(const matrix<T,R,C>& left, U&& right);
template<typename T, typename U, size_t C, size_t R>
template<class T, class U, size_t C, size_t R>
constexpr auto operator+(const matrix<T,R,C>& left, const matrix<U,R,C>& right);
template<typename T, typename U, size_t C, size_t R>
template<class T, class U, size_t C, size_t R>
constexpr auto operator-(const matrix<T,R,C>& left, const matrix<U,R,C>& right);
template<typename T, typename U, size_t C, size_t R>
template<class T, class U, size_t C, size_t R>
constexpr auto operator-(const matrix<T,R,C>& left);
template<typename T, size_t R, size_t C>
template<class T, size_t R, size_t C>
constexpr auto abs(const matrix_base<T,R,C>& left);
template<typename T, typename U, typename V, size_t R, size_t C>
template<class T, class U, class V, size_t R, size_t C>
constexpr bool fuzzy_eq(const matrix_base<T,R,C>& left, const matrix_base<U,R,C>& right, const V& epsilon);
template<typename T, typename U, typename V, size_t R, size_t C>
template<class T, class U, class V, size_t R, size_t C>
constexpr bool fuzzy_neq(const matrix_base<T,R,C>& left, const matrix_base<U,R,C>& right, const V& epsilon);
//Arithmetic assignment operators
template<typename T, typename U, size_t R>
template<class T, class U, size_t R>
constexpr decltype(auto) operator*=(matrix<T,R,R>& left, const matrix<U,R,R>& right);
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int> = 0>
template<class T, class U, size_t C, size_t R> requires Compatible_Scalar<U,T>
constexpr decltype(auto) operator*=(matrix<T,R,C>& left, U&& right);
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int> = 0>
template<class T, class U, size_t C, size_t R> requires Compatible_Scalar<U,T>
constexpr decltype(auto) operator/=(matrix<T,R,C>& left, U&& right);
template<typename T, typename U, size_t C, size_t R>
template<class T, class U, size_t C, size_t R>
constexpr decltype(auto) operator+=(matrix<T,R,C>& left, const matrix<U,R,C>& right);
template<typename T, typename U, size_t C, size_t R>
template<class T, class U, size_t C, size_t R>
constexpr decltype(auto) operator-=(matrix<T,R,C>& left, const matrix<U,R,C>& right);
}

View File

@ -28,47 +28,47 @@
namespace math{
namespace detail{
template<typename T>
template<class T>
static constexpr const T& min(const T& l, const T& r){
return l < r ? l : r;
}
}
template<typename T, size_t R, size_t C>
template<class T, size_t R, size_t C>
template<size_t... Ss>
constexpr matrix_base<T,R,C>::matrix_base(std::integer_sequence<size_type,Ss...>):
m_data{Ss...}{}
template<typename T, size_t R, size_t C>
template<class T, size_t R, size_t C>
constexpr matrix_base<T,R,C>::matrix_base(void):
matrix_base(typename detail::default_initialization_matrix<Columns,Rows>::tuple{}){}
template<typename T, size_t R, size_t C>
template<class T, size_t R, size_t C>
constexpr matrix_base<T,R,C>::matrix_base(detail::zero_initialize_t):
m_data{}{}
template<typename T, size_t R, size_t C>
template<class T, size_t R, size_t C>
constexpr matrix_base<T,R,C>::matrix_base(detail::no_initialize_t){}
template<typename T, size_t R, size_t C>
template<class T, size_t R, size_t C>
constexpr matrix_base<T,R,C>::matrix_base(value_type v){
for(size_type i = 0; i < Columns*Rows; ++i)
m_data[i] = v;
}
template<typename T, size_t R, size_t C>
template<typename... Args, std::enable_if_t<(std::is_convertible_v<Args,T> && ...),int>>
template<class T, size_t R, size_t C>
template<class... Args, std::enable_if_t<(std::is_convertible_v<Args,T> && ...),int>>
constexpr matrix_base<T,R,C>::matrix_base(Args&&... args):
m_data{static_cast<value_type>(std::forward<Args>(args))...}{}
template<typename T, size_t R, size_t C>
template<typename U>
template<class T, size_t R, size_t C>
template<class U>
constexpr matrix_base<T,R,C>::matrix_base(const matrix_base<U,Columns,Rows>& m){
using mat = matrix_base<U,Columns,Rows>;
for(typename mat::size_type i = 0; i < mat::Columns*mat::Rows; ++i)
m_data[i] = m.get(i);
}
template<typename T, size_t R, size_t C>
template<typename U, size_t TR, size_t TC>
template<class T, size_t R, size_t C>
template<class U, size_t TR, size_t TC>
constexpr matrix_base<T,R,C>& matrix_base<T,R,C>::operator=(const matrix_base<U,TR,TC>& m){
constexpr auto cols = detail::min(TC, C);
constexpr auto rws = detail::min(TR, R);
@ -81,62 +81,62 @@ namespace math{
}
template<typename T, size_t R, size_t C>
template<class T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::operator[](size_type x){
return detail::mat_ref_obj<value_type,Rows>{m_data, x};
}
template<typename T, size_t R, size_t C>
template<class T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::operator[](size_type x)const{
return detail::mat_ref_obj<const value_type,Rows>{m_data, x};
}
template<typename T, size_t R, size_t C>
template<class T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::get(size_type x, size_type y) -> reference{
return m_data[(x*Rows)+y];
}
template<typename T, size_t R, size_t C>
template<class T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::get(size_type x, size_type y)const -> const_reference{
return m_data[(x*Rows)+y];
}
template<typename T, size_t R, size_t C>
template<class T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::get(size_type i) -> reference{
return m_data[i];
}
template<typename T, size_t R, size_t C>
template<class T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::get(size_type i)const -> const_reference{
return m_data[i];
}
template<typename T, size_t R, size_t C>
template<class T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::columns(void)const -> size_type{
return Columns;
}
template<typename T, size_t R, size_t C>
template<class T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::rows(void)const -> size_type{
return Rows;
}
template<typename T, size_t R, size_t C>
template<class T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::size(void)const -> size_type{
return Columns*Rows;
}
template<typename T, size_t R, size_t C>
template<class T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::raw(void) -> pointer{
return m_data;
}
template<typename T, size_t R, size_t C>
template<class T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::raw(void)const -> const_pointer{
return m_data;
}
template<typename T, size_t R, size_t C>
template<class T, size_t R, size_t C>
constexpr matrix_base<T,R,C>::operator pointer(void){
return m_data;
}
template<typename T, size_t R, size_t C>
template<class T, size_t R, size_t C>
constexpr matrix_base<T,R,C>::operator const_pointer(void)const{
return m_data;
}
template<typename T, size_t R, size_t C>
template<class T, size_t R, size_t C>
template<size_t TR, size_t TC, std::enable_if_t<TR <= R && TC <= C,int>>
constexpr matrix<T,R,C>::matrix(const matrix_base<value_type,TR,TC>& other){
for(size_type i = 0;i < TC;++i){
@ -145,8 +145,8 @@ namespace math{
}
}
}
template<typename T, size_t R, size_t C>
template<typename U>
template<class T, size_t R, size_t C>
template<class U>
constexpr matrix<T,R,C>::matrix(const matrix<U,R,C>& other){
for(size_type i = 0;i < C;++i){
for(size_type j = 0;j < R;++j){
@ -155,17 +155,17 @@ namespace math{
}
}
template<typename T, size_t R, size_t C>
template<typename U>
template<class T, size_t R, size_t C>
template<class U>
constexpr matrix<T,R,C>& matrix<T,R,C>::operator=(const matrix<U,R,C>& m){
base::operator=(m);
return *this;
}
template<typename T, size_t R>
template<class T, size_t R>
constexpr matrix<T,R,R>::matrix(detail::id_initialize_t):
base(){}
template<typename T, size_t R>
template<class T, size_t R>
template<size_t TR, size_t TC, std::enable_if_t<TR <= R && TC <= R,int>>
constexpr matrix<T,R,R>::matrix(const matrix_base<value_type,TR,TC>& other):
matrix(id_initialize)
@ -176,8 +176,8 @@ namespace math{
}
}
}
template<typename T, size_t R>
template<typename U>
template<class T, size_t R>
template<class U>
constexpr matrix<T,R,R>::matrix(const matrix<U,R,R>& other){
for(size_type i = 0;i < R;++i){
for(size_type j = 0;j < R;++j){
@ -187,18 +187,18 @@ namespace math{
}
template<typename T, size_t R>
template<typename U>
template<class T, size_t R>
template<class U>
constexpr matrix<T,R,R>& matrix<T,R,R>::operator=(const matrix<U,R,R>& m){
base::operator=(m);
return *this;
}
template<typename T, size_t R>
template<class T, size_t R>
constexpr auto matrix<T,R,R>::determinate(void)const -> value_type{
return math::determinate(*this);
}
template<typename T, size_t R>
template<class T, size_t R>
constexpr auto matrix<T,R,R>::trace(void)const -> value_type{
value_type sum = 0;
for(size_type i = 0; i < R; ++i){
@ -206,7 +206,7 @@ namespace math{
}
return sum;
}
template<typename T, size_t R>
template<class T, size_t R>
constexpr matrix<T,R,R> matrix<T,R,R>::transpose(void)const{
matrix m(no_initialize);
for(size_type i = 0; i < R; ++i){
@ -216,63 +216,63 @@ namespace math{
}
return m;
}
template<typename T, size_t R>
template<class T, size_t R>
constexpr matrix<T,R,R> matrix<T,R,R>::inverse(void)const{
return math::inverse(*this);
}
template<typename T, size_t R>
template<class T, size_t R>
constexpr T determinate(const matrix<T,R,R>& m){
return detail::determinate_helper<T,R>::perform(m);
}
template<typename T, size_t R>
template<class T, size_t R>
constexpr matrix<T,R,R> inverse(const matrix<T,R,R>& m){
return detail::inverse_helper<T,R>::perform(m);
}
template<typename T>
template<class T>
matrix<T,2,2> rotation2d_pure(T angle){
return rotation2d_pure(std::sin(angle), std::cos(angle));
}
template<typename T>
template<class T>
constexpr matrix<T,2,2> rotation2d_pure(T sin, T cos){
return matrix<T,2,2>(cos, sin, -sin, cos);
}
template<typename T>
template<class T>
constexpr matrix<T,2,2> scale2d(T x, T y){
return matrix<T,2,2>(x, T{0}, T{0}, y);
}
template<typename T>
template<class T>
matrix<T,3,3> rotation2d(T angle){
return rotation2d(std::sin(angle), std::cos(angle));
}
template<typename T>
template<class T>
constexpr matrix<T,3,3> rotation2d(T sin, T cos){
return matrix<T,3,3>(cos, -sin, T{0},
sin, cos, T{0},
T{0}, T{0}, T{1});
}
template<typename T>
template<class T>
matrix<T,3,3> rotation2d(T x, T y, T z){
quaternion<T> q(x, y, z);
return q.to_mat3();
}
template<typename T>
template<class T>
constexpr matrix<T,4,4> rotation3d(T angle_x, T angle_y, T angle_z){
quaternion<T> q(angle_x, angle_y, angle_z);
return q.to_mat4();
}
template<typename T>
template<class T>
constexpr matrix<T,4,4> translation3d(T x, T y, T z){
return matrix<T,4,4>(T{1}, T{0}, T{0}, T{0},
T{0}, T{1}, T{0}, T{0},
T{0}, T{0}, T{1}, T{0},
x, y, z, T{1});
}
template<typename T>
template<class T>
constexpr matrix<T,4,4> scale3d(T x, T y, T z){
return matrix<T,4,4>(x, T{0}, T{0}, T{0},
T{0}, y, T{0}, T{0},
@ -281,7 +281,7 @@ namespace math{
}
template<typename T, typename U, size_t R, size_t C>
template<class T, class U, size_t R, size_t C>
constexpr bool operator==(const matrix_base<T,R,C>& left, const matrix_base<U,R,C> right){
for(size_t i = 0; i < left.size(); ++i){
if(left.get(i) != right.get(i))
@ -289,12 +289,12 @@ namespace math{
}
return true;
}
template<typename T, typename U, size_t R, size_t C>
template<class T, class U, size_t R, size_t C>
constexpr bool operator!=(const matrix_base<T,R,C>& left, const matrix_base<U,R,C> right){
return !(left == right);
}
template<typename T, typename U, size_t R1, size_t C1, size_t C2>
template<class T, class U, size_t R1, size_t C1, size_t C2>
constexpr auto operator*(const matrix<T,R1,C1>& left, const matrix<U,C1,C2>& right){
using res_t = decltype(std::declval<T>() * std::declval<U>());
matrix<res_t,R1,C2> res(zero_initialize);
@ -309,7 +309,7 @@ namespace math{
}
return res;
}
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<!is_matrix<U>::value,int>>
template<class T, class U, size_t C, size_t R> requires Compatible_Scalar<U,T>
constexpr auto operator*(const matrix<T,R,C>& left, U&& right){
using res_t = decltype(std::declval<T>() * std::declval<U>());
matrix<res_t,R,C> res(no_initialize);
@ -318,7 +318,7 @@ namespace math{
}
return res;
}
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<!is_matrix<U>::value,int>>
template<class T, class U, size_t C, size_t R> requires Compatible_Scalar<U,T>
constexpr auto operator*(U&& left, const matrix<T,R,C>& right){
using res_t = decltype(std::declval<T>() * std::declval<U>());
matrix<res_t,R,C> res(no_initialize);
@ -327,7 +327,7 @@ namespace math{
}
return res;
}
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<!is_matrix<U>::value,int>>
template<class T, class U, size_t C, size_t R> requires Compatible_Scalar<U,T>
constexpr auto operator/(const matrix<T,R,C>& left, U&& right){
using res_t = decltype(std::declval<T>() / std::declval<U>());
matrix<res_t,R,C> res(no_initialize);
@ -336,7 +336,7 @@ namespace math{
}
return res;
}
template<typename T, typename U, size_t C, size_t R>
template<class T, class U, size_t C, size_t R>
constexpr auto operator+(const matrix<T,R,C>& left, const matrix<U,R,C>& right){
using res_t = decltype(std::declval<T>() + std::declval<U>());
matrix<res_t,R,C> res(no_initialize);
@ -345,7 +345,7 @@ namespace math{
}
return res;
}
template<typename T, typename U, size_t C, size_t R>
template<class T, class U, size_t C, size_t R>
constexpr auto operator-(const matrix<T,R,C>& left, const matrix<U,R,C>& right){
using res_t = decltype(std::declval<T>() - std::declval<U>());
matrix<res_t,R,C> res(no_initialize);
@ -354,7 +354,7 @@ namespace math{
}
return res;
}
template<typename T, typename U, size_t C, size_t R>
template<class T, class U, size_t C, size_t R>
constexpr auto operator-(const matrix<T,R,C>& left){
using res_t = decltype(-std::declval<U>());
matrix<res_t,R,C> res(no_initialize);
@ -363,7 +363,7 @@ namespace math{
}
return res;
}
template<typename T, size_t R, size_t C>
template<class T, size_t R, size_t C>
constexpr auto abs(const matrix_base<T,R,C>& left){
matrix<T,R,C> res(no_initialize);
for(size_t i = 0; i < left.size(); ++i){
@ -371,7 +371,7 @@ namespace math{
}
return res;
}
template<typename T, typename U, typename V, size_t R, size_t C>
template<class T, class U, class V, size_t R, size_t C>
constexpr bool fuzzy_eq(const matrix_base<T,R,C>& left, const matrix_base<U,R,C>& right, const V& epsilon){
for(size_t i = 0;i < left.size();++i){
if(std::abs(left.get(i) - right.get(i)) > epsilon)
@ -379,39 +379,39 @@ namespace math{
}
return true;
}
template<typename T, typename U, typename V, size_t R, size_t C>
template<class T, class U, class V, size_t R, size_t C>
constexpr bool fuzzy_neq(const matrix_base<T,R,C>& left, const matrix_base<U,R,C>& right, const V& epsilon){
return !fuzzy_eq(left, right, epsilon);
}
template<typename T, typename U, size_t R>
template<class T, class U, size_t R>
constexpr decltype(auto) operator*=(matrix<T,R,R>& left, const matrix<U,R,R>& right){
//have to evaluate entire expression first since matrix multiplication depends on reusing many elements
//cannot be expression templatized, TODO
return (left = (left * right));
}
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<!is_matrix<U>::value,int>>
template<class T, class U, size_t C, size_t R> requires Compatible_Scalar<U,T>
constexpr decltype(auto) operator*=(matrix<T,R,C>& left, U&& right){
for(size_t i = 0; i < left.size(); ++i){
left.get(i) = left.get(i) * std::forward<U>(right);
}
return left;
}
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<!is_matrix<U>::value,int>>
template<class T, class U, size_t C, size_t R> requires Compatible_Scalar<U,T>
constexpr decltype(auto) operator/=(matrix<T,R,C>& left, U&& right){
for(size_t i = 0; i < left.size(); ++i){
left.get(i) = left.get(i) / std::forward<U>(right);
}
return left;
}
template<typename T, typename U, size_t C, size_t R>
template<class T, class U, size_t C, size_t R>
constexpr decltype(auto) operator+=(matrix<T,R,C>& left, const matrix<U,R,C>& right){
for(size_t i = 0; i < left.size(); ++i){
left.get(i) = left.get(i) + right.get(i);
}
return left;
}
template<typename T, typename U, size_t C, size_t R>
template<class T, class U, size_t C, size_t R>
constexpr decltype(auto) operator-=(matrix<T,R,C>& left, const matrix<U,R,C>& right){
for(size_t i = 0; i < left.size(); ++i){
left.get(i) = left.get(i) - right.get(i);

View File

@ -29,7 +29,7 @@
namespace math{
//( ͡° ͜ʖ ͡°)
template<typename T>
template<class T>
class quaternion
{
public:
@ -113,7 +113,7 @@ namespace math{
namespace detail{
template<typename T>
template<class T>
struct is_quat_helper {
template<class U>
static std::true_type test(quaternion<U>*);
@ -121,39 +121,39 @@ namespace math{
static constexpr bool value = std::is_same<std::true_type,decltype(test(static_cast<std::decay_t<T>*>(nullptr)))>::value;
};
}
template<typename... Qs>
template<class... Qs>
struct is_quaternion {
static constexpr bool value = (detail::is_quat_helper<Qs>::value && ...);
};
template<typename T, typename U>
template<class T, class U>
bool operator==(const quaternion<T>& left, const quaternion<U>& right);
template<typename T, typename U>
template<class T, class U>
bool operator!=(const quaternion<T>& left, const quaternion<U>& right);
template<typename T>
template<class T>
auto operator-(const quaternion<T>& left);
template<typename T, typename U>
template<class T, class U>
auto operator-(const quaternion<T>& left, const quaternion<U>& right);
template<typename T, typename U>
template<class T, class U>
auto operator+(const quaternion<T>& left, const quaternion<U>& right);
template<typename T, typename U>
template<class T, class U>
auto operator*(const quaternion<T>& left, const quaternion<U>& right);
template<typename T, typename U>
template<class T, class U>
auto operator*(const quaternion<T>& left, const vec3<U>& right);
template<typename T, typename U, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int> = 0>
template<class T, class U> requires Compatible_Scalar<U,T>
auto operator*(const quaternion<T>& left, U&& right);
template<typename T, typename U, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int> = 0>
template<class T, class U> requires Compatible_Scalar<U,T>
auto operator/(const quaternion<T>& left, U&& right);
template<typename T, typename U>
template<class T, class U>
decltype(auto) operator+=(quaternion<T>& left, const quaternion<U>& right);
template<typename T, typename U>
template<class T, class U>
decltype(auto) operator-=(quaternion<T>& left, const quaternion<U>& right);
template<typename T, typename U>
template<class T, class U>
decltype(auto) operator*=(quaternion<T>& left, const quaternion<U>& right);
template<typename T, typename U, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int> = 0>
template<class T, class U> requires Compatible_Scalar<U,T>
decltype(auto) operator*=(quaternion<T>& left, U&& right);
template<typename T, typename U, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int> = 0>
template<class T, class U> requires Compatible_Scalar<U,T>
decltype(auto) operator/=(quaternion<T>& left, U&& right);
}

View File

@ -25,25 +25,25 @@
namespace math{
template<typename T>
template<class T>
constexpr quaternion<T>::quaternion(void):
quaternion(id_initialize){}
template<typename T>
template<class T>
constexpr quaternion<T>::quaternion(detail::zero_initialize_t):
m_data{0, 0, 0, 0}{}
template<typename T>
template<class T>
constexpr quaternion<T>::quaternion(detail::id_initialize_t):
m_data{1, 0, 0, 0}{}
template<typename T>
template<class T>
constexpr quaternion<T>::quaternion(detail::no_initialize_t){}
template<typename T>
template<class T>
constexpr quaternion<T>::quaternion(detail::manual_initialize_t,
value_type w, value_type x,
value_type y, value_type z):
m_data{w, x, y, z}{}
template<typename T>
template<class T>
quaternion<T>::quaternion(const mat3<T>& rotmat){
auto tr = rotmat.trace();
if(tr > 0){
@ -72,12 +72,12 @@ namespace math{
m_data[3] = f * 0.25;
}
}
template<typename T>
template<class T>
quaternion<T>::quaternion(const mat4<T>& rotmat):
quaternion(mat3<T>{rotmat.get(0), rotmat.get(1), rotmat.get(2),
rotmat.get(4), rotmat.get(5), rotmat.get(6),
rotmat.get(8), rotmat.get(9), rotmat.get(10)}){}
template<typename T>
template<class T>
quaternion<T>::quaternion(value_type bank, value_type heading, value_type attitude){
bank /= value_type{2};
heading /= value_type{2};
@ -94,13 +94,13 @@ namespace math{
m_data[2] = (sin_heading * cos_attitude * cos_bank) + (cos_heading * sin_attitude * sin_bank);
m_data[3] = (cos_heading * sin_attitude * cos_bank) - (sin_heading * cos_attitude * sin_bank);
}
template<typename T>
template<class T>
quaternion<T>::quaternion(const vec3<T>& angles):
quaternion(angles.x(), angles.y(), angles.z()){}
template<typename T>
template<class T>
quaternion<T>::quaternion(value_type angle, const vec3<value_type>& axis):
quaternion(angle, axis.get_x(), axis.get_y(), axis.get_z()){}
template<typename T>
template<class T>
quaternion<T>::quaternion(value_type angle, value_type x, value_type y, value_type z){
angle /= value_type{2.0};
value_type sin_angle = std::sin(angle);
@ -110,74 +110,74 @@ namespace math{
m_data[3] = sin_angle * z;
}
template<typename T>
template<class T>
constexpr quaternion<T>::operator pointer(void){
return m_data;
}
template<typename T>
template<class T>
constexpr quaternion<T>::operator const_pointer(void)const{
return m_data;
}
template<typename T>
template<class T>
constexpr auto quaternion<T>::operator[](size_type i) -> reference{
return m_data[i];
}
template<typename T>
template<class T>
constexpr auto quaternion<T>::operator[](size_type i)const -> const_reference{
return m_data[i];
}
template<typename T>
template<class T>
constexpr auto quaternion<T>::get(size_type i) -> reference{
return m_data[i];
}
template<typename T>
template<class T>
constexpr auto quaternion<T>::get(size_type i)const -> const_reference{
return m_data[i];
}
template<typename T>
template<class T>
constexpr auto quaternion<T>::w(void) -> reference{
return m_data[0];
}
template<typename T>
template<class T>
constexpr auto quaternion<T>::w(void)const -> const_reference{
return m_data[0];
}
template<typename T>
template<class T>
constexpr auto quaternion<T>::x(void) -> reference{
return m_data[1];
}
template<typename T>
template<class T>
constexpr auto quaternion<T>::x(void)const -> const_reference{
return m_data[1];
}
template<typename T>
template<class T>
constexpr auto quaternion<T>::y(void) -> reference{
return m_data[2];
}
template<typename T>
template<class T>
constexpr auto quaternion<T>::y(void)const -> const_reference{
return m_data[2];
}
template<typename T>
template<class T>
constexpr auto quaternion<T>::z(void) -> reference{
return m_data[3];
}
template<typename T>
template<class T>
constexpr auto quaternion<T>::z(void)const -> const_reference{
return m_data[3];
}
template<typename T>
template<class T>
void quaternion<T>::set_axis(value_type x, value_type y, value_type z){
value_type sin_angle = std::sin(std::acos(m_data[0]));
m_data[1] = sin_angle * x;
m_data[2] = sin_angle * y;
m_data[3] = sin_angle * z;
}
template<typename T>
template<class T>
void quaternion<T>::set_axis(const vec3<value_type>& v){
set_axis(v.x(), v.y(), v.z());
}
template<typename T>
template<class T>
auto quaternion<T>::get_axis(void)const -> vec3<value_type>{
quaternion tmp(*this);
if(m_data[0] > value_type{1.0})
@ -187,7 +187,7 @@ namespace math{
return vec3<T>(1, 0, 0);
return vec3<T>(tmp.data[1] / s, tmp.data[2] / s, tmp.data[3] / s);
}
template<typename T>
template<class T>
void quaternion<T>::set_angle(value_type t){
t /= value_type{2.0};
value_type old_sin_angle = std::sin(std::acos(m_data[0]));
@ -197,58 +197,58 @@ namespace math{
m_data[2] = (m_data[2] / old_sin_angle) * sin_angle;
m_data[3] = (m_data[3] / old_sin_angle) * sin_angle;
}
template<typename T>
template<class T>
auto quaternion<T>::get_angle(void)const -> value_type{
return 2.0 * std::acos(m_data[0]);
}
template<typename T>
template<class T>
auto quaternion<T>::norm(void)const -> value_type{
return m_data[0] * m_data[0] + m_data[1] * m_data[1] + m_data[2] * m_data[2] + m_data[3] * m_data[3];
}
template<typename T>
template<class T>
quaternion<T> quaternion<T>::conjugate(void)const{
return quaternion(manual_initialize, m_data[0], -m_data[1], -m_data[2], -m_data[3]);
}
template<typename T>
template<class T>
quaternion<T> quaternion<T>::inverse(void)const{
return conjugate() / norm();
}
template<typename T>
template<class T>
auto quaternion<T>::magnitude(void)const -> value_type{
return std::sqrt(norm());
}
template<typename T>
template<class T>
quaternion<T> quaternion<T>::normalize(void)const{
value_type mag = magnitude();
return quaternion(manual_initialize, m_data[0] / mag, m_data[1] / mag, m_data[2] / mag, m_data[3] / mag);
}
template<typename T>
template<class T>
auto quaternion<T>::get_right(void)const -> vec3<value_type>{
return vec3<value_type>(1 - 2 * ((m_data[2] * m_data[2]) + (m_data[3] * m_data[3])),
2 * ((m_data[1] * m_data[2]) - (m_data[3] * m_data[0])),
2 * ((m_data[1] * m_data[3]) + (m_data[2] * m_data[0])));
}
template<typename T>
template<class T>
auto quaternion<T>::get_up(void)const -> vec3<value_type>{
return vec3<value_type>( 2 * ((m_data[1] * m_data[2]) + (m_data[3] * m_data[0])),
1 - 2 * ((m_data[1] * m_data[1]) + (m_data[3] * m_data[3])),
2 * ((m_data[2] * m_data[3]) - (m_data[1] * m_data[0])));
}
template<typename T>
template<class T>
auto quaternion<T>::get_forward(void)const -> vec3<value_type>{
return vec3<value_type>( 2 * ((m_data[1] * m_data[3]) - (m_data[2] * m_data[0])),
2 * ((m_data[2] * m_data[3]) + (m_data[1] * m_data[0])),
1 - 2 * ((m_data[1] * m_data[1]) + (m_data[2] * m_data[2])));
}
template<typename T>
template<class T>
auto quaternion<T>::to_vec3(void)const -> vec3<value_type>{
return vec3<value_type>(m_data[1], m_data[2], m_data[3]);
}
template<typename T>
template<class T>
auto quaternion<T>::to_vec4(void)const -> vec4<value_type>{
return vec4<value_type>(m_data[1], m_data[2], m_data[3]);
}
template<typename T>
template<class T>
auto quaternion<T>::to_mat3(void)const -> mat3<value_type>{
mat3<value_type> m;
@ -274,7 +274,7 @@ namespace math{
m.get(8) = 1 - 2 * (xx + yy);
return m;
}
template<typename T>
template<class T>
auto quaternion<T>::to_mat4(void)const -> mat4<value_type>{
mat4<value_type> m;
@ -307,7 +307,7 @@ namespace math{
m.get(15) = 1;
return m;
}
template<typename T>
template<class T>
auto quaternion<T>::to_euler_angles(void)const -> vec3<value_type>{
value_type ww = m_data[0] * m_data[0];
value_type xx = m_data[1] * m_data[1];
@ -325,7 +325,7 @@ namespace math{
std::atan2((2 * m_data[2] * m_data[0]) - (2 * m_data[1] * m_data[3]), xx - yy - zz + ww),
std::asin(2 * test / correction));
}
template<typename T>
template<class T>
auto quaternion<T>::to_axis_angle(void)const -> std::pair<value_type,vec3<value_type>>{
quaternion q(*this);
if(m_data[0] > 1.0)
@ -338,35 +338,35 @@ namespace math{
return {2 * std::acos(q.m_data[0]), {q.m_data[1] / s, q.m_data[2] / s, q.m_data[3] / s}};
}
template<typename T, typename U>
template<class T, class U>
bool operator==(const quaternion<T>& left, const quaternion<U>& right){
return left.w() == right.w() &&
left.x() == right.x() &&
left.y() == right.y() &&
left.z() == right.z();
}
template<typename T, typename U>
template<class T, class U>
bool operator!=(const quaternion<T>& left, const quaternion<U>& right){
return !(left == right);
}
template<typename T>
template<class T>
auto operator-(const quaternion<T>& left){
using res_t = T;
return quaternion<res_t>(manual_initialize, -left.w(), -left.x(), -left.y(), -left.z());
}
template<typename T, typename U>
template<class T, class U>
auto operator-(const quaternion<T>& left, const quaternion<U>& right){
using res_t = decltype(std::declval<T>() - std::declval<U>());
return quaternion<res_t>(manual_initialize, left.w() - right.w(), left.x() - right.x(),
left.y() - right.y(), left.z() - right.z());
}
template<typename T, typename U>
template<class T, class U>
auto operator+(const quaternion<T>& left, const quaternion<U>& right){
using res_t = decltype(std::declval<T>() + std::declval<U>());
return quaternion<res_t>(manual_initialize, left.w() + right.w(), left.x() + right.x(),
left.y() + right.y(), left.z() + right.z());
}
template<typename T, typename U>
template<class T, class U>
auto operator*(const quaternion<T>& left, const quaternion<U>& right){
using res_t = decltype(std::declval<T>() * std::declval<U>());
return quaternion<res_t>(manual_initialize,
@ -379,21 +379,21 @@ namespace math{
(right.w() * left.z()) + (right.x() * left.y()) -
(right.y() * left.x()) + (right.z() * left.w()));
}
template<typename T, typename U>
template<class T, class U>
auto operator*(const quaternion<T>& left, const vec3<U>& right){
return left.to_mat3() * right;
}
template<typename T, typename U, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int>>
template<class T, class U> requires Compatible_Scalar<U,T>
auto operator*(const quaternion<T>& left, U&& right){
using res_t = decltype(std::declval<T>() * std::declval<U>());
return quaternion<res_t>(manual_initialize, left.w() * right, left.x() * right, left.y() * right, left.z() * right);
}
template<typename T, typename U, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int>>
template<class T, class U> requires Compatible_Scalar<U,T>
auto operator/(const quaternion<T>& left, U&& right){
using res_t = decltype(std::declval<T>() / std::declval<U>());
return quaternion<res_t>(manual_initialize, left.w() / right, left.x() / right, left.y() / right, left.z() / right);
}
template<typename T, typename U>
template<class T, class U>
decltype(auto) operator+=(quaternion<T>& left, const quaternion<U>& right){
left.w() += right.w();
left.x() += right.x();
@ -401,7 +401,7 @@ namespace math{
left.z() += right.z();
return left;
}
template<typename T, typename U>
template<class T, class U>
decltype(auto) operator-=(quaternion<T>& left, const quaternion<U>& right){
left.w() -= right.w();
left.x() -= right.x();
@ -409,13 +409,13 @@ namespace math{
left.z() -= right.z();
return left;
}
template<typename T, typename U>
template<class T, class U>
decltype(auto) operator*=(quaternion<T>& left, const quaternion<U>& right){
left = left * right;
return left;
}
template<typename T, typename U, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int>>
template<class T, class U> requires Compatible_Scalar<U,T>
decltype(auto) operator*=(quaternion<T>& left, U&& right){
left.w() *= right;
left.x() *= right;
@ -423,7 +423,7 @@ namespace math{
left.z() *= right;
return left;
}
template<typename T, typename U, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int>>
template<class T, class U> requires Compatible_Scalar<U,T>
decltype(auto) operator/=(quaternion<T>& left, U&& right){
left.w() /= right;
left.x() /= right;

View File

@ -25,7 +25,7 @@ namespace math{
//class representing vectors
//inherit from matrix base because it also shared matrix attributes
template<typename T, size_t R>
template<class T, size_t R>
class vector : public matrix_base<T,R,1>
{
private:
@ -41,9 +41,9 @@ namespace math{
public:
using base::base;
template<size_t TR,typename... Args,std::enable_if_t<TR <= R && (std::is_convertible_v<Args,T> && ...),int> = 0>
template<size_t TR,class... Args,std::enable_if_t<TR <= R && (std::is_convertible_v<Args,T> && ...),int> = 0>
constexpr vector(const vector<T,TR>& other, Args&&... args);
template<typename U>
template<class U>
constexpr vector(const vector<U,R>& other);
constexpr vector(const vector&) = default;
constexpr vector(vector&&) = default;
@ -52,7 +52,7 @@ namespace math{
//Assignement
constexpr vector& operator=(const vector&) = default;
constexpr vector& operator=(vector&&) = default;
template<typename U, size_t TR>
template<class U, size_t TR>
constexpr vector& operator=(const vector<U,TR>& m);
constexpr reference operator[](size_type i);
@ -60,60 +60,80 @@ namespace math{
constexpr reference x(void);
constexpr const_reference x(void)const;
template<typename U = T>
template<class U = T>
constexpr reference y(void);
template<typename U = T>
template<class U = T>
constexpr const_reference y(void)const;
template<typename U = T>
template<class U = T>
constexpr reference z(void);
template<typename U = T>
template<class U = T>
constexpr const_reference z(void)const;
template<typename U = T>
template<class U = T>
constexpr reference w(void);
template<typename U = T>
template<class U = T>
constexpr const_reference w(void)const;
value_type magnitude(void)const;
vector normalize(void);
protected:
template<typename U, typename... Args>
template<class U, class... Args>
constexpr void assign_(size_type offset, U&& u, Args&&... args);
};
template<typename T>
namespace detail{
template<class T>
struct is_vector_helper {
template<class U, size_t R>
static std::true_type test(vector<U,R>*);
static std::false_type test(void*);
static constexpr bool value = std::is_same<std::true_type,decltype(test(static_cast<std::decay_t<T>*>(nullptr)))>::value;
};
}
template<class... Ms>
struct is_vector{
static constexpr bool value = (detail::is_vector_helper<Ms>::value && ...);
};
template<class T>
concept Vector = is_vector<T>::value;
template<class T>
constexpr auto perp(const vector<T,2>& v);
template<typename T, typename U, size_t R1, size_t R2>
template<class T, class U, size_t R1, size_t R2>
constexpr auto perp(const vector<T,R1>& left, const vector<U,R2>& right);
template<typename T, typename U>
template<class T, class U>
constexpr auto cross(const vector<T,3>& left, const vector<U,3>& right);
template<typename T, size_t R>
template<class T, size_t R>
constexpr auto magnitude(const vector<T,R>& v);
template<typename T, typename U, size_t C, size_t R>
template<class T, class U, size_t C, size_t R>
constexpr auto operator*(const matrix<U,R,C>& left, const vector<T,C>& right);
template<typename T, typename U, size_t R>
template<class T, class U, size_t R>
constexpr auto operator*(const vector<T,R>& left, const vector<U,R>& right);
template<typename T, typename U, size_t R, std::enable_if_t<!is_matrix<U>::value,int> = 0>
template<class T, class U, size_t R> requires Compatible_Scalar<U,T>
constexpr auto operator*(const vector<T,R>& left, U&& right);
template<typename T, typename U, size_t R, std::enable_if_t<!is_matrix<U>::value,int> = 0>
template<class T, class U, size_t R> requires Compatible_Scalar<U,T>
constexpr auto operator*(U&& left, const vector<T,R>& right);
template<typename T, typename U, size_t R, std::enable_if_t<!is_matrix<U>::value,int> = 0>
template<class T, class U, size_t R> requires Compatible_Scalar<U,T>
constexpr auto operator/(const vector<T,R>& left, U&& right);
template<typename T, typename U, size_t R>
template<class T, class U, size_t R>
constexpr auto operator+(const vector<T,R>& left, const vector<U,R>& right);
template<typename T, typename U, size_t R>
template<class T, class U, size_t R>
constexpr auto operator-(const vector<T,R>& left, const vector<U,R>& right);
template<typename T, typename U, size_t R>
template<class T, class U, size_t R>
constexpr auto operator-(const vector<T,R>& left);
template<typename T, typename U, size_t R, std::enable_if_t<!is_matrix<U>::value,int> = 0>
template<class T, class U, size_t R> requires Compatible_Scalar<U,T>
constexpr decltype(auto) operator*=(vector<T,R>& left, U&& right);
template<typename T, typename U, size_t R, std::enable_if_t<!is_matrix<U>::value,int> = 0>
template<class T, class U, size_t R> requires Compatible_Scalar<U,T>
constexpr decltype(auto) operator/=(vector<T,R>& left, U&& right);
template<typename T, typename U, size_t R>
template<class T, class U, size_t R>
constexpr decltype(auto) operator+=(vector<T,R>& left, const vector<U,R>& right);
template<typename T, typename U, size_t R>
template<class T, class U, size_t R>
constexpr decltype(auto) operator-=(vector<T,R>& left, const vector<U,R>& right);
}

View File

@ -23,8 +23,8 @@
namespace math{
template<typename T, size_t R>
template<size_t TR,typename... Args,std::enable_if_t<TR <= R && (std::is_convertible_v<Args,T> && ...),int>>
template<class T, size_t R>
template<size_t TR,class... Args,std::enable_if_t<TR <= R && (std::is_convertible_v<Args,T> && ...),int>>
constexpr vector<T,R>::vector(const vector<T,TR>& other, Args&&... args){
static_assert(sizeof...(args) + TR <= R);
size_type i = 0;
@ -35,81 +35,81 @@ namespace math{
assign_(i, std::forward<Args>(args)...);
}
}
template<typename T, size_t R>
template<typename U>
template<class T, size_t R>
template<class U>
constexpr vector<T,R>::vector(const vector<U,R>& other){
for(size_type i = 0;i < R;++i){
this->m_data[i] = other[i];
}
}
template<typename T, size_t R>
template<typename U, typename... Args>
template<class T, size_t R>
template<class U, class... Args>
constexpr void vector<T,R>::assign_(size_type offset, U&& u, Args&&... args){
this->m_data[offset] = std::forward<U>(u);
if constexpr(sizeof...(args) > 0){
assign_(offset + 1, std::forward<Args>(args)...);
}
}
template<typename T, size_t R>
template<typename U, size_t TR>
template<class T, size_t R>
template<class U, size_t TR>
constexpr vector<T,R>& vector<T,R>::operator=(const vector<U,TR>& m){
base::operator=(m);
return *this;
}
template<typename T, size_t R>
template<class T, size_t R>
constexpr auto vector<T,R>::operator[](size_type i) -> reference{
return this->m_data[i];
}
template<typename T, size_t R>
template<class T, size_t R>
constexpr auto vector<T,R>::operator[](size_type i)const -> const_reference{
return this->m_data[i];
}
template<typename T, size_t R>
template<class T, size_t R>
constexpr auto vector<T,R>::x(void) -> reference{
return this->m_data[0];
}
template<typename T, size_t R>
template<class T, size_t R>
constexpr auto vector<T,R>::x(void)const -> const_reference{
return this->m_data[0];
}
template<typename T, size_t R>
template<typename U>
template<class T, size_t R>
template<class U>
constexpr auto vector<T,R>::y(void) -> reference{
static_assert(R > 1, "Vector does not contain a 2nd element");
return this->m_data[1];
}
template<typename T, size_t R>
template<typename U>
template<class T, size_t R>
template<class U>
constexpr auto vector<T,R>::y(void)const -> const_reference{
static_assert(R > 1, "Vector does not contain a 2nd element");
return this->m_data[1];
}
template<typename T, size_t R>
template<typename U>
template<class T, size_t R>
template<class U>
constexpr auto vector<T,R>::z(void) -> reference{
static_assert(R > 2, "Vector does not contain a 3rd element");
return this->m_data[2];
}
template<typename T, size_t R>
template<typename U>
template<class T, size_t R>
template<class U>
constexpr auto vector<T,R>::z(void)const -> const_reference{
static_assert(R > 2, "Vector does not contain a 3rd element");
return this->m_data[2];
}
template<typename T, size_t R>
template<typename U>
template<class T, size_t R>
template<class U>
constexpr auto vector<T,R>::w(void) -> reference{
static_assert(R > 3, "Vector does not contain a 4th element");
return this->m_data[3];
}
template<typename T, size_t R>
template<typename U>
template<class T, size_t R>
template<class U>
constexpr auto vector<T,R>::w(void)const -> const_reference{
static_assert(R > 3, "Vector does not contain a 4th element");
return this->m_data[3];
}
template<typename T, size_t R>
template<class T, size_t R>
auto vector<T,R>::magnitude(void)const -> value_type{
value_type sum = 0;
for(size_type i = 0;i < R;++i){
@ -117,32 +117,32 @@ namespace math{
}
return sqrt(sum);
}
template<typename T, size_t R>
template<class T, size_t R>
vector<T,R> vector<T,R>::normalize(void){
return (*this) / magnitude();
}
template<typename T>
template<class T>
constexpr auto perp(const vector<T,2>& v){
return vec2<T>(-v[1], v[0]);
}
template<typename T, typename U, size_t R1, size_t R2>
template<class T, class U, size_t R1, size_t R2>
constexpr auto perp(const vector<T,R1>& left, const vector<U,R2>& right){
return (left[0] * right[1]) - (left[1] * right[0]);
}
template<typename T, typename U>
template<class T, class U>
constexpr auto cross(const vector<T,3>& left, const vector<U,3>& right){
using res_t = decltype(left[0] * right[0]);
return vec3<res_t>((left[1] * right[2]) - (left[2] * right[1]),
(left[2] * right[0]) - (left[0] * right[2]),
(left[0] * right[1]) - (left[1] * right[0]));
}
template<typename T, size_t R>
template<class T, size_t R>
constexpr auto magnitude(const vector<T,R>& v){
return v.magnitude();
}
template<typename T, typename U, size_t C, size_t R>
template<class T, class U, size_t C, size_t R>
constexpr auto operator*(const matrix<U,R,C>& left, const vector<T,C>& right){
using res_t = decltype(std::declval<T>() * std::declval<U>());
vector<res_t,R> res(zero_initialize);
@ -156,7 +156,7 @@ namespace math{
}
return res;
}
template<typename T, typename U, size_t R>
template<class T, class U, size_t R>
constexpr auto operator*(const vector<T,R>& left, const vector<U,R>& right){
using res_t = decltype(std::declval<T>() * std::declval<U>());
res_t res = 0;
@ -165,7 +165,7 @@ namespace math{
}
return res;
}
template<typename T, typename U, size_t R, std::enable_if_t<!is_matrix<U>::value,int>>
template<class T, class U, size_t R> requires Compatible_Scalar<U,T>
constexpr auto operator*(const vector<T,R>& left, U&& right){
using res_t = decltype(std::declval<T>() * std::declval<U>());
vector<res_t,R> res(zero_initialize);
@ -174,7 +174,7 @@ namespace math{
}
return res;
}
template<typename T, typename U, size_t R, std::enable_if_t<!is_matrix<U>::value,int>>
template<class T, class U, size_t R> requires Compatible_Scalar<U,T>
constexpr auto operator*(U&& left, const vector<T,R>& right){
using res_t = decltype(std::declval<U>() * std::declval<T>());
vector<res_t,R> res(zero_initialize);
@ -183,7 +183,7 @@ namespace math{
}
return res;
}
template<typename T, typename U, size_t R, std::enable_if_t<!is_matrix<U>::value,int>>
template<class T, class U, size_t R> requires Compatible_Scalar<U,T>
constexpr auto operator/(const vector<T,R>& left, U&& right){
using res_t = decltype(std::declval<T>() / std::declval<U>());
vector<res_t,R> res(zero_initialize);
@ -192,7 +192,7 @@ namespace math{
}
return res;
}
template<typename T, typename U, size_t R>
template<class T, class U, size_t R>
constexpr auto operator+(const vector<T,R>& left, const vector<U,R>& right){
using res_t = decltype(std::declval<T>() + std::declval<U>());
vector<res_t,R> res(zero_initialize);
@ -201,7 +201,7 @@ namespace math{
}
return res;
}
template<typename T, typename U, size_t R>
template<class T, class U, size_t R>
constexpr auto operator-(const vector<T,R>& left, const vector<U,R>& right){
using res_t = decltype(std::declval<T>() - std::declval<U>());
vector<res_t,R> res(zero_initialize);
@ -210,7 +210,7 @@ namespace math{
}
return res;
}
template<typename T, typename U, size_t R>
template<class T, class U, size_t R>
constexpr auto operator-(const vector<T,R>& left){
using res_t = decltype(-std::declval<U>());
vector<res_t,R> res(zero_initialize);
@ -220,28 +220,28 @@ namespace math{
return res;
}
template<typename T, typename U, size_t R, std::enable_if_t<!is_matrix<U>::value,int>>
template<class T, class U, size_t R> requires Compatible_Scalar<U,T>
constexpr decltype(auto) operator*=(vector<T,R>& left, U&& right){
for(size_t i = 0; i < R; ++i){
left[i] *= right;
}
return left;
}
template<typename T, typename U, size_t R, std::enable_if_t<!is_matrix<U>::value,int>>
template<class T, class U, size_t R> requires Compatible_Scalar<U,T>
constexpr decltype(auto) operator/=(vector<T,R>& left, U&& right){
for(size_t i = 0; i < R; ++i){
left[i] /= right;
}
return left;
}
template<typename T, typename U, size_t R>
template<class T, class U, size_t R>
constexpr decltype(auto) operator+=(vector<T,R>& left, const vector<U,R>& right){
for(size_t i = 0; i < R; ++i){
left[i] += right[i];
}
return left;
}
template<typename T, typename U, size_t R>
template<class T, class U, size_t R>
constexpr decltype(auto) operator-=(vector<T,R>& left, const vector<U,R>& right){
for(size_t i = 0; i < R; ++i){
left[i] -= right[i];

View File

@ -22,7 +22,6 @@
#include "gfx/ogl/shader_program.hpp"
#include "renderable.hpp"
#include "gfx/resource_manager.hpp"
#include "math/vec.hpp"
#include "config.hpp"
@ -33,6 +32,7 @@
#include "gfx/ogl/vbo.hpp"
#include "gfx/ogl/vao.hpp"
#include "gfx/ogl/texture.hpp"
#include "wip/renderer.hpp"
class board_gfx;
@ -120,7 +120,7 @@ private:
std::unique_ptr<board_gfx> m_gfx;
public:
board(gfx::resource_manager& r);
board(wip::gfx::renderer& r);
~board(void)override = default;
tile::value check_winner(void)const;

View File

@ -23,7 +23,7 @@
#include "gfx/ogl/vbo.hpp"
#include "gfx/ogl/vao.hpp"
#include "gfx/ogl/shader_program.hpp"
#include "gfx/resource_manager.hpp"
#include "wip/renderer.hpp"
#include <utility> //pair
#include <memory> //shared_ptr
@ -38,7 +38,7 @@ private:
gfx::ogl::vbo m_vbo;
public:
board_gfx(gfx::resource_manager& resman);
board_gfx(wip::gfx::renderer& resman);
~board_gfx(void) = default;
void set_uniforms(gfx::ogl::shader_program& sh);

View File

@ -24,9 +24,10 @@
#include "gfx/ogl/vbo.hpp"
#include "math/math.hpp"
#include "scene.hpp"
#include "gfx/resource_manager.hpp"
#include "basic_framebuffer.hpp"
#include "wip/renderer.hpp"
#include <memory> //shared_ptr
class main_renderer
@ -55,7 +56,7 @@ private:
gfx::ogl::vbo m_board_vbo;
public:
main_renderer(gfx::resource_manager& res, int width, int height);
main_renderer(wip::gfx::renderer& res, int width, int height);
void set_vp_matrix(const math::mat4f& vp);
void render(scene&);

View File

@ -23,12 +23,17 @@
#include "egn/input.hpp"
#include "gfx/ogl/texture.hpp"
#include "screen_renderer.hpp"
#include "wip/renderer.hpp"
#include "wip/square.hpp"
class pause_state : public egn::game_state_iface
{
private:
egn::game_state_iface* m_under_state;
screen_renderer m_screen_renderer;
std::shared_ptr<wip::square> m_square;
egn::ortho_camera m_main_camera;
double m_elapsed_time;
public:
pause_state(egn::game& owner, egn::game_state_iface* under);

View File

@ -24,8 +24,8 @@
#include "gfx/ogl/texture.hpp"
#include "math/math.hpp"
#include "gfx/ogl/shader_program.hpp"
#include "gfx/resource_manager.hpp"
#include "scene.hpp"
#include "wip/renderer.hpp"
#include "egn/font.hpp"
@ -54,7 +54,7 @@ private:
int m_screen_width, m_screen_height;
public:
screen_renderer(gfx::resource_manager& res, int width, int height, const std::shared_ptr<gfx::ogl::texture>& base_tex);
screen_renderer(wip::gfx::renderer& res, int width, int height, const std::shared_ptr<gfx::ogl::texture>& base_tex);
void render(scene&);
void resize_viewport(int width, int height);

29
include/util/demangle.hpp Normal file
View File

@ -0,0 +1,29 @@
/**
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_UTIL_DEMANGLE_HPP
#define OUR_DICK_UTIL_DEMANGLE_HPP
#include <string>
namespace util{
std::string demangle(const char* name);
}
#endif

View File

@ -0,0 +1,68 @@
/**
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_WIP_BASE_SHADER_HPP
#define OUR_DICK_GRAPHICS_WIP_BASE_SHADER_HPP
namespace wip::gfx::base_shader{
static constexpr char vertex_shader_text[] =
R"glsl(
#version 430 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 tex_coords;
layout (std140) uniform mvp_matrix{
mat4 vp_mat;
mat4 model_mat;
};
out VS_OUT{
vec2 tex_coords;
}vs_out;
const vec4 vertices[6] = vec4[](vec4(0,1,0,1), vec4(0,0,0,1), vec4(1,0,0,1), vec4(1,0,0,1), vec4(1,1,0,1), vec4(0,1,0,1));
void main(){
gl_Position = vp_mat * model_mat * vec4(position, 1);
vs_out.tex_coords = tex_coords;
}
)glsl";
static constexpr char fragment_shader_text[] =
R"glsl(
#version 430 core
in VS_OUT{
vec2 tex_coords;
}fs_in;
out vec4 frag_color;
uniform sampler2D diffuse_texture;
void main(){
frag_color = texture(diffuse_texture, fs_in.tex_coords);;
}
)glsl";
}
#endif

View File

@ -21,13 +21,18 @@
#include "mesh.hpp"
#include "material.hpp"
#include "surface.hpp"
#include "renderable.hpp"
namespace wip::gfx{
struct draw_command{
renderable* instance;
material* mat;
mesh* msh;
surface* surf;
float distance;
void* userptr;
};
}

View File

@ -45,7 +45,7 @@ namespace wip::gfx::ogl{
void bind(void);
void render(::wip::gfx::renderer& r, material&);
void render(::wip::gfx::renderer& r);
};
}

View File

@ -37,7 +37,7 @@ namespace wip::gfx::ogl{
using container_type = resource_manager::container_type<T>;
protected:
::gfx::ogl::ubo<math::mat4f> m_camera_uniform;
::gfx::ogl::ubo<math::mat4f,math::mat4f> m_camera_uniform;
public:
renderer(void) = default;
@ -49,8 +49,12 @@ namespace wip::gfx::ogl{
renderer& operator=(renderer&&) = default;
void set_viewport(const math::vec4f& vp);
void set_model_matrix(const math::mat4f& mat);
void set_camera(const math::mat4f& view, const math::mat4f& proj);
void bind_default_surface(void);
void clear_current_surface(void);
void draw_tris(int offset, int vertex_count);
void process_command(draw_command& c);

View File

@ -22,6 +22,7 @@
#include "gfx/resource_container.hpp"
#include "gfx/ogl/shader_program.hpp"
#include "gfx/ogl/texture.hpp"
#include "gfx/ogl/fbo.hpp"
namespace wip::gfx::ogl{
@ -36,8 +37,11 @@ namespace wip::gfx::ogl{
container_type<::gfx::ogl::shader> m_shaders;
container_type<::gfx::ogl::texture> m_textures;
container_type<::gfx::ogl::texture_array> m_texture_arrays;
container_type<::gfx::ogl::fbo> m_framebuffers;
public:
resource_manager(void);
const container_type<::gfx::ogl::shader_program>& shader_programs(void)const;
container_type<::gfx::ogl::shader_program>& shader_programs(void);
const container_type<::gfx::ogl::shader>& shaders(void)const;
@ -46,6 +50,8 @@ namespace wip::gfx::ogl{
container_type<::gfx::ogl::texture>& textures(void);
const container_type<::gfx::ogl::texture_array>& texture_arrays(void)const;
container_type<::gfx::ogl::texture_array>& texture_arrays(void);
const container_type<::gfx::ogl::fbo>& framebuffers(void)const;
container_type<::gfx::ogl::fbo>& framebuffers(void);
};
}

View File

@ -0,0 +1,42 @@
/**
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_WIP_OGL_SURFACE_HPP
#define OUR_DICK_GRAPHICS_WIP_OGL_SURFACE_HPP
#include "gfx/ogl/fbo.hpp"
#include <memory> //shared_ptr
namespace wip::gfx::ogl{
class surface
{
public:
std::shared_ptr<::gfx::ogl::fbo> framebuffer;
public:
surface(const std::shared_ptr<::gfx::ogl::fbo>& fb);
void bind(void);
};
}
#endif

View File

@ -0,0 +1,40 @@
/**
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_WIP_RENDERABLE_HPP
#define OUR_DICK_GRAPHICS_WIP_RENDERABLE_HPP
#include "gfx/ogl/shader_program.hpp"
namespace wip::gfx{
class renderer;
struct draw_command;
class renderable
{
public:
virtual ~renderable(void) = default;
virtual void submit_render(renderer& r) = 0;
virtual void render(renderer& r, draw_command& c) = 0;
};
}
#endif

View File

@ -22,6 +22,7 @@
#include "ogl_renderer.hpp"
#include "material.hpp"
#include "mesh.hpp"
#include "surface.hpp"
#include "draw_command.hpp"
#include <list>
@ -38,11 +39,12 @@ namespace wip::gfx{
protected:
container_type<material> m_materials;
container_type<mesh> m_meshs;
container_type<surface> m_surfaces;
std::list<draw_command> m_commands;
public:
renderer(void) = default;
renderer(void);
renderer(const renderer&) = default;
renderer(renderer&&) = default;
~renderer(void) = default;
@ -55,6 +57,8 @@ namespace wip::gfx{
container_type<mesh>& meshs(void);
const container_type<material>& materials(void)const;
container_type<material>& materials(void);
const container_type<surface>& surfaces(void)const;
container_type<surface>& surfaces(void);
void submit_command(const draw_command& c);
void render(void);

View File

@ -23,33 +23,33 @@
#include "mesh.hpp"
#include "material.hpp"
#include "renderer.hpp"
#include "renderable.hpp"
#include <memory> //shared_ptr
namespace wip{
class square
class square : public gfx::renderable
{
public:
static constexpr gfx::vertex mesh_vertices[] = {
{{0, 1, 0}, {0, 1}},
{{0, 0, 0}, {0, 0}},
{{1, 0, 0}, {1, 0}},
{{1, 0, 0}, {1, 0}},
{{1, 1, 0}, {1, 1}},
{{0, 1, 0}, {0, 1}}
{{-1, 1, 0}, {0, 1}},
{{-1, -1, 0}, {0, 0}},
{{ 1, -1, 0}, {1, 0}},
{{ 1, -1, 0}, {1, 0}},
{{ 1, 1, 0}, {1, 1}},
{{-1, 1, 0}, {0, 1}}
};
private:
public:
std::shared_ptr<gfx::mesh> m_mesh;
std::shared_ptr<gfx::material> m_material;
public:
square(const std::shared_ptr<gfx::mesh>& msh, const std::shared_ptr<gfx::material>& mat);
void render(gfx::renderer& r){
r.submit_command({m_material.get(), m_mesh.get(), 0});
}
void submit_render(gfx::renderer& r)override;
void render(gfx::renderer& r, gfx::draw_command&)override;
};
}

34
include/wip/surface.hpp Normal file
View File

@ -0,0 +1,34 @@
/**
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_WIP_SURFACE_HPP
#define OUR_DICK_GRAPHICS_WIP_SURFACE_HPP
#include "ogl_surface.hpp"
namespace wip::gfx{
class surface : public ogl::surface
{
public:
using ogl::surface::surface;
};
}
#endif

View File

@ -19,7 +19,7 @@ ifeq ($(OS),Windows_NT)
WINDOWS::=1
endif
SOURCE_DIRS::=src src/audio src/audio/impl src/gfx src/gfx/ogl src/egn src/ttt src/wip
SOURCE_DIRS::=src src/audio src/audio/impl src/gfx src/gfx/ogl src/egn src/ttt src/wip src/util
SOURCES::=
OBJDIR::=obj
DEPDIR::=$(OBJDIR)/dep

View File

@ -108,7 +108,7 @@ namespace egn{
//contained within the rectangle. Otherwise, we must project the point onto the rectangle's border.
//If not in the rectangle, we can have 1 or 2 candidate edges to project onto. We want the closest one
//to the input point.
math::vec3f cand1, cand2;
//math::vec3f cand1, cand2;
/*
now we divide the plane into a voronoi diagram where each region is closest

View File

@ -71,10 +71,6 @@ namespace egn{
}
void game::render(void){
m_window.make_current();
m_window.framebuffer().bind();
m_window.framebuffer().clear_color_buffer();
m_window.framebuffer().clear_depth_buffer();
m_states_manager.render();
m_window.swap_buffers();
@ -101,12 +97,13 @@ namespace egn{
void game::on_notify(const game_state_event&){}
gfx::resource_manager& game::gfx_resource_manager(void){
return m_window.resource_man();
wip::gfx::renderer& game::renderer(void){
return m_renderer;
}
const gfx::resource_manager& game::gfx_resource_manager(void)const{
return m_window.resource_man();
const wip::gfx::renderer& game::renderer(void)const{
return m_renderer;
}
void game::push_state(std::unique_ptr<game_state_iface>&& state){
m_states_manager.push_state(std::move(state));
}

View File

@ -17,6 +17,7 @@
*/
#include "egn/game_state.hpp"
#include "egn/game.hpp"
#include "egn/input.hpp"
#include "config.hpp"
@ -72,4 +73,11 @@ namespace egn{
game_state_iface::game_state_iface(game* owner):
m_owner(owner){}
wip::gfx::renderer& game_state_iface::renderer(void){
return m_owner->renderer();
}
const wip::gfx::renderer& game_state_iface::renderer(void)const{
return m_owner->renderer();
}
}

View File

@ -27,7 +27,7 @@ namespace gfx::ogl{
scoped_buffer_map<void>::scoped_buffer_map(GLuint bid, buffer::maptype m):
m_buffer(bid)
{
debug_print_verbose("Mapping vertex buffer object %u\n", bid);
debug_print_verbose("Mapping buffer object %u\n", bid);
m_data = reinterpret_cast<pointer>(glMapNamedBuffer(m_buffer, static_cast<GLenum>(m)));
}
scoped_buffer_map<void>::scoped_buffer_map(scoped_buffer_map&& m):
@ -35,7 +35,7 @@ namespace gfx::ogl{
m_buffer(std::exchange(m.m_buffer, 0)){}
scoped_buffer_map<void>::~scoped_buffer_map(void){
if(m_data){
debug_print_verbose("Unmapping vertex buffer object %u\n", m_buffer);
debug_print_verbose("Unmapping buffer object %u\n", m_buffer);
glUnmapNamedBuffer(m_buffer);
}
}

View File

@ -19,6 +19,8 @@
#include "gfx/ogl/rbo.hpp"
#include <utility> //swap, exchange
#include "config.hpp"
namespace gfx::ogl{
rbo::rbo(GLsizei width, GLsizei height, GLenum format, GLsizei samples):
@ -60,11 +62,13 @@ namespace gfx::ogl{
}
void rbo::resize(GLsizei w, GLsizei h){
debug_print_warn("Resizing rbo!\n");
m_width = w;
m_height = h;
glNamedRenderbufferStorageMultisample(m_buffer, m_samples, m_format, m_width, m_height);
}
void rbo::resize(GLsizei w, GLsizei h, GLenum format, GLsizei samples){
debug_print_warn("Resizing rbo!\n");
m_width = w;
m_height = h;
m_format = format;
@ -72,6 +76,7 @@ namespace gfx::ogl{
glNamedRenderbufferStorageMultisample(m_buffer, m_samples, m_format, m_width, m_height);
}
void rbo::reformat(GLenum format){
debug_print_warn("Changing rbo format!\n");
m_format = format;
glNamedRenderbufferStorageMultisample(m_buffer, m_samples, m_format, m_width, m_height);
}

View File

@ -368,10 +368,6 @@ namespace gfx::ogl{
t.bind_unit(tex_unit);
glProgramUniform1i(m_shader_id, m_location, tex_unit);
}
void uniform::set(const weak_texture& t, GLuint tex_unit){
t.bind_unit(tex_unit);
glProgramUniform1i(m_shader_id, m_location, tex_unit);
}
void uniform::set(const vec2f& v){
glProgramUniform2fv(m_shader_id, m_location, 1, v);

View File

@ -301,9 +301,6 @@ namespace gfx::ogl{
void texture::bind_unit(GLuint tunit)const{
glBindTextureUnit(tunit, m_tex_id);
}
weak_texture texture::create_handle(void)const{
return weak_texture(*this);
}
bool texture::create_texture_storage_(void){
switch(m_format){
@ -524,32 +521,4 @@ namespace gfx::ogl{
return true;
}
weak_texture::weak_texture(GLuint tex):
m_texture(tex){}
weak_texture::weak_texture(const texture& tex):
m_texture(tex.raw()){}
GLuint weak_texture::raw(void)const{
return m_texture;
}
GLsizei weak_texture::get_width(void)const{
GLint retval;
glGetTextureLevelParameteriv(m_texture, 0, GL_TEXTURE_WIDTH, &retval);
return retval;
}
GLsizei weak_texture::get_height(void)const{
GLint retval;
glGetTextureLevelParameteriv(m_texture, 0, GL_TEXTURE_HEIGHT, &retval);
return retval;
}
void weak_texture::bind(GLuint target)const{
glBindTexture(target, m_texture);
}
void weak_texture::bind_unit(GLuint tunit)const{
glBindTextureUnit(tunit, m_texture);
}
}

View File

@ -140,15 +140,19 @@ static void enable_opengl_debug_context(void){
return false;
}
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstringop-truncation"
#endif
static char* copy_title(const char* src, size_t titlelen){
char* dest = new char[titlelen + 1];
strncpy(dest, src, titlelen);
dest[titlelen] = 0;
return dest;
}
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic pop
#endif
window::window(int width, int height, const char* title, bool makecurrent):
window(s_default_cver_maj, s_default_cver_min, width, height, title, makecurrent){}
@ -209,7 +213,6 @@ static void enable_opengl_debug_context(void){
debug_print("OpenGL debug context is disabled\n");
#endif
glfwMakeContextCurrent(m_window);
m_root_fbo.bind();
glViewport(0, 0, width, height);
set_swap_interval(m_swap_interval);
@ -270,7 +273,6 @@ static void enable_opengl_debug_context(void){
#endif
glfwMakeContextCurrent(m_window);
m_root_fbo.bind();
glViewport(0, 0, size.x(), size.y());
set_swap_interval(w.m_swap_interval);
@ -328,19 +330,6 @@ static void enable_opengl_debug_context(void){
m_title = nullptr;
}
resource_manager& window::resource_man(void){
return m_resources;
}
const resource_manager& window::resource_man(void)const{
return m_resources;
}
fbo& window::framebuffer(void){
return m_root_fbo;
}
const fbo& window::framebuffer(void)const{
return m_root_fbo;
}
void window::set_size(const math::vec2i& v){
set_size(v.x(), v.y());
}

View File

@ -1,63 +0,0 @@
/**
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/>.
*/
#include "gfx/resource_manager.hpp"
namespace gfx{
bool resource_manager::has_texture_array(const char* key)const{
return m_texture_arrays.has_value(key);
}
auto resource_manager::get_texture_array(const char* file) -> container_type<ogl::texture_array>::node{
return m_texture_arrays.get_value(file);
}
bool resource_manager::erase_texture_array(const char* key){
return m_texture_arrays.erase_value(key);
}
bool resource_manager::has_texture(const char* key)const{
return m_textures.has_value(key);
}
auto resource_manager::get_texture(const char* file) -> container_type<ogl::texture>::node{
return m_textures.get_value(file);
}
bool resource_manager::erase_texture(const char* key){
return m_textures.erase_value(key);
}
bool resource_manager::has_font(const char* key)const{
return m_fonts.has_value(key);
}
auto resource_manager::get_font(const char* file) -> container_type<egn::font_atlas>::node{
return m_fonts.get_value(file);
}
bool resource_manager::erase_font(const char* key){
return m_fonts.erase_value(key);
}
bool resource_manager::has_shader(const char* key)const{
return m_shaders.has_value(key);
}
auto resource_manager::get_shader(const char* key) -> container_type<ogl::shader_program>::node{
return m_shaders.get_value(key);
}
bool resource_manager::erase_shader(const char* key){
return m_shaders.erase_value(key);
}
}

View File

@ -32,7 +32,7 @@ const math::vec4f& tile::get_color(void)const{
return m_color_filter;
}
board::board(gfx::resource_manager& resman):
board::board(wip::gfx::renderer& resman):
m_tiles(new tile[9]),
m_gfx(new board_gfx(resman))
{

View File

@ -19,10 +19,10 @@
#include "ttt/board_gfx.hpp"
#include "ttt/board.hpp"
board_gfx::board_gfx(gfx::resource_manager& resman):
board_gfx::board_gfx(wip::gfx::renderer& resman):
m_vbo((16 * sizeof(float) + 4 * sizeof(float) + 1 * sizeof(int)) * 9, gfx::ogl::buffer::usage::DYNAMIC_DRAW)
{
auto result = resman.emplace_texture_array("board_textures", 3);
auto result = resman.texture_arrays().emplace_value("board_textures", 3);
m_textures = std::move(result.first);
if(result.second){
(*m_textures)[0].set_image(egn::image("assets/images/blank.jpg", true));

View File

@ -28,23 +28,26 @@
#define MAX_WIDTH 3840
#define MAX_HEIGHT 2160
main_renderer::main_renderer(gfx::resource_manager& res, int width, int height):
main_renderer::main_renderer(wip::gfx::renderer& res, int width, int height):
m_fb(MAX_WIDTH, MAX_HEIGHT),
m_primary_fb(util::no_initialize),
m_vbo(s_vertices, sizeof(s_vertices), gfx::ogl::buffer::usage::DYNAMIC_DRAW),
m_board_vbo((16*sizeof(float)+sizeof(int)+4*sizeof(float)) * 9, gfx::ogl::buffer::usage::DYNAMIC_DRAW)
{
m_square_shader = res.emplace_shader("square_shader", util::make_deferred<gfx::ogl::shader>(square_shader::fragment_shader_text, gfx::ogl::shader::type::FRAGMENT),
util::make_deferred<gfx::ogl::shader>(square_shader::geometry_shader_text, gfx::ogl::shader::type::GEOMETRY),
util::make_deferred<gfx::ogl::shader>(square_shader::vertex_shader_text, gfx::ogl::shader::type::VERTEX)).first;
auto vert = res.shaders().emplace_value("square_shader_vert", square_shader::vertex_shader_text, gfx::ogl::shader::type::VERTEX).first;
auto frag = res.shaders().emplace_value("square_shader_frag", square_shader::fragment_shader_text, gfx::ogl::shader::type::FRAGMENT).first;
auto geom = res.shaders().emplace_value("square_shader_geom", square_shader::geometry_shader_text, gfx::ogl::shader::type::GEOMETRY).first;
m_square_shader = res.shader_programs().emplace_value("square_shader", *vert, *frag, *geom).first;
if(m_square_shader->has_link_error()){
debug_print_error("%s\n", m_square_shader->get_error().c_str());
}
m_square_shader->get_uniform("vp_mat").set(math::mat4f{});
m_screen_shader = res.emplace_shader("screen_shader", util::make_deferred<gfx::ogl::shader>(screen_shader::fragment_shader_text, gfx::ogl::shader::type::FRAGMENT),
util::make_deferred<gfx::ogl::shader>(screen_shader::vertex_shader_text, gfx::ogl::shader::type::VERTEX)).first;
vert = res.shaders().emplace_value("screen_shader_vert", screen_shader::vertex_shader_text, gfx::ogl::shader::type::VERTEX).first;
frag = res.shaders().emplace_value("screen_shader_frag", screen_shader::fragment_shader_text, gfx::ogl::shader::type::FRAGMENT).first;
m_screen_shader = res.shader_programs().emplace_value("screen_shader", *vert, *frag).first;
m_screen_shader->get_uniform("vp_mat").set(math::mat4f{});
m_vao.bind_buffer(m_vbo, 0, 0, sizeof(vertex));

View File

@ -19,11 +19,17 @@
#include "ttt/pause_state.hpp"
#include "egn/game.hpp"
#include "util/deferred.hpp"
#include "egn/image.hpp"
#include "gfx/ogl/gl_include.hpp" //TODO
#include "wip/base_shader.hpp"
#include "wip/square.hpp"
#include "config.hpp"
#include <vector>
#include <utility> //pair
static egn::font_atlas generate_font_atlas_from_file(const char* file, int target_height){
egn::font f(file);
return f.generate_atlas(0, target_height, std::pair{' ', ('~' - ' ')});
@ -32,14 +38,34 @@ static egn::font_atlas generate_font_atlas_from_file(const char* file, int targe
pause_state::pause_state(egn::game& owner, egn::game_state_iface* under):
game_state_iface(&owner),
m_under_state(under),
m_screen_renderer(owner.gfx_resource_manager(), owner.get_width(), owner.get_height(), owner.gfx_resource_manager().emplace_texture("pause_screen", util::make_deferred<egn::image>("assets/images/pause.png", true)).first){}
m_screen_renderer(owner.renderer(), owner.get_width(), owner.get_height(), owner.renderer().textures().emplace_value("pause_screen", util::make_deferred<egn::image>("assets/images/pause.png", true)).first),
m_main_camera(10, 10, 0.1, 50),
m_elapsed_time(0)
{
//TODO hide GL implementation details somewhere else
auto vert = renderer().shaders().emplace_value("base_vert", wip::gfx::base_shader::vertex_shader_text, gfx::ogl::shader::type::VERTEX).first;
auto frag = renderer().shaders().emplace_value("base_frag", wip::gfx::base_shader::fragment_shader_text, gfx::ogl::shader::type::FRAGMENT).first;
auto shader = renderer().shader_programs().emplace_value("base_shader", *vert, *frag).first;
auto tex = renderer().textures().emplace_value("test_texture", util::make_deferred<egn::image>("assets/images/x.jpg", true)).first;
auto material = renderer().materials().emplace_value("test_material", shader).first;
material->diffuse_texture = tex;
tex = renderer().textures().emplace_value("test_texture2", util::make_deferred<egn::image>("assets/images/o.jpg", true)).first;
material = renderer().materials().emplace_value("test_material2", shader).first;
material->diffuse_texture = tex;
auto mesh = renderer().meshs().emplace_value("square_mesh", std::vector<wip::gfx::vertex>(wip::square::mesh_vertices, wip::square::mesh_vertices+6)).first;
m_square.reset(new wip::square(mesh, material));
m_main_camera.set_position({0, 0, 5});
renderer().set_camera(m_main_camera.get_view_matrix(), m_main_camera.get_projection_matrix());
}
void pause_state::enter(){
const float w = m_owner->get_width();
const float h = m_owner->get_height();
m_screen_renderer.resize_viewport(w, h);
renderer().set_viewport({0, 0, w, h});
}
void pause_state::leave(){}
void pause_state::handle_input(const egn::input_event& event){
@ -54,11 +80,20 @@ void pause_state::handle_input(const egn::input_event& event){
}else if(event.ev_type == egn::input_event::type::RESIZE){
m_under_state->handle_input(event);
m_screen_renderer.resize_viewport(event.x, event.y);
renderer().set_viewport({0, 0, event.x, event.y});
}
}
void pause_state::update(double dtime){
m_elapsed_time += dtime;
if(m_elapsed_time > 1){
m_elapsed_time -= 1;
m_square->m_material = renderer().materials().get_value(rand() % 2 == 0 ? "test_material" : "test_material2");
}
}
void pause_state::update(double){}
void pause_state::render(){
m_under_state->render();
scene tmp;
m_screen_renderer.render(tmp);
renderer().bind_default_surface();
//renderer().clear_current_surface();
m_square->submit_render(renderer());
renderer().render();
}

View File

@ -28,12 +28,12 @@
play_state::play_state(egn::game& owner, int width, int height):
game_state_iface(&owner),
m_main_renderer(owner.gfx_resource_manager(), width, height),
m_main_renderer(owner.renderer(), width, height),
m_current_player(rand() % 2)
{
debug_print("First player chosen is %c\n", m_current_player ? 'X' : 'O');
m_scene.objects.emplace_back(new board(m_owner->gfx_resource_manager()));
m_scene.objects.emplace_back(new board(m_owner->renderer()));
m_scene.renderables.emplace_back(static_cast<board*>(m_scene.objects[0].get()));
m_scene.cameras.emplace_back(new egn::ortho_camera(10 * ((float)width / height), 10, 0.1, 50));
@ -131,7 +131,7 @@ void play_state::handle_input(const egn::input_event& ev){
}
}
}
void play_state::update(double time_diff){
void play_state::update(double /*time_diff*/){
}
void play_state::render(){
m_main_renderer.set_vp_matrix(m_main_camera->get_projection_matrix() * m_main_camera->get_view_matrix());

View File

@ -28,14 +28,15 @@
#include "ttt/font_shader.hpp"
#include "math/debug.hpp"
screen_renderer::screen_renderer(gfx::resource_manager& res, int width, int height, const std::shared_ptr<gfx::ogl::texture>& base_tex):
screen_renderer::screen_renderer(wip::gfx::renderer& res, int width, int height, const std::shared_ptr<gfx::ogl::texture>& base_tex):
m_vbo(s_vertices, sizeof(s_vertices), gfx::ogl::buffer::usage::DYNAMIC_DRAW),
m_texture(base_tex),
m_screen_width(width), m_screen_height(height)
{
m_screen_shader = res.emplace_shader("screen_shader", util::make_deferred<gfx::ogl::shader>(screen_shader::vertex_shader_text, gfx::ogl::shader::type::VERTEX),
util::make_deferred<gfx::ogl::shader>(screen_shader::fragment_shader_text, gfx::ogl::shader::type::FRAGMENT)).first;
auto vert = res.shaders().emplace_value("screen_shader_vert", screen_shader::vertex_shader_text, gfx::ogl::shader::type::VERTEX).first;
auto frag = res.shaders().emplace_value("screen_shader_frag", screen_shader::fragment_shader_text, gfx::ogl::shader::type::FRAGMENT).first;
m_screen_shader = res.shader_programs().emplace_value("screen_shader", *vert, *frag).first;
if(m_screen_shader->has_link_error()){
debug_print_error("%s\n", m_screen_shader->get_error().c_str());
}

48
src/util/demangle.cpp Normal file
View File

@ -0,0 +1,48 @@
/**
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/>.
*/
#include "config.hpp"
#if defined(OUR_DICK_ENABLE_DEBUG_VERBOSE_OUTPUT) && (defined(__GNUC__) && !defined(_MSC_VER))
#include <cstdlib> //free
#include <string>
#include <memory>
#include <cxxabi.h>
namespace util{
std::string demangle(const char* name){
int status = 0;
std::unique_ptr<char,void(*)(void*)> res{
abi::__cxa_demangle(name, nullptr, nullptr, &status),
std::free
};
return (status == 0) ? res.get() : name;
}
}
#else
#include <string>
namespace util{
std::string demangle(const char* name){
return name;
}
}
#endif

View File

@ -25,7 +25,7 @@
namespace wip::gfx::ogl{
static constexpr size_t vertex_position_loc = 0;
static constexpr size_t vertex_tex_coord_loc = 0;
static constexpr size_t vertex_tex_coord_loc = 1;
static void setup_mesh_attributes_(::gfx::ogl::vao& v){
auto attrib = v.get_attribute(vertex_position_loc);
@ -44,12 +44,15 @@ namespace wip::gfx::ogl{
m_buffer(sizeof(vertex) * m_num_vertices, ::gfx::ogl::buffer::usage::STATIC_DRAW),
m_attributes()
{
m_buffer.buffer(vertices.data(), vertices.size() * sizeof(vertex));
m_attributes.bind_buffer(m_buffer, 0, 0, sizeof(vertex));
setup_mesh_attributes_(m_attributes);
}
void mesh::bind(void){
m_attributes.bind();
}
void mesh::render(::wip::gfx::renderer& r, material&){
void mesh::render(::wip::gfx::renderer& r){
r.draw_tris(0, m_num_vertices);
}

View File

@ -24,24 +24,39 @@ namespace wip::gfx::ogl{
void renderer::set_viewport(const math::vec4f& vp){
glViewport(vp.x(), vp.y(), vp.z(), vp.w());
}
void renderer::set_model_matrix(const math::mat4f& mat){
m_camera_uniform.set<1>(mat);
}
void renderer::set_camera(const math::mat4f& view, const math::mat4f& proj){
m_camera_uniform.set<0>(proj * view);
}
void renderer::bind_default_surface(void){
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void renderer::clear_current_surface(void){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
void renderer::draw_tris(int offset, int vertex_count){
glDrawArrays(GL_TRIANGLES, offset, vertex_count);
}
void renderer::process_command(draw_command& c){
if(!c.surf){
bind_default_surface();
}else{
c.surf->bind();
}
if(c.msh){
c.msh->bind();
}
if(c.mat){
::gfx::ogl::shader_program& shade = *c.mat->shader;
shade.use();
shade.get_uniform_block("vp_matrix").set_binding(0, m_camera_uniform);
shade.get_uniform_block("mvp_matrix").set_binding(0, m_camera_uniform);
c.mat->bind();
//static_cast is fine; we know this is always the base class of renderer if we made it to this point
c.msh->render(static_cast<::wip::gfx::renderer&>(*this), *c.mat);
}
//static_cast is fine; we know this is always the base class of renderer if we made it to this point
c.instance->render(static_cast<::wip::gfx::renderer&>(*this), c);
}
}

View File

@ -20,6 +20,10 @@
namespace wip::gfx::ogl{
resource_manager::resource_manager(void){
m_framebuffers.emplace_value("default");
}
auto resource_manager::shader_programs(void)const -> const container_type<::gfx::ogl::shader_program>&{
return m_shader_programs;
}
@ -44,5 +48,11 @@ namespace wip::gfx::ogl{
auto resource_manager::texture_arrays(void) -> container_type<::gfx::ogl::texture_array>&{
return m_texture_arrays;
}
auto resource_manager::framebuffers(void)const -> const container_type<::gfx::ogl::fbo>&{
return m_framebuffers;
}
auto resource_manager::framebuffers(void) -> container_type<::gfx::ogl::fbo>&{
return m_framebuffers;
}
}

29
src/wip/ogl_surface.cpp Normal file
View File

@ -0,0 +1,29 @@
/**
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/>.
*/
#include "wip/ogl_surface.hpp"
namespace wip::gfx::ogl{
surface::surface(const std::shared_ptr<::gfx::ogl::fbo>& fb):
framebuffer(fb){}
void surface::bind(void){
framebuffer->bind();
}
}

View File

@ -18,8 +18,16 @@
#include "wip/renderer.hpp"
#include "gfx/ogl/gl_include.hpp" //TODO
namespace wip::gfx{
renderer::renderer(void):
ogl::renderer()
{
m_surfaces.emplace_value("default", m_framebuffers.get_value("default"));
}
void renderer::submit_command(const draw_command& c){
m_commands.push_back(c);
}
@ -35,6 +43,12 @@ namespace wip::gfx{
auto renderer::materials(void) -> container_type<material>&{
return m_materials;
}
auto renderer::surfaces(void)const -> const container_type<surface>&{
return m_surfaces;
}
auto renderer::surfaces(void) -> container_type<surface>&{
return m_surfaces;
}
void renderer::render(void){
for(auto& command : m_commands){
process_command(command);

38
src/wip/square.cpp Normal file
View File

@ -0,0 +1,38 @@
/**
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/>.
*/
#include "wip/square.hpp"
#include "math/mat.hpp"
namespace wip{
square::square(const std::shared_ptr<gfx::mesh>& msh, const std::shared_ptr<gfx::material>& mat):
m_mesh(msh),
m_material(mat){}
void square::submit_render(gfx::renderer& r){
r.submit_command({this, m_material.get(), m_mesh.get(), nullptr, 0, nullptr});
}
void square::render(gfx::renderer& r, gfx::draw_command&){
r.set_model_matrix(math::mat4f(math::id_initialize));
m_mesh->render(r);
}
}