]> git.tdb.fi Git - libs/gl.git/blob - source/framebuffer.h
Remember the camera given to Renderer constructor
[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/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 public:
123         void attach(FramebufferAttachment attch, Renderbuffer &rbuf);
124         void attach(FramebufferAttachment attch, Texture2D &tex, unsigned level = 0);
125         void attach(FramebufferAttachment attch, Texture3D &tex, unsigned layer, unsigned level = 0);
126         void attach(FramebufferAttachment attch, TextureCube &tex, TextureCubeFace face, unsigned level = 0);
127         void detach(FramebufferAttachment attch);
128
129         /** Checks the completeness of the framebuffer.  Returns
130         FRAMEBUFFER_COMPLETE if the framebuffer is complete and can be rendered to,
131         or one of the error status codes otherwise. */
132         FramebufferStatus check_status() const;
133
134         /** Ensures that the framebuffer is complete, throwing an exception if it
135         isn't. */
136         void require_complete() const;
137
138         void viewport(int, int, unsigned, unsigned);
139         void reset_viewport();
140
141         void clear(BufferBits);
142
143         /** Blits a region from another framebuffer into this one.  If the source
144         and destination regions have different dimensions, the contents will be
145         stretched.  If filter is true, linear interpolation will be used, otherwise
146         no interpolation is done. */
147         void blit_from(const Framebuffer &other, int sx0, int sy0, int sx1, int sy1,
148                 int dx0, int dy0, int dx1, int dy1, BufferBits bits, bool filter);
149
150         /** Blits a region from another framebuffer into this one, retaining its
151         dimensions. */
152         void blit_from(const Framebuffer & other, int sx, int sy,
153                 unsigned wd, unsigned ht, int dx, int dy, BufferBits bits);
154
155         /** Blits the entire contents of another framebuffer into this one. */
156         void blit_from(const Framebuffer &other, BufferBits bits, bool filter);
157
158         void bind() const;
159
160         static const Framebuffer *current();
161         static void unbind();
162
163         static Framebuffer &system();
164 };
165
166 inline BufferBits operator|(BufferBits a, BufferBits b)
167 { return static_cast<BufferBits>(static_cast<int>(a)|static_cast<int>(b)); }
168
169 } // namespace GL
170 } // namespace Msp
171
172 #endif