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