]> git.tdb.fi Git - libs/gl.git/blob - source/core/framebuffer.h
Remove RenderBuffer and always use textures as framebuffer attachments
[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 Texture;
16 class Texture2D;
17 class Texture2DMultisample;
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.  Textures can be attached to the logical buffers.  At least one image
67 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                 Texture *tex;
79                 unsigned level;
80                 int layer;
81
82                 Attachment(FramebufferAttachment);
83                 void set(Texture &, unsigned, int);
84                 void clear();
85         };
86
87         unsigned id;
88         std::vector<Attachment> attachments;
89         unsigned width;
90         unsigned height;
91         mutable FramebufferStatus status;
92         mutable unsigned dirty;
93
94         Framebuffer(unsigned);
95 public:
96         Framebuffer();
97         ~Framebuffer();
98
99         unsigned get_width() const { return width; }
100         unsigned get_height() const { return height; }
101
102 private:
103         void update() const;
104         void check_size();
105         unsigned get_attachment_index(FramebufferAttachment);
106         void set_attachment(FramebufferAttachment, Texture &, unsigned, int);
107 public:
108         void attach(FramebufferAttachment attch, Texture2D &tex, unsigned level = 0);
109         void attach(FramebufferAttachment attch, Texture2DMultisample &tex);
110         void attach(FramebufferAttachment attch, Texture3D &tex, unsigned layer, unsigned level = 0);
111         void attach(FramebufferAttachment attch, TextureCube &tex, TextureCubeFace face, unsigned level = 0);
112         void attach_layered(FramebufferAttachment attch, Texture3D &tex, unsigned level = 0);
113         void attach_layered(FramebufferAttachment attch, TextureCube &tex, unsigned level = 0);
114         void detach(FramebufferAttachment attch);
115
116         void resize(const WindowView &);
117
118         /** Returns FRAMEBUFFER_COMPLETE if the framebuffer is complete and can be
119         rendered to, or one of the error status codes otherwise. */
120         FramebufferStatus get_status() const { return status; }
121
122         /** Ensures that the framebuffer is complete, throwing an exception if it
123         isn't. */
124         void require_complete() const;
125
126         void refresh() const { if(dirty) update(); }
127
128         unsigned get_id() const { return id; }
129
130         void set_debug_name(const std::string &);
131
132         static Framebuffer &system();
133 };
134
135 inline BufferBits operator|(BufferBits a, BufferBits b)
136 { return static_cast<BufferBits>(static_cast<int>(a)|static_cast<int>(b)); }
137
138 } // namespace GL
139 } // namespace Msp
140
141 #endif