]> git.tdb.fi Git - libs/gl.git/blob - source/core/framebuffer.h
Rework multisample resolve to use resolve attachments
[libs/gl.git] / source / core / framebuffer.h
1 #ifndef MSP_GL_FRAMEBUFFER_H_
2 #define MSP_GL_FRAMEBUFFER_H_
3
4 #include <vector>
5 #include "color.h"
6 #include "framebuffer_backend.h"
7 #include "frameformat.h"
8 #include "rect.h"
9 #include "texturecube.h"
10
11 namespace Msp {
12 namespace GL {
13
14 class Texture2D;
15 class Texture2DMultisample;
16 class Texture3D;
17 class WindowView;
18
19 class framebuffer_incomplete: public std::runtime_error
20 {
21 public:
22         framebuffer_incomplete(const std::string &);
23         virtual ~framebuffer_incomplete() throw() { }
24 };
25
26 /**
27 Uses one or more textures as buffers to draw into.  Framebuffers can contain
28 multiple color buffers to match multiple outputs from a fragment shader, but
29 only one depth and stencil buffer.
30
31 If a framebuffer has a multisampled format, each attachment can optionally have
32 a single-sampled resolve attachment associated with it.  When a multisample
33 resolve operation is performed on the framebuffer (such as by a Sequence), the
34 sample values from the primary attachments are converted to a single value per
35 pixel in the corresponding resolve attachments.
36
37 RenderTarget provides a higher-level interface which manages the textures as
38 well as the framebuffer itself.
39 */
40 class Framebuffer: public FramebufferBackend
41 {
42         friend FramebufferBackend;
43
44 protected:
45         struct Attachment
46         {
47                 Texture *tex = 0;
48                 Texture *resolve = 0;
49                 unsigned level = 0;
50                 int layer = 0;
51
52                 void set(Texture &, Texture *, unsigned, int);
53                 void clear();
54         };
55
56         FrameFormat format;
57         std::vector<Attachment> attachments;
58         unsigned width = 0;
59         unsigned height = 0;
60         unsigned layers = 0;
61         mutable unsigned dirty = 0;
62
63         Framebuffer(bool);
64 public:
65         /** Creates an empty framebuffer.  Format must be set before textures can
66         be attached. */
67         Framebuffer();
68
69         /** Creates a framebuffer and sets its format to a single attachment. */
70         Framebuffer(FrameAttachment);
71
72         /** Creates a framebuffer and sets its format. */
73         Framebuffer(const FrameFormat &);
74
75         /** Sets the format of the framebuffer.  Once the format is set, it can't
76         be changed. */
77         void set_format(const FrameFormat &);
78
79         const FrameFormat &get_format() const { return format; }
80
81         unsigned get_width() const { return width; }
82         unsigned get_height() const { return height; }
83         Rect get_rect() const { return Rect(0, 0, width, height); }
84         unsigned get_layers() const { return layers; }
85
86 protected:
87         void update() const;
88         void check_size();
89         void set_attachment(FrameAttachment, Texture &, Texture *, unsigned, int, unsigned);
90
91 public:
92         /** Attaches a texture to the framebuffer.  Only the attachment point
93         portion of attch is considered; pixel format is ignored.  The framebuffer
94         must have a format and the format of the texture must match that defined
95         in the framebuffer for this attachment point. */
96         void attach(FrameAttachment attch, Texture2D &, unsigned level = 0);
97
98         /** Attaches a multisample texture to the framebuffer.  The texture must
99         have a sample count matching the frame format.  A resolve attachment may
100         be given as well and used to resolve the multisample image into a single
101         value per texel. */
102         void attach(FrameAttachment attch, Texture2DMultisample &, Texture2D *);
103
104         /** Attaches a single layer from a 3-dimensional texture to the
105         framebuffer. */
106         void attach(FrameAttachment attch, Texture3D &, unsigned layer, unsigned level = 0);
107
108         void attach(FrameAttachment attch, TextureCube &, TextureCubeFace face, unsigned level = 0);
109
110         /** Attaches a layered texture to the framebuffer.  Shaders can direct
111         output to a particular layer. */
112         void attach_layered(FrameAttachment attch, Texture3D &, unsigned level = 0);
113
114         void attach_layered(FrameAttachment attch, TextureCube &, unsigned level = 0);
115         void detach(FrameAttachment attch);
116
117         const Texture *get_attachment(FrameAttachment) const;
118         const Texture *get_attachment(unsigned) const;
119         const Texture *get_resolve_attachment(FrameAttachment) const;
120         const Texture *get_resolve_attachment(unsigned) const;
121         bool has_resolve_attachments() const;
122
123         /** Ensures that the framebuffer is complete, throwing an exception if it
124         isn't. */
125         void require_complete() const;
126
127         void refresh() const { if(dirty) update(); }
128
129         using FramebufferBackend::set_debug_name;
130 };
131
132
133 union ClearValue
134 {
135         Color color;
136         struct
137         {
138                 float depth;
139                 int stencil;
140         } depth_stencil;
141
142         ClearValue(): color(0.0f, 0.0f, 0.0f, 0.0f) { }
143 };
144
145 } // namespace GL
146 } // namespace Msp
147
148 #endif