Commit b780129f authored by Johannes Braun's avatar Johannes Braun
Browse files

New Texture implementation

parent 3cb5164e
......@@ -17,49 +17,16 @@ int main(int argc, char* argv[])
auto context_id = core::Context::createAsCurrent(files::asset("/preferences/default.xml"));
// Load a scene and attach it to the constant root
//core::Context::current().graph()->attach(core::global_resources::scenes.get(files::asset("meshes/scenery/cbox.dae"), 1.0f));
core::Context::current().graph()->attach(core::global_resources::scenes.get(files::asset("meshes/scenery/cbox.dae"), 1.0f));
// Create a skybox
core::Context::current().skybox()->reset(core::Skybox::collectFilesFrom(files::asset("textures/ryfjallet/")));
// Add a PlayerController to move around
core::Context::current().camera()->owner()->makeComponent<component::PlayerController>();
static auto default_shader_program = std::make_shared<core::Program>(std::vector<std::shared_ptr<core::Shader>>{
std::make_shared<core::Shader>(gl::ShaderType::eVertex, files::shader("simple_instanced/simple.vert")),
std::make_shared<core::Shader>(gl::ShaderType::eFragment, files::shader("simple_instanced/simple.frag"))
});
std::shared_ptr<core::MeshDrawable> drawable = std::make_shared<core::MeshDrawable>();
core::Buffer mat_bfr;
std::vector<glm::mat4> matrices;
for (auto y = 0; y < 1000; ++y)
{
for (auto x = 0; x < 200; ++x)
{
matrices.push_back(glm::translate(glm::mat4(1.f), glm::vec3(3.f*x, 0, 3.f*y)));
}
}
core::ClockGL::instance().start();
mat_bfr.upload(matrices, gl::BufferUsage::eDynamicCopy);
auto i = core::ClockGL::instance().end();
Log_Info << "Upload took " << i;
drawable->mesh = std::make_shared<core::Mesh>();
drawable->mesh->vertexArray().linkAttributeMatrix4(mat_bfr.id(), 5, sizeof(glm::mat4), 0, 1);
// Render the scene with the pathtracer
core::Context::current().loop([&drawable, &mat_bfr]() {
core::Context::current().renderList().submit(default_shader_program, std::make_shared<core::BatchDrawable>([&drawable, &mat_bfr](std::shared_ptr<core::Program> shader) {
if (drawable->material)
shader->uniformStruct("u_material", *(drawable->material));
drawable->mesh->drawInstanced(mat_bfr.size() / sizeof(glm::mat4));
}), glm::mat4(1.f));
core::Context::current().draw(core::Context::DrawMode::eColors);
core::Context::current().loop([]() {
core::Context::current().draw(core::Context::DrawMode::eGBuffer);
});
}
\ No newline at end of file
#include "framebuffer.h"
namespace glare::core
{
Framebuffer::Framebuffer(unsigned width, unsigned height, unsigned samples)
{
m_width = width;
m_height = height;
m_samples = samples;
}
Framebuffer::~Framebuffer()
{
}
/**
* \brief Resizes all attachments to the new resolution.
* \param samples Only used when using a multisampled texture.
*/
void Framebuffer::resize(unsigned width, unsigned height, unsigned samples)
{
if (width == m_width && height == m_height && samples == m_samples)
return;
m_width = width;
m_height = height;
m_samples = samples;
for (auto &&texture : m_color_attachments) {
if (m_samples == 1)
{
texture.second->resize<color::rgba32f>(gl::TextureImageTarget2D::e2D, width, height, 4, gl::TextureInternalFormat::eRGBA32Float, gl::TextureFormat::eRGBA, gl::Type::eFloat);
}
else
{
texture.second->resize<color::rgba32f>(gl::TextureImageTargetMultisample2D::e2DMultisample, width, height, samples, 4, gl::TextureInternalFormat::eRGBA32Float, gl::TextureFormat::eRGBA, gl::Type::eFloat);
}
}
if (m_depth_attachment) {
if (m_samples == 1)
{
m_depth_attachment->resize<color::r32f>(gl::TextureImageTarget2D::e2D, width, height, 4, gl::TextureInternalFormat::eDepthComponent32Float, gl::TextureFormat::eDepthComponent, gl::Type::eFloat);
}
else
{
m_depth_attachment->resize<float>(gl::TextureImageTargetMultisample2D::e2DMultisample, width, height, samples, 4, gl::TextureInternalFormat::eDepthComponent32Float, gl::TextureFormat::eDepthComponent, gl::Type::eFloat);
}
}
}
/**
* \brief Set this framebuffer as active to receive rendered things.
*/
void Framebuffer::activate() const
{
gl::bindFramebuffer(gl::FramebufferTarget::eDefault, m_handle);
}
/**
* \brief Set the default framebuffer as active.
*/
void Framebuffer::deactivate() const
{
gl::bindFramebuffer(gl::FramebufferTarget::eDefault, 0);
}
void Framebuffer::attach(gl::Attachment att)
{
switch (att)
{
case gl::Attachment::eDepth:
case gl::Attachment::eDepthStencil:
m_depth_attachment = std::make_shared<TextureEXT>();
if (m_samples == 1)
{
m_depth_attachment->resize<color::r32f>(gl::TextureImageTarget2D::e2D, m_width, m_height, 4, gl::TextureInternalFormat::eDepthComponent32Float, gl::TextureFormat::eDepthComponent, gl::Type::eFloat);
}
else
{
m_depth_attachment->resize<color::r32f>(gl::TextureImageTargetMultisample2D::e2DMultisample, m_width, m_height, m_samples, 4, gl::TextureInternalFormat::eDepthComponent32Float, gl::TextureFormat::eDepthComponent, gl::Type::eFloat);
}
gl::namedFramebufferTexture(m_handle, att, m_depth_attachment->id(), 0);
break;
default:
{
std::shared_ptr<TextureEXT> new_attachment = std::make_shared<TextureEXT>();
if (m_samples == 1)
{
new_attachment->resize<color::rgba32f>(gl::TextureImageTarget2D::e2D, m_width, m_height, 4, gl::TextureInternalFormat::eRGBA32Float, gl::TextureFormat::eRGBA, gl::Type::eFloat);
}
else
{
new_attachment->resize<color::rgba32f>(gl::TextureImageTargetMultisample2D::e2DMultisample, m_width, m_height, m_samples, 4, gl::TextureInternalFormat::eRGBA32Float, gl::TextureFormat::eRGBA, gl::Type::eFloat);
}
m_color_attachments.emplace(att, new_attachment);
putAttachment(att, new_attachment->id());
} break;
}
}
const TextureEXT &Framebuffer::attachment(gl::Attachment attachment) const
{
switch (attachment)
{
case gl::Attachment::eDepth:
case gl::Attachment::eDepthStencil:
return *m_depth_attachment;
default:
return *(m_color_attachments.at(attachment));
}
}
unsigned Framebuffer::attachments() const
{
return static_cast<unsigned>(m_color_attachments.size()) + unsigned(bool(m_depth_attachment));
}
unsigned Framebuffer::samples() const
{
return m_samples;
}
void Framebuffer::putAttachment(gl::Attachment attachment, unsigned texture)
{
gl::namedFramebufferTexture(m_handle, attachment, texture, 0);
if (std::find(m_draw_buffers.begin(), m_draw_buffers.end(), attachment) == m_draw_buffers.end()) {
m_draw_buffers.push_back(attachment);
gl::namedFramebufferDrawBuffers(m_handle, m_draw_buffers);
}
if (auto status = gl::checkNamedFramebufferStatus(m_handle, gl::FramebufferTarget::eDraw) != gl::FramebufferStatus::eComplete)
Log_Error << "An error occured when generating the framebuffer: " << static_cast<int>(status);
}
}
\ No newline at end of file
......@@ -8,30 +8,15 @@
// --- EXTERN ---------------------------------------------
#include <util/log.h>
#include <util/opengl.h>
#include <core/res/texture.h>
// --- INTERN ---------------------------------------------
namespace glare::core
{
/**
* \brief A frame buffer object wrapper for varying types of attachment textures.
* \tparam TTextureBase The base type of attachment textures. (Texture2D, Texture2DMultisample etc.)
*/
template<template<gl::TextureFormat, gl::TextureInternalFormat, gl::Type> typename TTextureBase>
class Framebuffer
{
public:
// The type of texture used for color attachments
using texture_color_type = TTextureBase<gl::TextureFormat::eRGBA, gl::TextureInternalFormat::eRGBA32Float, gl::Type::eFloat>;
static constexpr bool is_multisampled = texture_color_type::is_multisampled;
// The type of texture used for the depth attachment
using texture_depth_type = TTextureBase<gl::TextureFormat::eDepthComponent, gl::TextureInternalFormat::eDepthComponent32Float, gl::Type::eFloat>;
/**
* \param samples Only used when using a multisampled texture.
*/
Framebuffer(unsigned width, unsigned height, unsigned samples = 1);
Framebuffer(Framebuffer& other) = delete;
Framebuffer& operator=(Framebuffer& other) = delete;
......@@ -43,21 +28,20 @@ namespace glare::core
* \brief Resizes all attachments to the new resolution.
* \param samples Only used when using a multisampled texture.
*/
void resize(unsigned width, unsigned height, unsigned samples);
void resize(unsigned width, unsigned height, unsigned samples = 1);
/**
* \brief Set this framebuffer as active to receive rendered things.
*/
* \brief Set this framebuffer as active to receive rendered things.
*/
void activate() const;
/**
* \brief Set the default framebuffer as active.
*/
* \brief Set the default framebuffer as active.
*/
void deactivate() const;
void attach(gl::Attachment attachment);
const texture_color_type &colorAttachment(gl::Attachment attachment) const;
const texture_depth_type &depthAttachment() const;
const TextureEXT &attachment(gl::Attachment attachment) const;
unsigned attachments() const;
unsigned samples() const;
......@@ -65,123 +49,186 @@ namespace glare::core
private:
void putAttachment(gl::Attachment attachment, unsigned texture);
gl::handle::framebuffer m_handle;
unsigned m_width;
unsigned m_height;
unsigned m_samples;
std::vector<gl::Attachment> m_draw_buffers;
std::map<gl::Attachment, std::shared_ptr<texture_color_type>> m_color_attachments;
std::shared_ptr<texture_depth_type> m_depth_attachment;
};
// -------------------------------------------------------------------------------------------------------------------------
// --- IMPLEMENTATIONS -----------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------------------------------
template<template<gl::TextureFormat, gl::TextureInternalFormat, gl::Type> typename TTextureBase>
Framebuffer<TTextureBase>::Framebuffer(unsigned width, unsigned height, unsigned samples)
: m_width(width), m_height(height), m_samples(samples) {}
template<template<gl::TextureFormat, gl::TextureInternalFormat, gl::Type> typename TTextureBase>
Framebuffer<TTextureBase>::~Framebuffer() {}
std::map<gl::Attachment, std::shared_ptr<core::TextureEXT>> m_color_attachments;
std::shared_ptr<core::TextureEXT> m_depth_attachment;
template<template<gl::TextureFormat, gl::TextureInternalFormat, gl::Type> typename TTextureBase>
void Framebuffer<TTextureBase>::resize(unsigned width, unsigned height, unsigned samples)
{
if (width == m_width && height == m_height)
return;
m_width = width;
m_height = height;
m_samples = samples;
for (auto &&texture : m_color_attachments) {
is_multisampled ? texture.second->resize(width, height, m_samples) : texture.second->resize(width, height);
}
if (m_depth_attachment) {
is_multisampled ? m_depth_attachment->resize(width, height, m_samples) : m_depth_attachment->resize(width, height);
}
}
template<template<gl::TextureFormat, gl::TextureInternalFormat, gl::Type> typename TTextureBase>
void Framebuffer<TTextureBase>::activate() const
{
gl::bindFramebuffer(gl::FramebufferTarget::eDefault, m_handle);
}
template<template<gl::TextureFormat, gl::TextureInternalFormat, gl::Type> typename TTextureBase>
void Framebuffer<TTextureBase>::deactivate() const
{
gl::bindFramebuffer(gl::FramebufferTarget::eDefault, 0);
}
template<template<gl::TextureFormat, gl::TextureInternalFormat, gl::Type> typename TTextureBase>
void Framebuffer<TTextureBase>::attach(gl::Attachment attachment)
{
switch (attachment)
{
case gl::Attachment::eDepth:
case gl::Attachment::eDepthStencil:
if (is_multisampled)
m_depth_attachment = std::make_shared<texture_depth_type>(m_width, m_height, m_samples);
else
m_depth_attachment = std::make_shared<texture_depth_type>(m_width, m_height);
gl::namedFramebufferTexture(m_handle, attachment, m_depth_attachment->id(), 0);
break;
default:
{
std::shared_ptr<texture_color_type> new_attachment;
if (is_multisampled)
new_attachment = std::make_shared<texture_color_type>(m_width, m_height, m_samples);
else
new_attachment = std::make_shared<texture_color_type>(m_width, m_height);
m_color_attachments.emplace(attachment, new_attachment);
putAttachment(attachment, new_attachment->id());
} break;
}
}
template<template<gl::TextureFormat, gl::TextureInternalFormat, gl::Type> typename TTextureBase>
const typename Framebuffer<TTextureBase>::texture_color_type &Framebuffer<TTextureBase>::colorAttachment(gl::Attachment attachment) const
{
return *(m_color_attachments.at(attachment));
}
int m_samples = 1;
int m_width = 1;
int m_height = 1;
template<template<gl::TextureFormat, gl::TextureInternalFormat, gl::Type> typename TTextureBase>
const typename Framebuffer<TTextureBase>::texture_depth_type &Framebuffer<TTextureBase>::depthAttachment() const
{
return *m_depth_attachment;
}
gl::handle::framebuffer m_handle;
};
template<template<gl::TextureFormat, gl::TextureInternalFormat, gl::Type> typename TTextureBase>
unsigned Framebuffer<TTextureBase>::attachments() const
{
return m_color_attachments.size() + unsigned(bool(m_depth_attachment));
}
template<template<gl::TextureFormat, gl::TextureInternalFormat, gl::Type> typename TTextureBase>
void Framebuffer<TTextureBase>::putAttachment(gl::Attachment attachment, unsigned texture)
{
gl::namedFramebufferTexture(m_handle, attachment, texture, 0);
if (std::find(m_draw_buffers.begin(), m_draw_buffers.end(), attachment) == m_draw_buffers.end()) {
m_draw_buffers.push_back(attachment);
gl::namedFramebufferDrawBuffers(m_handle, m_draw_buffers);
}
if (auto status = gl::checkNamedFramebufferStatus(m_handle, gl::FramebufferTarget::eDraw) != gl::FramebufferStatus::eComplete)
Log_Error << "An error occured when generating the framebuffer: " << static_cast<int>(status);
}
template<template<gl::TextureFormat, gl::TextureInternalFormat, gl::Type> typename TTextureBase>
unsigned Framebuffer<TTextureBase>::samples() const
{
return m_samples;
}
/**
// * \brief A frame buffer object wrapper for varying types of attachment textures.
// * \tparam TTextureBase The base type of attachment textures. (Texture2D, Texture2DMultisample etc.)
// */
//template<template<gl::TextureFormat, gl::TextureInternalFormat, gl::Type> typename TTextureBase>
//class FramebufferOLD
//{
//public:
// // The type of texture used for color attachments
// using texture_color_type = TTextureBase<gl::TextureFormat::eRGBA, gl::TextureInternalFormat::eRGBA32Float, gl::Type::eFloat>;
// static constexpr bool is_multisampled = texture_color_type::is_multisampled;
// // The type of texture used for the depth attachment
// using texture_depth_type = TTextureBase<gl::TextureFormat::eDepthComponent, gl::TextureInternalFormat::eDepthComponent32Float, gl::Type::eFloat>;
// /**
// * \param samples Only used when using a multisampled texture.
// */
// FramebufferOLD(unsigned width, unsigned height, unsigned samples = 1);
// FramebufferOLD(FramebufferOLD& other) = delete;
// FramebufferOLD& operator=(FramebufferOLD& other) = delete;
// FramebufferOLD(FramebufferOLD&& other) = default;
// FramebufferOLD& operator=(FramebufferOLD&& other) = default;
// ~FramebufferOLD();
// /**
// * \brief Resizes all attachments to the new resolution.
// * \param samples Only used when using a multisampled texture.
// */
// void resize(unsigned width, unsigned height, unsigned samples = 1);
// /**
// * \brief Set this framebuffer as active to receive rendered things.
// */
// void activate() const;
// /**
// * \brief Set the default framebuffer as active.
// */
// void deactivate() const;
// void attach(gl::Attachment attachment);
// const texture_color_type &colorAttachment(gl::Attachment attachment) const;
// const texture_depth_type &depthAttachment() const;
// unsigned attachments() const;
// unsigned samples() const;
//private:
// void putAttachment(gl::Attachment attachment, unsigned texture);
// gl::handle::framebuffer m_handle;
// unsigned m_width;
// unsigned m_height;
// unsigned m_samples;
// std::vector<gl::Attachment> m_draw_buffers;
// std::map<gl::Attachment, std::shared_ptr<core::TextureEXT>> m_color_attachments;
// std::shared_ptr<core::TextureEXT> m_depth_attachment;
//};
//// -------------------------------------------------------------------------------------------------------------------------
//// --- IMPLEMENTATIONS -----------------------------------------------------------------------------------------------------
//// -------------------------------------------------------------------------------------------------------------------------
//template<template<gl::TextureFormat, gl::TextureInternalFormat, gl::Type> typename TTextureBase>
//FramebufferOLD<TTextureBase>::FramebufferOLD(unsigned width, unsigned height, unsigned samples)
// : m_width(width), m_height(height), m_samples(samples) {}
//template<template<gl::TextureFormat, gl::TextureInternalFormat, gl::Type> typename TTextureBase>
//FramebufferOLD<TTextureBase>::~FramebufferOLD() {}
//template<template<gl::TextureFormat, gl::TextureInternalFormat, gl::Type> typename TTextureBase>
//void FramebufferOLD<TTextureBase>::resize(unsigned width, unsigned height, unsigned samples)
//{
// if (width == m_width && height == m_height)
// return;
// m_width = width;
// m_height = height;
// m_samples = samples;
// for (auto &&texture : m_color_attachments) {
// is_multisampled ? texture.second->resize(width, height, m_samples) : texture.second->resize(width, height);
// }
// if (m_depth_attachment) {
// is_multisampled ? m_depth_attachment->resize(width, height, m_samples) : m_depth_attachment->resize(width, height);
// }
//}
//template<template<gl::TextureFormat, gl::TextureInternalFormat, gl::Type> typename TTextureBase>
//void FramebufferOLD<TTextureBase>::activate() const
//{
// gl::bindFramebuffer(gl::FramebufferTarget::eDefault, m_handle);
//}
//template<template<gl::TextureFormat, gl::TextureInternalFormat, gl::Type> typename TTextureBase>
//void FramebufferOLD<TTextureBase>::deactivate() const
//{
// gl::bindFramebuffer(gl::FramebufferTarget::eDefault, 0);
//}
//template<template<gl::TextureFormat, gl::TextureInternalFormat, gl::Type> typename TTextureBase>
//void FramebufferOLD<TTextureBase>::attach(gl::Attachment attachment)
//{
// switch (attachment)
// {
// case gl::Attachment::eDepth:
// case gl::Attachment::eDepthStencil:
// if (is_multisampled)
// m_depth_attachment = std::make_shared<texture_depth_type>(m_width, m_height, m_samples);
// else
// m_depth_attachment = std::make_shared<texture_depth_type>(m_width, m_height);
// gl::namedFramebufferTexture(m_handle, attachment, m_depth_attachment->id(), 0);
// break;
// default:
// {
// std::shared_ptr<texture_color_type> new_attachment;
// if (is_multisampled)
// new_attachment = std::make_shared<texture_color_type>(m_width, m_height, m_samples);
// else
// new_attachment = std::make_shared<texture_color_type>(m_width, m_height);
// m_color_attachments.emplace(attachment, new_attachment);
// putAttachment(attachment, new_attachment->id());
// } break;
// }
//}
//template<template<gl::TextureFormat, gl::TextureInternalFormat, gl::Type> typename TTextureBase>
//const typename FramebufferOLD<TTextureBase>::texture_color_type &Framebuffer<TTextureBase>::colorAttachment(gl::Attachment attachment) const
//{
// return *(m_color_attachments.at(attachment));
//}
//template<template<gl::TextureFormat, gl::TextureInternalFormat, gl::Type> typename TTextureBase>
//const typename FramebufferOLD<TTextureBase>::texture_depth_type &Framebuffer<TTextureBase>::depthAttachment() const
//{
// return *m_depth_attachment;
//}
//template<template<gl::TextureFormat, gl::TextureInternalFormat, gl::Type> typename TTextureBase>
//unsigned FramebufferOLD<TTextureBase>::attachments() const
//{
// return m_color_attachments.size() + unsigned(bool(m_depth_attachment));
//}
//template<template<gl::TextureFormat, gl::TextureInternalFormat, gl::Type> typename TTextureBase>
//void FramebufferOLD<TTextureBase>::putAttachment(gl::Attachment attachment, unsigned texture)
//{
// gl::namedFramebufferTexture(m_handle, attachment, texture, 0);
// if (std::find(m_draw_buffers.begin(), m_draw_buffers.end(), attachment) == m_draw_buffers.end()) {
// m_draw_buffers.push_back(attachment);
// gl::namedFramebufferDrawBuffers(m_handle, m_draw_buffers);
// }
// if (auto status = gl::checkNamedFramebufferStatus(m_handle, gl::FramebufferTarget::eDraw) != gl::FramebufferStatus::eComplete)
// Log_Error << "An error occured when generating the framebuffer: " << static_cast<int>(status);
//}
//template<template<gl::TextureFormat, gl::TextureInternalFormat, gl::Type> typename TTextureBase>
//unsigned FramebufferOLD<TTextureBase>::samples() const
//{
// return m_samples;
//}
}
#endif //INCLUDE_FRAMEBUFFER_H
......@@ -100,7 +100,7 @@ namespace glare::core
{
ShadowMapData shadow_map;
shadow_map.available = m_shadow_map_renderer ? 1 : 0;
shadow_map.map = shadow_map.available ? m_shadow_map_renderer->framebuffer().depthAttachment().makeTextureResident() : 0;
shadow_map.map = shadow_map.available ? m_shadow_map_renderer->framebuffer().attachment(gl::Attachment::eDepth).residentTextureAddress() : 0;
shadow_map.matrix = shadow_map.available ? m_shadow_map_renderer->matrix() : glm::mat4(1.f);
return{ buildLight(), shadow_map };
}
......
......@@ -8,7 +8,7 @@ namespace glare::core
ShadowMap::ShadowMap(unsigned size, unsigned zoom, std::shared_ptr<SceneNode> light_node)
: m_size(size), m_zoom(zoom)
{
m_framebuffer = std::make_unique<core::Framebuffer<Texture>>(size, size);
m_framebuffer = std::make_unique<core::Framebuffer>(size, size);
//m_framebuffer->addAttachment(gl::Attachment::eColor0);
m_framebuffer->attach(gl::Attachment::eDepth);
......@@ -46,10 +46,10 @@ namespace glare::core
m_matrix = m_bias_matrix * m_camera->viewProjectionMatrix();
gl::generateTextureMipmap(m_framebuffer->depthAttachment().id());
gl::generateTextureMipmap(m_framebuffer->attachment(gl::Attachment::eDepth).id());
}
const core::Framebuffer<Texture> &ShadowMap::framebuffer() const
const core::Framebuffer &ShadowMap::framebuffer() const
{
return *m_framebuffer;
}
......
......@@ -17,7 +17,7 @@ namespace glare::core
std::shared_ptr<SceneNode> preUpdate() const;
void build(std::shared_ptr<SceneNode> scene_root);
const Framebuffer<Texture> &framebuffer() const;
const Framebuffer &framebuffer() const;
const Camera &camera() const;
const glm::uvec2 &size() const;
const glm::mat4 &matrix() const;
......@@ -25,7 +25,7 @@ namespace glare::core
private:
std::shared_ptr<SceneNode> m_renderer_node;
std::unique_ptr<Framebuffer<Texture>> m_framebuffer;
std::unique_ptr<Framebuffer> m_framebuffer;
std::shared_ptr<Camera> m_camera;
const glm::mat4 m_bias_matrix = glm::mat4(
......
......@@ -28,7 +28,7 @@ namespace glare::core