I forgot to commit for a while so there's a lot in here.

Added ubo class template for handling Uniform Buffer Objects. This class automatically finds the offset and alignment for given data in a GLSL std140 uniform block. This makes it easy to just assign data through the gfx::ubo interface and bind that to the relevant shader_program's uniform block
Changed shader_program's method of handling uniforms to match more closely to how vao handles its attributes. That is to call  with the location as argument to get a proxy object on which to operate. I find this nicer to work with than having everything to do with uniforms in the shader_program class itself
Add a flat_camera class which just assigns the near and far plane to 0 and 1 respectively
Start work on a gui system which i'm really not confident about.
Attempting to rethink how renderers work, but also no really confident about where i'm going with it
Break out vbo_scoped_map into a more general scoped_buffer_map class so that vbo and ubo can utilize it
Remove old gl_buffers units that were not really being used since my change over to opengl DSA functions
Change the gfx::resource_manager to keep shared_ptr's in the container so the data can be more nicely shared
Add missing aliases in math::fwd_declare.hpp for boolean types
Change orthographic projection generator function to have the z values behave more in line with how opengl handles z depth. May have to undo this at some point but it seems to behave correctly now
Fix some rvalue related aspects of util::deferred
'
This commit is contained in:
rexy712 2022-02-04 13:49:22 -08:00
parent 1b884a9a48
commit e0924c5895
50 changed files with 2063 additions and 1665 deletions

View File

@ -103,6 +103,18 @@ namespace egn{
void recalc_projection_matrix()const override;
};
class flat_camera : public ortho_camera
{
public:
flat_camera(float w, float h);
flat_camera(const flat_camera&) = default;
flat_camera(flat_camera&&) = default;
~flat_camera(void) = default;
flat_camera& operator=(const flat_camera&) = default;
flat_camera& operator=(flat_camera&&) = default;
};
}
#endif

View File

@ -117,6 +117,7 @@ namespace egn{
}
template<class... Ts>
font_atlas font::generate_atlas(size_t glyph_w, size_t glyph_h, Ts&&... ranges){
debug_print_verbose("Generating font atlas for font '%s'\n", m_face->family_name);
FT_Set_Pixel_Sizes(m_face, glyph_w, glyph_h);
auto [atlas_width, atlas_height, max_glyph_width, max_glyph_height] = get_atlas_size_ranges_(std::forward<Ts>(ranges)...);
const auto format = (m_depth == 3) ? GL_RGB : GL_RED;

105
include/engine/menu.hpp Normal file
View File

@ -0,0 +1,105 @@
/**
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_ENGINE_MENU_HPP
#define OUR_DICK_ENGINE_MENU_HPP
#include "camera.hpp"
#include "font.hpp"
#include "menu_renderer.hpp"
#include "math/vec.hpp"
#include <vector>
#include <memory> //unique_ptr, shared_ptr
namespace egn::gui{
class menu;
class menu_item
{
protected:
menu* m_owner = nullptr;
protected:
menu_item(menu* owner);
public:
menu_item(const menu_item&) = default;
menu_item(menu_item&&) = default;
virtual ~menu_item(void) = default;
menu_item& operator=(const menu_item&) = default;
menu_item& operator=(menu_item&&) = default;
void set_owner(menu* owner);
virtual void render(menu_renderer& r) = 0;
virtual menu_item* clone(void)const = 0;
};
struct menu_node{
math::vec2f scale;
};
struct position_node : public menu_node{
std::unique_ptr<menu_item> item;
math::vec2f position;
};
class menu
{
private:
std::vector<position_node> m_items;
std::shared_ptr<font_atlas> m_default_font;
flat_camera m_camera;
public:
menu(void);
menu(const menu&) = default;
menu(menu&&) = default;
~menu(void) = default;
menu& operator=(const menu&) = default;
menu& operator=(menu&&) = default;
position_node& add_item(const menu_item& m);
template<class T, class... Args>
position_node& emplace_item(Args&&... args);
void set_default_font(const std::shared_ptr<egn::font_atlas>& font);
const std::shared_ptr<font_atlas>& get_default_font(void)const;
void resize(float w, float h);
void render(menu_renderer& r);
};
template<class T, class... Args>
position_node& menu::emplace_item(Args&&... args){
position_node tmp;
tmp.scale = math::vec2f{1, 1};
tmp.item = std::unique_ptr<menu_item>(new T{this, std::forward<Args>(args)...});
tmp.position = math::vec2f{0, 0};
return m_items.emplace_back(std::move(tmp));
}
}
#endif

View File

@ -0,0 +1,69 @@
/**
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_ENGINE_MENU_RENDERER_HPP
#define OUR_DICK_ENGINE_MENU_RENDERER_HPP
#include "math/vec.hpp"
#include "graphics/resource_manager.hpp"
#include "graphics/shader_program.hpp"
#include "graphics/fbo.hpp"
#include "graphics/ubo.hpp"
namespace egn{
class renderer
{
private:
math::vec4f m_saved_viewport{0, 0, 0, 0};
public:
void set_viewport(float x, float y, float w, float h);
void resize_viewport(float w, float h);
void reposition_viewport(float x, float y);
void apply_viewport(void);
};
class menu_renderer : public renderer
{
private:
gfx::ubo<math::mat4f> m_vp_matrix;
std::shared_ptr<gfx::shader_program> m_font_shader;
public:
menu_renderer(gfx::resource_manager& resman);
menu_renderer(const menu_renderer&) = default;
menu_renderer(menu_renderer&&) = default;
~menu_renderer(void) = default;
menu_renderer& operator=(const menu_renderer&) = default;
menu_renderer& operator=(menu_renderer&&) = default;
void set_font(const gfx::texture& atlas);
void set_position(const math::vec2f& pos);
void set_vp_matrix(const math::mat4f& matrix);
void begin(void);
void draw_text(int count);
void draw_text_to(gfx::fbo& target, int count);
void end(void);
};
}
#endif

View File

@ -22,12 +22,15 @@
#include "graphics/vbo.hpp"
#include "graphics/vao.hpp"
#include "graphics/texture.hpp"
#include "graphics/shader_program.hpp"
#include "font.hpp"
#include "math/vec.hpp"
#include "flat_object.hpp"
#include <string>
#include <vector>
#include <memory>
class font_renderer;
namespace egn{
@ -49,10 +52,11 @@ namespace egn{
void set_text(const char* string);
void render(gfx::shader_program& sh, const math::vec2f& pos);
void render(font_renderer& sh, const math::vec2f& pos);
};
class text : public flat::object_base
{
private:
@ -64,7 +68,7 @@ namespace egn{
void set_text(const char* string);
void render(gfx::shader_program& sh);
void render(font_renderer& sh);
};
}

View File

@ -0,0 +1,63 @@
/**
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_ENGINE_TEXT_FIELD_HPP
#define OUR_DICK_ENGINE_TEXT_FIELD_HPP
#include "menu.hpp"
#include "graphics/text_field_view.hpp"
#include "engine/font.hpp"
#include <string>
#include <memory> //shared_ptr
namespace egn::gui{
struct text_field_model{
std::string text;
std::shared_ptr<font_atlas> font;
};
class text_field : public menu_item
{
private:
text_field_model m_model;
gfx::text_field_view m_view;
public:
text_field(menu* m);
text_field(menu* m, const char* data);
text_field(const text_field&);
text_field(text_field&&);
text_field& operator=(const text_field&) = default;
text_field& operator=(text_field&&) = default;
const std::string& get_text(void)const;
void set_font(const std::shared_ptr<font_atlas>& f);
const std::shared_ptr<font_atlas>& get_font(void)const;
void render(menu_renderer& r)override;
text_field* clone(void)const override;
};
}
#endif

View File

@ -0,0 +1,136 @@
/**
This file is a part of our_dick
Copyright (C) 2020-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_BUFFER_MAP_HPP
#define OUR_DICK_GRAPHICS_BUFFER_MAP_HPP
#include "gl_include.hpp"
#include <cstdlib> //size_t, ptrdiff_t
namespace gfx{
namespace buffer{
//strongly typed enum for different mapping styles
enum class maptype : GLenum{
READ = GL_READ_ONLY,
WRITE = GL_WRITE_ONLY,
RW = GL_READ_WRITE,
};
//strongly typed enum for different usages
enum class usage : GLenum{
STATIC_DRAW = GL_STATIC_DRAW,
DYNAMIC_DRAW = GL_DYNAMIC_DRAW,
STREAM_DRAW = GL_STREAM_DRAW,
STATIC_READ = GL_STATIC_READ,
DYNAMIC_READ = GL_DYNAMIC_READ,
STREAM_READ = GL_STREAM_READ,
STATIC_COPY = GL_STATIC_COPY,
DYNAMIC_COPY = GL_DYNAMIC_COPY,
STREAM_COPY = GL_STREAM_COPY,
};
}
//RAII wrapper for mapping vbo's
template<typename T>
class scoped_buffer_map
{
public:
using value_type = T;
using size_type = size_t;
using difference_type = ptrdiff_t;
using reference = T&;
using const_reference = const T&;
using pointer = T*;
using const_pointer = const T*;
private:
pointer m_data = nullptr; //pointer to the mapped region
GLuint m_buffer;
public:
//create a mapping for 'v' on 'targ' with map style 'm'
explicit scoped_buffer_map(GLuint bid, buffer::maptype m);
scoped_buffer_map(const scoped_buffer_map&) = delete;
scoped_buffer_map(scoped_buffer_map&&);
~scoped_buffer_map(void);
scoped_buffer_map& operator=(const scoped_buffer_map&) = delete;
scoped_buffer_map& operator=(scoped_buffer_map&&);
//size of the mapped region as reported by glGetBufferParameteriv
size_type length(void)const;
//release ownership of the mapping. unsafe
pointer release(void);
//direct access to the underlaying data region
operator pointer(void);
operator const_pointer(void)const;
pointer raw(void);
const_pointer raw(void)const;
bool valid(void)const;
//indexed access to the data region
reference operator[](size_type i);
const_reference operator[](size_type i)const;
};
//specialization for void pointers. The same in every way except no subscript operators
template<>
class scoped_buffer_map<void>
{
public:
using value_type = void;
using size_type = size_t;
using difference_type = ptrdiff_t;
using reference = void;
using const_reference = void;
using pointer = void*;
using const_pointer = const void*;
private:
pointer m_data = nullptr;
GLuint m_buffer;
public:
explicit scoped_buffer_map(GLuint bid, buffer::maptype m);
scoped_buffer_map(const scoped_buffer_map&) = delete;
scoped_buffer_map(scoped_buffer_map&&);
~scoped_buffer_map(void);
scoped_buffer_map& operator=(const scoped_buffer_map&) = delete;
scoped_buffer_map& operator=(scoped_buffer_map&&);
size_type length(void)const;
pointer release(void);
operator pointer(void);
operator const_pointer(void)const;
pointer raw(void);
const_pointer raw(void)const;
bool valid(void)const;
};
}
#include "buffer_map.tpp"
#endif

View File

@ -0,0 +1,91 @@
/**
This file is a part of our_dick
Copyright (C) 2020-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_BUFFER_MAP_TPP
#define OUR_DICK_GRAPHICS_BUFFER_MAP_TPP
#include <utility> //exchange, swap
#include "gl_include.hpp"
namespace gfx{
template<typename T>
scoped_buffer_map<T>::scoped_buffer_map(GLuint bid, buffer::maptype m):
m_buffer(bid)
{
m_data = reinterpret_cast<pointer>(glMapNamedBuffer(m_buffer, static_cast<GLenum>(m)));
}
template<typename T>
scoped_buffer_map<T>::scoped_buffer_map(scoped_buffer_map&& m):
m_data(std::exchange(m.m_data, nullptr)),
m_buffer(std::exchange(m.m_buffer, 0)){}
template<typename T>
scoped_buffer_map<T>::~scoped_buffer_map(void){
if(m_data){
glUnmapNamedBuffer(m_buffer);
}
}
template<typename T>
scoped_buffer_map<T>& scoped_buffer_map<T>::operator=(scoped_buffer_map&& m){
std::swap(m_data, m.m_data);
std::swap(m_buffer, m.m_buffer);
return *this;
}
template<typename T>
auto scoped_buffer_map<T>::length(void)const -> size_type{
GLint64 retval;
glGetNamedBufferParameteri64v(m_buffer, GL_BUFFER_MAP_LENGTH, &retval);
return retval;
}
template<typename T>
auto scoped_buffer_map<T>::release(void) -> pointer{
m_buffer = 0;
return std::exchange(m_data, nullptr);
}
template<typename T>
scoped_buffer_map<T>::operator pointer(void){
return m_data;
}
template<typename T>
scoped_buffer_map<T>::operator const_pointer(void)const{
return m_data;
}
template<typename T>
auto scoped_buffer_map<T>::raw(void) -> pointer{
return m_data;
}
template<typename T>
auto scoped_buffer_map<T>::raw(void)const -> const_pointer{
return m_data;
}
template<typename T>
bool scoped_buffer_map<T>::valid(void)const{
return m_data;
}
template<typename T>
auto scoped_buffer_map<T>::operator[](size_type i) -> reference{
return m_data[i];
}
template<typename T>
auto scoped_buffer_map<T>::operator[](size_type i)const -> const_reference{
return m_data[i];
}
}
#endif

View File

@ -20,7 +20,6 @@
#define OUR_DICK_GRAPHICS_FBO_HPP
#include "gl_include.hpp"
#include "gl_buffers.hpp"
#include "texture.hpp"
#include "rbo.hpp"
#include "math/vec.hpp"
@ -62,7 +61,6 @@ namespace gfx{
const math::vec4<GLfloat>& get_viewport()const;
bool bind()const;
bool bind(gl_frame_buffer_manager& b)const;
private:
template<typename... Args>
void i_attach(const rbo& r, GLenum point, Args&&... args);

View File

@ -1,159 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2020 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_GL_BUFFERS_HPP
#define OUR_DICK_GRAPHICS_GL_BUFFERS_HPP
#include "gl_include.hpp"
namespace gfx{
class gl_buffer_manager;
class gl_frame_buffer_manager;
//handle interfacing with the gl_buffer objects. Used as intermediary so that multiple classes have the ability to
//access gl_buffers easily
template<typename T>
class buffer_accessor_iface
{
public:
using buffer_type = T;
using reference = buffer_type&;
using const_reference = const buffer_type&;
using pointer = buffer_type*;
using const_pointer = const buffer_type*;
protected:
mutable pointer m_bound = nullptr; //pointer to currently bound target
GLuint m_raw_id = 0;
protected:
buffer_accessor_iface() = default;
buffer_accessor_iface(GLuint raw_id);
buffer_accessor_iface(const buffer_accessor_iface&) = delete;
buffer_accessor_iface(buffer_accessor_iface&&);
~buffer_accessor_iface();
buffer_accessor_iface& operator=(const buffer_accessor_iface&) = delete;
buffer_accessor_iface& operator=(buffer_accessor_iface&&);
protected:
//set the given gl_buffer target to use this buffer
bool i_bind(reference b)const;
//same as bind, but also disallow rebinding until unlock is called
bool i_bind_lock(reference b)const;
//set the associated target to point to nothing. also calls unlock
void i_unbind()const;
public:
//release the lock held on the target
void lock()const;
void unlock()const;
//check if a lock is held on the associated target
bool is_locked()const;
//get raw access to opengl target id
GLenum get_bound_id()const;
//get raw access to opengl buffer id
GLuint get_buffer_id()const;
void set_buffer_id(GLuint raw_id);
//get access to opengl target buffer
pointer get_bound_buffer()const;
};
//implement bind/unbind with glBindBuffer
class buffer_accessor : public buffer_accessor_iface<gl_buffer_manager>
{
public:
using buffer_accessor_iface<gl_buffer_manager>::buffer_accessor_iface;
bool bind(reference b)const;
bool bind_lock(reference b)const;
void unbind(GLuint id = 0)const;
};
//implement bind/unbind with glBindFramebuffer
class frame_buffer_accessor : public buffer_accessor_iface<gl_frame_buffer_manager>
{
public:
using buffer_accessor_iface<gl_frame_buffer_manager>::buffer_accessor_iface;
bool bind(reference b)const;
bool bind_lock(reference b)const;
void unbind(GLuint id = 0)const;
};
template<typename T>
class gl_buffer_manager_base
{
public:
protected:
const T* m_bound = nullptr;
const GLenum m_buffer;
bool m_lock = false;
protected:
gl_buffer_manager_base(GLenum buf);
~gl_buffer_manager_base() = default;
//rely on static polymorphism with this parameter
void bind(const buffer_accessor_iface<typename T::buffer_type>* newbind);
void lock(bool b);
bool is_locked()const;
public:
//return id of the target this represents
GLenum get_buffer_id()const;
const T* get_bound_accessor();
};
//Manage active opengl buffers and targets
class gl_buffer_manager : public gl_buffer_manager_base<buffer_accessor>
{
friend class buffer;
friend buffer_accessor_iface<gl_buffer_manager>; //base class of buffer_accessor
protected:
using gl_buffer_manager_base::gl_buffer_manager_base;
};
class gl_frame_buffer_manager : public gl_buffer_manager_base<frame_buffer_accessor>
{
friend class buffer;
friend buffer_accessor_iface<gl_frame_buffer_manager>; //base class of frame_buffer_accessor
protected:
using gl_buffer_manager_base::gl_buffer_manager_base;
};
class buffer //glorified namespace for added access control
{
//list of all the standard opengl buffer targets
public:
static inline gl_buffer_manager array{GL_ARRAY_BUFFER};
static inline gl_buffer_manager atomic_counter{GL_ATOMIC_COUNTER_BUFFER};
static inline gl_buffer_manager copy_read{GL_COPY_READ_BUFFER};
static inline gl_buffer_manager copy_write{GL_COPY_WRITE_BUFFER};
static inline gl_buffer_manager dispatch_indirect{GL_DISPATCH_INDIRECT_BUFFER};
static inline gl_buffer_manager draw_indirect{GL_DRAW_INDIRECT_BUFFER};
static inline gl_buffer_manager element_array{GL_ELEMENT_ARRAY_BUFFER};
static inline gl_buffer_manager pixel_pack{GL_PIXEL_PACK_BUFFER};
static inline gl_buffer_manager pixel_unpack{GL_PIXEL_UNPACK_BUFFER};
static inline gl_buffer_manager query{GL_QUERY_BUFFER};
static inline gl_buffer_manager shader_storage{GL_SHADER_STORAGE_BUFFER};
static inline gl_buffer_manager texture{GL_TEXTURE_BUFFER};
static inline gl_buffer_manager transform_feedback{GL_TRANSFORM_FEEDBACK_BUFFER};
static inline gl_buffer_manager uniform{GL_UNIFORM_BUFFER};
static inline gl_frame_buffer_manager fb_draw{GL_DRAW_FRAMEBUFFER};
static inline gl_frame_buffer_manager fb_read{GL_READ_FRAMEBUFFER};
private:
buffer() = default;
~buffer() = default;
};
}
#include "gl_buffers.tpp"
#endif

View File

@ -1,138 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2020 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_GL_BUFFERS_TPP
#define OUR_DICK_GRAPHICS_GL_BUFFERS_TPP
#include <utility> //exchange
namespace gfx{
template<typename T>
gl_buffer_manager_base<T>::gl_buffer_manager_base(GLenum buf):
m_buffer(buf){}
template<typename T>
void gl_buffer_manager_base<T>::bind(const buffer_accessor_iface<typename T::buffer_type>* newbind){
if(m_bound){
const T* tmp = std::exchange(m_bound, nullptr);
tmp->unbind();
}
m_bound = static_cast<const T*>(newbind);
}
template<typename T>
void gl_buffer_manager_base<T>::lock(bool b){
m_lock = b;
}
template<typename T>
bool gl_buffer_manager_base<T>::is_locked()const{
return m_lock;
}
template<typename T>
GLenum gl_buffer_manager_base<T>::get_buffer_id()const{
return m_buffer;
}
template<typename T>
const T* gl_buffer_manager_base<T>::get_bound_accessor(){
return m_bound;
}
template<typename T>
buffer_accessor_iface<T>::buffer_accessor_iface(GLuint raw_id):
m_raw_id(raw_id){}
template<typename T>
buffer_accessor_iface<T>::buffer_accessor_iface(buffer_accessor_iface&& b):
m_bound(std::exchange(b.m_bound, nullptr)),
m_raw_id(b.m_raw_id){}
template<typename T>
buffer_accessor_iface<T>::~buffer_accessor_iface(){
if(m_bound)
i_unbind();
}
template<typename T>
buffer_accessor_iface<T>& buffer_accessor_iface<T>::operator=(buffer_accessor_iface&& b){
std::swap(m_bound, b.m_bound);
std::swap(m_raw_id, b.m_raw_id);
return *this;
}
template<typename T>
bool buffer_accessor_iface<T>::i_bind(reference b)const{
if(b.is_locked())
return false;
if(m_bound){
pointer tmp = std::exchange(m_bound, nullptr);
tmp->bind(nullptr);
}
m_bound = &b;
m_bound->bind(this);
return true;
}
template<typename T>
bool buffer_accessor_iface<T>::i_bind_lock(reference b)const{
if(!i_bind(b))
return false;
m_bound->lock(true);
return true;
}
template<typename T>
void buffer_accessor_iface<T>::lock()const{
if(m_bound)
m_bound->lock(true);
}
template<typename T>
void buffer_accessor_iface<T>::unlock()const{
if(m_bound)
m_bound->lock(false);
}
template<typename T>
void buffer_accessor_iface<T>::i_unbind()const{
//check for null pointers in derived implementation class
m_bound->lock(false);
m_bound->bind(nullptr);
m_bound = nullptr;
}
template<typename T>
bool buffer_accessor_iface<T>::is_locked()const{
return m_bound && m_bound->is_locked();
}
template<typename T>
GLenum buffer_accessor_iface<T>::get_bound_id()const{
if(m_bound)
return m_bound->get_buffer_id();
return 0;
}
template<typename T>
GLuint buffer_accessor_iface<T>::get_buffer_id()const{
return m_raw_id;
}
template<typename T>
void buffer_accessor_iface<T>::set_buffer_id(GLuint raw_id){
m_raw_id = raw_id;
}
template<typename T>
auto buffer_accessor_iface<T>::get_bound_buffer()const -> pointer{
if(m_bound)
return m_bound;
return nullptr;
}
}
#endif

View File

@ -28,6 +28,7 @@
#include "graphics/shader_program.hpp"
#include "engine/font.hpp"
#include "util/deferred.hpp"
namespace gfx{
@ -42,9 +43,11 @@ namespace gfx{
using const_reference = const T&;
using pointer = T*;
using const_pointer = const T*;
using node = std::shared_ptr<value_type>;
using const_node = std::shared_ptr<value_type>;
private:
std::map<key_type,value_type> m_map;
std::map<key_type,std::shared_ptr<value_type>> m_map;
public:
resource_manager(void) = default;
@ -58,18 +61,21 @@ namespace gfx{
bool has_value(const char* key)const;
template<class... Args>
std::pair<pointer,bool> emplace_value(const char* key, Args&&... args);
pointer get_value(const char* file);
std::pair<node,bool> emplace_value(const char* key, Args&&... args);
node get_value(const char* file);
bool erase_value(const char* key);
};
}
class resource_manager
{
public:
template<class T>
using container_type = detail::resource_manager<T>;
private:
detail::resource_manager<texture> m_textures;
detail::resource_manager<egn::font_atlas> m_fonts;
detail::resource_manager<texture_array> m_texture_arrays;
detail::resource_manager<shader_program> m_shaders;
container_type<texture> m_textures;
container_type<egn::font_atlas> m_fonts;
container_type<texture_array> m_texture_arrays;
container_type<shader_program> m_shaders;
public:
resource_manager(void) = default;
@ -84,25 +90,25 @@ namespace gfx{
bool has_texture_array(const char* key)const;
template<class... Args>
auto emplace_texture_array(const char* key, Args&&... args);
gfx::texture_array* get_texture_array(const char* file);
container_type<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);
gfx::texture* get_texture(const char* file);
container_type<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);
egn::font_atlas* get_font(const char* file);
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);
gfx::shader_program* get_shader(const char* key);
container_type<shader_program>::node get_shader(const char* key);
bool erase_shader(const char* key);
};
@ -115,16 +121,14 @@ namespace gfx{
}
template<class T>
template<class... Args>
auto resource_manager<T>::emplace_value(const char* key, Args&&... args) -> std::pair<pointer,bool>{
if(auto it = m_map.find(key);it != m_map.end())
return {&(*it).second, false};
auto ret = m_map.emplace(std::piecewise_construct, std::tuple(key), std::tuple(std::forward<Args>(args)...));
return {&(*(ret.first)).second, true};
auto resource_manager<T>::emplace_value(const char* key, Args&&... args) -> std::pair<node,bool>{
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};
}
template<class T>
auto resource_manager<T>::get_value(const char* key) -> pointer{
auto resource_manager<T>::get_value(const char* key) -> node{
if(auto it = m_map.find(key);it != m_map.end())
return &(*it).second;
return (*it).second;
return nullptr;
}
template<class T>

View File

@ -1,56 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2020 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_SCOPED_BUFFER_BIND_HPP
#define OUR_DICK_GRAPHICS_SCOPED_BUFFER_BIND_HPP
#include "gl_buffers.hpp"
namespace gfx{
template<typename T>
class scoped_buffer_bind
{
public:
using accessor_type = T;
using manager_type = typename T::buffer_type;
protected:
const accessor_type* m_accessor_handle;
manager_type* m_manager_handle;
const accessor_type* m_already_bound;
public:
explicit scoped_buffer_bind(const accessor_type& accessor, manager_type& buffer, bool lock = false);
scoped_buffer_bind(const scoped_buffer_bind&) = delete;
scoped_buffer_bind(scoped_buffer_bind&& s);
~scoped_buffer_bind();
scoped_buffer_bind& operator=(const scoped_buffer_bind&) = delete;
scoped_buffer_bind& operator=(scoped_buffer_bind&& s);
bool valid()const;
void release();
GLenum get_bound_id()const;
GLuint get_buffer_id()const;
};
}
#include "scoped_buffer_bind.tpp"
#endif

View File

@ -1,86 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2020 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_SCOPED_BUFFER_BIND_TPP
#define OUR_DICK_GRAPHICS_SCOPED_BUFFER_BIND_TPP
#include <utility> //exchange, swap
namespace gfx{
template<typename T, typename U>
scoped_buffer_bind(T&, U&, GLuint) -> scoped_buffer_bind<T>;
template<typename T>
scoped_buffer_bind<T>::scoped_buffer_bind(const accessor_type& accessor, manager_type& buffer, bool lock):
m_accessor_handle(&accessor),
m_manager_handle(&buffer),
m_already_bound(buffer.get_bound_accessor())
{
if(m_already_bound != m_accessor_handle){
if(lock)
m_accessor_handle->bind_lock(*m_manager_handle);
else
m_accessor_handle->bind(*m_manager_handle);
}else if(lock){
m_accessor_handle->lock();
}
}
template<typename T>
scoped_buffer_bind<T>::scoped_buffer_bind(scoped_buffer_bind&& s):
m_accessor_handle(std::exchange(s.m_accessor_handle, nullptr)),
m_manager_handle(std::exchange(s.m_manager_handle, nullptr)),
m_already_bound(std::exchange(s.m_already_bound, nullptr)){}
template<typename T>
scoped_buffer_bind<T>::~scoped_buffer_bind(){
if(m_already_bound != m_accessor_handle){
release();
if(m_already_bound)
m_already_bound->bind(*m_manager_handle);
}
}
template<typename T>
scoped_buffer_bind<T>& scoped_buffer_bind<T>::operator=(scoped_buffer_bind&& s){
std::swap(m_accessor_handle, s.m_accessor_handle);
std::swap(m_manager_handle, s.m_manager_handle);
std::swap(m_already_bound, s.m_already_bound);
return *this;
}
template<typename T>
bool scoped_buffer_bind<T>::valid()const{
return m_accessor_handle->get_bound_buffer() == m_manager_handle;
}
template<typename T>
void scoped_buffer_bind<T>::release(){
m_accessor_handle->unbind();
}
template<typename T>
GLenum scoped_buffer_bind<T>::get_bound_id()const{
return m_accessor_handle->get_bound_id();
}
template<typename T>
GLuint scoped_buffer_bind<T>::get_buffer_id()const{
return m_accessor_handle->get_buffer_id();
}
extern template class scoped_buffer_bind<buffer_accessor>;
extern template class scoped_buffer_bind<frame_buffer_accessor>;
}
#endif

View File

@ -22,6 +22,7 @@
#include "gl_include.hpp"
#include "shader.hpp"
#include "texture.hpp"
#include "ubo.hpp"
#include <utility> //forward
#include <string>
@ -32,6 +33,189 @@ namespace gfx{
using namespace math;
class uniform
{
private:
GLuint m_shader_id;
GLint m_location;
public:
uniform(GLuint owner, const char* name);
uniform(GLuint owner, GLuint location);
uniform(const uniform&) = default;
uniform(uniform&&) = default;
~uniform(void) = default;
uniform& operator=(const uniform&) = default;
uniform& operator=(uniform&&) = default;
GLenum get_type(void)const;
GLfloat get_float(void)const;
math::vec2<GLfloat> get_vec2(void)const;
math::vec3<GLfloat> get_vec3(void)const;
math::vec4<GLfloat> get_vec4(void)const;
GLdouble get_double(void)const;
math::vec2<GLdouble> get_dvec2(void)const;
math::vec3<GLdouble> get_dvec3(void)const;
math::vec4<GLdouble> get_dvec4(void)const;
GLint get_int(void)const;
math::vec2<GLint> get_ivec2(void)const;
math::vec3<GLint> get_ivec3(void)const;
math::vec4<GLint> get_ivec4(void)const;
GLuint get_uint(void)const;
math::vec2<GLuint> get_uvec2(void)const;
math::vec3<GLuint> get_uvec3(void)const;
math::vec4<GLuint> get_uvec4(void)const;
GLboolean get_bool(void)const;
math::vec2<GLboolean> get_bvec2(void)const;
math::vec3<GLboolean> get_bvec3(void)const;
math::vec4<GLboolean> get_bvec4(void)const;
math::mat2<GLfloat> get_mat2(void)const;
math::mat3<GLfloat> get_mat3(void)const;
math::mat4<GLfloat> get_mat4(void)const;
math::matrix<GLfloat,2,3> get_mat2x3(void)const;
math::matrix<GLfloat,2,4> get_mat2x4(void)const;
math::matrix<GLfloat,3,2> get_mat3x2(void)const;
math::matrix<GLfloat,3,4> get_mat3x4(void)const;
math::matrix<GLfloat,4,2> get_mat4x2(void)const;
math::matrix<GLfloat,4,3> get_mat4x3(void)const;
math::mat2<GLdouble> get_dmat2(void)const;
math::mat3<GLdouble> get_dmat3(void)const;
math::mat4<GLdouble> get_dmat4(void)const;
math::matrix<GLdouble,2,3> get_dmat2x3(void)const;
math::matrix<GLdouble,2,4> get_dmat2x4(void)const;
math::matrix<GLdouble,3,2> get_dmat3x2(void)const;
math::matrix<GLdouble,3,4> get_dmat3x4(void)const;
math::matrix<GLdouble,4,2> get_dmat4x2(void)const;
math::matrix<GLdouble,4,3> get_dmat4x3(void)const;
//float
void set(GLfloat);
void set(GLfloat, GLfloat);
void set(GLfloat, GLfloat, GLfloat);
void set(GLfloat, GLfloat, GLfloat, GLfloat);
//int
void set(GLint);
void set(GLint, GLint);
void set(GLint, GLint, GLint);
void set(GLint, GLint, GLint, GLint);
//unsigned int
void set(GLuint);
void set(GLuint, GLuint);
void set(GLuint, GLuint, GLuint);
void set(GLuint, GLuint, GLuint, GLuint);
//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 vec2<GLfloat>&);
void set(const vec3<GLfloat>&);
void set(const vec4<GLfloat>&);
//Float vector array
void set(GLsizei count, const vec2<GLfloat>*);
void set(GLsizei count, const vec3<GLfloat>*);
void set(GLsizei count, const vec4<GLfloat>*);
//Explicit float vectors
void set_1(GLsizei count, const GLfloat*);
void set_2(GLsizei count, const GLfloat*);
void set_3(GLsizei count, const GLfloat*);
void set_4(GLsizei count, const GLfloat*);
//Int vectors
void set(const vec2<GLint>&);
void set(const vec3<GLint>&);
void set(const vec4<GLint>&);
//Int vector array
void set(GLsizei count, const vec2<GLint>*);
void set(GLsizei count, const vec3<GLint>*);
void set(GLsizei count, const vec4<GLint>*);
//Explicit int vectors
void set_1(GLsizei count, const GLint*);
void set_2(GLsizei count, const GLint*);
void set_3(GLsizei count, const GLint*);
void set_4(GLsizei count, const GLint*);
//Unsigned int vectors
void set(const vec2<GLuint>&);
void set(const vec3<GLuint>&);
void set(const vec4<GLuint>&);
//Unsigned int vector array
void set(GLsizei count, const vec2<GLuint>*);
void set(GLsizei count, const vec3<GLuint>*);
void set(GLsizei count, const vec4<GLuint>*);
//Explicit unsigned int vectors
void set_1(GLsizei count, const GLuint*);
void set_2(GLsizei count, const GLuint*);
void set_3(GLsizei count, const GLuint*);
void set_4(GLsizei count, const GLuint*);
//Matrices
void set(const mat2<GLfloat>&);
void set(const mat3<GLfloat>&);
void set(const mat4<GLfloat>&);
//Matrix array
void set(GLsizei count, const mat2<GLfloat>*);
void set(GLsizei count, const mat3<GLfloat>*);
void set(GLsizei count, const mat4<GLfloat>*);
//Explicit matrices
void set_mat2(GLsizei count, const GLfloat*);
void set_mat3(GLsizei count, const GLfloat*);
void set_mat4(GLsizei count, const GLfloat*);
void set_mat2x3(GLsizei count, const GLfloat*);
void set_mat3x2(GLsizei count, const GLfloat*);
void set_mat2x4(GLsizei count, const GLfloat*);
void set_mat4x2(GLsizei count, const GLfloat*);
void set_mat3x4(GLsizei count, const GLfloat*);
void set_mat4x3(GLsizei count, const GLfloat*);
private:
GLint get_location_from_name_(const char* name);
};
class uniform_block
{
private:
GLuint m_shader_id;
GLuint m_index;
public:
uniform_block(GLuint owner, GLuint index);
uniform_block(GLuint owner, const char* name);
uniform_block(const uniform_block&) = default;
uniform_block(uniform_block&&) = default;
~uniform_block(void) = default;
uniform_block& operator=(const uniform_block&) = default;
uniform_block& operator=(uniform_block&&) = default;
void set_binding(size_t binding);
template<class... Types>
void set_binding(size_t binding, const ubo<Types...>& u);
private:
GLuint get_index_from_name_(const char* name);
};
//represents an opengl program (NOT a shader object)
class shader_program
{
@ -40,19 +224,19 @@ namespace gfx{
public:
//create the program with no shaders attached
shader_program();
shader_program(void);
//create the program and attach 'args'... as shaders
template<class... Args>
shader_program(Args&&... args);
shader_program(const shader_program&) = delete;
shader_program(shader_program&&);
~shader_program();
~shader_program(void);
shader_program& operator=(const shader_program&) = delete;
shader_program& operator=(shader_program&&);
//release ownership of the program handle. unsafe
GLuint release();
GLuint release(void);
//attach a single shader to this program
void attach_shader(const shader& s);
@ -61,283 +245,32 @@ namespace gfx{
void attach_shaders(const shader& s, Args&&... args);
//attempt to link the program with the currently attached shaders. returns true on success
bool link();
bool link(void);
//set this program as the currently active one in the gl context
void use();
void use(void);
//search for a uniform by name in this program
GLint get_uniform_loc(const char* u)const;
GLuint get_uniform_block_loc(const char* u)const;
//raw access to the program handle
GLuint raw()const;
GLuint raw(void)const;
//check if an error exists after a link attempt
bool has_link_error()const;
bool has_link_error(void)const;
//get the most recently generated error from this program's infolog
std::string get_error()const;
std::string get_error(void)const;
uniform get_uniform(const char* name);
uniform get_uniform(int uloc);
GLenum get_uniform_type(const char* name)const;
GLenum get_uniform_type(int uloc)const;
GLfloat get_uniform_float(int uloc)const;
math::vec2<GLfloat> get_uniform_vec2(int uloc)const;
math::vec3<GLfloat> get_uniform_vec3(int uloc)const;
math::vec4<GLfloat> get_uniform_vec4(int uloc)const;
GLdouble get_uniform_double(int uloc)const;
math::vec2<GLdouble> get_uniform_dvec2(int uloc)const;
math::vec3<GLdouble> get_uniform_dvec3(int uloc)const;
math::vec4<GLdouble> get_uniform_dvec4(int uloc)const;
GLint get_uniform_int(int uloc)const;
math::vec2<GLint> get_uniform_ivec2(int uloc)const;
math::vec3<GLint> get_uniform_ivec3(int uloc)const;
math::vec4<GLint> get_uniform_ivec4(int uloc)const;
GLuint get_uniform_uint(int uloc)const;
math::vec2<GLuint> get_uniform_uvec2(int uloc)const;
math::vec3<GLuint> get_uniform_uvec3(int uloc)const;
math::vec4<GLuint> get_uniform_uvec4(int uloc)const;
GLboolean get_uniform_bool(int uloc)const;
math::vec2<GLboolean> get_uniform_bvec2(int uloc)const;
math::vec3<GLboolean> get_uniform_bvec3(int uloc)const;
math::vec4<GLboolean> get_uniform_bvec4(int uloc)const;
math::mat2<GLfloat> get_uniform_mat2(int uloc)const;
math::mat3<GLfloat> get_uniform_mat3(int uloc)const;
math::mat4<GLfloat> get_uniform_mat4(int uloc)const;
math::matrix<GLfloat,2,3> get_uniform_mat2x3(int uloc)const;
math::matrix<GLfloat,2,4> get_uniform_mat2x4(int uloc)const;
math::matrix<GLfloat,3,2> get_uniform_mat3x2(int uloc)const;
math::matrix<GLfloat,3,4> get_uniform_mat3x4(int uloc)const;
math::matrix<GLfloat,4,2> get_uniform_mat4x2(int uloc)const;
math::matrix<GLfloat,4,3> get_uniform_mat4x3(int uloc)const;
math::mat2<GLdouble> get_uniform_dmat2(int uloc)const;
math::mat3<GLdouble> get_uniform_dmat3(int uloc)const;
math::mat4<GLdouble> get_uniform_dmat4(int uloc)const;
math::matrix<GLdouble,2,3> get_uniform_dmat2x3(int uloc)const;
math::matrix<GLdouble,2,4> get_uniform_dmat2x4(int uloc)const;
math::matrix<GLdouble,3,2> get_uniform_dmat3x2(int uloc)const;
math::matrix<GLdouble,3,4> get_uniform_dmat3x4(int uloc)const;
math::matrix<GLdouble,4,2> get_uniform_dmat4x2(int uloc)const;
math::matrix<GLdouble,4,3> get_uniform_dmat4x3(int uloc)const;
GLfloat get_uniform_float(const char* name)const;
math::vec2<GLfloat> get_uniform_vec2(const char* name)const;
math::vec3<GLfloat> get_uniform_vec3(const char* name)const;
math::vec4<GLfloat> get_uniform_vec4(const char* name)const;
GLdouble get_uniform_double(const char* name)const;
math::vec2<GLdouble> get_uniform_dvec2(const char* name)const;
math::vec3<GLdouble> get_uniform_dvec3(const char* name)const;
math::vec4<GLdouble> get_uniform_dvec4(const char* name)const;
GLint get_uniform_int(const char* name)const;
math::vec2<GLint> get_uniform_ivec2(const char* name)const;
math::vec3<GLint> get_uniform_ivec3(const char* name)const;
math::vec4<GLint> get_uniform_ivec4(const char* name)const;
GLuint get_uniform_uint(const char* name)const;
math::vec2<GLuint> get_uniform_uvec2(const char* name)const;
math::vec3<GLuint> get_uniform_uvec3(const char* name)const;
math::vec4<GLuint> get_uniform_uvec4(const char* name)const;
GLboolean get_uniform_bool(const char* name)const;
math::vec2<GLboolean> get_uniform_bvec2(const char* name)const;
math::vec3<GLboolean> get_uniform_bvec3(const char* name)const;
math::vec4<GLboolean> get_uniform_bvec4(const char* name)const;
math::mat2<GLfloat> get_uniform_mat2(const char* name)const;
math::mat3<GLfloat> get_uniform_mat3(const char* name)const;
math::mat4<GLfloat> get_uniform_mat4(const char* name)const;
math::matrix<GLfloat,2,3> get_uniform_mat2x3(const char* name)const;
math::matrix<GLfloat,2,4> get_uniform_mat2x4(const char* name)const;
math::matrix<GLfloat,3,2> get_uniform_mat3x2(const char* name)const;
math::matrix<GLfloat,3,4> get_uniform_mat3x4(const char* name)const;
math::matrix<GLfloat,4,2> get_uniform_mat4x2(const char* name)const;
math::matrix<GLfloat,4,3> get_uniform_mat4x3(const char* name)const;
math::mat2<GLdouble> get_uniform_dmat2(const char* name)const;
math::mat3<GLdouble> get_uniform_dmat3(const char* name)const;
math::mat4<GLdouble> get_uniform_dmat4(const char* name)const;
math::matrix<GLdouble,2,3> get_uniform_dmat2x3(const char* name)const;
math::matrix<GLdouble,2,4> get_uniform_dmat2x4(const char* name)const;
math::matrix<GLdouble,3,2> get_uniform_dmat3x2(const char* name)const;
math::matrix<GLdouble,3,4> get_uniform_dmat3x4(const char* name)const;
math::matrix<GLdouble,4,2> get_uniform_dmat4x2(const char* name)const;
math::matrix<GLdouble,4,3> get_uniform_dmat4x3(const char* name)const;
//Uniforms
//float
void set_uniform(const char* name, GLfloat);
void set_uniform(const char* name, GLfloat, GLfloat);
void set_uniform(const char* name, GLfloat, GLfloat, GLfloat);
void set_uniform(const char* name, GLfloat, GLfloat, GLfloat, GLfloat);
void set_uniform(GLuint loc, GLfloat);
void set_uniform(GLuint loc, GLfloat, GLfloat);
void set_uniform(GLuint loc, GLfloat, GLfloat, GLfloat);
void set_uniform(GLuint loc, GLfloat, GLfloat, GLfloat, GLfloat);
//int
void set_uniform(const char* name, GLint);
void set_uniform(const char* name, GLint, GLint);
void set_uniform(const char* name, GLint, GLint, GLint);
void set_uniform(const char* name, GLint, GLint, GLint, GLint);
void set_uniform(GLuint loc, GLint);
void set_uniform(GLuint loc, GLint, GLint);
void set_uniform(GLuint loc, GLint, GLint, GLint);
void set_uniform(GLuint loc, GLint, GLint, GLint, GLint);
//unsigned int
void set_uniform(const char* name, GLuint);
void set_uniform(const char* name, GLuint, GLuint);
void set_uniform(const char* name, GLuint, GLuint, GLuint);
void set_uniform(const char* name, GLuint, GLuint, GLuint, GLuint);
void set_uniform(GLuint loc, GLuint);
void set_uniform(GLuint loc, GLuint, GLuint);
void set_uniform(GLuint loc, GLuint, GLuint, GLuint);
void set_uniform(GLuint loc, GLuint, GLuint, GLuint, GLuint);
//Texture
void set_uniform(const char* name, const texture&, GLuint tex_unit = 0);
void set_uniform(GLuint loc, const texture&, GLuint tex_unit = 0);
void set_uniform(const char* name, const texture_array& t, GLuint tex_unit = 0);
void set_uniform(GLuint loc, const texture_array& t, GLuint tex_unit = 0);
void set_uniform(const char* name, const weak_texture&, GLuint tex_unit = 0);
void set_uniform(GLuint loc, const weak_texture&, GLuint tex_unit = 0);
//Float vectors
void set_uniform(const char* name, const vec2<GLfloat>&);
void set_uniform(const char* name, const vec3<GLfloat>&);
void set_uniform(const char* name, const vec4<GLfloat>&);
void set_uniform(GLuint loc, const vec2<GLfloat>&);
void set_uniform(GLuint loc, const vec3<GLfloat>&);
void set_uniform(GLuint loc, const vec4<GLfloat>&);
//Float vector array
void set_uniform(const char* name, GLsizei count, const vec2<GLfloat>*);
void set_uniform(const char* name, GLsizei count, const vec3<GLfloat>*);
void set_uniform(const char* name, GLsizei count, const vec4<GLfloat>*);
void set_uniform(GLuint loc, GLsizei count, const vec2<GLfloat>*);
void set_uniform(GLuint loc, GLsizei count, const vec3<GLfloat>*);
void set_uniform(GLuint loc, GLsizei count, const vec4<GLfloat>*);
//Explicit float vectors
void set_uniform_1(const char* name, GLsizei count, const GLfloat*);
void set_uniform_2(const char* name, GLsizei count, const GLfloat*);
void set_uniform_3(const char* name, GLsizei count, const GLfloat*);
void set_uniform_4(const char* name, GLsizei count, const GLfloat*);
void set_uniform_1(GLuint loc, GLsizei count, const GLfloat*);
void set_uniform_2(GLuint loc, GLsizei count, const GLfloat*);
void set_uniform_3(GLuint loc, GLsizei count, const GLfloat*);
void set_uniform_4(GLuint loc, GLsizei count, const GLfloat*);
//Int vectors
void set_uniform(const char* name, const vec2<GLint>&);
void set_uniform(const char* name, const vec3<GLint>&);
void set_uniform(const char* name, const vec4<GLint>&);
void set_uniform(GLuint loc, const vec2<GLint>&);
void set_uniform(GLuint loc, const vec3<GLint>&);
void set_uniform(GLuint loc, const vec4<GLint>&);
//Int vector array
void set_uniform(const char* name, GLsizei count, const vec2<GLint>*);
void set_uniform(const char* name, GLsizei count, const vec3<GLint>*);
void set_uniform(const char* name, GLsizei count, const vec4<GLint>*);
void set_uniform(GLuint loc, GLsizei count, const vec2<GLint>*);
void set_uniform(GLuint loc, GLsizei count, const vec3<GLint>*);
void set_uniform(GLuint loc, GLsizei count, const vec4<GLint>*);
//Explicit int vectors
void set_uniform_1(const char* name, GLsizei count, const GLint*);
void set_uniform_2(const char* name, GLsizei count, const GLint*);
void set_uniform_3(const char* name, GLsizei count, const GLint*);
void set_uniform_4(const char* name, GLsizei count, const GLint*);
void set_uniform_1(GLuint loc, GLsizei count, const GLint*);
void set_uniform_2(GLuint loc, GLsizei count, const GLint*);
void set_uniform_3(GLuint loc, GLsizei count, const GLint*);
void set_uniform_4(GLuint loc, GLsizei count, const GLint*);
//Unsigned int vectors
void set_uniform(const char* name, const vec2<GLuint>&);
void set_uniform(const char* name, const vec3<GLuint>&);
void set_uniform(const char* name, const vec4<GLuint>&);
void set_uniform(GLuint loc, const vec2<GLuint>&);
void set_uniform(GLuint loc, const vec3<GLuint>&);
void set_uniform(GLuint loc, const vec4<GLuint>&);
//Unsigned int vector array
void set_uniform(const char* name, GLsizei count, const vec2<GLuint>*);
void set_uniform(const char* name, GLsizei count, const vec3<GLuint>*);
void set_uniform(const char* name, GLsizei count, const vec4<GLuint>*);
void set_uniform(GLuint loc, GLsizei count, const vec2<GLuint>*);
void set_uniform(GLuint loc, GLsizei count, const vec3<GLuint>*);
void set_uniform(GLuint loc, GLsizei count, const vec4<GLuint>*);
//Explicit unsigned int vectors
void set_uniform_1(const char* name, GLsizei count, const GLuint*);
void set_uniform_2(const char* name, GLsizei count, const GLuint*);
void set_uniform_3(const char* name, GLsizei count, const GLuint*);
void set_uniform_4(const char* name, GLsizei count, const GLuint*);
void set_uniform_1(GLuint loc, GLsizei count, const GLuint*);
void set_uniform_2(GLuint loc, GLsizei count, const GLuint*);
void set_uniform_3(GLuint loc, GLsizei count, const GLuint*);
void set_uniform_4(GLuint loc, GLsizei count, const GLuint*);
//Matrices
void set_uniform(const char* name, const mat2<GLfloat>&);
void set_uniform(const char* name, const mat3<GLfloat>&);
void set_uniform(const char* name, const mat4<GLfloat>&);
void set_uniform(GLuint loc, const mat2<GLfloat>&);
void set_uniform(GLuint loc, const mat3<GLfloat>&);
void set_uniform(GLuint loc, const mat4<GLfloat>&);
//Matrix array
void set_uniform(const char* name, GLsizei count, const mat2<GLfloat>*);
void set_uniform(const char* name, GLsizei count, const mat3<GLfloat>*);
void set_uniform(const char* name, GLsizei count, const mat4<GLfloat>*);
void set_uniform(GLuint loc, GLsizei count, const mat2<GLfloat>*);
void set_uniform(GLuint loc, GLsizei count, const mat3<GLfloat>*);
void set_uniform(GLuint loc, GLsizei count, const mat4<GLfloat>*);
//Explicit matrices
void set_uniform_mat2(const char* name, GLsizei count, const GLfloat*);
void set_uniform_mat3(const char* name, GLsizei count, const GLfloat*);
void set_uniform_mat4(const char* name, GLsizei count, const GLfloat*);
void set_uniform_mat2x3(const char* name, GLsizei count, const GLfloat*);
void set_uniform_mat3x2(const char* name, GLsizei count, const GLfloat*);
void set_uniform_mat2x4(const char* name, GLsizei count, const GLfloat*);
void set_uniform_mat4x2(const char* name, GLsizei count, const GLfloat*);
void set_uniform_mat3x4(const char* name, GLsizei count, const GLfloat*);
void set_uniform_mat4x3(const char* name, GLsizei count, const GLfloat*);
void set_uniform_mat2(GLuint loc, GLsizei count, const GLfloat*);
void set_uniform_mat3(GLuint loc, GLsizei count, const GLfloat*);
void set_uniform_mat4(GLuint loc, GLsizei count, const GLfloat*);
void set_uniform_mat2x3(GLuint loc, GLsizei count, const GLfloat*);
void set_uniform_mat3x2(GLuint loc, GLsizei count, const GLfloat*);
void set_uniform_mat2x4(GLuint loc, GLsizei count, const GLfloat*);
void set_uniform_mat4x2(GLuint loc, GLsizei count, const GLfloat*);
void set_uniform_mat3x4(GLuint loc, GLsizei count, const GLfloat*);
void set_uniform_mat4x3(GLuint loc, GLsizei count, const GLfloat*);
uniform_block get_uniform_block(const char* name);
uniform_block get_uniform_block(unsigned int uloc);
};
template<class... Args>
@ -355,6 +288,12 @@ namespace gfx{
}
}
template<class... Types>
void uniform_block::set_binding(size_t binding, const ubo<Types...>& u){
u.bind(binding);
set_binding(binding);
}
}
#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_TEXT_FIELD_VIEW_HPP
#define OUR_DICK_GRAPHICS_TEXT_FIELD_VIEW_HPP
#include "engine/font.hpp"
#include "engine/menu_renderer.hpp"
#include "vao.hpp"
#include "vbo.hpp"
#include <memory> //shared_ptr
namespace egn::gui{
struct text_field_model;
}
namespace gfx{
class text_field_view
{
private:
static constexpr int s_size_per_char = sizeof(float) * 12;
private:
egn::gui::text_field_model* m_model;
gfx::vbo m_buffer;
gfx::vao m_vao;
mutable unsigned char m_dirty_bit:1 = 0;
public:
text_field_view(egn::gui::text_field_model& m);
text_field_view(egn::gui::text_field_model& m, const char* data);
text_field_view(const text_field_view&);
text_field_view(text_field_view&&) = default;
~text_field_view(void) = default;
text_field_view& operator=(const text_field_view&);
text_field_view& operator=(text_field_view&&) = default;
bool set_text(const char* text);
void set_model(egn::gui::text_field_model& t);
void render(egn::menu_renderer& r);
private:
void init_arrays_(void);
};
}
#endif

153
include/graphics/ubo.hpp Normal file
View File

@ -0,0 +1,153 @@
/**
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_UBO_HPP
#define OUR_DICK_GRAPHICS_UBO_HPP
#include "gl_include.hpp"
#include "math/mat.hpp"
#include "math/vec.hpp"
#include <type_traits> //a lot of stuff
#include "buffer_map.hpp"
namespace gfx{
namespace detail{
template<class T>
struct is_bounded_array{
static constexpr bool value = false;
};
template<class T, size_t I>
struct is_bounded_array<T[I]>{
static constexpr bool value = true;
};
template<class T>
struct is_valid_uniform_scalar{
static constexpr bool value = std::is_same_v<T,GLint> ||
std::is_same_v<T,GLuint> ||
std::is_same_v<T,bool> ||
std::is_same_v<T,GLfloat> ||
std::is_same_v<T,GLdouble>;
};
template<class T>
struct is_valid_uniform_matrix{
template<class U, size_t R, size_t C>
static constexpr bool test(math::matrix_base<U,R,C>*){
return is_valid_uniform_scalar<typename T::value_type>::value && T::Columns <= 4 && T::Rows <= 4;
}
static constexpr bool test(void*){
return false;
}
static constexpr bool value = test(static_cast<std::decay_t<T>*>(nullptr));
};
template<class T>
struct is_valid_uniform_type{
static constexpr bool value = is_valid_uniform_scalar<T>::value || is_valid_uniform_matrix<T>::value || is_bounded_array<T>::value;
};
template<size_t I, class Type, class... Types>
struct get_type{
using type = typename get_type<I-1, Types...>::type;
};
template<class Type, class... Types>
struct get_type<0, Type, Types...>{
using type = Type;
};
template<class... Types>
struct get_type<0,bool,Types...>{
using type = int;
};
template<size_t I, class... Types>
using get_type_t = typename get_type<I, Types...>::type;
template<class T>
constexpr size_t get_alignment_of_(void);
template<class T>
constexpr size_t get_alignment_multiple_(void);
template<class T>
constexpr size_t size_of_(void);
}
template<class... Types>
class ubo
{
private:
static_assert((detail::is_valid_uniform_type<Types>::value && ...));
public:
static constexpr size_t num_elements = sizeof...(Types);
template<size_t I>
using type_of = detail::get_type_t<I, Types...>;
private:
GLuint m_buffer = 0;
public:
ubo(buffer::usage usage = buffer::usage::DYNAMIC_DRAW);
ubo(const ubo&);
ubo(ubo&&);
~ubo(void);
ubo& operator=(const ubo&);
ubo& operator=(ubo&&);
//raw modify the data (NOT A GOOD IDEA)
scoped_buffer_map<void> map(buffer::maptype m);
void buffer(const void* data, size_t datasize, size_t start);
void initialize(unsigned char value = 0);
//Safely modify the data to comply with GLSL std140 layout
template<size_t I>
auto get(void);
template<size_t I, class T>
void set(T&& t);
GLuint raw(void)const;
size_t get_size(void)const;
size_t get_cap(void)const;
buffer::usage get_usage(void)const;
void bind(size_t index)const;
private:
template<size_t I>
static constexpr size_t get_offset_of_(void);
template<size_t I>
static constexpr size_t get_alignment_of_(void);
static constexpr size_t get_total_size_(void);
public:
template<size_t I>
static constexpr size_t offset_of = get_offset_of_<I>();
template<size_t I>
static constexpr size_t alignment_of = get_alignment_of_<I>();
};
}
#include "ubo.tpp"
#endif

263
include/graphics/ubo.tpp Normal file
View File

@ -0,0 +1,263 @@
/**
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_UBO_TPP
#define OUR_DICK_GRAPHICS_UBO_TPP
#include <utility> //swap, exchange
#include <type_traits> //a lot of stuff
#include <array>
#include <cstring> //memcpy, memset
namespace gfx{
template<class... Types>
ubo<Types...>::ubo(buffer::usage usage){
glCreateBuffers(1, &m_buffer);
glNamedBufferData(m_buffer, get_total_size_(), NULL, static_cast<GLenum>(usage));
}
template<class... Types>
ubo<Types...>::ubo(const ubo& u){
glCreateBuffers(1, &m_buffer);
auto data = u.map(buffer::maptype::READ);
if(!data)
return;
glNamedBufferData(m_buffer, u.get_size(), data, static_cast<GLenum>(u.get_usage()));
}
template<class... Types>
ubo<Types...>::ubo(ubo&& u):
m_buffer(std::exchange(u.m_buffer, 0)){}
template<class... Types>
ubo<Types...>::~ubo(void){
if(m_buffer)
glDeleteBuffers(1, &m_buffer);
}
template<class... Types>
auto ubo<Types...>::operator=(const ubo& u) -> ubo&{
return (*this = ubo(u));
}
template<class... Types>
auto ubo<Types...>::operator=(ubo&& u) -> ubo&{
std::swap(m_buffer, u.m_buffer);
return *this;
}
template<class... Types>
template<size_t I>
constexpr size_t ubo<Types...>::get_offset_of_(void){
static_assert(I < sizeof...(Types), "Index out of bounds");
if constexpr(I == 0){
return 0;
}else{
using this_type = detail::get_type_t<I,Types...>;
using prev_type = detail::get_type_t<I-1,Types...>;
size_t prev_offset = get_offset_of_<I-1>();
constexpr size_t prev_alignment = detail::get_alignment_of_<prev_type>();
constexpr size_t this_alignment = detail::get_alignment_of_<this_type>();
prev_offset += (prev_alignment * (detail::get_alignment_multiple_<prev_type>() - 1));
bool is_on_alignment_multiple = (((prev_offset + prev_alignment) % this_alignment) == 0);
if(is_on_alignment_multiple){
return prev_offset + prev_alignment;
}else if(this_alignment > prev_alignment){
return prev_offset + this_alignment;
}else{
size_t i;
for(i = this_alignment * 2;i < prev_alignment;i += this_alignment);
return prev_offset + i;
}
}
}
template<class... Types>
template<size_t I>
constexpr size_t ubo<Types...>::get_alignment_of_(void){
return detail::get_alignment_of_<detail::get_type_t<I,Types...>>();
}
template<class... Types>
constexpr size_t ubo<Types...>::get_total_size_(void){
constexpr size_t type_num = sizeof...(Types) - 1;
using last_type = detail::get_type_t<type_num,Types...>;
return get_offset_of_<type_num>() + (detail::get_alignment_of_<last_type>() * detail::get_alignment_multiple_<last_type>());
}
template<class... Types>
scoped_buffer_map<void> ubo<Types...>::map(buffer::maptype m){
return scoped_buffer_map<void>(m_buffer, m);
}
template<class... Types>
void ubo<Types...>::buffer(const void* data, size_t datasize, size_t start){
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){
const size_t size = get_size();
auto m = map(buffer::maptype::WRITE);
if(!m){
return;
}
memset(m, size, value);
}
template<class... Types>
template<size_t I>
auto ubo<Types...>::get(void){
using type = detail::get_type_t<I, Types...>;
constexpr size_t offset = get_offset_of_<I>();
constexpr size_t align = detail::get_alignment_of_<type>();
auto m = map(buffer::maptype::READ);
unsigned char* data = static_cast<unsigned char*>(m.raw());
data += offset;
if constexpr(detail::is_valid_uniform_matrix<type>::value){
type t{};
constexpr size_t rows = type::Rows;
constexpr size_t cols = type::Columns;
for(size_t i = 0;i < cols;++i){
memcpy(t.raw() + (rows * i), data + (align * i), sizeof(typename type::value_type) * rows);
}
return t;
}else if constexpr(detail::is_bounded_array<type>::value){
static constexpr size_t arr_size = std::extent<type>::value;
using this_value = std::decay_t<decltype(std::declval<type>()[0])>;
std::array<this_value,arr_size> t;
for(size_t i = 0;i < arr_size;++i){
t[i] = *reinterpret_cast<this_value*>(data + (align * i));
}
return t;
}else{
type t{};
memcpy(&t, data, sizeof(type));
return t;
}
}
template<class... Types>
template<size_t I, class T>
void ubo<Types...>::set(T&& t){
using type = detail::get_type_t<I, Types...>;
constexpr size_t offset = get_offset_of_<I>();
constexpr size_t align = detail::get_alignment_of_<type>();
auto m = map(buffer::maptype::WRITE);
unsigned char* data = static_cast<unsigned char*>(m.raw());
data += offset;
if constexpr(detail::is_valid_uniform_matrix<type>::value){
static_assert(std::is_convertible_v<std::decay_t<T>,type>);
constexpr size_t rows = type::Rows;
constexpr size_t cols = type::Columns;
for(size_t i = 0;i < cols;++i){
memcpy(data + (align * i), t.raw() + (rows * i), sizeof(typename type::value_type) * rows);
}
}else if constexpr(detail::is_bounded_array<type>::value){
using this_value = std::decay_t<decltype(std::declval<type>()[0])>;
using that_value = std::decay_t<decltype(std::declval<T>()[0])>;
static_assert(std::is_convertible_v<that_value,this_value>);
for(size_t i = 0;i < std::extent<type>::value;++i){
this_value tmp = t[i];
memcpy(data + (align * i), &tmp, sizeof(this_value));
}
}else{
static_assert(std::is_convertible_v<std::decay_t<T>,type>);
type tmp = t;
memcpy(data, &tmp, sizeof(type));
}
}
template<class... Types>
GLuint ubo<Types...>::raw(void)const{
return m_buffer;
}
template<class... Types>
size_t ubo<Types...>::get_size(void)const{
return get_total_size_();
}
template<class... Types>
size_t ubo<Types...>::get_cap(void)const{
return get_total_size_();
}
template<class... Types>
buffer::usage ubo<Types...>::get_usage(void)const{
GLint retval;
glGetNamedBufferParameteriv(m_buffer, GL_BUFFER_USAGE, &retval);
return static_cast<buffer::usage>(retval);
}
template<class... Types>
void ubo<Types...>::bind(size_t index)const{
glBindBufferBase(GL_UNIFORM_BUFFER, index, m_buffer);
}
namespace detail{
template<class T>
constexpr size_t get_alignment_of_(void){
if constexpr(detail::is_valid_uniform_scalar<T>::value){ //scalar
if constexpr(std::is_same_v<T,GLdouble>){
return 8;
}else{
return 4;
}
}else if constexpr(detail::is_bounded_array<T>::value){
return get_alignment_of_<math::vec4f>();
}else{
constexpr size_t element_alignment = get_alignment_of_<typename T::value_type>();
if constexpr(T::Columns > 1){ //matrix
return element_alignment * 4;
}else{ //vector
if constexpr(T::Rows == 2){
return element_alignment * 2;
}else{
return element_alignment * 4;
}
}
}
}
template<class T>
constexpr size_t get_alignment_multiple_(void){
if constexpr(detail::is_valid_uniform_scalar<T>::value){
return 1;
}else if constexpr(detail::is_bounded_array<T>::value){
return std::extent<T>::value;
}else{
return T::Columns;
}
}
template<class T>
constexpr size_t size_of_(void){
if constexpr(std::is_same<bool,std::decay_t<T>>::value){
return 4;
}
return sizeof(T);
}
}
}
#endif

View File

@ -1,6 +1,6 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
Copyright (C) 2020-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
@ -20,220 +20,54 @@
#define OUR_DICK_GRAPHICS_VBO_HPP
#include "gl_include.hpp"
#include "gl_buffers.hpp"
#include <cstdlib> //size_t, ptrdiff_t
#include <utility> //exchange, swap
#include <cstdlib> //size_t
#include "buffer_map.hpp"
namespace gfx{
template<typename T>
class scoped_vbo_map;
//class representing a vertex buffer object
class vbo
{
public:
//strongly typed enum for different usages
enum class usage : GLenum{
STATIC_DRAW = GL_STATIC_DRAW,
DYNAMIC_DRAW = GL_DYNAMIC_DRAW,
STREAM_DRAW = GL_STREAM_DRAW,
STATIC_READ = GL_STATIC_READ,
DYNAMIC_READ = GL_DYNAMIC_READ,
STREAM_READ = GL_STREAM_READ,
STATIC_COPY = GL_STATIC_COPY,
DYNAMIC_COPY = GL_DYNAMIC_COPY,
STREAM_COPY = GL_STREAM_COPY,
};
//strongly typed enum for different mapping styles
enum class maptype : GLenum{
READ = GL_READ_ONLY,
WRITE = GL_WRITE_ONLY,
RW = GL_READ_WRITE,
};
private:
GLuint m_buffer; //handle to vbo
size_t m_buffer_size; //amount of buffer currently in use
public:
//create a buffer with given capacity with predicted usage case 't'
vbo(size_t cap, usage t);
vbo(const void* data, size_t datasize, usage t);
vbo(size_t cap, buffer::usage t);
vbo(const void* data, size_t datasize, buffer::usage t);
vbo(const vbo&);
vbo(vbo&&);
~vbo();
~vbo(void);
vbo& operator=(const vbo&);
vbo& operator=(vbo&&);
//attempt binding to given gl_buffer_manager. returns true on success
bool bind(gl_buffer_manager& b)const;
//add data to the end of this buffer (starts loading at data+get_size())
bool buffer(const void* data, size_t datasize);
bool buffer(const void* data, size_t datasize, size_t start);
bool initialize(unsigned char value = 0);
//change capacity of buffer
bool resize(size_t newcap);
GLuint raw()const;
GLuint raw(void)const;
//glMapBuffer to given target with map style 'm'
scoped_vbo_map<void> map(maptype m)const;
scoped_buffer_map<void> map(buffer::maptype m)const;
//emties the buffer. does not clear contents, just sets size to 0.
void clear();
size_t get_size()const;
size_t get_cap()const;
usage get_usage()const;
void clear(void);
size_t get_size(void)const;
size_t get_cap(void)const;
buffer::usage get_usage(void)const;
private:
static bool copy_buffer(vbo& dest, const vbo& src);
};
//RAII wrapper for mapping vbo's
template<typename T>
class scoped_vbo_map
{
public:
using value_type = T;
using size_type = size_t;
using difference_type = ptrdiff_t;
using reference = T&;
using const_reference = const T&;
using pointer = T*;
using const_pointer = const T*;
private:
pointer m_data = nullptr; //pointer to the mapped region
GLuint m_buffer;
public:
//create a mapping for 'v' on 'targ' with map style 'm'
explicit scoped_vbo_map(GLuint bid, vbo::maptype m);
scoped_vbo_map(const scoped_vbo_map&) = delete;
scoped_vbo_map(scoped_vbo_map&&);
~scoped_vbo_map();
scoped_vbo_map& operator=(const scoped_vbo_map&) = delete;
scoped_vbo_map& operator=(scoped_vbo_map&&);
//size of the mapped region as reported by glGetBufferParameteriv
size_type length()const;
//release ownership of the mapping. unsafe
pointer release();
//direct access to the underlaying data region
operator pointer();
operator const_pointer()const;
pointer raw();
const_pointer raw()const;
bool valid()const;
//indexed access to the data region
reference operator[](size_type i);
const_reference operator[](size_type i)const;
};
//specialization for void pointers. The same in every way except no subscript operators
template<>
class scoped_vbo_map<void>
{
public:
using value_type = void;
using size_type = size_t;
using difference_type = ptrdiff_t;
using reference = void;
using const_reference = void;
using pointer = void*;
using const_pointer = const void*;
private:
pointer m_data = nullptr;
GLuint m_buffer;
public:
explicit scoped_vbo_map(GLuint bid, vbo::maptype m);
scoped_vbo_map(const scoped_vbo_map&) = delete;
scoped_vbo_map(scoped_vbo_map&&);
~scoped_vbo_map();
scoped_vbo_map& operator=(const scoped_vbo_map&) = delete;
scoped_vbo_map& operator=(scoped_vbo_map&&);
size_type length()const;
pointer release();
operator pointer();
operator const_pointer()const;
pointer raw();
const_pointer raw()const;
bool valid()const;
};
template<typename T>
scoped_vbo_map<T>::scoped_vbo_map(GLuint bid, vbo::maptype m):
m_buffer(bid)
{
m_data = reinterpret_cast<pointer>(glMapNamedBuffer(m_buffer, static_cast<GLenum>(m)));
}
template<typename T>
scoped_vbo_map<T>::scoped_vbo_map(scoped_vbo_map&& m):
m_data(std::exchange(m.m_data, nullptr)),
m_buffer(std::exchange(m.m_buffer, 0)){}
template<typename T>
scoped_vbo_map<T>::~scoped_vbo_map(){
if(m_data){
glUnmapNamedBuffer(m_buffer);
}
}
template<typename T>
scoped_vbo_map<T>& scoped_vbo_map<T>::operator=(scoped_vbo_map&& m){
std::swap(m_data, m.m_data);
std::swap(m_buffer, m.m_buffer);
return *this;
}
template<typename T>
auto scoped_vbo_map<T>::length()const -> size_type{
GLint64 retval;
glGetNamedBufferParameteri64v(m_buffer, GL_BUFFER_MAP_LENGTH, &retval);
return retval;
}
template<typename T>
auto scoped_vbo_map<T>::release() -> pointer{
m_buffer = 0;
return std::exchange(m_data, nullptr);
}
template<typename T>
scoped_vbo_map<T>::operator pointer(){
return m_data;
}
template<typename T>
scoped_vbo_map<T>::operator const_pointer()const{
return m_data;
}
template<typename T>
auto scoped_vbo_map<T>::raw() -> pointer{
return m_data;
}
template<typename T>
auto scoped_vbo_map<T>::raw()const -> const_pointer{
return m_data;
}
template<typename T>
bool scoped_vbo_map<T>::valid()const{
return m_data;
}
template<typename T>
auto scoped_vbo_map<T>::operator[](size_type i) -> reference{
return m_data[i];
}
template<typename T>
auto scoped_vbo_map<T>::operator[](size_type i)const -> const_reference{
return m_data[i];
}
}
#endif

View File

@ -51,24 +51,28 @@ namespace math{
using vec2u = vec2<unsigned int>;
using vec2d = vec2<double>;
using vec2s = vec2<size_t>;
using vec2b = vec2<int>;
using vec3f = vec3<float>;
using vec3i = vec3<int>;
using vec3u = vec3<unsigned int>;
using vec3d = vec3<double>;
using vec3s = vec3<size_t>;
using vec3b = vec3<int>;
using vec4f = vec4<float>;
using vec4i = vec4<int>;
using vec4u = vec4<unsigned int>;
using vec4d = vec4<double>;
using vec4s = vec4<size_t>;
using vec4b = vec4<int>;
using mat2f = mat2<float>;
using mat2i = mat2<int>;
using mat2u = mat2<unsigned int>;
using mat2d = mat2<double>;
using mat2s = mat2<size_t>;
using mat2b = mat2<int>;
using mat3f = mat3<float>;
using mat3i = mat3<int>;
@ -81,6 +85,7 @@ namespace math{
using mat4u = mat4<unsigned int>;
using mat4d = mat4<double>;
using mat4s = mat4<size_t>;
using mat4b = mat4<int>;
template<typename T>
using quat = quaternion<T>;
@ -90,6 +95,7 @@ namespace math{
using quat_u = quat<unsigned int>;
using quat_d = quat<double>;
using quat_s = quat<size_t>;
using quat_b = quat<int>;
}
#endif

View File

@ -49,14 +49,14 @@ namespace math{
matrix<T,4,4> ortho_projection(T w, T h, T n, T f){
return matrix<T,4,4>(T{2} / w, T{0}, T{0}, T{0},
T{0}, T{2} / h, T{0}, T{0},
T{0}, T{0}, T{2} / (n - f), T{0},
T{0}, T{0}, T{1} / (n - f), T{0},
T{0}, T{0}, (n + f) / (n - f), T{1});
}
template<typename T>
matrix<T,4,4> ortho_asymetric_projection(T l, T r, T b, T t, T n, T f){
return matrix<T,4,4>(T{2} / (r - l), T{0}, T{0}, T{0},
T{0}, T{2} / (t - b), T{0}, T{0},
T{0}, T{0}, T{2} / (n - f), T{0},
T{0}, T{0}, T{1} / (n - f), T{0},
(r + l) / (l - r), (t + b) / (b - t), (n + f) / (n - f), T{1});
}

View File

@ -23,20 +23,22 @@
#include "graphics/vbo.hpp"
#include "graphics/vao.hpp"
#include "graphics/shader_program.hpp"
#include "graphics/resource_manager.hpp"
#include <utility> //pair
#include <memory> //shared_ptr
class tile;
class board_gfx
{
private:
gfx::texture_array* m_textures;
std::shared_ptr<gfx::texture_array> m_textures;
gfx::vao m_vao;
gfx::vbo m_vbo;
public:
board_gfx(std::pair<gfx::texture_array*,bool> resman_result);
board_gfx(gfx::resource_manager& resman);
~board_gfx(void) = default;
void set_uniforms(gfx::shader_program& sh);

View File

@ -30,16 +30,23 @@
#include "engine/font.hpp"
#include "engine/text.hpp"
#include <memory> //shared_ptr
class font_renderer
{
private:
gfx::shader_program* m_font_shader;
std::shared_ptr<gfx::shader_program> m_font_shader;
int m_screen_width, m_screen_height;
public:
font_renderer(gfx::resource_manager& res, int width, int height);
void render(egn::text&);
void set_position(const math::vec2f& pos);
void use_texture(const gfx::texture& tex);
void use_texture(const gfx::weak_texture& tex);
void set_aspect(float aspect);
void begin(void);
void resize_viewport(int width, int height);
};

View File

@ -60,52 +60,66 @@ static constexpr char geometry_shader_text[] =
flat vec4 color;
}gs_out;
uniform vec2 out_size;
layout (std140) uniform view_proj_matrix{
mat4 vp_mat;
};
uniform vec2 start_pos;
//map from [0, max_out] to [0, 2]
float size_to_screen_space(float x, float max_out){
const float ratio = 2.0 / max_out;
return x * ratio;
}
//map from [0, max_out] to [-1, 1]
float pos_to_screen_space(float x, float max_out){
return size_to_screen_space(x, max_out) - 1.0;
}
void main(){
//texture coordinates need done botleft->topleft->botright->topright
//whereas the position goes topleft->botleft->topright->botright
//because freetype generates bitmaps with inverse y axis to opengl
const vec4 position = vec4(gs_in[0].offset, -1, 1);
const mat2 scaler = mat2(vp_mat[0][0], vp_mat[0][1], vp_mat[1][0], vp_mat[1][1]);
vec2 start_screen_pos = vec2(pos_to_screen_space(start_pos.x, out_size.x), pos_to_screen_space(start_pos.y, out_size.y));
const vec2 start_position = scaler * start_pos;
const vec2 screen_pos = start_position + (scaler * gs_in[0].offset);
const vec2 size = scaler * gs_in[0].size;
const vec3 position = vec3(start_screen_pos.x + size_to_screen_space(gs_in[0].offset.x, out_size.x),
start_screen_pos.y + size_to_screen_space(gs_in[0].offset.y, out_size.y),
-1);
const vec2 size = vec2(size_to_screen_space(gs_in[0].size.x, out_size.x),
size_to_screen_space(gs_in[0].size.y, out_size.y));
const mat4 scale = vp_mat;
gl_Position = vec4(position.x, position.y + size.y, position.z, 1.0);
const vec4 p1 = scale * vec4(gs_in[0].offset.x, gs_in[0].offset.y + gs_in[0].size.y, -1, 1);
const vec4 p2 = scale * vec4(gs_in[0].offset, -1, 1);
const vec4 p3 = scale * vec4(gs_in[0].offset.x + gs_in[0].size.x, gs_in[0].offset.y + gs_in[0].size.y, -1, 1);
const vec4 p4 = scale * vec4(gs_in[0].offset.x + gs_in[0].size.x, gs_in[0].offset.y, -1, 1);
gl_Position = p1;
gs_out.tex_coords = gs_in[0].tex_coords.xy;
gs_out.color = gs_in[0].color;
EmitVertex();
gl_Position = vec4(position, 1.0);
gl_Position = p2;
gs_out.tex_coords = gs_in[0].tex_coords.xw;
gs_out.color = gs_in[0].color;
EmitVertex();
gl_Position = vec4(position.x + size.x, position.y + size.y, position.z, 1.0);
gl_Position = p3;
gs_out.tex_coords = gs_in[0].tex_coords.zy;
gs_out.color = gs_in[0].color;
EmitVertex();
gl_Position = vec4(position.x + size.x, position.y, position.z, 1.0);
gl_Position = p4;
gs_out.tex_coords = gs_in[0].tex_coords.zw;
gs_out.color = gs_in[0].color;
EmitVertex();
/* gl_Position = vec4(screen_pos.x, screen_pos.y + size.y, -1.0, 1.0);
gs_out.tex_coords = gs_in[0].tex_coords.xy;
gs_out.color = gs_in[0].color;
EmitVertex();
gl_Position = vec4(screen_pos, -1.0, 1.0);
gs_out.tex_coords = gs_in[0].tex_coords.xw;
gs_out.color = gs_in[0].color;
EmitVertex();
gl_Position = vec4(screen_pos.x + size.x, screen_pos.y + size.y, -1.0, 1.0);
gs_out.tex_coords = gs_in[0].tex_coords.zy;
gs_out.color = gs_in[0].color;
EmitVertex();
gl_Position = vec4(screen_pos.x + size.x, screen_pos.y, -1.0, 1.0);
gs_out.tex_coords = gs_in[0].tex_coords.zw;
gs_out.color = gs_in[0].color;
EmitVertex();
*/
EndPrimitive();
}
)glsl";

View File

@ -27,6 +27,8 @@
#include "graphics/resource_manager.hpp"
#include "basic_framebuffer.hpp"
#include <memory> //shared_ptr
class main_renderer
{
private:
@ -45,8 +47,8 @@ private:
private:
basic_framebuffer m_fb;
gfx::fbo m_primary_fb;
gfx::shader_program* m_square_shader;
gfx::shader_program* m_screen_shader;
std::shared_ptr<gfx::shader_program> m_square_shader;
std::shared_ptr<gfx::shader_program> m_screen_shader;
gfx::vbo m_vbo;
gfx::vao m_vao;
gfx::vao m_board_vao;

View File

@ -23,17 +23,17 @@
#include "engine/input.hpp"
#include "graphics/texture.hpp"
#include "screen_renderer.hpp"
#include "font_renderer.hpp"
#include "engine/text.hpp"
#include "engine/menu.hpp"
#include "engine/menu_renderer.hpp"
class pause_state : public egn::game_state_iface
{
private:
egn::game_state_iface* m_under_state;
screen_renderer m_screen_renderer;
font_renderer m_font_renderer;
egn::text m_text;
egn::menu_renderer m_menu_renderer;
egn::gui::menu m_menu;
public:
pause_state(egn::game& owner, egn::game_state_iface* under);

View File

@ -29,6 +29,8 @@
#include "engine/font.hpp"
#include <memory> //shared_ptr
class screen_renderer
{
private:
@ -45,14 +47,14 @@ private:
{{-1.0f, 1.0f}, {0.0f, 1.0f}}
};
private:
gfx::shader_program* m_screen_shader;
std::shared_ptr<gfx::shader_program> m_screen_shader;
gfx::vbo m_vbo;
gfx::vao m_vao;
gfx::texture* m_texture;
std::shared_ptr<gfx::texture> m_texture;
int m_screen_width, m_screen_height;
public:
screen_renderer(gfx::resource_manager& res, int width, int height, gfx::texture& base_tex);
screen_renderer(gfx::resource_manager& res, int width, int height, const std::shared_ptr<gfx::texture>& base_tex);
void render(scene&);
void resize_viewport(int width, int height);

View File

@ -30,7 +30,7 @@ namespace util{
using value_type = T;
private:
std::tuple<Args...> m_args;
std::tuple<Args&&...> m_args;
public:
template<class... FArgs>
@ -58,7 +58,7 @@ namespace util{
private:
Fn m_fn;
std::tuple<Args...> m_args;
std::tuple<Args&&...> m_args;
public:
template<class F, class... FArgs>
@ -89,7 +89,7 @@ namespace util{
template<class T, class... Args>
template<size_t... Is>
constexpr auto deferred<T,Args...>::get_value_(std::index_sequence<Is...>) -> value_type{
return T{std::get<Is>(m_args)...};
return T{std::forward<std::tuple_element_t<Is,decltype(m_args)>>(std::get<Is>(m_args))...};
}
template<class Fn, class... Args>
@ -114,7 +114,7 @@ namespace util{
template<class Fn, class... Args>
template<size_t... Is>
constexpr decltype(auto) deferred_function<Fn,Args...>::get_value_(std::index_sequence<Is...>){
return std::forward<Fn>(m_fn)(std::get<Is>(m_args)...);
return std::forward<Fn>(m_fn)(std::forward<std::tuple_element_t<Is,decltype(m_args)>>(std::get<Is>(m_args))...);
}
template<class Fn, class... Args>

View File

@ -103,4 +103,6 @@ namespace egn{
m_projection_matrix = math::ortho_projection(m_width, m_height, m_near, m_far);
}
flat_camera::flat_camera(float w, float h):
ortho_camera(w, h, 0, 1){}
}

58
src/engine/menu.cpp Normal file
View File

@ -0,0 +1,58 @@
/**
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 "engine/menu.hpp"
namespace egn::gui{
menu_item::menu_item(menu* owner):
m_owner(owner){}
void menu_item::set_owner(menu* owner){
m_owner = owner;
}
menu::menu(void):
m_camera(100, 100){}
position_node& menu::add_item(const menu_item& m){
return m_items.emplace_back(position_node{{math::vec2f{1, 1}}, std::unique_ptr<menu_item>(m.clone()), math::vec2f{0, 0}});
}
void menu::set_default_font(const std::shared_ptr<egn::font_atlas>& font){
m_default_font = font;
}
const std::shared_ptr<font_atlas>& menu::get_default_font(void)const{
return m_default_font;
}
void menu::resize(float w, float h){
m_camera.set_projection_box(w, h);
}
void menu::render(menu_renderer& r){
math::mat4f tmp = m_camera.get_projection_matrix() * m_camera.get_view_matrix();
r.set_vp_matrix(tmp);
for(auto& node : m_items){
menu_item& item = (*node.item);
item.render(r);
}
}
}

View File

@ -0,0 +1,88 @@
/**
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 "engine/menu_renderer.hpp"
#include "graphics/gl_include.hpp"
#include "ttt/font_shader.hpp"
namespace egn{
void renderer::set_viewport(float x, float y, float w, float h){
m_saved_viewport[0] = x;
m_saved_viewport[1] = y;
m_saved_viewport[2] = w;
m_saved_viewport[3] = h;
}
void renderer::resize_viewport(float w, float h){
m_saved_viewport[2] = w;
m_saved_viewport[3] = h;
}
void renderer::reposition_viewport(float x, float y){
m_saved_viewport[0] = x;
m_saved_viewport[1] = y;
}
void renderer::apply_viewport(void){
glViewport(m_saved_viewport[0], m_saved_viewport[1], m_saved_viewport[2], m_saved_viewport[3]);
}
menu_renderer::menu_renderer(gfx::resource_manager& resman):
m_font_shader(resman.emplace_shader("font_shader",
util::make_deferred<gfx::shader>(font_shader::vertex_shader_text, gfx::shader::type::VERTEX),
util::make_deferred<gfx::shader>(font_shader::geometry_shader_text, gfx::shader::type::GEOMETRY),
util::make_deferred<gfx::shader>(font_shader::fragment_shader_text, gfx::shader::type::FRAGMENT)).first)
{
m_font_shader->get_uniform_block("view_proj_matrix").set_binding(0, m_vp_matrix);
}
void menu_renderer::set_font(const gfx::texture& atlas){
m_font_shader->get_uniform("texture1").set(atlas);
}
void menu_renderer::set_vp_matrix(const math::mat4f& matrix){
m_vp_matrix.set<0>(matrix);
}
void menu_renderer::set_position(const math::vec2f& pos){
m_font_shader->get_uniform("start_pos").set(pos);
}
void menu_renderer::begin(void){
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
apply_viewport();
}
void menu_renderer::draw_text(int count){
m_font_shader->use();
glDrawArrays(GL_POINTS, 0, count);
}
void menu_renderer::draw_text_to(gfx::fbo& target, int count){
target.bind();
target.apply_viewport();
draw_text(count);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void menu_renderer::end(void){
}
}

View File

@ -17,13 +17,14 @@
*/
#include "engine/text.hpp"
#include "ttt/font_renderer.hpp"
namespace egn{
text_gfx::text_gfx(const egn::font_atlas& font, int target_px, size_t initsize):
m_atlas(font),
m_font(font.metadata()),
m_vbo(initsize * s_size_per_char, gfx::vbo::usage::DYNAMIC_DRAW),
m_vbo(initsize * s_size_per_char, gfx::buffer::usage::DYNAMIC_DRAW),
m_original_height(font.glyph_size().y()),
m_scale(((float)target_px) / m_original_height){}
text_gfx::text_gfx(const egn::font_atlas& font, int target_px, const char* string):
@ -80,10 +81,10 @@ namespace egn{
pos_offset.x() += (m_scale * ch.advance.x());
}
}
void text_gfx::render(gfx::shader_program& sh, const math::vec2f& pos){
void text_gfx::render(font_renderer& sh, const math::vec2f& pos){
m_vao.bind();
sh.set_uniform("texture1", m_atlas);
sh.set_uniform("start_pos", pos);
sh.use_texture(m_atlas);
sh.set_position(pos);
glDrawArrays(GL_POINTS, 0, m_vbo.get_size() / s_size_per_char);
}
@ -99,8 +100,8 @@ namespace egn{
m_gfx.set_text(string);
}
void text::render(gfx::shader_program& sh){
m_gfx.render(sh, m_position);
void text::render(font_renderer& f){
m_gfx.render(f, m_position);
}
}

65
src/engine/text_field.cpp Normal file
View File

@ -0,0 +1,65 @@
/**
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 "engine/text_field.hpp"
namespace egn::gui{
text_field::text_field(menu* m):
menu_item(m),
m_model{nullptr, m->get_default_font()},
m_view(m_model){}
text_field::text_field(menu* m, const char* data):
menu_item(m),
m_model{data, m->get_default_font()},
m_view(m_model, data){}
text_field::text_field(const text_field& t):
menu_item(t),
m_model(t.m_model),
m_view(t.m_view)
{
m_view.set_model(m_model);
}
text_field::text_field(text_field&& t):
menu_item(std::move(t)),
m_model(std::move(t.m_model)),
m_view(std::move(t.m_view))
{
m_view.set_model(m_model);
}
const std::string& text_field::get_text(void)const{
return m_model.text;
}
void text_field::set_font(const std::shared_ptr<font_atlas>& f){
m_model.font = f;
}
const std::shared_ptr<font_atlas>& text_field::get_font(void)const{
return m_model.font;
}
void text_field::render(menu_renderer& r){
m_view.render(r);
}
text_field* text_field::clone(void)const{
return new text_field(*this);
}
}

View File

@ -0,0 +1,72 @@
/**
This file is a part of our_dick
Copyright (C) 2020-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 "graphics/buffer_map.hpp"
#include "config.hpp"
#include <utility> //exchange, swap
namespace gfx{
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);
m_data = reinterpret_cast<pointer>(glMapNamedBuffer(m_buffer, static_cast<GLenum>(m)));
}
scoped_buffer_map<void>::scoped_buffer_map(scoped_buffer_map&& m):
m_data(std::exchange(m.m_data, nullptr)),
m_buffer(std::exchange(m.m_buffer, 0)){}
scoped_buffer_map<void>::~scoped_buffer_map(){
if(m_data){
debug_print_verbose("Unmapping vertex buffer object %u\n", m_buffer);
glUnmapNamedBuffer(m_buffer);
}
}
scoped_buffer_map<void>& scoped_buffer_map<void>::operator=(scoped_buffer_map&& m){
std::swap(m_data, m.m_data);
std::swap(m_buffer, m.m_buffer);
return *this;
}
auto scoped_buffer_map<void>::length(void)const -> size_type{
GLint64 retval;
glGetNamedBufferParameteri64v(m_buffer, GL_BUFFER_MAP_LENGTH, &retval);
return retval;
}
auto scoped_buffer_map<void>::release(void) -> pointer{
m_buffer = 0;
return std::exchange(m_data, nullptr);
}
scoped_buffer_map<void>::operator pointer(void){
return m_data;
}
scoped_buffer_map<void>::operator const_pointer(void)const{
return m_data;
}
auto scoped_buffer_map<void>::raw(void) -> pointer{
return m_data;
}
auto scoped_buffer_map<void>::raw(void)const -> const_pointer{
return m_data;
}
bool scoped_buffer_map<void>::valid(void)const{
return m_data;
}
}

View File

@ -18,7 +18,6 @@
#include "graphics/fbo.hpp"
#include <utility> //swap, exchange
#include "graphics/scoped_buffer_bind.hpp"
#include "config.hpp"
namespace gfx{
@ -94,9 +93,5 @@ namespace gfx{
glBindFramebuffer(GL_FRAMEBUFFER, m_buffer);
return true;
}
bool fbo::bind(gl_frame_buffer_manager& b)const{
glBindFramebuffer(b.get_buffer_id(), m_buffer);
return true;
}
}

View File

@ -1,61 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2020 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 "graphics/gl_buffers.hpp"
namespace gfx{
bool buffer_accessor::bind(reference b)const{
if(!buffer_accessor_iface<gl_buffer_manager>::i_bind(b))
return false;
glBindBuffer(b.get_buffer_id(), m_raw_id);
return true;
}
bool buffer_accessor::bind_lock(reference b)const{
if(!buffer_accessor_iface<gl_buffer_manager>::i_bind_lock(b))
return false;
glBindBuffer(b.get_buffer_id(), m_raw_id);
return true;
}
void buffer_accessor::unbind(GLuint id)const{
if(!m_bound)
return;
glBindBuffer(m_bound->get_buffer_id(), id);
buffer_accessor_iface<gl_buffer_manager>::i_unbind();
}
bool frame_buffer_accessor::bind(reference b)const{
if(!buffer_accessor_iface<gl_frame_buffer_manager>::i_bind(b))
return false;
glBindFramebuffer(b.get_buffer_id(), m_raw_id);
return true;
}
bool frame_buffer_accessor::bind_lock(reference b)const{
if(!buffer_accessor_iface<gl_frame_buffer_manager>::i_bind_lock(b))
return false;
glBindFramebuffer(b.get_buffer_id(), m_raw_id);
return true;
}
void frame_buffer_accessor::unbind(GLuint id)const{
if(!m_bound)
return;
glBindFramebuffer(m_bound->get_buffer_id(), id);
buffer_accessor_iface<gl_frame_buffer_manager>::i_unbind();
}
}

View File

@ -26,20 +26,20 @@ namespace gfx{
vertex_mesh::vertex_mesh(const std::vector<vertex>& verts):
m_vertices(verts),
m_vbo(&verts[0], sizeof(vertex) * verts.size(), vbo::usage::STATIC_DRAW)
m_vbo(&verts[0], sizeof(vertex) * verts.size(), buffer::usage::STATIC_DRAW)
{
m_vao.bind_buffer(m_vbo, 0, 0, sizeof(vertex));
configure();
}
vertex_mesh::vertex_mesh(std::vector<vertex>&& verts):
m_vertices(std::move(verts)),
m_vbo(&verts[0], sizeof(vertex) * verts.size(), vbo::usage::STATIC_DRAW)
m_vbo(&verts[0], sizeof(vertex) * verts.size(), buffer::usage::STATIC_DRAW)
{
m_vao.bind_buffer(m_vbo, 0, 0, sizeof(vertex));
configure();
}
vertex_mesh::vertex_mesh(const vertex* verts, size_t nverts):
m_vbo(verts, sizeof(vertex) * nverts, vbo::usage::STATIC_DRAW)
m_vbo(verts, sizeof(vertex) * nverts, buffer::usage::STATIC_DRAW)
{
m_vertices.reserve(nverts);
for(size_t i = 0;i < nverts;++i)
@ -99,7 +99,7 @@ namespace gfx{
size_t tex1_loc = shader.get_uniform_loc("texture1");
for(size_t i = 0;i < m_materials.size();++i){
m_materials[i]->bind_unit(i);
shader.set_uniform(tex1_loc + i, *m_materials[i]);
shader.get_uniform(tex1_loc + i).set(*m_materials[i]);
}
}

View File

@ -23,7 +23,7 @@ namespace gfx{
bool resource_manager::has_texture_array(const char* key)const{
return m_texture_arrays.has_value(key);
}
gfx::texture_array* resource_manager::get_texture_array(const char* file){
auto resource_manager::get_texture_array(const char* file) -> container_type<texture_array>::node{
return m_texture_arrays.get_value(file);
}
bool resource_manager::erase_texture_array(const char* key){
@ -33,7 +33,7 @@ namespace gfx{
bool resource_manager::has_texture(const char* key)const{
return m_textures.has_value(key);
}
gfx::texture* resource_manager::get_texture(const char* file){
auto resource_manager::get_texture(const char* file) -> container_type<texture>::node{
return m_textures.get_value(file);
}
bool resource_manager::erase_texture(const char* key){
@ -43,7 +43,7 @@ namespace gfx{
bool resource_manager::has_font(const char* key)const{
return m_fonts.has_value(key);
}
egn::font_atlas* resource_manager::get_font(const char* file){
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){
@ -53,7 +53,7 @@ namespace gfx{
bool resource_manager::has_shader(const char* key)const{
return m_shaders.has_value(key);
}
gfx::shader_program* resource_manager::get_shader(const char* key){
auto resource_manager::get_shader(const char* key) -> container_type<shader_program>::node{
return m_shaders.get_value(key);
}
bool resource_manager::erase_shader(const char* key){

View File

@ -1,26 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2020 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 "graphics/scoped_buffer_bind.hpp"
namespace gfx{
template class scoped_buffer_bind<buffer_accessor>;
template class scoped_buffer_bind<frame_buffer_accessor>;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,124 @@
/**
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 "graphics/text_field_view.hpp"
#include "engine/text_field.hpp"
#include <cstring> //strlen
namespace gfx{
text_field_view::text_field_view(egn::gui::text_field_model& m):
m_model(&m),
m_buffer(s_size_per_char * 10, buffer::usage::DYNAMIC_DRAW),
m_dirty_bit(0)
{
init_arrays_();
}
text_field_view::text_field_view(egn::gui::text_field_model& m, const char* data):
m_model(&m),
m_buffer(s_size_per_char * strlen(data), buffer::usage::DYNAMIC_DRAW)
{
init_arrays_();
set_text(data);
}
text_field_view::text_field_view(const text_field_view& f):
m_model(nullptr),
m_buffer(f.m_buffer),
m_dirty_bit(f.m_dirty_bit)
{
init_arrays_();
}
text_field_view& text_field_view::operator=(const text_field_view& f){
return (*this = text_field_view(f));
}
bool text_field_view::set_text(const char* text){
m_dirty_bit = 1;
const auto& font = m_model->font;
if(!font){
m_buffer.initialize(0);
return false;
}
m_buffer.clear();
constexpr float tmp_color[] = {1, 1, 1, 1};
math::vec2f pos_offset = {0, 0};
for(int i = 0;text[i] != 0;++i){
if(text[i] == '\n'){
pos_offset.x() = 0;
pos_offset.y() -= font->glyph_size().y();
}
const auto ch = (*font)[text[i]];
const math::vec2f char_size = ch.size; //convert from size_t to float
const math::vec2f char_offset = {ch.bearing.x() + pos_offset.x(),
ch.bearing.y() - ch.size.y() + pos_offset.y()};
m_buffer.buffer(ch.texture_coords[1], sizeof(float) * 2);
m_buffer.buffer(ch.texture_coords[2], sizeof(float) * 2);
m_buffer.buffer(tmp_color, sizeof(float) * 4);
m_buffer.buffer(char_offset, sizeof(float) * 2);
m_buffer.buffer(char_size, sizeof(float) * 2);
pos_offset.x() += ch.advance.x();
}
m_dirty_bit = 0;
return true;
}
void text_field_view::set_model(egn::gui::text_field_model& t){
m_model = &t;
}
void text_field_view::render(egn::menu_renderer& r){
if(m_dirty_bit){
set_text(m_model->text.c_str());
}
m_vao.bind();
r.set_position({10, 10});
r.set_font(*m_model->font);
r.draw_text(m_model->text.length());
}
void text_field_view::init_arrays_(void){
m_vao.bind_buffer(m_buffer, 0, 0, s_size_per_char);
auto attrib = m_vao.get_attribute(0);
attrib.set_float_array(4, 0);
attrib.associate_with(0);
attrib.enable();
attrib = m_vao.get_attribute(1);
attrib.set_float_array(4, sizeof(float) * 4);
attrib.associate_with(0);
attrib.enable();
attrib = m_vao.get_attribute(2);
attrib.set_float_array(2, sizeof(float) * 8);
attrib.associate_with(0);
attrib.enable();
attrib = m_vao.get_attribute(3);
attrib.set_float_array(2, sizeof(float) * 10);
attrib.associate_with(0);
attrib.enable();
}
}

View File

@ -22,15 +22,17 @@
#include <rexy/utility.hpp>
#include <utility> //exchange, swap, move
#include <cstring> //memset
namespace gfx{
vbo::vbo(size_t size, usage t):
vbo::vbo(size_t size, buffer::usage t):
m_buffer_size(0)
{
glCreateBuffers(1, &m_buffer);
glNamedBufferData(m_buffer, size, NULL, static_cast<GLenum>(t));
}
vbo::vbo(const void* data, size_t size, usage t):
vbo::vbo(const void* data, size_t size, buffer::usage t):
m_buffer_size(size)
{
glCreateBuffers(1, &m_buffer);
@ -40,7 +42,7 @@ namespace gfx{
m_buffer_size(v.m_buffer_size)
{
glCreateBuffers(1, &m_buffer);
scoped_vbo_map<void> data = v.map(maptype::READ);
scoped_buffer_map<void> data = v.map(buffer::maptype::READ);
if(!data)
return;
glNamedBufferData(m_buffer, v.get_size(), data, static_cast<GLenum>(v.get_usage()));
@ -48,7 +50,7 @@ namespace gfx{
vbo::vbo(vbo&& v):
m_buffer(std::exchange(v.m_buffer, 0)),
m_buffer_size(v.m_buffer_size){}
vbo::~vbo(){
vbo::~vbo(void){
if(m_buffer)
glDeleteBuffers(1, &m_buffer);
}
@ -61,10 +63,6 @@ namespace gfx{
m_buffer_size = v.m_buffer_size;
return *this;
}
bool vbo::bind(gl_buffer_manager& buf)const{
glBindBuffer(buf.get_buffer_id(), m_buffer);
return true;
}
bool vbo::buffer(const void* data, size_t datasize){
if(datasize + m_buffer_size > get_cap()){
@ -88,6 +86,16 @@ namespace gfx{
m_buffer_size = rexy::max(m_buffer_size, datasize + start);
return true;
}
bool vbo::initialize(unsigned char value){
const size_t capacity = get_cap();
auto m = map(buffer::maptype::WRITE);
if(!m){
return false;
}
memset(m, capacity, value);
return true;
}
bool vbo::resize(size_t newsize){
vbo tmp(newsize, get_usage());
if(!copy_buffer(tmp, *this))
@ -95,82 +103,36 @@ namespace gfx{
*this = std::move(tmp);
return true;
}
GLuint vbo::raw()const{
GLuint vbo::raw(void)const{
return m_buffer;
}
scoped_vbo_map<void> vbo::map(maptype m)const{
return scoped_vbo_map<void>(m_buffer, m);
scoped_buffer_map<void> vbo::map(buffer::maptype m)const{
return scoped_buffer_map<void>(m_buffer, m);
}
void vbo::clear(){
void vbo::clear(void){
m_buffer_size = 0;
}
size_t vbo::get_size()const{
size_t vbo::get_size(void)const{
return m_buffer_size;
}
size_t vbo::get_cap()const{
size_t vbo::get_cap(void)const{
GLint retval;
glGetNamedBufferParameteriv(m_buffer, GL_BUFFER_SIZE, &retval);
return retval;
}
auto vbo::get_usage()const -> usage{
auto vbo::get_usage(void)const -> buffer::usage{
GLint retval;
glGetNamedBufferParameteriv(m_buffer, GL_BUFFER_USAGE, &retval);
return static_cast<usage>(retval);
return static_cast<buffer::usage>(retval);
}
bool vbo::copy_buffer(vbo& dest, const vbo& src){
size_t bytes = rexy::min(dest.get_cap(), src.get_size());
scoped_vbo_map<void> data(src.m_buffer, maptype::READ);
scoped_buffer_map<void> data(src.m_buffer, buffer::maptype::READ);
if(!data.valid())
return false;
return dest.buffer(data, bytes);
}
scoped_vbo_map<void>::scoped_vbo_map(GLuint bid, vbo::maptype m):
m_buffer(bid)
{
debug_print_verbose("Mapping vertex buffer object %u\n", bid);
m_data = reinterpret_cast<pointer>(glMapNamedBuffer(m_buffer, static_cast<GLenum>(m)));
}
scoped_vbo_map<void>::scoped_vbo_map(scoped_vbo_map&& m):
m_data(std::exchange(m.m_data, nullptr)),
m_buffer(std::exchange(m.m_buffer, 0)){}
scoped_vbo_map<void>::~scoped_vbo_map(){
if(m_data){
debug_print_verbose("Unmapping vertex buffer object %u\n", m_buffer);
glUnmapNamedBuffer(m_buffer);
}
}
scoped_vbo_map<void>& scoped_vbo_map<void>::operator=(scoped_vbo_map&& m){
std::swap(m_data, m.m_data);
std::swap(m_buffer, m.m_buffer);
return *this;
}
auto scoped_vbo_map<void>::length()const -> size_type{
GLint64 retval;
glGetNamedBufferParameteri64v(m_buffer, GL_BUFFER_MAP_LENGTH, &retval);
return retval;
}
auto scoped_vbo_map<void>::release() -> pointer{
m_buffer = 0;
return std::exchange(m_data, nullptr);
}
scoped_vbo_map<void>::operator pointer(){
return m_data;
}
scoped_vbo_map<void>::operator const_pointer()const{
return m_data;
}
auto scoped_vbo_map<void>::raw() -> pointer{
return m_data;
}
auto scoped_vbo_map<void>::raw()const -> const_pointer{
return m_data;
}
bool scoped_vbo_map<void>::valid()const{
return m_data;
}
}

View File

@ -27,6 +27,10 @@
#include "ttt/tic_tac_toe.hpp"
#include "engine/font.hpp"
#include "graphics/ubo.hpp"
#include "math/debug.hpp"
int main(){
srand(time(NULL));

View File

@ -16,11 +16,12 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ENABLE_MEMCHK
#include <cstddef> //size_t
#include <cstdlib> //malloc, free
#include <new>
#ifndef ENABLE_MEMCHK
void* operator new(size_t newsize){
return std::malloc(newsize);
}
@ -38,4 +39,5 @@ void operator delete(void* ptr, std::align_val_t al)noexcept{
void operator delete(void* ptr, size_t)noexcept{
::operator delete(ptr);
}
#endif

View File

@ -36,7 +36,7 @@ const math::vec4<float>& tile::get_color(void)const{
board::board(gfx::resource_manager& resman):
m_tiles(new tile[9]),
m_gfx(new board_gfx(resman.emplace_texture_array("board_textures", 3)))
m_gfx(new board_gfx(resman))
{
m_tiles[0].set_position({-2.125, 2.125, -1});
m_tiles[1].set_position({-2.125, 0, -1});

View File

@ -19,11 +19,12 @@
#include "ttt/board_gfx.hpp"
#include "ttt/board.hpp"
board_gfx::board_gfx(std::pair<gfx::texture_array*,bool> resman_result):
m_vbo((16 * sizeof(GLfloat) + 4 * sizeof(GLfloat) + 1 * sizeof(GLint)) * 9, gfx::vbo::usage::DYNAMIC_DRAW)
board_gfx::board_gfx(gfx::resource_manager& resman):
m_vbo((16 * sizeof(GLfloat) + 4 * sizeof(GLfloat) + 1 * sizeof(GLint)) * 9, gfx::buffer::usage::DYNAMIC_DRAW)
{
m_textures = resman_result.first;
if(resman_result.second){
auto result = resman.emplace_texture_array("board_textures", 3);
m_textures = std::move(result.first);
if(result.second){
(*m_textures)[0].set_image(egn::image("assets/images/blank.jpg", true));
(*m_textures)[1].set_image(egn::image("assets/images/o.jpg", true));
(*m_textures)[2].set_image(egn::image("assets/images/x.jpg", true));
@ -63,7 +64,7 @@ board_gfx::board_gfx(std::pair<gfx::texture_array*,bool> resman_result):
}
void board_gfx::set_uniforms(gfx::shader_program& sh){
sh.set_uniform("textures", *m_textures, 0);
sh.get_uniform("textures").set(*m_textures, 0);
}
void board_gfx::bind_buffers(void){
m_vao.bind();

View File

@ -31,6 +31,7 @@ font_renderer::font_renderer(gfx::resource_manager& res, int width, int height):
m_font_shader = res.emplace_shader("font_shader", util::make_deferred<gfx::shader>(font_shader::vertex_shader_text, gfx::shader::type::VERTEX),
util::make_deferred<gfx::shader>(font_shader::geometry_shader_text, gfx::shader::type::GEOMETRY),
util::make_deferred<gfx::shader>(font_shader::fragment_shader_text, gfx::shader::type::FRAGMENT)).first;
if(m_font_shader->has_link_error()){
debug_print_error("%s\n", m_font_shader->get_error().c_str());
}
@ -38,7 +39,7 @@ font_renderer::font_renderer(gfx::resource_manager& res, int width, int height):
resize_viewport(width, height);
}
void font_renderer::render(egn::text& t){
void font_renderer::begin(void){
//Clear the global state to that which this renderer prefers
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@ -47,9 +48,20 @@ void font_renderer::render(egn::text& t){
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
m_font_shader->use();
m_font_shader->set_uniform("out_size", math::vec2f{m_screen_width, m_screen_height});
set_aspect(((float)m_screen_width) / m_screen_height);
}
t.render(*m_font_shader);
void font_renderer::set_position(const math::vec2f& pos){
m_font_shader->get_uniform("start_pos").set(pos);
}
void font_renderer::use_texture(const gfx::texture& tex){
m_font_shader->get_uniform("texture1").set(tex);
}
void font_renderer::use_texture(const gfx::weak_texture& tex){
m_font_shader->get_uniform("texture1").set(tex);
}
void font_renderer::set_aspect(float aspect){
m_font_shader->get_uniform("aspect").set(aspect);
}
void font_renderer::resize_viewport(int width, int height){

View File

@ -31,8 +31,8 @@
main_renderer::main_renderer(gfx::resource_manager& 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::vbo::usage::DYNAMIC_DRAW),
m_board_vbo((16*sizeof(GLfloat)+sizeof(GLint)+4*sizeof(GLfloat)) * 9, gfx::vbo::usage::DYNAMIC_DRAW)
m_vbo(s_vertices, sizeof(s_vertices), gfx::buffer::usage::DYNAMIC_DRAW),
m_board_vbo((16*sizeof(GLfloat)+sizeof(GLint)+4*sizeof(GLfloat)) * 9, gfx::buffer::usage::DYNAMIC_DRAW)
{
m_square_shader = res.emplace_shader("square_shader", util::make_deferred<gfx::shader>(square_shader::fragment_shader_text, gfx::shader::type::FRAGMENT),
util::make_deferred<gfx::shader>(square_shader::geometry_shader_text, gfx::shader::type::GEOMETRY),
@ -41,11 +41,11 @@ main_renderer::main_renderer(gfx::resource_manager& res, int width, int height):
debug_print_error("%s\n", m_square_shader->get_error().c_str());
}
m_square_shader->set_uniform("vp_mat", math::mat4<GLfloat>{});
m_square_shader->get_uniform("vp_mat").set(math::mat4<GLfloat>{});
m_screen_shader = res.emplace_shader("screen_shader", util::make_deferred<gfx::shader>(screen_shader::fragment_shader_text, gfx::shader::type::FRAGMENT),
util::make_deferred<gfx::shader>(screen_shader::vertex_shader_text, gfx::shader::type::VERTEX)).first;
m_screen_shader->set_uniform("vp_mat", math::mat4<GLfloat>{});
m_screen_shader->get_uniform("vp_mat").set(math::mat4<GLfloat>{});
m_vao.bind_buffer(m_vbo, 0, 0, sizeof(vertex));
auto attrib = m_vao.get_attribute(0);
@ -61,7 +61,7 @@ main_renderer::main_renderer(gfx::resource_manager& res, int width, int height):
}
void main_renderer::set_vp_matrix(const math::mat4<GLfloat>& vp){
m_square_shader->set_uniform("vp_mat", vp);
m_square_shader->get_uniform("vp_mat").set(vp);
}
void main_renderer::render(scene& s){
m_fb.bind();
@ -79,7 +79,7 @@ void main_renderer::render(scene& s){
glDisable(GL_DEPTH_TEST);
m_screen_shader->use();
m_screen_shader->set_uniform("texture1", m_fb.colorbuffer(), 0);
m_screen_shader->get_uniform("texture1").set(m_fb.colorbuffer(), 0);
m_vao.bind();
glDrawArrays(GL_TRIANGLES, 0, 6);
@ -87,7 +87,7 @@ void main_renderer::render(scene& s){
void main_renderer::resize_viewport(int width, int height){
m_fb.set_viewport(0, 0, width, height);
auto map = m_vbo.map(gfx::vbo::maptype::WRITE);
auto map = m_vbo.map(gfx::buffer::maptype::WRITE);
vertex* data = reinterpret_cast<vertex*>(map.raw());
GLfloat x1 = 0, y1 = 0;
GLfloat x2 = (GLfloat)width / m_fb.colorbuffer().get_width();

View File

@ -22,6 +22,8 @@
#include "graphics/gl_include.hpp" //TODO
#include "engine/text_field.hpp"
#include "config.hpp"
static egn::font_atlas generate_font_atlas_from_file(const char* file, int target_height){
@ -32,13 +34,21 @@ 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_font_renderer(owner.gfx_resource_manager(), owner.get_width(), owner.get_height()),
m_text(*owner.gfx_resource_manager().emplace_font("hinted-RosaSans-Regular-atlas-50px", util::deferred_function(generate_font_atlas_from_file, "assets/hinted-RosaSans-Regular.ttf", 50)).first, "Pause Menu", 50, 100, 100){}
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_menu_renderer(owner.gfx_resource_manager()),
m_menu()
{
m_menu.set_default_font(owner.gfx_resource_manager().emplace_font("pause_screen_font", util::deferred_function(generate_font_atlas_from_file, "assets/hinted-RosaSans-Regular.ttf", 50)).first);
[[maybe_unused]] auto& item = m_menu.emplace_item<egn::gui::text_field>("test text");
}
void pause_state::enter(){
m_screen_renderer.resize_viewport(m_owner->get_width(), m_owner->get_height());
m_font_renderer.resize_viewport(m_owner->get_width(), m_owner->get_height());
const float w = m_owner->get_width();
const float h = m_owner->get_height();
m_screen_renderer.resize_viewport(w, h);
//m_menu_renderer.resize_viewport(w, h);
}
void pause_state::leave(){}
void pause_state::handle_input(const egn::input_event& event){
@ -53,12 +63,16 @@ 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);
m_font_renderer.resize_viewport(event.x, event.y);
//m_menu_renderer.resize_viewport(event.x, event.y);
}
}
void pause_state::update(double){}
void pause_state::render(){
m_under_state->render();
//m_screen_renderer.render(tmp);
m_font_renderer.render(m_text);
scene tmp;
m_screen_renderer.render(tmp);
// m_menu_renderer.begin();
// m_menu.render(m_menu_renderer);
// m_menu_renderer.end();
}

View File

@ -28,9 +28,9 @@
#include "ttt/font_shader.hpp"
#include "math/debug.hpp"
screen_renderer::screen_renderer(gfx::resource_manager& res, int width, int height, gfx::texture& base_tex):
m_vbo(s_vertices, sizeof(s_vertices), gfx::vbo::usage::DYNAMIC_DRAW),
m_texture(&base_tex),
screen_renderer::screen_renderer(gfx::resource_manager& res, int width, int height, const std::shared_ptr<gfx::texture>& base_tex):
m_vbo(s_vertices, sizeof(s_vertices), gfx::buffer::usage::DYNAMIC_DRAW),
m_texture(base_tex),
m_screen_width(width), m_screen_height(height)
{
@ -62,7 +62,7 @@ void screen_renderer::render(scene&){
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//Apply our shader and vao
m_screen_shader->use();
m_screen_shader->set_uniform("texture1", *m_texture, 0);
m_screen_shader->get_uniform("texture1").set(*m_texture, 0);
m_vao.bind();
//Draw