]> git.tdb.fi Git - libs/gl.git/blob - source/core/framebuffer.h
Add debug name capability to more classes
[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                 int layer;
86
87                 Attachment(FramebufferAttachment);
88                 void set(Renderbuffer &);
89                 void set(Texture &, unsigned, int);
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         void set_texture_attachment(FramebufferAttachment, Texture &, unsigned, int);
123 public:
124         void attach(FramebufferAttachment attch, Renderbuffer &rbuf);
125         void attach(FramebufferAttachment attch, Texture2D &tex, unsigned level = 0);
126         void attach(FramebufferAttachment attch, Texture3D &tex, unsigned layer, unsigned level = 0);
127         void attach(FramebufferAttachment attch, TextureCube &tex, TextureCubeFace face, unsigned level = 0);
128         void attach_layered(FramebufferAttachment attch, Texture3D &tex, unsigned level = 0);
129         void attach_layered(FramebufferAttachment attch, TextureCube &tex, unsigned level = 0);
130         void detach(FramebufferAttachment attch);
131
132         /** Checks the completeness of the framebuffer.  Returns
133         FRAMEBUFFER_COMPLETE if the framebuffer is complete and can be rendered to,
134         or one of the error status codes otherwise. */
135         FramebufferStatus check_status() const;
136
137         /** Ensures that the framebuffer is complete, throwing an exception if it
138         isn't. */
139         void require_complete() const;
140
141         void viewport(int, int, unsigned, unsigned);
142         void reset_viewport();
143
144         void clear();
145         void clear(BufferBits);
146
147         /** Blits a region from another framebuffer into this one.  If the source
148         and destination regions have different dimensions, the contents will be
149         stretched.  If filter is true, linear interpolation will be used, otherwise
150         no interpolation is done. */
151         void blit_from(const Framebuffer &other, int sx0, int sy0, int sx1, int sy1,
152                 int dx0, int dy0, int dx1, int dy1, BufferBits bits, bool filter);
153
154         /** Blits a region from another framebuffer into this one, retaining its
155         dimensions. */
156         void blit_from(const Framebuffer & other, int sx, int sy,
157                 unsigned wd, unsigned ht, int dx, int dy, BufferBits bits);
158
159         /** Blits the entire contents of another framebuffer into this one. */
160         void blit_from(const Framebuffer &other, BufferBits bits, bool filter);
161
162         void bind() const;
163
164         static const Framebuffer *current();
165         static void unbind();
166
167         void set_debug_name(const std::string &);
168
169         static Framebuffer &system();
170 };
171
172 inline BufferBits operator|(BufferBits a, BufferBits b)
173 { return static_cast<BufferBits>(static_cast<int>(a)|static_cast<int>(b)); }
174
175 } // namespace GL
176 } // namespace Msp
177
178 #endif