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