-
-
Notifications
You must be signed in to change notification settings - Fork 455
Expand file tree
/
Copy pathFramebuffer.hpp
More file actions
258 lines (224 loc) · 10.3 KB
/
Framebuffer.hpp
File metadata and controls
258 lines (224 loc) · 10.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
/**
* @file Framebuffer.hpp
* @brief Defines a class to hold one or more render framebuffers.
*/
#pragma once
#include "Renderer/TextureAttachment.hpp"
#include <map>
#include <vector>
namespace libprojectM {
namespace Renderer {
/**
* @brief A framebuffer class holding one or more framebuffer objects.
*
* <p>Framebuffers act as both render targets and sampling sources. This class holds one or more of those
* objects, either used to store current and previous frame images or sub images for multi-stage
* rendering.</p>
*
* <p>Each framebuffer can have multiple color attachments (at least up to 8), one depth buffer,
* one stencil buffer and one depth stencil buffer.</p>
*
* <p>All framebuffers and their attachments will share the same size.</p>
*
* <p>Draw buffers will be configured in this order for each framebuffer:</p>
*
* <ol>
* <li>Color attachments in ascending order</li>
* <li>Depth</li>
* <li>Stencil</li>
* <li>Depth Stencil</li>
* </ol>
*/
class Framebuffer
{
public:
/**
* @brief Creates a new framebuffer object with one framebuffer.
*/
Framebuffer();
/**
* @brief Creates a new framebuffer object with a given number of framebuffers.
* @param framebufferCount The number of framebuffers to create. Must be at least 1.
*/
explicit Framebuffer(int framebufferCount);
/**
* @brief Destroys the framebuffer object and all attachments.
*/
~Framebuffer();
/**
* @brief Returns the number of framebuffers in this object.
* @return The number of framebuffers in this object.
*/
int Count() const;
/**
* @brief Binds the given index as the current read/write framebuffer.
* @param framebufferIndex The framebuffer index.
*/
void Bind(int framebufferIndex);
/**
* @brief Binds the given index as the current read framebuffer.
* @param framebufferIndex The framebuffer index.
*/
void BindRead(int framebufferIndex);
/**
* @brief Binds the given index as the current write/draw framebuffer.
* @param framebufferIndex The framebuffer index.
*/
void BindDraw(int framebufferIndex);
/**
* @brief Binds the default framebuffer for both reading and writing.
*
* When using libprojectM inside a shared OpenGL context,
* the default framebuffer may not be FBO 0. Use the overloaded version with the
* actual default FBO ID in such cases.
*/
static void Unbind();
/**
* @brief Binds the given framebuffer ID as the current read/write framebuffer.
*
* This overload should be used when the host application's default framebuffer
* object is not 0.
*
* @param defaultFramebufferObject The framebuffer ID to bind.
*/
static void Unbind(GLuint defaultFramebufferObject);
/**
* @brief Sets the framebuffer texture size.
*
* This will bind the framebuffers and reallocate all attachment textures, creating new
* textures with the given size. The default framebuffer is bound after the call is finished.
* If either width or height is zero or both equal the the current size, the framebuffer contents
* won't be changed.
* @param width The width of the framebuffer.
* @param height The height of the framebuffer.
* @return true if the framebuffer was resized, false if it's contents remain unchanged.
*/
auto SetSize(int width, int height) -> bool;
/**
* Returns the width in pixels of the framebuffer.
* @return The horizontal resolution.
*/
auto Width() const -> int;
/**
* Returns the height in pixels of the framebuffer.
* @return the vertical resolution.
*/
auto Height() const -> int;
/**
* @brief Returns a texture attachment object.
* @param framebufferIndex The framebuffer index.
* @param type The attachment type to retrieve.
* @param attachmentIndex The index of the color attachment, at least indices 0-7 are guaranteed
* to be available. Ignored for non-color attachments.
* @return The requested attachment or nullptr if there is no attachment in the requested slot.
*/
auto GetAttachment(int framebufferIndex, TextureAttachment::AttachmentType type, int attachmentIndex = 0) const -> std::shared_ptr<TextureAttachment>;
/**
* @brief Sets a texture attachment slot to the given object.
* Sets the read/write FBOs to the previously used ones in this instance. If a different
* Framebuffer instance was used to read or draw, it must be bound again explicitly after this call.
* @param framebufferIndex The framebuffer index.
* @param attachmentIndex The index of the color attachment, at least indices 0-7 are guaranteed
* to be available. Ignored for non-color attachments.
* @param attachment The attachment to add to the framebuffer.
*/
void SetAttachment(int framebufferIndex, int attachmentIndex, const std::shared_ptr<TextureAttachment>& attachment);
/**
* @brief Adds a new color attachment to the framebuffer.
* The texture is always created in RGBA format.
* @param framebufferIndex The framebuffer index.
* @param attachmentIndex The index of the attachment, at least indices 0-7 are guaranteed to be available.
*/
void CreateColorAttachment(int framebufferIndex, int attachmentIndex);
/**
* @brief Adds a new color attachment to the framebuffer with the specified format.
* @param framebufferIndex The framebuffer index.
* @param index The index of the attachment, at least indices 0-7 are guaranteed to be available.
* @param internalFormat OpenGL internal format, e.g. GL_RGBA8
* @param format OpenGL color format, e.g. GL_RGBA
* @param type OpenGL component storage type, e.g. GL_UNSIGNED _BYTE
*/
void CreateColorAttachment(int framebufferIndex, int attachmentIndex,
GLint internalFormat, GLenum format, GLenum type);
/**
* Removes the color attachment from the given slot, if there is any assigned.
* Sets the read/write FBOs to the previously used ones in this instance. If a different
* Framebuffer instance was used to read or draw, it must be bound again explicitly after this call.
* @param framebufferIndex The framebuffer index.
* @param attachmentIndex The index of the attachment to remove, at least indices 0-7 are guaranteed to be available.
*/
void RemoveColorAttachment(int framebufferIndex, int attachmentIndex);
/**
* @brief Returns the texture ID of the given framebuffer and color attachment.
* @param framebufferIndex The framebuffer index.
* @param attachmentIndex The index of the attachment to return the texture for.
* @return A shared pointer to the texture or nullptr if no texture is assigned.
*/
auto GetColorAttachmentTexture(int framebufferIndex, int attachmentIndex) const -> std::shared_ptr<class Texture>;
/**
* @brief Adds a depth attachment to the framebuffer.
* @param framebufferIndex The framebuffer index.
*/
void CreateDepthAttachment(int framebufferIndex);
/**
* @brief Removes the depth attachment from the given framebuffer, if there is any assigned.
* Sets the read/write FBOs to the previously used ones in this instance. If a different
* Framebuffer instance was used to read or draw, it must be bound again explicitly after this call.
* @param framebufferIndex The framebuffer index.
*/
void RemoveDepthAttachment(int framebufferIndex);
/**
* @brief Adds a stencil buffer attachment to the framebuffer.
* @param framebufferIndex The framebuffer index.
*/
void CreateStencilAttachment(int framebufferIndex);
/**
* @brief Removes the stencil attachment from the given framebuffer, if there is any assigned.
* Sets the read/write FBOs to the previously used ones in this instance. If a different
* Framebuffer instance was used to read or draw, it must be bound again explicitly after this call.
* @param framebufferIndex The framebuffer index.
*/
void RemoveStencilAttachment(int framebufferIndex);
/**
* @brief Adds a depth stencil buffer attachment to the framebuffer.
* @param framebufferIndex The framebuffer index.
*/
void CreateDepthStencilAttachment(int framebufferIndex);
/**
* @brief Removes the depth stencil attachment from the given framebuffer, if there is any assigned.
* Sets the read/write FBOs to the previously used ones in this instance. If a different
* Framebuffer instance was used to read or draw, it must be bound again explicitly after this call.
* @param framebufferIndex The framebuffer index.
*/
void RemoveDepthStencilAttachment(int framebufferIndex);
/**
* @brief Sets the masked flag for a specific draw buffer.
* This can be used to enable or disable rendering to specific color attachments.
* With GLES 3.1 and lower, this will always mask all buffers.
* @param bufferIndex The index of the buffer to set the mask flag on.
* @param masked true if the attachment should be masked, false if not.
*/
void MaskDrawBuffer(int bufferIndex, bool masked);
private:
/**
* @brief Updates the draw buffer list for the fragment shader outputs of the given framebuffer.
* Note that when calling this function, the framebuffer must already be bound.
* @param framebufferIndex The framebuffer index.
*/
void UpdateDrawBuffers(int framebufferIndex);
/**
* @brief Removes the given attachment type from the framebuffer.
* @param framebufferIndex The framebuffer index.
* @param attachmentType The attachment type to remove.
*/
void RemoveAttachment(int framebufferIndex, GLenum attachmentType);
using AttachmentsPerSlot = std::map<GLenum, std::shared_ptr<TextureAttachment>>;
std::vector<unsigned int> m_framebufferIds{}; //!< The framebuffer IDs returned by OpenGL
std::map<int, AttachmentsPerSlot> m_attachments; //!< Framebuffer texture attachments.
int m_width{}; //!< Framebuffers texture width
int m_height{}; //!< Framebuffers texture height.
int m_readFramebuffer{}; //!< Index of the framebuffer currently being read.
int m_drawFramebuffer{}; //!< Index of the framebuffer currently being drawn to.
};
} // namespace Renderer
} // namespace libprojectM