]> git.tdb.fi Git - libs/gl.git/blob - source/core/framebuffer.h
Don't use an index when attaching lights
[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 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();
142         void clear(BufferBits);
143
144         /** Blits a region from another framebuffer into this one.  If the source
145         and destination regions have different dimensions, the contents will be
146         stretched.  If filter is true, linear interpolation will be used, otherwise
147         no interpolation is done. */
148         void blit_from(const Framebuffer &other, int sx0, int sy0, int sx1, int sy1,
149                 int dx0, int dy0, int dx1, int dy1, BufferBits bits, bool filter);
150
151         /** Blits a region from another framebuffer into this one, retaining its
152         dimensions. */
153         void blit_from(const Framebuffer & other, int sx, int sy,
154                 unsigned wd, unsigned ht, int dx, int dy, BufferBits bits);
155
156         /** Blits the entire contents of another framebuffer into this one. */
157         void blit_from(const Framebuffer &other, BufferBits bits, bool filter);
158
159         void bind() const;
160
161         static const Framebuffer *current();
162         static void unbind();
163
164         static Framebuffer &system();
165 };
166
167 inline BufferBits operator|(BufferBits a, BufferBits b)
168 { return static_cast<BufferBits>(static_cast<int>(a)|static_cast<int>(b)); }
169
170 } // namespace GL
171 } // namespace Msp
172
173 #endif