From b9e720f36185c6fe4d39a1056ecb88dec0ce950d Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Wed, 10 Nov 2021 01:50:19 +0200 Subject: [PATCH] Restructure system framebuffer and make WindowView own it This works very differently on Vulkan, so the system framebuffer can't be exposed from the Framebuffer class. --- .../backends/opengl/framebuffer_backend.cpp | 39 ++++------------- source/backends/opengl/framebuffer_backend.h | 4 +- source/backends/opengl/systemframebuffer.cpp | 43 +++++++++++++++++++ source/backends/opengl/systemframebuffer.h | 22 ++++++++++ source/backends/opengl/windowview_backend.cpp | 12 ++++++ source/backends/opengl/windowview_backend.h | 27 ++++++++++++ source/core/framebuffer.cpp | 23 +--------- source/core/framebuffer.h | 8 +--- source/render/windowview.cpp | 7 +-- source/render/windowview.h | 6 +-- 10 files changed, 121 insertions(+), 70 deletions(-) create mode 100644 source/backends/opengl/systemframebuffer.cpp create mode 100644 source/backends/opengl/systemframebuffer.h create mode 100644 source/backends/opengl/windowview_backend.cpp create mode 100644 source/backends/opengl/windowview_backend.h diff --git a/source/backends/opengl/framebuffer_backend.cpp b/source/backends/opengl/framebuffer_backend.cpp index 1adcb7f9..b56499d1 100644 --- a/source/backends/opengl/framebuffer_backend.cpp +++ b/source/backends/opengl/framebuffer_backend.cpp @@ -39,37 +39,9 @@ OpenGLFramebuffer::~OpenGLFramebuffer() glDeleteFramebuffers(1, &id); } -FrameFormat OpenGLFramebuffer::get_system_format() +void OpenGLFramebuffer::set_system_format(const FrameFormat &fmt) { - FrameFormat format; - - if(EXT_framebuffer_object) - { - int value; - glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_BACK, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &value); - if(value==GL_NONE) - glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_FRONT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &value); - if(value!=GL_NONE) - format = (format,COLOR_ATTACHMENT); - - glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &value); - if(value!=GL_NONE) - format = (format,DEPTH_ATTACHMENT); - - glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_STENCIL, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &value); - if(value!=GL_NONE) - format = (format,STENCIL_ATTACHMENT); - } - - return format; -} - -void OpenGLFramebuffer::get_system_size(unsigned &width, unsigned &height) -{ - int view[4]; - glGetIntegerv(GL_VIEWPORT, view); - width = view[2]; - height = view[3]; + static_cast(this)->format = fmt; } bool OpenGLFramebuffer::is_format_supported(const FrameFormat &fmt) @@ -96,6 +68,13 @@ void OpenGLFramebuffer::require_layered() static Require _req(ARB_geometry_shader4); } +void OpenGLFramebuffer::resize_system(unsigned w, unsigned h) +{ + Framebuffer *self = static_cast(this); + self->width = w; + self->height = h; +} + void OpenGLFramebuffer::update(unsigned mask) const { const FrameFormat &format = static_cast(this)->format; diff --git a/source/backends/opengl/framebuffer_backend.h b/source/backends/opengl/framebuffer_backend.h index 84f6eddf..090071f7 100644 --- a/source/backends/opengl/framebuffer_backend.h +++ b/source/backends/opengl/framebuffer_backend.h @@ -19,11 +19,11 @@ protected: OpenGLFramebuffer(bool); ~OpenGLFramebuffer(); - static FrameFormat get_system_format(); - static void get_system_size(unsigned &, unsigned &); + void set_system_format(const FrameFormat &); static bool is_format_supported(const FrameFormat &); static void require_layered(); + void resize_system(unsigned, unsigned); void update(unsigned) const; void require_complete() const; diff --git a/source/backends/opengl/systemframebuffer.cpp b/source/backends/opengl/systemframebuffer.cpp new file mode 100644 index 00000000..dbfe0b82 --- /dev/null +++ b/source/backends/opengl/systemframebuffer.cpp @@ -0,0 +1,43 @@ +#include +#include "gl.h" +#include "systemframebuffer.h" + +namespace Msp { +namespace GL { + +OpenGLSystemFramebuffer::OpenGLSystemFramebuffer(): + Framebuffer(true) +{ + FrameFormat sys_format; + + if(EXT_framebuffer_object) + { + int value; + glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_BACK, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &value); + if(value==GL_NONE) + glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_FRONT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &value); + if(value!=GL_NONE) + sys_format = (sys_format, COLOR_ATTACHMENT); + + glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_DEPTH, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &value); + if(value!=GL_NONE) + sys_format = (sys_format, DEPTH_ATTACHMENT); + + glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_STENCIL, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &value); + if(value!=GL_NONE) + sys_format = (sys_format, STENCIL_ATTACHMENT); + } + else + // Make a guess if we can't query the format + sys_format = (COLOR_ATTACHMENT, DEPTH_ATTACHMENT); + + set_system_format(sys_format); +} + +void OpenGLSystemFramebuffer::resize(unsigned w, unsigned h) +{ + resize_system(w, h); +} + +} // namespace GL +} // namespace Msp diff --git a/source/backends/opengl/systemframebuffer.h b/source/backends/opengl/systemframebuffer.h new file mode 100644 index 00000000..a2ba9837 --- /dev/null +++ b/source/backends/opengl/systemframebuffer.h @@ -0,0 +1,22 @@ +#ifndef MSP_GL_SYSTEMFRAMEBUFFER_H_ +#define MSP_GL_SYSTEMFRAMEBUFFER_H_ + +#include "framebuffer.h" + +namespace Msp { +namespace GL { + +class OpenGLSystemFramebuffer: public Framebuffer +{ + friend class OpenGLWindowView; + +private: + OpenGLSystemFramebuffer(); + + void resize(unsigned, unsigned); +}; + +} // namespace GL +} // namespace Msp + +#endif diff --git a/source/backends/opengl/windowview_backend.cpp b/source/backends/opengl/windowview_backend.cpp new file mode 100644 index 00000000..3bda4107 --- /dev/null +++ b/source/backends/opengl/windowview_backend.cpp @@ -0,0 +1,12 @@ +#include "windowview_backend.h" + +namespace Msp { +namespace GL { + +void OpenGLWindowView::resize_framebuffer(unsigned w, unsigned h) +{ + sys_framebuf.resize(w, h); +} + +} // namespace GL +} // namespace Msp diff --git a/source/backends/opengl/windowview_backend.h b/source/backends/opengl/windowview_backend.h new file mode 100644 index 00000000..f51c4bb6 --- /dev/null +++ b/source/backends/opengl/windowview_backend.h @@ -0,0 +1,27 @@ +#ifndef MSP_GL_WINDOWVIEW_BACKEND_H_ +#define MSP_GL_WINDOWVIEW_BACKEND_H_ + +#include "systemframebuffer.h" +#include "view.h" + +namespace Msp { +namespace GL { + +class OpenGLWindowView: public View +{ +protected: + OpenGLSystemFramebuffer sys_framebuf; + + OpenGLWindowView() = default; + + virtual const Framebuffer &get_target() const { return sys_framebuf; } + + void resize_framebuffer(unsigned, unsigned); +}; + +using WindowViewBackend = OpenGLWindowView; + +} // namespace GL +} // namespace Msp + +#endif diff --git a/source/core/framebuffer.cpp b/source/core/framebuffer.cpp index 01fd6265..70c19859 100644 --- a/source/core/framebuffer.cpp +++ b/source/core/framebuffer.cpp @@ -18,13 +18,7 @@ framebuffer_incomplete::framebuffer_incomplete(const std::string &reason): Framebuffer::Framebuffer(bool s): FramebufferBackend(s), dirty(0) -{ - if(s) - { - format = get_system_format(); - get_system_size(width, height); - } -} +{ } Framebuffer::Framebuffer(): FramebufferBackend(false), @@ -175,15 +169,6 @@ void Framebuffer::detach(FrameAttachment attch) } } -void Framebuffer::resize(const WindowView &view) -{ - if(attachments.empty()) - throw invalid_operation("Framebuffer::resize"); - - width = view.get_width(); - height = view.get_height(); -} - void Framebuffer::require_complete() const { bool layered = (!attachments.empty() && attachments.front().layer<0); @@ -198,12 +183,6 @@ void Framebuffer::require_complete() const FramebufferBackend::require_complete(); } -Framebuffer &Framebuffer::system() -{ - static Framebuffer sys_framebuf(true); - return sys_framebuf; -} - void Framebuffer::Attachment::set(Texture &t, unsigned l, int z) { diff --git a/source/core/framebuffer.h b/source/core/framebuffer.h index d2029022..fd7b8eb4 100644 --- a/source/core/framebuffer.h +++ b/source/core/framebuffer.h @@ -34,7 +34,7 @@ class Framebuffer: public FramebufferBackend { friend FramebufferBackend; -private: +protected: struct Attachment { Texture *tex = 0; @@ -72,7 +72,7 @@ public: unsigned get_width() const { return width; } unsigned get_height() const { return height; } -private: +protected: void update() const; void check_size(); void set_attachment(FrameAttachment, Texture &, unsigned, int, unsigned); @@ -99,8 +99,6 @@ public: void attach_layered(FrameAttachment attch, TextureCube &, unsigned level = 0); void detach(FrameAttachment attch); - void resize(const WindowView &); - /** Ensures that the framebuffer is complete, throwing an exception if it isn't. */ void require_complete() const; @@ -108,8 +106,6 @@ public: void refresh() const { if(dirty) update(); } using FramebufferBackend::set_debug_name; - - static Framebuffer &system(); }; diff --git a/source/render/windowview.cpp b/source/render/windowview.cpp index bbc7bb00..44e6187a 100644 --- a/source/render/windowview.cpp +++ b/source/render/windowview.cpp @@ -22,16 +22,11 @@ void WindowView::render(Renderer &renderer) void WindowView::window_resized(unsigned w, unsigned h) { - Framebuffer::system().resize(*this); + resize_framebuffer(w, h); float aspect = static_cast(w)/h; if(camera) camera->set_aspect_ratio(aspect); } -const Framebuffer &WindowView::get_target() const -{ - return Framebuffer::system(); -} - } // namespace GL } // namespace Msp diff --git a/source/render/windowview.h b/source/render/windowview.h index 031cd49d..93769f19 100644 --- a/source/render/windowview.h +++ b/source/render/windowview.h @@ -4,7 +4,7 @@ #include #include #include "device.h" -#include "view.h" +#include "windowview_backend.h" namespace Msp { namespace GL { @@ -17,7 +17,7 @@ After rendering, buffers are swapped to show the result in the window. The aspect ratio of the view's Camera is automatically updated to match that of the window. */ -class WindowView: public View, public sigc::trackable +class WindowView: public WindowViewBackend, public sigc::trackable { private: Graphics::Window &window; @@ -35,8 +35,6 @@ public: private: void window_resized(unsigned, unsigned); - - virtual const Framebuffer &get_target() const; }; } // namespace GL -- 2.43.0