]> git.tdb.fi Git - libs/gl.git/blob - source/core/framebuffer.h
2f867e6c591ec69706df22fc2a90bbeef52575f8
[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 "frameformat.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 Texture;
17 class Texture2D;
18 class Texture2DMultisample;
19 class Texture3D;
20 class WindowView;
21
22 enum FramebufferStatus
23 {
24         FRAMEBUFFER_INCOMPLETE_ATTACHMENT         = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
25         FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT,
26         FRAMEBUFFER_INCOMPLETE_DIMENSIONS         = GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT,
27         FRAMEBUFFER_INCOMPLETE_FORMATS            = GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT,
28         FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER        = GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER,
29         FRAMEBUFFER_INCOMPLETE_READ_BUFFER        = GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER,
30         FRAMEBUFFER_INCOMPLETE_MULTISAMPLE        = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
31         FRAMEBUFFER_INCOMPLETE_LAYER_COUNT        = GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB,
32         FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS      = GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS,
33         FRAMEBUFFER_UNSUPPORTED                   = GL_FRAMEBUFFER_UNSUPPORTED,
34         FRAMEBUFFER_COMPLETE                      = GL_FRAMEBUFFER_COMPLETE
35 };
36
37 enum BufferBits
38 {
39         COLOR_BUFFER_BIT   = GL_COLOR_BUFFER_BIT,
40         DEPTH_BUFFER_BIT   = GL_DEPTH_BUFFER_BIT,
41         STENCIL_BUFFER_BIT = GL_STENCIL_BUFFER_BIT
42 };
43
44 class framebuffer_incomplete: public std::runtime_error
45 {
46 public:
47         framebuffer_incomplete(FramebufferStatus);
48         virtual ~framebuffer_incomplete() throw() { }
49 };
50
51 /**
52 Framebuffer objects can be used to perform offscreen rendering.  The most
53 common application is rendering to a texture, which can then be used for
54 fullscreen shader effects.
55
56 A framebuffer consist of a number of logical buffers, such as color and depth
57 buffers.  Textures can be attached to the logical buffers.  At least one image
58 must be attached for the framebuffer to be usable.
59
60 Requires the GL_EXT_framebuffer_object extension.  The blit functions require
61 the GL_EXT_framebuffer_blit extension.
62 */
63 class Framebuffer
64 {
65         friend class Commands;
66         friend class PipelineState;
67
68 private:
69         struct Attachment
70         {
71                 Texture *tex;
72                 unsigned level;
73                 int layer;
74
75                 Attachment();
76                 void set(Texture &, unsigned, int);
77                 void clear();
78         };
79
80         unsigned id;
81         FrameFormat format;
82         std::vector<Attachment> attachments;
83         unsigned width;
84         unsigned height;
85         mutable FramebufferStatus status;
86         mutable unsigned dirty;
87
88         Framebuffer(unsigned);
89 public:
90         /** Creates an empty framebuffer.  Format must be set before textures can
91         be attached. */
92         Framebuffer();
93
94         /** Creates a framebuffer and sets its format to a single attachment. */
95         Framebuffer(FrameAttachment);
96
97         /** Creates a framebuffer and sets its format. */
98         Framebuffer(const FrameFormat &);
99
100 private:
101         void init();
102 public:
103         ~Framebuffer();
104
105         /** Sets the format of the framebuffer.  Once the format is set, it can't
106         be changed. */
107         void set_format(const FrameFormat &);
108
109         const FrameFormat &get_format() const { return format; }
110
111         unsigned get_width() const { return width; }
112         unsigned get_height() const { return height; }
113
114 private:
115         void update() const;
116         void check_size();
117         void set_attachment(FrameAttachment, Texture &, unsigned, int, unsigned);
118 public:
119
120         /** Attaches a texture to the framebuffer.  Only the attachment point
121         portion of attch is considered; pixel format is ignored.  The framebuffer
122         must have a format and the format of the texture must match that defined
123         in the framebuffer for this attachment point. */
124         void attach(FrameAttachment attch, Texture2D &tex, unsigned level = 0);
125
126         void attach(FrameAttachment attch, Texture2DMultisample &tex);
127         void attach(FrameAttachment attch, Texture3D &tex, unsigned layer, unsigned level = 0);
128         void attach(FrameAttachment attch, TextureCube &tex, TextureCubeFace face, unsigned level = 0);
129         void attach_layered(FrameAttachment attch, Texture3D &tex, unsigned level = 0);
130         void attach_layered(FrameAttachment attch, TextureCube &tex, unsigned level = 0);
131         void detach(FrameAttachment attch);
132
133         void resize(const WindowView &);
134
135         /** Returns FRAMEBUFFER_COMPLETE if the framebuffer is complete and can be
136         rendered to, or one of the error status codes otherwise. */
137         FramebufferStatus get_status() const { return status; }
138
139         /** Ensures that the framebuffer is complete, throwing an exception if it
140         isn't. */
141         void require_complete() const;
142
143         void refresh() const { if(dirty) update(); }
144
145         void set_debug_name(const std::string &);
146
147         static Framebuffer &system();
148 };
149
150 inline BufferBits operator|(BufferBits a, BufferBits b)
151 { return static_cast<BufferBits>(static_cast<int>(a)|static_cast<int>(b)); }
152
153 } // namespace GL
154 } // namespace Msp
155
156 #endif