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