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