Added methods to Framebuffer class to add externally created texture attachments and remove existing ones.

This commit is contained in:
Kai Blaschke
2023-09-09 15:45:07 +02:00
parent b05a8cc812
commit 561ea8cf8b
2 changed files with 117 additions and 13 deletions

View File

@ -87,8 +87,8 @@ bool Framebuffer::SetSize(int width, int height)
Bind(attachments.first);
for (auto& texture : attachments.second)
{
texture.second.SetSize(width, height);
glFramebufferTexture2D(GL_FRAMEBUFFER, texture.first, GL_TEXTURE_2D, texture.second.Texture()->TextureID(), 0);
texture.second->SetSize(width, height);
glFramebufferTexture2D(GL_FRAMEBUFFER, texture.first, GL_TEXTURE_2D, texture.second->Texture()->TextureID(), 0);
}
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
@ -96,6 +96,39 @@ bool Framebuffer::SetSize(int width, int height)
return true;
}
void Framebuffer::SetAttachment(int framebufferIndex, int attachmentIndex, const std::shared_ptr<TextureAttachment>& attachment)
{
if (!attachment)
{
return;
}
GLenum textureType;
Bind(framebufferIndex);
switch (attachment->Type())
{
case TextureAttachment::AttachmentType::Color:
textureType = GL_COLOR_ATTACHMENT0 + attachmentIndex;
break;
case TextureAttachment::AttachmentType::Depth:
textureType = GL_DEPTH_ATTACHMENT;
break;
case TextureAttachment::AttachmentType::Stencil:
textureType = GL_STENCIL_ATTACHMENT;
break;
case TextureAttachment::AttachmentType::DepthStencil:
textureType = GL_DEPTH_STENCIL_ATTACHMENT;
break;
}
m_attachments.at(framebufferIndex).insert({textureType, attachment});
if (m_width > 0 && m_height > 0)
{
glFramebufferTexture2D(GL_FRAMEBUFFER, textureType, GL_TEXTURE_2D, attachment->Texture()->TextureID(), 0);
}
UpdateDrawBuffers(framebufferIndex);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void Framebuffer::CreateColorAttachment(int framebufferIndex, int attachmentIndex)
{
CreateColorAttachment(framebufferIndex, attachmentIndex, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
@ -108,8 +141,8 @@ void Framebuffer::CreateColorAttachment(int framebufferIndex, int attachmentInde
return;
}
TextureAttachment textureAttachment{internalFormat, format, type, m_width, m_height };
const auto texture = textureAttachment.Texture();
auto textureAttachment = std::make_shared<TextureAttachment>(internalFormat, format, type, m_width, m_height);
const auto texture = textureAttachment->Texture();
m_attachments.at(framebufferIndex).insert({GL_COLOR_ATTACHMENT0 + attachmentIndex, std::move(textureAttachment)});
Bind(framebufferIndex);
@ -121,6 +154,11 @@ void Framebuffer::CreateColorAttachment(int framebufferIndex, int attachmentInde
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void Framebuffer::RemoveColorAttachment(int framebufferIndex, int attachmentIndex)
{
RemoveAttachment(framebufferIndex, GL_COLOR_ATTACHMENT0 + attachmentIndex);
}
auto Framebuffer::GetColorAttachmentTexture(int framebufferIndex, int attachmentIndex) const -> std::shared_ptr<class Texture>
{
if (framebufferIndex < 0 || framebufferIndex >= static_cast<int>(m_framebufferIds.size()))
@ -134,7 +172,7 @@ auto Framebuffer::GetColorAttachmentTexture(int framebufferIndex, int attachment
return {};
}
return attachment.at(GL_COLOR_ATTACHMENT0 + attachmentIndex).Texture();
return attachment.at(GL_COLOR_ATTACHMENT0 + attachmentIndex)->Texture();
}
void Framebuffer::CreateDepthAttachment(int framebufferIndex)
@ -144,8 +182,8 @@ void Framebuffer::CreateDepthAttachment(int framebufferIndex)
return;
}
TextureAttachment textureAttachment{TextureAttachment::AttachmentType::Depth, m_width, m_height};
const auto texture = textureAttachment.Texture();
auto textureAttachment = std::make_shared<TextureAttachment>(TextureAttachment::AttachmentType::Depth, m_width, m_height);
const auto texture = textureAttachment->Texture();
m_attachments.at(framebufferIndex).insert({GL_DEPTH_ATTACHMENT, std::move(textureAttachment)});
Bind(framebufferIndex);
@ -157,6 +195,11 @@ void Framebuffer::CreateDepthAttachment(int framebufferIndex)
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void Framebuffer::RemoveDepthAttachment(int framebufferIndex)
{
RemoveAttachment(framebufferIndex, GL_DEPTH_ATTACHMENT);
}
void Framebuffer::CreateStencilAttachment(int framebufferIndex)
{
if (framebufferIndex < 0 || framebufferIndex >= static_cast<int>(m_framebufferIds.size()))
@ -164,8 +207,8 @@ void Framebuffer::CreateStencilAttachment(int framebufferIndex)
return;
}
TextureAttachment textureAttachment{TextureAttachment::AttachmentType::Stencil, m_width, m_height};
const auto texture = textureAttachment.Texture();
auto textureAttachment = std::make_shared<TextureAttachment>(TextureAttachment::AttachmentType::Stencil, m_width, m_height);
const auto texture = textureAttachment->Texture();
m_attachments.at(framebufferIndex).insert({GL_STENCIL_ATTACHMENT, std::move(textureAttachment)});
Bind(framebufferIndex);
@ -177,6 +220,11 @@ void Framebuffer::CreateStencilAttachment(int framebufferIndex)
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void Framebuffer::RemoveStencilAttachment(int framebufferIndex)
{
RemoveAttachment(framebufferIndex, GL_STENCIL_ATTACHMENT);
}
void Framebuffer::CreateDepthStencilAttachment(int framebufferIndex)
{
if (framebufferIndex < 0 || framebufferIndex >= static_cast<int>(m_framebufferIds.size()))
@ -184,8 +232,8 @@ void Framebuffer::CreateDepthStencilAttachment(int framebufferIndex)
return;
}
TextureAttachment textureAttachment{TextureAttachment::AttachmentType::DepthStencil, m_width, m_height};
const auto texture = textureAttachment.Texture();
auto textureAttachment = std::make_shared<TextureAttachment>(TextureAttachment::AttachmentType::DepthStencil, m_width, m_height);
const auto texture = textureAttachment->Texture();
m_attachments.at(framebufferIndex).insert({GL_DEPTH_STENCIL_ATTACHMENT, std::move(textureAttachment)});
Bind(framebufferIndex);
@ -197,6 +245,11 @@ void Framebuffer::CreateDepthStencilAttachment(int framebufferIndex)
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void Framebuffer::RemoveDepthStencilAttachment(int framebufferIndex)
{
RemoveAttachment(framebufferIndex, GL_DEPTH_STENCIL_ATTACHMENT);
}
void Framebuffer::MaskDrawBuffer(int bufferIndex, bool masked)
{
// Invert the flag, as "true" means the color channel *will* be written.
@ -265,3 +318,12 @@ void Framebuffer::UpdateDrawBuffers(int framebufferIndex)
glDrawBuffers(static_cast<GLsizei>(buffers.size()), buffers.data());
}
void Framebuffer::RemoveAttachment(int framebufferIndex, GLenum attachmentType)
{
m_attachments.at(framebufferIndex).erase(attachmentType);
Bind(framebufferIndex);
glFramebufferTexture2D(GL_FRAMEBUFFER, attachmentType, GL_TEXTURE_2D, 0, 0);
UpdateDrawBuffers(framebufferIndex);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

View File

@ -93,11 +93,20 @@ public:
*/
bool SetSize(int width, int height);
/**
* @brief Sets a texture attachment slot to the given object.
* @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 index The index of the attachment, at least indices 0-7 are guaranteed to be available.
* @param attachmentIndex The index of the attachment, at least indices 0-7 are guaranteed to be available.
*/
void CreateColorAttachment(int framebufferIndex, int attachmentIndex);
@ -112,6 +121,13 @@ public:
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.
* @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.
@ -126,21 +142,40 @@ public:
*/
void CreateDepthAttachment(int framebufferIndex);
/**
* @brief Removes the depth attachment from the given framebuffer, if there is any assigned.
* @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.
* @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.
* @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.
*/
@ -154,7 +189,14 @@ private:
*/
void UpdateDrawBuffers(int framebufferIndex);
using AttachmentsPerSlot = std::map<GLenum, TextureAttachment>;
/**
* @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.