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