]> git.tdb.fi Git - libs/gl.git/blob - source/core/framebuffer.h
3086685e1ce29234e8f1e8629bb7ffd103f7050f
[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 "bindable.h"
6 #include "gl.h"
7 #include "texturecube.h"
8 #include <msp/gl/extensions/arb_geometry_shader4.h>
9 #include <msp/gl/extensions/ext_framebuffer_multisample.h>
10 #include <msp/gl/extensions/ext_framebuffer_object.h>
11 #include <msp/gl/extensions/nv_fbo_color_attachments.h>
12
13 namespace Msp {
14 namespace GL {
15
16 class Renderbuffer;
17 class Texture;
18 class Texture2D;
19 class Texture3D;
20
21 enum FramebufferAttachment
22 {
23         COLOR_ATTACHMENT0  = GL_COLOR_ATTACHMENT0,
24         COLOR_ATTACHMENT1  = GL_COLOR_ATTACHMENT1,
25         COLOR_ATTACHMENT2  = GL_COLOR_ATTACHMENT2,
26         COLOR_ATTACHMENT3  = GL_COLOR_ATTACHMENT3,
27         DEPTH_ATTACHMENT   = GL_DEPTH_ATTACHMENT,
28         STENCIL_ATTACHMENT = GL_STENCIL_ATTACHMENT
29 };
30
31 enum FramebufferStatus
32 {
33         FRAMEBUFFER_INCOMPLETE_ATTACHMENT         = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
34         FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT,
35         FRAMEBUFFER_INCOMPLETE_DIMENSIONS         = GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT,
36         FRAMEBUFFER_INCOMPLETE_FORMATS            = GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT,
37         FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER        = GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER,
38         FRAMEBUFFER_INCOMPLETE_READ_BUFFER        = GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER,
39         FRAMEBUFFER_INCOMPLETE_MULTISAMPLE        = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
40         FRAMEBUFFER_INCOMPLETE_LAYER_COUNT        = GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB,
41         FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS      = GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS,
42         FRAMEBUFFER_UNSUPPORTED                   = GL_FRAMEBUFFER_UNSUPPORTED,
43         FRAMEBUFFER_COMPLETE                      = GL_FRAMEBUFFER_COMPLETE
44 };
45
46 enum BufferBits
47 {
48         COLOR_BUFFER_BIT   = GL_COLOR_BUFFER_BIT,
49         DEPTH_BUFFER_BIT   = GL_DEPTH_BUFFER_BIT,
50         STENCIL_BUFFER_BIT = GL_STENCIL_BUFFER_BIT
51 };
52
53 class framebuffer_incomplete: public std::runtime_error
54 {
55 public:
56         framebuffer_incomplete(FramebufferStatus);
57         virtual ~framebuffer_incomplete() throw() { }
58 };
59
60 /**
61 Framebuffer objects can be used to perform offscreen rendering.  The most
62 common application is rendering to a texture, which can then be used for
63 fullscreen shader effects.
64
65 A framebuffer consist of a number of logical buffers, such as color and depth
66 buffers.  Renderbuffers and Textures can be attached to the logical buffers.  At
67 least one image must be attached for the framebuffer to be usable.
68
69 Requires the GL_EXT_framebuffer_object extension.  The blit functions require
70 the GL_EXT_framebuffer_blit extension.
71 */
72 class Framebuffer: public Bindable<Framebuffer>
73 {
74 private:
75         struct Attachment
76         {
77                 FramebufferAttachment attachment;
78                 GLenum type;
79                 union
80                 {
81                         Renderbuffer *rbuf;
82                         Texture *tex;
83                 };
84                 unsigned level;
85                 unsigned layer;
86
87                 Attachment(FramebufferAttachment);
88                 void set(Renderbuffer &);
89                 void set(Texture &, unsigned, unsigned);
90                 void clear();
91         };
92
93         struct Viewport
94         {
95                 int left;
96                 int bottom;
97                 unsigned width;
98                 unsigned height;
99
100                 Viewport();
101         };
102
103         unsigned id;
104         std::vector<Attachment> attachments;
105         unsigned width;
106         unsigned height;
107         Viewport view;
108         mutable unsigned dirty;
109
110         Framebuffer(unsigned);
111 public:
112         Framebuffer();
113         ~Framebuffer();
114
115         unsigned get_width() const { return width; }
116         unsigned get_height() const { return height; }
117
118 private:
119         void update_attachment(unsigned) const;
120         void check_size();
121         unsigned get_attachment_index(FramebufferAttachment);
122         void set_texture_attachment(FramebufferAttachment, Texture &, unsigned, int);
123 public:
124         void attach(FramebufferAttachment attch, Renderbuffer &rbuf);
125         void attach(FramebufferAttachment attch, Texture2D &tex, unsigned level = 0);
126         void attach(FramebufferAttachment attch, Texture3D &tex, unsigned layer, unsigned level = 0);
127         void attach(FramebufferAttachment attch, TextureCube &tex, TextureCubeFace face, unsigned level = 0);
128         void detach(FramebufferAttachment attch);
129
130         /** Checks the completeness of the framebuffer.  Returns
131         FRAMEBUFFER_COMPLETE if the framebuffer is complete and can be rendered to,
132         or one of the error status codes otherwise. */
133         FramebufferStatus check_status() const;
134
135         /** Ensures that the framebuffer is complete, throwing an exception if it
136         isn't. */
137         void require_complete() const;
138
139         void viewport(int, int, unsigned, unsigned);
140         void reset_viewport();
141
142         void clear();
143         void clear(BufferBits);
144
145         /** Blits a region from another framebuffer into this one.  If the source
146         and destination regions have different dimensions, the contents will be
147         stretched.  If filter is true, linear interpolation will be used, otherwise
148         no interpolation is done. */
149         void blit_from(const Framebuffer &other, int sx0, int sy0, int sx1, int sy1,
150                 int dx0, int dy0, int dx1, int dy1, BufferBits bits, bool filter);
151
152         /** Blits a region from another framebuffer into this one, retaining its
153         dimensions. */
154         void blit_from(const Framebuffer & other, int sx, int sy,
155                 unsigned wd, unsigned ht, int dx, int dy, BufferBits bits);
156
157         /** Blits the entire contents of another framebuffer into this one. */
158         void blit_from(const Framebuffer &other, BufferBits bits, bool filter);
159
160         void bind() const;
161
162         static const Framebuffer *current();
163         static void unbind();
164
165         static Framebuffer &system();
166 };
167
168 inline BufferBits operator|(BufferBits a, BufferBits b)
169 { return static_cast<BufferBits>(static_cast<int>(a)|static_cast<int>(b)); }
170
171 } // namespace GL
172 } // namespace Msp
173
174 #endif