275f516e8d4d3b22acca3393a48065cb5d5422fb
[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 "gl.h"
6 #include "texturecube.h"
7 #include <msp/gl/extensions/arb_geometry_shader4.h>
8 #include <msp/gl/extensions/ext_framebuffer_multisample.h>
9 #include <msp/gl/extensions/ext_framebuffer_object.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 class WindowView;
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
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         unsigned id;
94         std::vector<Attachment> attachments;
95         unsigned width;
96         unsigned height;
97         mutable FramebufferStatus status;
98         mutable unsigned dirty;
99
100         Framebuffer(unsigned);
101 public:
102         Framebuffer();
103         ~Framebuffer();
104
105         unsigned get_width() const { return width; }
106         unsigned get_height() const { return height; }
107
108 private:
109         void update() const;
110         void check_size();
111         unsigned get_attachment_index(FramebufferAttachment);
112         void set_texture_attachment(FramebufferAttachment, Texture &, unsigned, int);
113 public:
114         void attach(FramebufferAttachment attch, Renderbuffer &rbuf);
115         void attach(FramebufferAttachment attch, Texture2D &tex, unsigned level = 0);
116         void attach(FramebufferAttachment attch, Texture3D &tex, unsigned layer, unsigned level = 0);
117         void attach(FramebufferAttachment attch, TextureCube &tex, TextureCubeFace face, unsigned level = 0);
118         void attach_layered(FramebufferAttachment attch, Texture3D &tex, unsigned level = 0);
119         void attach_layered(FramebufferAttachment attch, TextureCube &tex, unsigned level = 0);
120         void detach(FramebufferAttachment attch);
121
122         void resize(const WindowView &);
123
124         /** Returns FRAMEBUFFER_COMPLETE if the framebuffer is complete and can be
125         rendered to, or one of the error status codes otherwise. */
126         FramebufferStatus get_status() const { return status; }
127
128         /** Ensures that the framebuffer is complete, throwing an exception if it
129         isn't. */
130         void require_complete() const;
131
132         void refresh() const { if(dirty) update(); }
133
134         unsigned get_id() const { return id; }
135
136         void set_debug_name(const std::string &);
137
138         static Framebuffer &system();
139 };
140
141 inline BufferBits operator|(BufferBits a, BufferBits b)
142 { return static_cast<BufferBits>(static_cast<int>(a)|static_cast<int>(b)); }
143
144 } // namespace GL
145 } // namespace Msp
146
147 #endif