Asset+Render: Add Framebuffers
This commit is contained in:
@@ -36,6 +36,7 @@ public:
|
|||||||
virtual bool isTexture() const { return false; }
|
virtual bool isTexture() const { return false; }
|
||||||
virtual bool isTexture2D() const { return false; }
|
virtual bool isTexture2D() const { return false; }
|
||||||
virtual bool isTextureCubemap() const { return false; }
|
virtual bool isTextureCubemap() const { return false; }
|
||||||
|
virtual bool isTextureFramebuffer() const { return false; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Asset(std::string_view path)
|
Asset(std::string_view path)
|
||||||
|
|||||||
@@ -24,12 +24,20 @@ Texture::~Texture()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Texture::init(uint32_t width, uint32_t height, uint8_t channels)
|
void Texture::init(uint32_t width, uint32_t height, uint8_t channels)
|
||||||
|
{
|
||||||
|
init(width, height,
|
||||||
|
(channels == 3) ? GL_RGB8 : GL_RGBA8,
|
||||||
|
(channels == 3) ? GL_RGB : GL_RGBA,
|
||||||
|
GL_UNSIGNED_BYTE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Texture::init(uint32_t width, uint32_t height, uint32_t internalFormat, uint32_t dataFormat, uint32_t dataType)
|
||||||
{
|
{
|
||||||
m_width = width;
|
m_width = width;
|
||||||
m_height = height;
|
m_height = height;
|
||||||
|
m_internalFormat = internalFormat;
|
||||||
m_internalFormat = (channels == 3) ? GL_RGB8 : GL_RGBA8;
|
m_dataFormat = dataFormat;
|
||||||
m_dataFormat = (channels == 3) ? GL_RGB : GL_RGBA;
|
m_dataType = dataType;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
@@ -49,7 +57,7 @@ std::shared_ptr<Texture2D> Texture2D::create(std::string_view path)
|
|||||||
VERIFY(data, "failed to load image: '{}'", path);
|
VERIFY(data, "failed to load image: '{}'", path);
|
||||||
|
|
||||||
result->init(width, height, channels);
|
result->init(width, height, channels);
|
||||||
result->create(data);
|
result->createImpl(data);
|
||||||
|
|
||||||
// Clean resources
|
// Clean resources
|
||||||
stbi_image_free(data);
|
stbi_image_free(data);
|
||||||
@@ -78,7 +86,7 @@ std::shared_ptr<Texture2D> Texture2D::create(aiTexture* texture)
|
|||||||
}
|
}
|
||||||
|
|
||||||
result->init(width, height, channels);
|
result->init(width, height, channels);
|
||||||
result->create(data);
|
result->createImpl(data);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -99,7 +107,7 @@ void Texture2D::unbind() const
|
|||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture2D::create(unsigned char* data)
|
void Texture2D::createImpl(unsigned char* data)
|
||||||
{
|
{
|
||||||
m_id = UINT_MAX;
|
m_id = UINT_MAX;
|
||||||
|
|
||||||
@@ -121,7 +129,7 @@ void Texture2D::create(unsigned char* data)
|
|||||||
m_width, m_height, // Image width/height
|
m_width, m_height, // Image width/height
|
||||||
0, // Always 0 (legacy)
|
0, // Always 0 (legacy)
|
||||||
m_dataFormat, // Texture source format
|
m_dataFormat, // Texture source format
|
||||||
GL_UNSIGNED_BYTE, // Texture source datatype
|
m_dataType, // Texture source datatype
|
||||||
data); // Image data
|
data); // Image data
|
||||||
|
|
||||||
// Set the texture wrapping / filtering options
|
// Set the texture wrapping / filtering options
|
||||||
@@ -143,7 +151,7 @@ std::shared_ptr<TextureCubemap> TextureCubemap::create(std::string_view path)
|
|||||||
{
|
{
|
||||||
auto result = std::shared_ptr<TextureCubemap>(new TextureCubemap(path));
|
auto result = std::shared_ptr<TextureCubemap>(new TextureCubemap(path));
|
||||||
|
|
||||||
result->create();
|
result->createImpl();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -164,7 +172,7 @@ void TextureCubemap::unbind() const
|
|||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCubemap::create()
|
void TextureCubemap::createImpl()
|
||||||
{
|
{
|
||||||
m_id = UINT_MAX;
|
m_id = UINT_MAX;
|
||||||
|
|
||||||
@@ -206,7 +214,7 @@ void TextureCubemap::create()
|
|||||||
m_width, m_height, // Image width/height
|
m_width, m_height, // Image width/height
|
||||||
0, // Always 0 (legacy)
|
0, // Always 0 (legacy)
|
||||||
m_dataFormat, // Texture source format
|
m_dataFormat, // Texture source format
|
||||||
GL_UNSIGNED_BYTE, // Texture source datatype
|
m_dataType, // Texture source datatype
|
||||||
data); // Image data
|
data); // Image data
|
||||||
|
|
||||||
// Clean resources
|
// Clean resources
|
||||||
@@ -224,4 +232,44 @@ void TextureCubemap::create()
|
|||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------
|
||||||
|
|
||||||
|
std::shared_ptr<TextureFramebuffer> TextureFramebuffer::create(uint32_t width, uint32_t height, uint32_t internalFormat, uint32_t dataFormat, uint32_t dataType)
|
||||||
|
{
|
||||||
|
auto result = std::shared_ptr<TextureFramebuffer>(new TextureFramebuffer(""));
|
||||||
|
|
||||||
|
result->init(width, height, internalFormat, dataFormat, dataType);
|
||||||
|
result->createImpl();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextureFramebuffer::createImpl()
|
||||||
|
{
|
||||||
|
m_id = UINT_MAX;
|
||||||
|
|
||||||
|
// Create texture object
|
||||||
|
glGenTextures(1, &m_id);
|
||||||
|
|
||||||
|
// Bind texture object
|
||||||
|
glBindTexture(GL_TEXTURE_2D, m_id);
|
||||||
|
|
||||||
|
// Generate texture
|
||||||
|
glTexImage2D(
|
||||||
|
GL_TEXTURE_2D, // Texture target
|
||||||
|
0, // Midmap level, base starts at level 0
|
||||||
|
m_internalFormat, // Texture format
|
||||||
|
m_width, m_height, // Image width/height
|
||||||
|
0, // Always 0 (legacy)
|
||||||
|
m_dataFormat, // Texture source format
|
||||||
|
m_dataType, // Texture source datatype
|
||||||
|
NULL); // Image data
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
|
// Unbind texture object
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Inferno
|
} // namespace Inferno
|
||||||
|
|||||||
+38
-12
@@ -10,20 +10,20 @@
|
|||||||
#include <memory> // std::shared_ptr
|
#include <memory> // std::shared_ptr
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
|
#include "glad/glad.h"
|
||||||
|
|
||||||
#include "inferno/asset/asset-manager.h"
|
#include "inferno/asset/asset-manager.h"
|
||||||
|
|
||||||
struct aiTexture;
|
struct aiTexture;
|
||||||
|
|
||||||
namespace Inferno {
|
namespace Inferno {
|
||||||
|
|
||||||
class Texture2D;
|
|
||||||
class TextureCubemap;
|
|
||||||
|
|
||||||
class Texture : public Asset {
|
class Texture : public Asset {
|
||||||
public:
|
public:
|
||||||
virtual ~Texture();
|
virtual ~Texture();
|
||||||
|
|
||||||
void init(uint32_t width, uint32_t height, uint8_t channels);
|
void init(uint32_t width, uint32_t height, uint8_t channels);
|
||||||
|
void init(uint32_t width, uint32_t height, uint32_t internalFormat, uint32_t dataFormat, uint32_t dataType);
|
||||||
|
|
||||||
virtual void bind(uint32_t unit = 0) const = 0;
|
virtual void bind(uint32_t unit = 0) const = 0;
|
||||||
virtual void unbind() const = 0;
|
virtual void unbind() const = 0;
|
||||||
@@ -33,12 +33,11 @@ public:
|
|||||||
uint32_t id() const { return m_id; }
|
uint32_t id() const { return m_id; }
|
||||||
uint32_t internalFormat() const { return m_internalFormat; }
|
uint32_t internalFormat() const { return m_internalFormat; }
|
||||||
uint32_t dataFormat() const { return m_dataFormat; }
|
uint32_t dataFormat() const { return m_dataFormat; }
|
||||||
|
uint32_t dataType() const { return m_dataType; }
|
||||||
|
|
||||||
virtual bool is2D() const { return false; }
|
virtual bool isTexture2D() const override { return false; }
|
||||||
virtual bool isCubemap() const { return false; }
|
virtual bool isTextureCubemap() const override { return false; }
|
||||||
|
virtual bool isTextureFramebuffer() const override { return false; }
|
||||||
friend Texture2D;
|
|
||||||
friend TextureCubemap;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Texture(std::string_view path)
|
Texture(std::string_view path)
|
||||||
@@ -52,6 +51,7 @@ protected:
|
|||||||
uint32_t m_id { 0 };
|
uint32_t m_id { 0 };
|
||||||
uint32_t m_internalFormat { 0 };
|
uint32_t m_internalFormat { 0 };
|
||||||
uint32_t m_dataFormat { 0 };
|
uint32_t m_dataFormat { 0 };
|
||||||
|
uint32_t m_dataType { GL_UNSIGNED_BYTE };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual bool isTexture() const override { return true; }
|
virtual bool isTexture() const override { return true; }
|
||||||
@@ -76,10 +76,9 @@ private:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool isTexture2D() const override { return true; }
|
void createImpl(unsigned char* data);
|
||||||
|
|
||||||
private:
|
virtual bool isTexture2D() const override { return true; }
|
||||||
void create(unsigned char* data);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------
|
// -------------------------------------
|
||||||
@@ -100,10 +99,34 @@ private:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void createImpl();
|
||||||
|
|
||||||
virtual bool isTextureCubemap() const override { return true; }
|
virtual bool isTextureCubemap() const override { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// -----------------------------------------
|
||||||
|
|
||||||
|
class TextureFramebuffer final : public Texture {
|
||||||
|
public:
|
||||||
|
virtual ~TextureFramebuffer() = default;
|
||||||
|
|
||||||
|
// Factory function
|
||||||
|
static std::shared_ptr<TextureFramebuffer> create(
|
||||||
|
uint32_t width, uint32_t height,
|
||||||
|
uint32_t internalFormat, uint32_t dataFormat, uint32_t dataType = GL_UNSIGNED_BYTE);
|
||||||
|
|
||||||
|
virtual void bind(uint32_t) const override {}
|
||||||
|
virtual void unbind() const override {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void create();
|
TextureFramebuffer(std::string_view path)
|
||||||
|
: Texture(path)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void createImpl();
|
||||||
|
|
||||||
|
virtual bool isTextureFramebuffer() const override { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
@@ -117,6 +140,9 @@ inline bool Asset::fastIs<Texture2D>() const { return isTexture2D(); }
|
|||||||
|
|
||||||
template<>
|
template<>
|
||||||
inline bool Asset::fastIs<TextureCubemap>() const { return isTextureCubemap(); }
|
inline bool Asset::fastIs<TextureCubemap>() const { return isTextureCubemap(); }
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline bool Asset::fastIs<TextureFramebuffer>() const { return isTextureFramebuffer(); }
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
} // namespace Inferno
|
} // namespace Inferno
|
||||||
|
|||||||
@@ -246,18 +246,13 @@ void BufferLayout::calculateOffsetsAndStride()
|
|||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
|
|
||||||
VertexBuffer::VertexBuffer(size_t size)
|
VertexBuffer::VertexBuffer(size_t size)
|
||||||
|
: VertexBuffer(size, nullptr)
|
||||||
{
|
{
|
||||||
glGenBuffers(1, &m_id);
|
|
||||||
bind();
|
|
||||||
|
|
||||||
// Reserve data on the GPU
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, size, nullptr, GL_DYNAMIC_DRAW);
|
|
||||||
|
|
||||||
unbind();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VertexBuffer::VertexBuffer(float* vertices, size_t size)
|
VertexBuffer::VertexBuffer(size_t size, float* vertices)
|
||||||
{
|
{
|
||||||
|
m_id = UINT_MAX;
|
||||||
glGenBuffers(1, &m_id);
|
glGenBuffers(1, &m_id);
|
||||||
bind();
|
bind();
|
||||||
|
|
||||||
@@ -297,6 +292,7 @@ void VertexBuffer::uploadData(const void* data, uint32_t size)
|
|||||||
IndexBuffer::IndexBuffer(uint32_t* indices, size_t size)
|
IndexBuffer::IndexBuffer(uint32_t* indices, size_t size)
|
||||||
: m_count(size / sizeof(uint32_t))
|
: m_count(size / sizeof(uint32_t))
|
||||||
{
|
{
|
||||||
|
m_id = UINT_MAX;
|
||||||
glCreateBuffers(1, &m_id);
|
glCreateBuffers(1, &m_id);
|
||||||
bind();
|
bind();
|
||||||
|
|
||||||
@@ -335,6 +331,7 @@ void IndexBuffer::uploadData(const void* data, uint32_t size)
|
|||||||
|
|
||||||
VertexArray::VertexArray()
|
VertexArray::VertexArray()
|
||||||
{
|
{
|
||||||
|
m_id = UINT_MAX;
|
||||||
glCreateVertexArrays(1, &m_id);
|
glCreateVertexArrays(1, &m_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 Riyyi
|
* Copyright (C) 2022,2024 Riyyi
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
@@ -31,9 +31,10 @@ enum class BufferElementType {
|
|||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
|
|
||||||
// Describes one element of the BufferLayout
|
// Describes one element of the BufferLayout
|
||||||
class BufferElement {
|
class BufferElement final {
|
||||||
public:
|
public:
|
||||||
BufferElement(BufferElementType type, std::string name, bool normalized = false);
|
BufferElement(BufferElementType type, std::string name, bool normalized = false);
|
||||||
|
~BufferElement() = default;
|
||||||
|
|
||||||
uint32_t getTypeSize() const;
|
uint32_t getTypeSize() const;
|
||||||
uint32_t getTypeCount() const;
|
uint32_t getTypeCount() const;
|
||||||
@@ -65,10 +66,11 @@ private:
|
|||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
|
|
||||||
// Layout that describes raw vertex data
|
// Layout that describes raw vertex data
|
||||||
class BufferLayout {
|
class BufferLayout final {
|
||||||
public:
|
public:
|
||||||
BufferLayout() {}
|
BufferLayout() {}
|
||||||
BufferLayout(const std::initializer_list<BufferElement>& elements);
|
BufferLayout(const std::initializer_list<BufferElement>& elements);
|
||||||
|
~BufferLayout() = default;
|
||||||
|
|
||||||
const std::vector<BufferElement>& getElements() const { return m_elements; }
|
const std::vector<BufferElement>& getElements() const { return m_elements; }
|
||||||
uint32_t getStride() const { return m_stride; }
|
uint32_t getStride() const { return m_stride; }
|
||||||
@@ -90,10 +92,10 @@ private:
|
|||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
|
|
||||||
// GPU memory which holds raw vertex data
|
// GPU memory which holds raw vertex data
|
||||||
class VertexBuffer { // Vertex Buffer Object, VBO
|
class VertexBuffer final { // Vertex Buffer Object, VBO
|
||||||
public:
|
public:
|
||||||
VertexBuffer(size_t size);
|
VertexBuffer(size_t size);
|
||||||
VertexBuffer(float* vertices, size_t size);
|
VertexBuffer(size_t size, float* vertices);
|
||||||
~VertexBuffer();
|
~VertexBuffer();
|
||||||
|
|
||||||
void bind() const;
|
void bind() const;
|
||||||
@@ -113,7 +115,7 @@ private:
|
|||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
|
|
||||||
// Vertices order of rendering
|
// Vertices order of rendering
|
||||||
class IndexBuffer { // Element Buffer Object, EBO
|
class IndexBuffer final { // Element Buffer Object, EBO
|
||||||
public:
|
public:
|
||||||
IndexBuffer(uint32_t* indices, size_t size);
|
IndexBuffer(uint32_t* indices, size_t size);
|
||||||
~IndexBuffer();
|
~IndexBuffer();
|
||||||
@@ -133,7 +135,7 @@ private:
|
|||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
|
|
||||||
// Array that holds the vertex attributes configuration
|
// Array that holds the vertex attributes configuration
|
||||||
class VertexArray { // Vertex Array Object, VAO
|
class VertexArray final { // Vertex Array Object, VAO
|
||||||
public:
|
public:
|
||||||
VertexArray();
|
VertexArray();
|
||||||
~VertexArray();
|
~VertexArray();
|
||||||
|
|||||||
@@ -1,21 +1,79 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 Riyyi
|
* Copyright (C) 2022,2024 Riyyi
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <cstdint> // int8_t
|
||||||
|
|
||||||
|
#include "glad/glad.h"
|
||||||
|
#include "ruc/format/log.h"
|
||||||
|
#include "ruc/meta/assert.h"
|
||||||
|
|
||||||
|
#include "inferno/asset/texture.h"
|
||||||
#include "inferno/render/framebuffer.h"
|
#include "inferno/render/framebuffer.h"
|
||||||
|
|
||||||
namespace Inferno {
|
namespace Inferno {
|
||||||
|
|
||||||
Framebuffer::Framebuffer()
|
Framebuffer::Framebuffer(const Properties& init)
|
||||||
{
|
{
|
||||||
|
VERIFY(static_cast<int8_t>(init.type) != 0,
|
||||||
|
"malformed framebuffer type: {}", init.type);
|
||||||
|
|
||||||
|
m_id = UINT_MAX;
|
||||||
|
glGenFramebuffers(1, &m_id);
|
||||||
|
bind();
|
||||||
|
|
||||||
|
if (init.type & Type::Color) {
|
||||||
|
ruc::error("color!");
|
||||||
|
// Set color attachment 0 out of 32
|
||||||
|
m_textures[0] = TextureFramebuffer::create(init.width, init.height, GL_RGB, GL_RGB);
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_textures[0]->id(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This combined texture is required for older GPUs
|
||||||
|
if (init.type & Type::Depth && init.type & Stencil) {
|
||||||
|
ruc::error("both!");
|
||||||
|
m_textures[3] = TextureFramebuffer::create(init.width, init.height, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8);
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_textures[3]->id(), 0);
|
||||||
|
}
|
||||||
|
else if (init.type & Type::Depth) {
|
||||||
|
ruc::error("depth!");
|
||||||
|
m_textures[1] = TextureFramebuffer::create(init.width, init.height, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT);
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_textures[1]->id(), 0);
|
||||||
|
}
|
||||||
|
else if (init.type & Type::Stencil) {
|
||||||
|
ruc::error("stencil!");
|
||||||
|
m_textures[2] = TextureFramebuffer::create(init.width, init.height, GL_STENCIL_INDEX, GL_STENCIL_INDEX);
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_textures[2]->id(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
check();
|
||||||
|
unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
Framebuffer::~Framebuffer()
|
Framebuffer::~Framebuffer()
|
||||||
{
|
{
|
||||||
|
glDeleteFramebuffers(1, &m_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
|
|
||||||
|
bool Framebuffer::check() const
|
||||||
|
{
|
||||||
|
VERIFY(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE,
|
||||||
|
"malformed framebuffer: {:#x}", glCheckFramebufferStatus(GL_FRAMEBUFFER));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Framebuffer::bind() const
|
||||||
|
{
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, m_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Framebuffer::unbind() const
|
||||||
|
{
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Inferno
|
} // namespace Inferno
|
||||||
|
|||||||
@@ -1,17 +1,52 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 Riyyi
|
* Copyright (C) 2022,2024 Riyyi
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint> // int8_t
|
||||||
|
#include <memory> // std::shared_ptr
|
||||||
|
|
||||||
|
#include "inferno/asset/texture.h"
|
||||||
|
#include "ruc/meta/core.h"
|
||||||
|
|
||||||
namespace Inferno {
|
namespace Inferno {
|
||||||
|
|
||||||
class Framebuffer {
|
class Framebuffer final { // Frame Buffer Object, FBO
|
||||||
public:
|
public:
|
||||||
Framebuffer();
|
enum Type : int8_t {
|
||||||
virtual ~Framebuffer();
|
None = 0,
|
||||||
|
Color = BIT(0),
|
||||||
|
Depth = BIT(1),
|
||||||
|
Stencil = BIT(2),
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Properties {
|
||||||
|
Type type { None };
|
||||||
|
uint32_t width { 1280 };
|
||||||
|
uint32_t height { 720 };
|
||||||
|
};
|
||||||
|
|
||||||
|
Framebuffer(const Properties& init);
|
||||||
|
~Framebuffer();
|
||||||
|
|
||||||
|
bool check() const;
|
||||||
|
|
||||||
|
void bind() const;
|
||||||
|
void unbind() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t m_id { 0 };
|
||||||
|
std::shared_ptr<TextureFramebuffer> m_textures[4] { nullptr, nullptr, nullptr, nullptr };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Make bitwise OR '|' return the enum type instead of int
|
||||||
|
inline Framebuffer::Type operator|(Framebuffer::Type lhs, Framebuffer::Type rhs)
|
||||||
|
{
|
||||||
|
return static_cast<Framebuffer::Type>(
|
||||||
|
static_cast<int8_t>(lhs) | static_cast<int8_t>(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Inferno
|
} // namespace Inferno
|
||||||
|
|||||||
Reference in New Issue
Block a user