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<Framebuffer *>(this)->format = fmt;
}
bool OpenGLFramebuffer::is_format_supported(const FrameFormat &fmt)
static Require _req(ARB_geometry_shader4);
}
+void OpenGLFramebuffer::resize_system(unsigned w, unsigned h)
+{
+ Framebuffer *self = static_cast<Framebuffer *>(this);
+ self->width = w;
+ self->height = h;
+}
+
void OpenGLFramebuffer::update(unsigned mask) const
{
const FrameFormat &format = static_cast<const Framebuffer *>(this)->format;
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;
--- /dev/null
+#include <msp/gl/extensions/ext_framebuffer_object.h>
+#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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
Framebuffer::Framebuffer(bool s):
FramebufferBackend(s),
dirty(0)
-{
- if(s)
- {
- format = get_system_format();
- get_system_size(width, height);
- }
-}
+{ }
Framebuffer::Framebuffer():
FramebufferBackend(false),
}
}
-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);
FramebufferBackend::require_complete();
}
-Framebuffer &Framebuffer::system()
-{
- static Framebuffer sys_framebuf(true);
- return sys_framebuf;
-}
-
void Framebuffer::Attachment::set(Texture &t, unsigned l, int z)
{
{
friend FramebufferBackend;
-private:
+protected:
struct Attachment
{
Texture *tex = 0;
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);
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;
void refresh() const { if(dirty) update(); }
using FramebufferBackend::set_debug_name;
-
- static Framebuffer &system();
};
void WindowView::window_resized(unsigned w, unsigned h)
{
- Framebuffer::system().resize(*this);
+ resize_framebuffer(w, h);
float aspect = static_cast<float>(w)/h;
if(camera)
camera->set_aspect_ratio(aspect);
}
-const Framebuffer &WindowView::get_target() const
-{
- return Framebuffer::system();
-}
-
} // namespace GL
} // namespace Msp
#include <sigc++/trackable.h>
#include <msp/graphics/window.h>
#include "device.h"
-#include "view.h"
+#include "windowview_backend.h"
namespace Msp {
namespace GL {
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;
private:
void window_resized(unsigned, unsigned);
-
- virtual const Framebuffer &get_target() const;
};
} // namespace GL