diff --git a/include/graphics/fbo.hpp b/include/graphics/fbo.hpp new file mode 100644 index 0000000..b35be62 --- /dev/null +++ b/include/graphics/fbo.hpp @@ -0,0 +1,62 @@ +/** + 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 . +*/ + +#ifndef OUR_DICK_GRAPHICS_FBO_HPP +#define OUR_DICK_GRAPHICS_FBO_HPP + +#include "gl_include.hpp" +#include "gl_buffers.hpp" +#include "texture.hpp" +#include "rbo.hpp" + +namespace gfx{ + + class fbo + { + private: + GLuint m_buffer; + frame_buffer_iface m_draw; + frame_buffer_iface m_read; + + public: + fbo(); + fbo(const fbo&) = delete; + fbo(fbo&& f); + ~fbo(); + + fbo& operator=(const fbo&) = delete; + fbo& operator=(fbo&& f); + + GLuint raw()const; + + bool detach(GLenum point); + bool attach(const texture& tex, GLenum point); + bool attach(const rbo& r, GLenum point); + + bool bind(gl_frame_buffer& b)const; + bool bind_lock(gl_frame_buffer& b)const; + void bind_unlock(gl_frame_buffer& b)const; + void unbind()const; + + gl_frame_buffer* get_bound_buffer()const; + GLenum get_bound_id()const; + }; + +} + +#endif diff --git a/include/graphics/gl_buffers.hpp b/include/graphics/gl_buffers.hpp index 6c39993..2cd0c63 100644 --- a/include/graphics/gl_buffers.hpp +++ b/include/graphics/gl_buffers.hpp @@ -24,6 +24,7 @@ namespace gfx{ class gl_buffer; + class gl_frame_buffer; //handle interfacing with the gl_buffer objects. Used as intermediary so that multiple classes have the ability to //access gl_buffers easily @@ -55,17 +56,38 @@ namespace gfx{ //get access to opengl target buffer gl_buffer* get_bound_buffer()const; }; + class frame_buffer_iface : protected buffer_iface + { + public: + frame_buffer_iface() = default; + frame_buffer_iface(const frame_buffer_iface&) = default; + frame_buffer_iface(frame_buffer_iface&&) = default; + ~frame_buffer_iface() = default; + + frame_buffer_iface& operator=(const frame_buffer_iface&) = default; + frame_buffer_iface& operator=(frame_buffer_iface&&) = default; + + bool bind(gl_frame_buffer& b)const; + bool bind_lock(gl_frame_buffer& b)const; + + using buffer_iface::unlock; + using buffer_iface::unbind; + using buffer_iface::is_locked; + using buffer_iface::get_bound_id; + + gl_frame_buffer* get_bound_buffer()const; + }; //Manage active opengl buffers and targets class gl_buffer { friend class buffer; //access to constructor/destructor friend class buffer_iface; //access to bind - private: + protected: const buffer_iface* bound = nullptr; //vbo bound to this buffer const GLenum m_buffer; //target this object represents bool m_lock = false; //if the target disallows ownership changes - private: + protected: gl_buffer(GLenum buf); ~gl_buffer() = default; void bind(const buffer_iface* newbind); @@ -75,6 +97,16 @@ namespace gfx{ //return id of the target this represents GLenum get_buffer_id()const; }; + class gl_frame_buffer : protected gl_buffer + { + friend class framebuffer; + friend class frame_buffer_iface; + protected: + using gl_buffer::gl_buffer; + ~gl_frame_buffer() = default; + public: + using gl_buffer::get_buffer_id; + }; class buffer //glorified namespace for added access control { @@ -99,6 +131,16 @@ namespace gfx{ buffer() = default; ~buffer() = default; }; + class framebuffer + { + //list of all the standard opengl framebuffer targets + public: + static inline gl_frame_buffer draw{GL_DRAW_FRAMEBUFFER}; + static inline gl_frame_buffer read{GL_READ_FRAMEBUFFER}; + private: + framebuffer() = default; + ~framebuffer() = default; + }; } #endif diff --git a/include/graphics/rbo.hpp b/include/graphics/rbo.hpp new file mode 100644 index 0000000..c5205c0 --- /dev/null +++ b/include/graphics/rbo.hpp @@ -0,0 +1,58 @@ +/** + 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 . +*/ + +#ifndef OUR_DICK_GRAPHICS_RBO_HPP +#define OUR_DICK_GRAPHICS_RBO_HPP + +#include "gl_include.hpp" + +namespace gfx{ + + class rbo + { + private: + GLuint m_buffer; + GLenum m_format; + GLsizei m_width; + GLsizei m_height; + + public: + rbo(GLsizei width, GLsizei height, GLenum format, GLsizei samples = 0); + rbo(const rbo& r) = delete; + rbo(rbo&& r); + ~rbo(); + + rbo& operator=(const rbo& r) = delete; + rbo& operator=(rbo&& r); + + GLuint raw()const; + + void bind()const; + void unbind()const; + + void resize(GLsizei w, GLsizei h); + void reformat(GLenum format); + + GLsizei get_width()const; + GLsizei get_height()const; + }; + +} + + +#endif diff --git a/include/graphics/texture.hpp b/include/graphics/texture.hpp index 97bb1c4..8a92113 100644 --- a/include/graphics/texture.hpp +++ b/include/graphics/texture.hpp @@ -68,6 +68,8 @@ namespace gfx{ texture& operator=(const texture&) = delete; texture& operator=(texture&&); + GLuint raw()const; + //overwrite the current image data with 'i' bool set_image(const image& i); diff --git a/include/graphics/vao.hpp b/include/graphics/vao.hpp index f348d32..c76c9dc 100644 --- a/include/graphics/vao.hpp +++ b/include/graphics/vao.hpp @@ -43,6 +43,8 @@ namespace gfx{ vao& operator=(const vao&) = delete; vao& operator=(vao&&); + GLuint raw()const; + //Get access to a generic vertex attribute within this vao vertex_attribute get_attribute(int index); diff --git a/include/graphics/vbo.hpp b/include/graphics/vbo.hpp index ea6d0e2..bf603ca 100644 --- a/include/graphics/vbo.hpp +++ b/include/graphics/vbo.hpp @@ -80,6 +80,8 @@ namespace gfx{ //change capacity of buffer void resize(size_t newcap); + GLuint raw()const; + //glMapBuffer to given target with map style 'm' scoped_vbo_map map(gl_buffer& target, maptype m)const; diff --git a/src/graphics/fbo.cpp b/src/graphics/fbo.cpp new file mode 100644 index 0000000..8d16d52 --- /dev/null +++ b/src/graphics/fbo.cpp @@ -0,0 +1,115 @@ +/** + 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 . +*/ + +#include "graphics/fbo.hpp" +#include //swap, exchange + +namespace gfx{ + + fbo::fbo(){ + glGenFramebuffers(1, &m_buffer); + } + fbo::fbo(fbo&& f): + m_buffer(std::exchange(f.m_buffer, 0)){} + fbo::~fbo(){ + if(m_buffer) + glDeleteFramebuffers(1, &m_buffer); + } + + fbo& fbo::operator=(fbo&& f){ + std::swap(m_buffer, f.m_buffer); + return *this; + } + + GLuint fbo::raw()const{ + return m_buffer; + } + + bool fbo::detach(GLenum point){ + if(!bind(framebuffer::draw)) + return false; + glFramebufferRenderbuffer(m_draw.get_bound_id(), point, GL_RENDERBUFFER, 0); + return true; + } + bool fbo::attach(const texture& tex, GLenum point){ + if(!bind(framebuffer::draw)) + return false; + glFramebufferTexture2D(m_draw.get_bound_id(), point, GL_TEXTURE_2D, tex.raw(), 0); + return true; + } + bool fbo::attach(const rbo& r, GLenum point){ + if(!bind(framebuffer::draw)) + return false; + glFramebufferRenderbuffer(m_draw.get_bound_id(), point, GL_RENDERBUFFER, r.raw()); + return true; + } + + bool fbo::bind(gl_frame_buffer& b)const{ + if(GL_DRAW_FRAMEBUFFER == b.get_buffer_id()){ + if(!m_draw.bind(b)) + return false; + }else{ + if(!m_read.bind(b)) + return false; + } + glBindFramebuffer(b.get_buffer_id(), m_buffer); + return true; + } + bool fbo::bind_lock(gl_frame_buffer& b)const{ + if(GL_DRAW_FRAMEBUFFER == b.get_buffer_id()){ + if(!m_draw.bind_lock(b)) + return false; + }else{ + if(!m_read.bind_lock(b)) + return false; + } + glBindFramebuffer(b.get_buffer_id(), m_buffer); + return true; + } + void fbo::bind_unlock(gl_frame_buffer& b)const{ + if(GL_DRAW_FRAMEBUFFER == b.get_buffer_id()){ + m_draw.unlock(); + }else{ + m_read.unlock(); + } + } + void fbo::unbind()const{ + if(m_draw.get_bound_buffer() && m_read.get_bound_buffer()){ + glBindFramebuffer(GL_FRAMEBUFFER, 0); + m_draw.unbind(); + m_read.unbind(); + }else if(m_draw.get_bound_buffer()){ + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + m_draw.unbind(); + }else if(m_read.get_bound_buffer()){ + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + m_read.unbind(); + } + } + GLenum fbo::get_bound_id()const{ + if(m_read.get_bound_buffer() && m_draw.get_bound_buffer()) + return GL_FRAMEBUFFER; + if(m_read.get_bound_buffer()) + return m_read.get_bound_id(); + if(m_draw.get_bound_buffer()) + return m_draw.get_bound_id(); + return 0; + } + + +} diff --git a/src/graphics/gl_buffers.cpp b/src/graphics/gl_buffers.cpp index 2206d75..f76dcf8 100644 --- a/src/graphics/gl_buffers.cpp +++ b/src/graphics/gl_buffers.cpp @@ -95,6 +95,18 @@ namespace gfx{ return nullptr; } + + bool frame_buffer_iface::bind(gl_frame_buffer& b)const{ + return buffer_iface::bind(b); + } + bool frame_buffer_iface::bind_lock(gl_frame_buffer& b)const{ + return buffer_iface::bind_lock(b); + } + gl_frame_buffer* frame_buffer_iface::get_bound_buffer()const{ + return static_cast(buffer_iface::get_bound_buffer()); + } + + gl_buffer::gl_buffer(GLenum buf): m_buffer(buf){} void gl_buffer::bind(const buffer_iface* newbind){ diff --git a/src/graphics/rbo.cpp b/src/graphics/rbo.cpp new file mode 100644 index 0000000..04ee284 --- /dev/null +++ b/src/graphics/rbo.cpp @@ -0,0 +1,77 @@ +/** + 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 . +*/ + +#include "graphics/rbo.hpp" +#include //swap, exchange + +namespace gfx{ + + rbo::rbo(GLsizei width, GLsizei height, GLenum format, GLsizei samples): + m_format(format), + m_width(width), + m_height(height) + { + glGenRenderbuffers(1, &m_buffer); + bind(); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, m_format, m_width, m_height); + unbind(); + } + rbo::rbo(rbo&& r): + m_buffer(std::exchange(r.m_buffer, 0)), + m_format(r.m_format), + m_width(r.m_width), + m_height(r.m_height){} + rbo::~rbo(){ + if(m_buffer) + glDeleteRenderbuffers(1, &m_buffer); + } + + rbo& rbo::operator=(rbo&& r){ + std::swap(m_buffer, r.m_buffer); + m_format = r.m_format; + m_width = r.m_width; + m_height = r.m_height; + return *this; + } + + GLuint rbo::raw()const{ + return m_buffer; + } + + void rbo::bind()const{ + glBindRenderbuffer(GL_RENDERBUFFER, m_buffer); + } + void rbo::unbind()const{ + glBindRenderbuffer(GL_RENDERBUFFER, 0); + } + + void rbo::resize(GLsizei w, GLsizei h){ + *this = rbo(w, h, m_format); + } + void rbo::reformat(GLenum format){ + *this = rbo(m_width, m_height, format); + } + + GLsizei rbo::get_width()const{ + return m_width; + } + GLsizei rbo::get_height()const{ + return m_height; + } + +} diff --git a/src/graphics/texture.cpp b/src/graphics/texture.cpp index 185ba4e..482f518 100644 --- a/src/graphics/texture.cpp +++ b/src/graphics/texture.cpp @@ -40,6 +40,9 @@ namespace gfx{ std::swap(m_tex_id, t.m_tex_id); return *this; } + GLuint texture::raw()const{ + return m_tex_id; + } bool texture::set_image(const image& i){ if(!i) diff --git a/src/graphics/vao.cpp b/src/graphics/vao.cpp index 4864b06..f138c0f 100644 --- a/src/graphics/vao.cpp +++ b/src/graphics/vao.cpp @@ -228,6 +228,10 @@ namespace gfx{ std::swap(m_buffer, v.m_buffer); return *this; } + GLuint vao::raw()const{ + return m_buffer; + } + vertex_attribute vao::get_attribute(int index){ return vertex_attribute(m_buffer, index); } diff --git a/src/graphics/vbo.cpp b/src/graphics/vbo.cpp index 94883f4..2b49d0e 100644 --- a/src/graphics/vbo.cpp +++ b/src/graphics/vbo.cpp @@ -100,6 +100,9 @@ namespace gfx{ copy_buffer(tmp, *this); *this = std::move(tmp); } + GLuint vbo::raw()const{ + return m_buffer; + } scoped_vbo_map vbo::map(gl_buffer& target, maptype m)const{ return scoped_vbo_map(*this, target, m); }