基类-帧缓冲纹理数据¶
并提供通过id来到纹理数据的方法
enum class FramebufferTextureFormat
{
None = 0,
// Color
RGBA8,
// Depth/stencil
DEPTH24STENCIL8,
// Defaults
Depth = DEPTH24STENCIL8
};
struct FramebufferTextureSpecification
{
FramebufferTextureSpecification() = default;
FramebufferTextureSpecification(FramebufferTextureFormat format)
: TextureFormat(format) {}
FramebufferTextureFormat TextureFormat = FramebufferTextureFormat::None;
// TODO: filtering/wrap
};
struct FramebufferAttachmentSpecification
{
FramebufferAttachmentSpecification() = default;
FramebufferAttachmentSpecification(std::initializer_list<FramebufferTextureSpecification> attachments)
: Attachments(attachments) {}
std::vector<FramebufferTextureSpecification> Attachments;
};
struct FramebufferSpecification
{
uint32_t Width = 0, Height = 0;
FramebufferAttachmentSpecification Attachments;
uint32_t Samples = 1;
bool SwapChainTarget = false;
};
virtual uint32_t GetColorAttachmentRendererID(uint32_t index = 0) const = 0;
Opengl的帧缓冲¶
virtual uint32_t GetColorAttachmentRendererID(uint32_t index = 0) const override { CORE_DEBUG_ASSERT(index < m_ColorAttachments.size()); return m_ColorAttachments[index]; }
private:
std::vector<FramebufferTextureSpecification> m_ColorAttachmentSpecifications;
FramebufferTextureSpecification m_DepthAttachmentSpecification = FramebufferTextureFormat::None;
std::vector<uint32_t> m_ColorAttachments;
uint32_t m_DepthAttachment = 0;
工具¶
纹理目标:多样本纹理(一般用于MSAA)\2D纹理 创建纹理: 绑定纹理: 附加颜色纹理: 附加深度纹理: 是否为深度格式
static const uint32_t s_MaxFramebufferSize = 8192;
namespace Utils {
static GLenum TextureTarget(bool multisampled)
{
return multisampled ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D;
}
static void CreateTextures(bool multisampled, uint32_t* outID, uint32_t count)
{
glCreateTextures(TextureTarget(multisampled), count, outID);
}
static void BindTexture(bool multisampled, uint32_t id)
{
glBindTexture(TextureTarget(multisampled), id);
}
static void AttachColorTexture(uint32_t id, int samples, GLenum format, uint32_t width, uint32_t height, int index)
{
bool multisampled = samples > 1;
if (multisampled)
{
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, format, width, height, GL_FALSE);
}
else
{
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + index, TextureTarget(multisampled), id, 0);
}
static void AttachDepthTexture(uint32_t id, int samples, GLenum format, GLenum attachmentType, uint32_t width, uint32_t height)
{
bool multisampled = samples > 1;
if (multisampled)
{
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, format, width, height, GL_FALSE);
}
else
{
glTexStorage2D(GL_TEXTURE_2D, 1, format, width, height);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
glFramebufferTexture2D(GL_FRAMEBUFFER, attachmentType, TextureTarget(multisampled), id, 0);
}
static bool IsDepthFormat(FramebufferTextureFormat format)
{
switch (format)
{
case FramebufferTextureFormat::DEPTH24STENCIL8: return true;
}
return false;
}
}
构造帧缓冲¶
不是深度纹理,加入到颜色规格数组中 是的话,规格就设置成当前深度纹理
OpenGLFramebuffer::OpenGLFramebuffer(const FramebufferSpecification& spec)
: m_Specification(spec)
{
for (auto spec : m_Specification.Attachments.Attachments)
{
if (!Utils::IsDepthFormat(spec.TextureFormat))
m_ColorAttachmentSpecifications.emplace_back(spec);
else
m_DepthAttachmentSpecification = spec;
}
Invalidate();
}
删除¶
一次性删除所有颜色渲染目标
glDeleteTextures(m_ColorAttachments.size(), m_ColorAttachments.data());
确保颜色附件不超过四个¶
//多颜色纹理
if (m_ColorAttachments.size() > 1)
{
CORE_DEBUG_ASSERT(m_ColorAttachments.size() <= 4);
GLenum buffers[4] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 };
glDrawBuffers(m_ColorAttachments.size(), buffers);
}
else if (m_ColorAttachments.empty())
{
// Only depth-pass
glDrawBuffer(GL_NONE);
}