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