]> git.tdb.fi Git - libs/gl.git/blob - source/framebuffer.h
Add a function to require the completeness of a framebuffer
[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
9 namespace Msp {
10 namespace GL {
11
12 class Renderbuffer;
13 class Texture;
14 class Texture2D;
15
16 enum FramebufferAttachment
17 {
18         COLOR_ATTACHMENT0  = GL_COLOR_ATTACHMENT0,
19         COLOR_ATTACHMENT1  = GL_COLOR_ATTACHMENT1,
20         COLOR_ATTACHMENT2  = GL_COLOR_ATTACHMENT2,
21         COLOR_ATTACHMENT3  = GL_COLOR_ATTACHMENT3,
22         DEPTH_ATTACHMENT   = GL_DEPTH_ATTACHMENT,
23         STENCIL_ATTACHMENT = GL_STENCIL_ATTACHMENT
24 };
25
26 enum FramebufferStatus
27 {
28         FRAMEBUFFER_INCOMPLETE_ATTACHMENT         = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
29         FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT,
30         FRAMEBUFFER_INCOMPLETE_DIMENSIONS         = GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT,
31         FRAMEBUFFER_INCOMPLETE_FORMATS            = GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT,
32         FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER        = GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER,
33         FRAMEBUFFER_INCOMPLETE_READ_BUFFER        = GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER,
34         FRAMEBUFFER_UNSUPPORTED                   = GL_FRAMEBUFFER_UNSUPPORTED,
35         FRAMEBUFFER_COMPLETE                      = GL_FRAMEBUFFER_COMPLETE
36 };
37
38 enum BufferBits
39 {
40         COLOR_BUFFER_BIT   = GL_COLOR_BUFFER_BIT,
41         DEPTH_BUFFER_BIT   = GL_DEPTH_BUFFER_BIT,
42         STENCIL_BUFFER_BIT = GL_STENCIL_BUFFER_BIT,
43         ACCUM_BUFFER_BIT   = GL_ACCUM_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         unsigned id;
101         std::vector<Attachment> attachments;
102         unsigned width;
103         unsigned height;
104         mutable unsigned dirty;
105
106         Framebuffer(unsigned);
107 public:
108         Framebuffer();
109         ~Framebuffer();
110
111         unsigned get_width() const { return width; }
112         unsigned get_height() const { return height; }
113
114 private:
115         void update_attachment(unsigned) const;
116         void check_size();
117         unsigned get_attachment_index(FramebufferAttachment);
118 public:
119         void attach(FramebufferAttachment attch, Renderbuffer &rbuf);
120         void attach(FramebufferAttachment attch, Texture2D &tex, unsigned level = 0);
121         void attach(FramebufferAttachment attch, TextureCube &tex, TextureCubeFace face, unsigned level = 0);
122         void detach(FramebufferAttachment attch);
123
124         /** Checks the completeness of the framebuffer.  Returns
125         FRAMEBUFFER_COMPLETE if the framebuffer is complete and can be rendered to,
126         or one of the error status codes otherwise. */
127         FramebufferStatus check_status() const;
128
129         /** Ensures that the framebuffer is complete, throwing an exception if it
130         isn't. */
131         void require_complete() const;
132
133         void clear(BufferBits);
134
135         /** Blits a region from another framebuffer into this one.  If the source
136         and destination regions have different dimensions, the contents will be
137         stretched.  If filter is true, linear interpolation will be used, otherwise
138         no interpolation is done. */
139         void blit_from(const Framebuffer &other, int sx0, int sy0, int sx1, int sy1,
140                 int dx0, int dy0, int dx1, int dy1, BufferBits bits, bool filter);
141
142         /** Blits a region from another framebuffer into this one, retaining its
143         dimensions. */
144         void blit_from(const Framebuffer & other, int sx, int sy,
145                 unsigned wd, unsigned ht, int dx, int dy, BufferBits bits);
146
147         /** Blits the entire contents of another framebuffer into this one. */
148         void blit_from(const Framebuffer &other, BufferBits bits, bool filter);
149
150         void bind() const;
151
152         static const Framebuffer *current();
153         static void unbind();
154
155         static Framebuffer &system();
156 };
157
158 inline BufferBits operator|(BufferBits a, BufferBits b)
159 { return static_cast<BufferBits>(static_cast<int>(a)|static_cast<int>(b)); }
160
161 } // namespace GL
162 } // namespace Msp
163
164 #endif