Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4dbac7ee38 | ||
|
|
a5b7a49447 | ||
|
|
fd72f6610e | ||
|
|
21319b93ad |
+23
-10
@@ -53,10 +53,19 @@ Application::Application()
|
|||||||
Input::initialize();
|
Input::initialize();
|
||||||
RenderCommand::initialize();
|
RenderCommand::initialize();
|
||||||
|
|
||||||
m_framebuffer = std::make_unique<Framebuffer>(
|
m_framebuffer = Framebuffer::create({
|
||||||
Framebuffer::Properties { .type = Framebuffer::Type::Color | Framebuffer::Type::Depth | Framebuffer::Type::Stencil,
|
.attachments = { Framebuffer::Type::Color, Framebuffer::Type::Depth },
|
||||||
.width = m_window->getWidth(),
|
.width = m_window->getWidth(),
|
||||||
.height = m_window->getHeight() });
|
.height = m_window->getHeight(),
|
||||||
|
.clearColor = { 0.2f, 0.3f, 0.3f, 1.0f },
|
||||||
|
.clearBit = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
|
||||||
|
});
|
||||||
|
|
||||||
|
m_screenFramebuffer = Framebuffer::create({
|
||||||
|
.renderToScreen = true,
|
||||||
|
.clearColor = { 1.0f, 1.0f, 1.0f, 1.0f },
|
||||||
|
.clearBit = GL_COLOR_BUFFER_BIT,
|
||||||
|
});
|
||||||
|
|
||||||
m_scene = std::make_shared<Scene>();
|
m_scene = std::make_shared<Scene>();
|
||||||
m_scene->initialize();
|
m_scene->initialize();
|
||||||
@@ -175,10 +184,10 @@ int Application::run()
|
|||||||
|
|
||||||
m_framebuffer->bind();
|
m_framebuffer->bind();
|
||||||
|
|
||||||
render();
|
RenderCommand::clearColor(m_framebuffer->clearColor());
|
||||||
|
RenderCommand::clearBit(m_framebuffer->clearBit());
|
||||||
|
|
||||||
RenderCommand::clearColor({ 0.2f, 0.3f, 0.3f, 1.0f });
|
render();
|
||||||
RenderCommand::clearColorDepthBit();
|
|
||||||
|
|
||||||
std::pair<glm::mat4, glm::mat4> projectionView = m_scene->cameraProjectionView();
|
std::pair<glm::mat4, glm::mat4> projectionView = m_scene->cameraProjectionView();
|
||||||
RendererCubemap::the().beginScene(projectionView.first, projectionView.second); // camera, lights, environment
|
RendererCubemap::the().beginScene(projectionView.first, projectionView.second); // camera, lights, environment
|
||||||
@@ -199,8 +208,10 @@ int Application::run()
|
|||||||
// ---------------------------------
|
// ---------------------------------
|
||||||
// Framebuffer
|
// Framebuffer
|
||||||
|
|
||||||
RenderCommand::clearColor({ 1.0f, 1.0f, 1.0f, 1.0f });
|
m_screenFramebuffer->bind();
|
||||||
RenderCommand::clearColorBit();
|
|
||||||
|
RenderCommand::clearColor(m_screenFramebuffer->clearColor());
|
||||||
|
RenderCommand::clearBit(m_screenFramebuffer->clearBit());
|
||||||
|
|
||||||
Renderer2D::the().setEnableDepthBuffer(false);
|
Renderer2D::the().setEnableDepthBuffer(false);
|
||||||
Renderer2D::the().beginScene(matIdentity, matIdentity);
|
Renderer2D::the().beginScene(matIdentity, matIdentity);
|
||||||
@@ -208,6 +219,8 @@ int Application::run()
|
|||||||
Renderer2D::the().endScene();
|
Renderer2D::the().endScene();
|
||||||
Renderer2D::the().setEnableDepthBuffer(true);
|
Renderer2D::the().setEnableDepthBuffer(true);
|
||||||
|
|
||||||
|
m_screenFramebuffer->unbind();
|
||||||
|
|
||||||
m_window->render();
|
m_window->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,7 +255,7 @@ bool Application::onWindowResize(WindowResizeEvent& e)
|
|||||||
ruc::info("WindowResizeEvent {}x{}", e.getWidth(), e.getHeight());
|
ruc::info("WindowResizeEvent {}x{}", e.getWidth(), e.getHeight());
|
||||||
|
|
||||||
RenderCommand::setViewport(0, 0, e.getWidth(), e.getHeight());
|
RenderCommand::setViewport(0, 0, e.getWidth(), e.getHeight());
|
||||||
m_framebuffer->setSize(e.getWidth(), e.getHeight());
|
m_framebuffer->resize(e.getWidth(), e.getHeight());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 Riyyi
|
* Copyright (C) 2022,2024 Riyyi
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
@@ -51,8 +51,9 @@ private:
|
|||||||
float m_lastFrameTime { 0.0f };
|
float m_lastFrameTime { 0.0f };
|
||||||
|
|
||||||
std::unique_ptr<Window> m_window;
|
std::unique_ptr<Window> m_window;
|
||||||
|
std::shared_ptr<Framebuffer> m_framebuffer;
|
||||||
|
std::shared_ptr<Framebuffer> m_screenFramebuffer;
|
||||||
std::shared_ptr<Scene> m_scene;
|
std::shared_ptr<Scene> m_scene;
|
||||||
std::unique_ptr<Framebuffer> m_framebuffer;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
std::shared_ptr<Font> m_font;
|
std::shared_ptr<Font> m_font;
|
||||||
|
|||||||
@@ -5,11 +5,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "glad/glad.h"
|
#include "glad/glad.h"
|
||||||
|
|
||||||
#include "inferno/core.h"
|
|
||||||
#include "inferno/render/buffer.h"
|
|
||||||
#include "ruc/meta/assert.h"
|
#include "ruc/meta/assert.h"
|
||||||
|
|
||||||
|
#include "inferno/render/buffer.h"
|
||||||
|
|
||||||
namespace Inferno {
|
namespace Inferno {
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
@@ -43,57 +42,38 @@ uint32_t BufferElement::getTypeSize(const BufferElementType type)
|
|||||||
case BufferElementType::None:
|
case BufferElementType::None:
|
||||||
return 0;
|
return 0;
|
||||||
case BufferElementType::Bool:
|
case BufferElementType::Bool:
|
||||||
return sizeof(bool);
|
|
||||||
case BufferElementType::Bool2:
|
case BufferElementType::Bool2:
|
||||||
return sizeof(bool) * 2;
|
|
||||||
case BufferElementType::Bool3:
|
case BufferElementType::Bool3:
|
||||||
return sizeof(bool) * 3;
|
|
||||||
case BufferElementType::Bool4:
|
case BufferElementType::Bool4:
|
||||||
return sizeof(bool) * 4;
|
return sizeof(bool) * getTypeCount(type);
|
||||||
case BufferElementType::Int:
|
case BufferElementType::Int:
|
||||||
return sizeof(int32_t);
|
|
||||||
case BufferElementType::Int2:
|
case BufferElementType::Int2:
|
||||||
return sizeof(int32_t) * 2;
|
|
||||||
case BufferElementType::Int3:
|
case BufferElementType::Int3:
|
||||||
return sizeof(int32_t) * 3;
|
|
||||||
case BufferElementType::Int4:
|
case BufferElementType::Int4:
|
||||||
return sizeof(int32_t) * 4;
|
return sizeof(int32_t) * getTypeCount(type);
|
||||||
case BufferElementType::Uint:
|
case BufferElementType::Uint:
|
||||||
return sizeof(uint32_t);
|
|
||||||
case BufferElementType::Uint2:
|
case BufferElementType::Uint2:
|
||||||
return sizeof(uint32_t) * 2;
|
|
||||||
case BufferElementType::Uint3:
|
case BufferElementType::Uint3:
|
||||||
return sizeof(uint32_t) * 3;
|
|
||||||
case BufferElementType::Uint4:
|
case BufferElementType::Uint4:
|
||||||
return sizeof(uint32_t) * 4;
|
return sizeof(uint32_t) * getTypeCount(type);
|
||||||
case BufferElementType::Float:
|
case BufferElementType::Float:
|
||||||
return sizeof(float);
|
|
||||||
case BufferElementType::Vec2:
|
case BufferElementType::Vec2:
|
||||||
return sizeof(float) * 2;
|
|
||||||
case BufferElementType::Vec3:
|
case BufferElementType::Vec3:
|
||||||
return sizeof(float) * 3;
|
|
||||||
case BufferElementType::Vec4:
|
case BufferElementType::Vec4:
|
||||||
return sizeof(float) * 4;
|
return sizeof(float) * getTypeCount(type);
|
||||||
case BufferElementType::Double:
|
case BufferElementType::VecDouble:
|
||||||
return sizeof(double);
|
case BufferElementType::VecDouble2:
|
||||||
case BufferElementType::Double2:
|
case BufferElementType::VecDouble3:
|
||||||
return sizeof(double);
|
case BufferElementType::VecDouble4:
|
||||||
case BufferElementType::Double3:
|
return sizeof(double) * getTypeCount(type);
|
||||||
return sizeof(double);
|
|
||||||
case BufferElementType::Double4:
|
|
||||||
return sizeof(double);
|
|
||||||
case BufferElementType::Mat2:
|
case BufferElementType::Mat2:
|
||||||
return sizeof(float) * 2 * 2;
|
|
||||||
case BufferElementType::Mat3:
|
case BufferElementType::Mat3:
|
||||||
return sizeof(float) * 3 * 3;
|
|
||||||
case BufferElementType::Mat4:
|
case BufferElementType::Mat4:
|
||||||
return sizeof(float) * 4 * 4;
|
return sizeof(float) * getTypeCount(type);
|
||||||
case BufferElementType::DoubleMat2:
|
case BufferElementType::MatDouble2:
|
||||||
return sizeof(double) * 2 * 2;
|
case BufferElementType::MatDouble3:
|
||||||
case BufferElementType::DoubleMat3:
|
case BufferElementType::MatDouble4:
|
||||||
return sizeof(double) * 3 * 3;
|
return sizeof(double) * getTypeCount(type);
|
||||||
case BufferElementType::DoubleMat4:
|
|
||||||
return sizeof(double) * 4 * 4;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
VERIFY(false, "BufferElement unknown BufferElementType size!");
|
VERIFY(false, "BufferElement unknown BufferElementType size!");
|
||||||
@@ -106,44 +86,28 @@ uint32_t BufferElement::getTypeCount(const BufferElementType type)
|
|||||||
case BufferElementType::None:
|
case BufferElementType::None:
|
||||||
return 0;
|
return 0;
|
||||||
case BufferElementType::Bool:
|
case BufferElementType::Bool:
|
||||||
|
case BufferElementType::Int:
|
||||||
|
case BufferElementType::Uint:
|
||||||
|
case BufferElementType::Float:
|
||||||
|
case BufferElementType::VecDouble:
|
||||||
return 1;
|
return 1;
|
||||||
case BufferElementType::Bool2:
|
case BufferElementType::Bool2:
|
||||||
|
case BufferElementType::Int2:
|
||||||
|
case BufferElementType::Uint2:
|
||||||
|
case BufferElementType::Vec2:
|
||||||
|
case BufferElementType::VecDouble2:
|
||||||
return 2;
|
return 2;
|
||||||
case BufferElementType::Bool3:
|
case BufferElementType::Bool3:
|
||||||
|
case BufferElementType::Int3:
|
||||||
|
case BufferElementType::Uint3:
|
||||||
|
case BufferElementType::Vec3:
|
||||||
|
case BufferElementType::VecDouble3:
|
||||||
return 3;
|
return 3;
|
||||||
case BufferElementType::Bool4:
|
case BufferElementType::Bool4:
|
||||||
return 4;
|
|
||||||
case BufferElementType::Int:
|
|
||||||
return 1;
|
|
||||||
case BufferElementType::Int2:
|
|
||||||
return 2;
|
|
||||||
case BufferElementType::Int3:
|
|
||||||
return 3;
|
|
||||||
case BufferElementType::Int4:
|
case BufferElementType::Int4:
|
||||||
return 4;
|
|
||||||
case BufferElementType::Uint:
|
|
||||||
return 1;
|
|
||||||
case BufferElementType::Uint2:
|
|
||||||
return 2;
|
|
||||||
case BufferElementType::Uint3:
|
|
||||||
return 3;
|
|
||||||
case BufferElementType::Uint4:
|
case BufferElementType::Uint4:
|
||||||
return 4;
|
|
||||||
case BufferElementType::Float:
|
|
||||||
return 1;
|
|
||||||
case BufferElementType::Vec2:
|
|
||||||
return 2;
|
|
||||||
case BufferElementType::Vec3:
|
|
||||||
return 3;
|
|
||||||
case BufferElementType::Vec4:
|
case BufferElementType::Vec4:
|
||||||
return 4;
|
case BufferElementType::VecDouble4:
|
||||||
case BufferElementType::Double:
|
|
||||||
return 1;
|
|
||||||
case BufferElementType::Double2:
|
|
||||||
return 2;
|
|
||||||
case BufferElementType::Double3:
|
|
||||||
return 3;
|
|
||||||
case BufferElementType::Double4:
|
|
||||||
return 4;
|
return 4;
|
||||||
case BufferElementType::Mat2:
|
case BufferElementType::Mat2:
|
||||||
return 2 * 2;
|
return 2 * 2;
|
||||||
@@ -151,11 +115,11 @@ uint32_t BufferElement::getTypeCount(const BufferElementType type)
|
|||||||
return 3 * 3;
|
return 3 * 3;
|
||||||
case BufferElementType::Mat4:
|
case BufferElementType::Mat4:
|
||||||
return 4 * 4;
|
return 4 * 4;
|
||||||
case BufferElementType::DoubleMat2:
|
case BufferElementType::MatDouble2:
|
||||||
return 2 * 2;
|
return 2 * 2;
|
||||||
case BufferElementType::DoubleMat3:
|
case BufferElementType::MatDouble3:
|
||||||
return 3 * 3;
|
return 3 * 3;
|
||||||
case BufferElementType::DoubleMat4:
|
case BufferElementType::MatDouble4:
|
||||||
return 4 * 4;
|
return 4 * 4;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -169,56 +133,37 @@ uint32_t BufferElement::getTypeGL(const BufferElementType type)
|
|||||||
case BufferElementType::None:
|
case BufferElementType::None:
|
||||||
return GL_NONE;
|
return GL_NONE;
|
||||||
case BufferElementType::Bool:
|
case BufferElementType::Bool:
|
||||||
return GL_BOOL;
|
|
||||||
case BufferElementType::Bool2:
|
case BufferElementType::Bool2:
|
||||||
return GL_BOOL;
|
|
||||||
case BufferElementType::Bool3:
|
case BufferElementType::Bool3:
|
||||||
return GL_BOOL;
|
|
||||||
case BufferElementType::Bool4:
|
case BufferElementType::Bool4:
|
||||||
return GL_BOOL;
|
return GL_BOOL;
|
||||||
case BufferElementType::Int:
|
case BufferElementType::Int:
|
||||||
return GL_INT;
|
|
||||||
case BufferElementType::Int2:
|
case BufferElementType::Int2:
|
||||||
return GL_INT;
|
|
||||||
case BufferElementType::Int3:
|
case BufferElementType::Int3:
|
||||||
return GL_INT;
|
|
||||||
case BufferElementType::Int4:
|
case BufferElementType::Int4:
|
||||||
return GL_INT;
|
return GL_INT;
|
||||||
case BufferElementType::Uint:
|
case BufferElementType::Uint:
|
||||||
return GL_UNSIGNED_INT;
|
|
||||||
case BufferElementType::Uint2:
|
case BufferElementType::Uint2:
|
||||||
return GL_UNSIGNED_INT;
|
|
||||||
case BufferElementType::Uint3:
|
case BufferElementType::Uint3:
|
||||||
return GL_UNSIGNED_INT;
|
|
||||||
case BufferElementType::Uint4:
|
case BufferElementType::Uint4:
|
||||||
return GL_UNSIGNED_INT;
|
return GL_UNSIGNED_INT;
|
||||||
case BufferElementType::Float:
|
case BufferElementType::Float:
|
||||||
return GL_FLOAT;
|
|
||||||
case BufferElementType::Vec2:
|
case BufferElementType::Vec2:
|
||||||
return GL_FLOAT;
|
|
||||||
case BufferElementType::Vec3:
|
case BufferElementType::Vec3:
|
||||||
return GL_FLOAT;
|
|
||||||
case BufferElementType::Vec4:
|
case BufferElementType::Vec4:
|
||||||
return GL_FLOAT;
|
return GL_FLOAT;
|
||||||
case BufferElementType::Double:
|
case BufferElementType::VecDouble:
|
||||||
return GL_DOUBLE;
|
case BufferElementType::VecDouble2:
|
||||||
case BufferElementType::Double2:
|
case BufferElementType::VecDouble3:
|
||||||
return GL_DOUBLE;
|
case BufferElementType::VecDouble4:
|
||||||
case BufferElementType::Double3:
|
|
||||||
return GL_DOUBLE;
|
|
||||||
case BufferElementType::Double4:
|
|
||||||
return GL_DOUBLE;
|
return GL_DOUBLE;
|
||||||
case BufferElementType::Mat2:
|
case BufferElementType::Mat2:
|
||||||
return GL_FLOAT;
|
|
||||||
case BufferElementType::Mat3:
|
case BufferElementType::Mat3:
|
||||||
return GL_FLOAT;
|
|
||||||
case BufferElementType::Mat4:
|
case BufferElementType::Mat4:
|
||||||
return GL_FLOAT;
|
return GL_FLOAT;
|
||||||
case BufferElementType::DoubleMat2:
|
case BufferElementType::MatDouble2:
|
||||||
return GL_DOUBLE;
|
case BufferElementType::MatDouble3:
|
||||||
case BufferElementType::DoubleMat3:
|
case BufferElementType::MatDouble4:
|
||||||
return GL_DOUBLE;
|
|
||||||
case BufferElementType::DoubleMat4:
|
|
||||||
return GL_DOUBLE;
|
return GL_DOUBLE;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -18,13 +18,13 @@ namespace Inferno {
|
|||||||
// https://www.khronos.org/opengl/wiki/Data_Type_(GLSL)
|
// https://www.khronos.org/opengl/wiki/Data_Type_(GLSL)
|
||||||
enum class BufferElementType {
|
enum class BufferElementType {
|
||||||
None = 0,
|
None = 0,
|
||||||
Bool, Bool2, Bool3, Bool4, // bvec
|
Bool, Bool2, Bool3, Bool4, // bvec
|
||||||
Int, Int2, Int3, Int4, // ivec
|
Int, Int2, Int3, Int4, // ivec
|
||||||
Uint, Uint2, Uint3, Uint4, // uvec
|
Uint, Uint2, Uint3, Uint4, // uvec
|
||||||
Float, Vec2, Vec3, Vec4, // vec
|
Float, Vec2, Vec3, Vec4, // vec
|
||||||
Double, Double2, Double3, Double4, // dvec
|
VecDouble, VecDouble2, VecDouble3, VecDouble4, // dvec
|
||||||
Mat2, Mat3, Mat4, // mat
|
Mat2, Mat3, Mat4, // mat
|
||||||
DoubleMat2, DoubleMat3, DoubleMat4, // dmat
|
MatDouble2, MatDouble3, MatDouble4, // dmat
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <cstdint> // int8_t
|
#include <cstddef> // size_t
|
||||||
|
#include <cstdint> // uint8_t, uint32_t
|
||||||
|
|
||||||
#include "glad/glad.h"
|
#include "glad/glad.h"
|
||||||
#include "ruc/meta/assert.h"
|
#include "ruc/meta/assert.h"
|
||||||
@@ -14,34 +15,34 @@
|
|||||||
|
|
||||||
namespace Inferno {
|
namespace Inferno {
|
||||||
|
|
||||||
Framebuffer::Framebuffer(const Properties& init)
|
std::shared_ptr<Framebuffer> Framebuffer::create(const Properties& properties)
|
||||||
: m_type(init.type)
|
|
||||||
, m_width(init.width)
|
|
||||||
, m_height(init.height)
|
|
||||||
{
|
{
|
||||||
VERIFY(static_cast<int8_t>(init.type) != 0,
|
VERIFY((properties.attachments.size() > 0 && !properties.renderToScreen) || properties.renderToScreen,
|
||||||
"malformed framebuffer type: {}", init.type);
|
"cant have attachments on the default framebuffer");
|
||||||
|
|
||||||
m_id = UINT_MAX;
|
auto result = std::shared_ptr<Framebuffer>(new Framebuffer(properties));
|
||||||
glGenFramebuffers(1, &m_id);
|
|
||||||
|
|
||||||
createTextures();
|
if (!properties.renderToScreen) {
|
||||||
|
result->m_id = UINT_MAX;
|
||||||
|
glGenFramebuffers(1, &result->m_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
result->createTextures();
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Framebuffer::~Framebuffer()
|
Framebuffer::~Framebuffer()
|
||||||
{
|
{
|
||||||
|
if (m_renderToScreen) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
glDeleteFramebuffers(1, &m_id);
|
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
|
void Framebuffer::bind() const
|
||||||
{
|
{
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, m_id);
|
glBindFramebuffer(GL_FRAMEBUFFER, m_id);
|
||||||
@@ -52,7 +53,14 @@ void Framebuffer::unbind() const
|
|||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Framebuffer::setSize(uint32_t width, uint32_t height)
|
bool Framebuffer::check() const
|
||||||
|
{
|
||||||
|
VERIFY(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE,
|
||||||
|
"malformed framebuffer: {:#x}", glCheckFramebufferStatus(GL_FRAMEBUFFER));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Framebuffer::resize(uint32_t width, uint32_t height)
|
||||||
{
|
{
|
||||||
if (m_width == width && m_height == height) {
|
if (m_width == width && m_height == height) {
|
||||||
return;
|
return;
|
||||||
@@ -68,40 +76,55 @@ void Framebuffer::setSize(uint32_t width, uint32_t height)
|
|||||||
|
|
||||||
void Framebuffer::createTextures()
|
void Framebuffer::createTextures()
|
||||||
{
|
{
|
||||||
|
if (m_renderToScreen) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_id) {
|
||||||
|
glDeleteFramebuffers(1, &m_id);
|
||||||
|
m_textures.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_id = UINT_MAX;
|
||||||
|
glGenFramebuffers(1, &m_id);
|
||||||
|
|
||||||
bind();
|
bind();
|
||||||
|
|
||||||
m_textures[0] = AssetManager::the().remove(FRAMEBUFFER_TEXTURE_COLOR);
|
auto it = m_attachments.begin();
|
||||||
m_textures[1] = AssetManager::the().remove(FRAMEBUFFER_TEXTURE_DEPTH);
|
uint8_t color_attachment = 0;
|
||||||
m_textures[2] = AssetManager::the().remove(FRAMEBUFFER_TEXTURE_STENCIL);
|
|
||||||
m_textures[3] = AssetManager::the().remove(FRAMEBUFFER_TEXTURE_DEPTH_STENCIL);
|
|
||||||
|
|
||||||
if (m_type & Type::Color) {
|
size_t size = m_attachments.size();
|
||||||
// Set color attachment 0 out of 32
|
m_textures.resize(size);
|
||||||
m_textures[0] = AssetManager::the().load<TextureFramebuffer>(
|
for (size_t i = 0; i < size; ++i) {
|
||||||
FRAMEBUFFER_TEXTURE_COLOR, m_width, m_height, GL_RGB, GL_RGB);
|
TypeProperties type = *(it + i);
|
||||||
m_textures[0]->bind(0);
|
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_textures[0]->id(), 0);
|
if (type.type == Type::Color) {
|
||||||
m_textures[0]->unbind();
|
// Set color attachment 0 out of 32
|
||||||
}
|
m_textures[i] = (TextureFramebuffer::create(
|
||||||
|
"", m_width, m_height, GL_RGB, GL_RGB));
|
||||||
// This combined texture is required for older GPUs
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + color_attachment, GL_TEXTURE_2D, m_textures[i]->id(), 0);
|
||||||
if (m_type & Type::Depth && m_type & Stencil) {
|
}
|
||||||
m_textures[3] = AssetManager::the().load<TextureFramebuffer>(
|
|
||||||
FRAMEBUFFER_TEXTURE_DEPTH_STENCIL, m_width, m_height, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8);
|
// This combined texture is required for older GPUs
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_textures[3]->id(), 0);
|
if (type.type == Type::Depth24Stencil8) {
|
||||||
}
|
m_textures[i] = (TextureFramebuffer::create(
|
||||||
else if (m_type & Type::Depth) {
|
"", m_width, m_height, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8));
|
||||||
m_textures[1] = AssetManager::the().load<TextureFramebuffer>(
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_textures[i]->id(), 0);
|
||||||
FRAMEBUFFER_TEXTURE_DEPTH, m_width, m_height, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT);
|
continue;
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_textures[1]->id(), 0);
|
}
|
||||||
}
|
|
||||||
else if (m_type & Type::Stencil) {
|
if (type.type == Type::Depth32F) {
|
||||||
m_textures[2] = AssetManager::the().load<TextureFramebuffer>(
|
// FIXME: This isnt a 32-bit float texture
|
||||||
FRAMEBUFFER_TEXTURE_STENCIL, m_width, m_height, GL_STENCIL_INDEX, GL_STENCIL_INDEX);
|
m_textures[i] = (TextureFramebuffer::create(
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_textures[2]->id(), 0);
|
"", m_width, m_height, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT));
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_textures[i]->id(), 0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VERIFY(color_attachment <= 32, "maximum color attachments was exceeded: {}/32", color_attachment);
|
||||||
check();
|
check();
|
||||||
|
|
||||||
unbind();
|
unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,67 +6,94 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdint> // int8_t
|
#include <cstddef> // size_t
|
||||||
#include <memory> // std::shared_ptr
|
#include <cstdint> // uint8_t
|
||||||
|
#include <initializer_list>
|
||||||
|
#include <memory> // std::shared_ptr
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "glm/ext/vector_float4.hpp" // glm::vec4
|
||||||
|
|
||||||
#include "inferno/asset/texture.h"
|
#include "inferno/asset/texture.h"
|
||||||
#include "ruc/meta/core.h"
|
|
||||||
|
|
||||||
// AssetManager paths to the global framebuffer textures
|
|
||||||
#define FRAMEBUFFER_TEXTURE_COLOR "@framebuffer-color"
|
|
||||||
#define FRAMEBUFFER_TEXTURE_DEPTH "@framebuffer-depth"
|
|
||||||
#define FRAMEBUFFER_TEXTURE_STENCIL "@framebuffer-stencil"
|
|
||||||
#define FRAMEBUFFER_TEXTURE_DEPTH_STENCIL "@framebuffer-depth-stencil"
|
|
||||||
|
|
||||||
namespace Inferno {
|
namespace Inferno {
|
||||||
|
|
||||||
class Framebuffer final { // Frame Buffer Object, FBO
|
class Framebuffer final { // Frame Buffer Object, FBO
|
||||||
public:
|
public:
|
||||||
enum Type : int8_t {
|
enum Type : uint8_t {
|
||||||
None = 0,
|
None = 0,
|
||||||
Color = BIT(0),
|
|
||||||
Depth = BIT(1),
|
// Color
|
||||||
Stencil = BIT(2),
|
RGBA8 = 1,
|
||||||
|
|
||||||
|
// Depth/stencil
|
||||||
|
Depth32F = 2,
|
||||||
|
Depth24Stencil8 = 3,
|
||||||
|
|
||||||
|
// Defaults
|
||||||
|
Color = RGBA8,
|
||||||
|
Depth = Depth24Stencil8,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TypeProperties {
|
||||||
|
TypeProperties() = default;
|
||||||
|
TypeProperties(Type type)
|
||||||
|
: type(type)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Properties {
|
struct Properties {
|
||||||
Type type { None };
|
std::initializer_list<TypeProperties> attachments {};
|
||||||
|
bool renderToScreen { false }; // (dummy framebuffer)
|
||||||
|
|
||||||
uint32_t width { 1280 };
|
uint32_t width { 1280 };
|
||||||
uint32_t height { 720 };
|
uint32_t height { 720 };
|
||||||
|
glm::vec4 clearColor { 1.0f, 0.0f, 1.0f, 1.0f }; // magenta
|
||||||
|
uint32_t clearBit { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
Framebuffer(const Properties& init);
|
|
||||||
~Framebuffer();
|
~Framebuffer();
|
||||||
|
|
||||||
bool check() const;
|
// Factory function
|
||||||
|
static std::shared_ptr<Framebuffer> create(const Properties& properties);
|
||||||
|
|
||||||
void bind() const;
|
void bind() const;
|
||||||
void unbind() const;
|
void unbind() const;
|
||||||
|
bool check() const;
|
||||||
|
void resize(uint32_t width, uint32_t height);
|
||||||
|
|
||||||
void setSize(uint32_t width, uint32_t height);
|
uint32_t id() const { return m_id; }
|
||||||
|
|
||||||
Type type() const { return m_type; }
|
|
||||||
uint32_t width() const { return m_width; }
|
uint32_t width() const { return m_width; }
|
||||||
uint32_t height() const { return m_height; }
|
uint32_t height() const { return m_height; }
|
||||||
uint32_t id() const { return m_id; }
|
uint32_t clearBit() const { return m_clearBit; }
|
||||||
std::shared_ptr<TextureFramebuffer> texture(uint8_t index) const { return m_textures[index]; }
|
glm::vec4 clearColor() const { return m_clearColor; }
|
||||||
|
const std::vector<TypeProperties>& attachments() const { return m_attachments; }
|
||||||
|
std::shared_ptr<TextureFramebuffer> texture(size_t index) const { return m_textures[index]; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Framebuffer(const Properties& properties)
|
||||||
|
: m_renderToScreen(properties.renderToScreen)
|
||||||
|
, m_width(properties.width)
|
||||||
|
, m_height(properties.height)
|
||||||
|
, m_clearBit(properties.clearBit)
|
||||||
|
, m_clearColor(properties.clearColor)
|
||||||
|
, m_attachments(properties.attachments)
|
||||||
|
{
|
||||||
|
}
|
||||||
void createTextures();
|
void createTextures();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Type m_type { None };
|
bool m_renderToScreen { false };
|
||||||
|
uint32_t m_id { 0 };
|
||||||
uint32_t m_width { 0 };
|
uint32_t m_width { 0 };
|
||||||
uint32_t m_height { 0 };
|
uint32_t m_height { 0 };
|
||||||
uint32_t m_id { 0 };
|
uint32_t m_clearBit { 0 };
|
||||||
std::shared_ptr<TextureFramebuffer> m_textures[4] { nullptr, nullptr, nullptr, nullptr };
|
glm::vec4 m_clearColor;
|
||||||
|
std::vector<TypeProperties> m_attachments;
|
||||||
|
std::vector<std::shared_ptr<TextureFramebuffer>> m_textures;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 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
|
||||||
|
|||||||
@@ -29,14 +29,10 @@ void RenderCommand::destroy()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderCommand::clearColorDepthBit()
|
void RenderCommand::clearBit(uint32_t bits)
|
||||||
{
|
{
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
// GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT
|
||||||
}
|
glClear(bits);
|
||||||
|
|
||||||
void RenderCommand::clearColorBit()
|
|
||||||
{
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderCommand::clearColor(const glm::vec4& color)
|
void RenderCommand::clearColor(const glm::vec4& color)
|
||||||
|
|||||||
@@ -19,8 +19,7 @@ public:
|
|||||||
static void initialize();
|
static void initialize();
|
||||||
static void destroy();
|
static void destroy();
|
||||||
|
|
||||||
static void clearColorDepthBit();
|
static void clearBit(uint32_t bits);
|
||||||
static void clearColorBit();
|
|
||||||
static void clearColor(const glm::vec4& color);
|
static void clearColor(const glm::vec4& color);
|
||||||
static void drawIndexed(std::shared_ptr<VertexArray> vertexArray, uint32_t indexCount = 0);
|
static void drawIndexed(std::shared_ptr<VertexArray> vertexArray, uint32_t indexCount = 0);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user