feat: Add OpenGL renderbuffer abstraction
This commit is contained in:
parent
df61386f9a
commit
88c78c8bae
10 changed files with 187 additions and 50 deletions
|
@ -169,6 +169,7 @@ set(RENDER_HEADERS
|
|||
src/render/model/modelnode.h
|
||||
src/render/model/models.h
|
||||
src/render/pbribl.h
|
||||
src/render/renderbuffer.h
|
||||
src/render/shaders.h
|
||||
src/render/stateutil.h
|
||||
src/render/texture.h
|
||||
|
@ -205,6 +206,7 @@ set(RENDER_SOURCES
|
|||
src/render/model/modelnode.cpp
|
||||
src/render/model/models.cpp
|
||||
src/render/pbribl.cpp
|
||||
src/render/renderbuffer.cpp
|
||||
src/render/shaders.cpp
|
||||
src/render/stateutil.cpp
|
||||
src/render/texture.cpp
|
||||
|
|
|
@ -76,6 +76,10 @@ void Framebuffer::attachDepth(const Texture &texture) const {
|
|||
}
|
||||
}
|
||||
|
||||
void Framebuffer::attachDepth(const Renderbuffer &renderbuffer) const {
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuffer.id());
|
||||
}
|
||||
|
||||
void Framebuffer::checkCompleteness() {
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||
throw logic_error("Framebuffer is not complete");
|
||||
|
|
|
@ -17,6 +17,11 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
#include "renderbuffer.h"
|
||||
#include "texture.h"
|
||||
|
||||
namespace reone {
|
||||
|
@ -26,7 +31,7 @@ namespace render {
|
|||
/**
|
||||
* Abstraction over the OpenGL framebuffer used for off-screen rendering.
|
||||
*/
|
||||
class Framebuffer {
|
||||
class Framebuffer : boost::noncopyable {
|
||||
public:
|
||||
Framebuffer() = default;
|
||||
~Framebuffer();
|
||||
|
@ -53,6 +58,8 @@ public:
|
|||
*/
|
||||
void attachDepth(const Texture &texture) const;
|
||||
|
||||
void attachDepth(const Renderbuffer &renderbuffer) const;
|
||||
|
||||
/**
|
||||
* Throws logic_error if this framebuffer is not complete. Framebuffer must be bound.
|
||||
*/
|
||||
|
@ -61,9 +68,6 @@ public:
|
|||
private:
|
||||
bool _inited { false };
|
||||
uint32_t _framebuffer { 0 };
|
||||
|
||||
Framebuffer(const Framebuffer &) = delete;
|
||||
Framebuffer &operator=(const Framebuffer &) = delete;
|
||||
};
|
||||
|
||||
} // namespace render
|
||||
|
|
|
@ -17,15 +17,16 @@
|
|||
|
||||
#include "pbribl.h"
|
||||
|
||||
#include "glm/ext.hpp"
|
||||
|
||||
#include "GL/glew.h"
|
||||
|
||||
#include "SDL2/SDL_opengl.h"
|
||||
|
||||
#include "glm/ext.hpp"
|
||||
|
||||
#include "meshes.h"
|
||||
#include "renderbuffer.h"
|
||||
#include "shaders.h"
|
||||
#include "stateutil.h"
|
||||
#include "texture.h"
|
||||
#include "textureutil.h"
|
||||
|
||||
using namespace std;
|
||||
|
@ -103,10 +104,10 @@ shared_ptr<Texture> PBRIBL::computeIrradianceMap(const Texture *envmap) {
|
|||
irradianceColor->bind();
|
||||
irradianceColor->clearPixels(32, 32, Texture::PixelFormat::RGB);
|
||||
|
||||
auto irradianceDepth = make_shared<Texture>(envmap->name() + "_irradiance_depth", getTextureProperties(TextureUsage::DepthBuffer));
|
||||
auto irradianceDepth = make_shared<Renderbuffer>();
|
||||
irradianceDepth->init();
|
||||
irradianceDepth->bind();
|
||||
irradianceDepth->clearPixels(32, 32, Texture::PixelFormat::Depth);
|
||||
irradianceDepth->configure(32, 32, Renderbuffer::PixelFormat::Depth);
|
||||
|
||||
_irradianceFB.bind();
|
||||
|
||||
|
@ -142,10 +143,10 @@ shared_ptr<Texture> PBRIBL::computePrefilterMap(const Texture *envmap) {
|
|||
prefilterColor->bind();
|
||||
prefilterColor->clearPixels(128, 128, Texture::PixelFormat::RGB);
|
||||
|
||||
auto prefilterDepth = make_shared<Texture>(envmap->name() + "_prefilter_depth", getTextureProperties(TextureUsage::DepthBuffer));
|
||||
auto prefilterDepth = make_shared<Renderbuffer>();
|
||||
prefilterDepth->init();
|
||||
prefilterDepth->bind();
|
||||
prefilterDepth->clearPixels(128, 128, Texture::PixelFormat::Depth);
|
||||
prefilterDepth->configure(128, 128, Renderbuffer::PixelFormat::Depth);
|
||||
|
||||
_prefilterFB.bind();
|
||||
|
||||
|
@ -192,10 +193,10 @@ shared_ptr<Texture> PBRIBL::computeBRDFLookup(const Texture *envmap) {
|
|||
brdfLookupColor->bind();
|
||||
brdfLookupColor->clearPixels(512, 512, Texture::PixelFormat::RGB);
|
||||
|
||||
auto brdfLookupDepth = make_shared<Texture>(envmap->name() + "_brdf_depth", getTextureProperties(TextureUsage::DepthBuffer));
|
||||
auto brdfLookupDepth = make_shared<Renderbuffer>();
|
||||
brdfLookupDepth->init();
|
||||
brdfLookupDepth->bind();
|
||||
brdfLookupDepth->clearPixels(512, 512, Texture::PixelFormat::Depth);
|
||||
brdfLookupDepth->configure(512, 512, Renderbuffer::PixelFormat::Depth);
|
||||
|
||||
_brdfLookupFB.bind();
|
||||
_brdfLookupFB.attachColor(*brdfLookupColor);
|
||||
|
|
73
src/render/renderbuffer.cpp
Normal file
73
src/render/renderbuffer.cpp
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (c) 2020-2021 The reone project contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "renderbuffer.h"
|
||||
|
||||
#include "GL/glew.h"
|
||||
#include "SDL2/SDL_opengl.h"
|
||||
|
||||
namespace reone {
|
||||
|
||||
namespace render {
|
||||
|
||||
void Renderbuffer::init() {
|
||||
if (!_inited) {
|
||||
glGenRenderbuffers(1, &_id);
|
||||
_inited = true;
|
||||
}
|
||||
}
|
||||
|
||||
Renderbuffer::~Renderbuffer() {
|
||||
deinit();
|
||||
}
|
||||
|
||||
void Renderbuffer::deinit() {
|
||||
if (_inited) {
|
||||
glDeleteRenderbuffers(1, &_id);
|
||||
_inited = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Renderbuffer::bind() const {
|
||||
if (_inited) {
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, _id);
|
||||
}
|
||||
}
|
||||
|
||||
void Renderbuffer::unbind() const {
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
}
|
||||
|
||||
static GLenum getInternalFormatGL(Renderbuffer::PixelFormat format) {
|
||||
switch (format) {
|
||||
case Renderbuffer::PixelFormat::Depth:
|
||||
return GL_DEPTH_COMPONENT;
|
||||
case Renderbuffer::PixelFormat::RGB:
|
||||
return GL_RGB8;
|
||||
case Renderbuffer::PixelFormat::RGBA:
|
||||
default:
|
||||
return GL_RGBA8;
|
||||
}
|
||||
}
|
||||
|
||||
void Renderbuffer::configure(int w, int h, PixelFormat format) {
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, getInternalFormatGL(format), w, h);
|
||||
}
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace reone
|
62
src/render/renderbuffer.h
Normal file
62
src/render/renderbuffer.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (c) 2020-2021 The reone project contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
namespace reone {
|
||||
|
||||
namespace render {
|
||||
|
||||
/**
|
||||
* Abstraction over the OpenGL renderbuffer.
|
||||
*/
|
||||
class Renderbuffer : boost::noncopyable {
|
||||
public:
|
||||
enum class PixelFormat {
|
||||
Depth,
|
||||
RGB,
|
||||
RGBA
|
||||
};
|
||||
|
||||
Renderbuffer() = default;
|
||||
~Renderbuffer();
|
||||
|
||||
void init();
|
||||
void deinit();
|
||||
|
||||
void bind() const;
|
||||
void unbind() const;
|
||||
|
||||
/**
|
||||
* Configures this renderbuffers size and internal format. Renderbuffer must be bound.
|
||||
*/
|
||||
void configure(int w, int h, PixelFormat format);
|
||||
|
||||
uint32_t id() const { return _id; }
|
||||
|
||||
private:
|
||||
bool _inited { false };
|
||||
uint32_t _id { 0 };
|
||||
};
|
||||
|
||||
} // namespace render
|
||||
|
||||
} // namespace reone
|
|
@ -17,10 +17,10 @@
|
|||
|
||||
#include "control.h"
|
||||
|
||||
#include "glm/ext.hpp"
|
||||
|
||||
#include "GL/glew.h"
|
||||
|
||||
#include "glm/ext.hpp"
|
||||
|
||||
#include "../../render/meshes.h"
|
||||
#include "../../render/shaders.h"
|
||||
#include "../../render/stateutil.h"
|
||||
|
@ -45,10 +45,10 @@ void ControlRenderPipeline::init() {
|
|||
_geometryColor->clearPixels(_extent[2], _extent[3], Texture::PixelFormat::RGBA);
|
||||
_geometryColor->unbind();
|
||||
|
||||
_geometryDepth = make_unique<Texture>("geometry_depth", getTextureProperties(TextureUsage::DepthBuffer));
|
||||
_geometryDepth = make_unique<Renderbuffer>();
|
||||
_geometryDepth->init();
|
||||
_geometryDepth->bind();
|
||||
_geometryDepth->clearPixels(_extent[2], _extent[3], Texture::PixelFormat::Depth);
|
||||
_geometryDepth->configure(_extent[2], _extent[3], Renderbuffer::PixelFormat::Depth);
|
||||
_geometryDepth->unbind();
|
||||
|
||||
_geometry.init();
|
||||
|
|
|
@ -17,10 +17,14 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
#include "glm/vec2.hpp"
|
||||
#include "glm/vec4.hpp"
|
||||
|
||||
#include "../../render/framebuffer.h"
|
||||
#include "../../render/renderbuffer.h"
|
||||
#include "../../render/texture.h"
|
||||
|
||||
#include "../scenegraph.h"
|
||||
|
||||
|
@ -28,7 +32,7 @@ namespace reone {
|
|||
|
||||
namespace scene {
|
||||
|
||||
class ControlRenderPipeline {
|
||||
class ControlRenderPipeline : boost::noncopyable {
|
||||
public:
|
||||
ControlRenderPipeline(SceneGraph *scene, const glm::ivec4 &extent);
|
||||
|
||||
|
@ -41,10 +45,7 @@ private:
|
|||
|
||||
render::Framebuffer _geometry;
|
||||
std::unique_ptr<render::Texture> _geometryColor;
|
||||
std::unique_ptr<render::Texture> _geometryDepth;
|
||||
|
||||
ControlRenderPipeline(const ControlRenderPipeline &) = delete;
|
||||
ControlRenderPipeline &operator=(const ControlRenderPipeline &) = delete;
|
||||
std::unique_ptr<render::Renderbuffer> _geometryDepth;
|
||||
};
|
||||
|
||||
} // namespace scene
|
||||
|
|
|
@ -49,6 +49,15 @@ WorldRenderPipeline::WorldRenderPipeline(SceneGraph *scene, const GraphicsOption
|
|||
}
|
||||
|
||||
void WorldRenderPipeline::init() {
|
||||
// Reusable depth renderbuffer
|
||||
|
||||
_depthRenderbuffer = make_unique<Renderbuffer>();
|
||||
_depthRenderbuffer->init();
|
||||
_depthRenderbuffer->bind();
|
||||
_depthRenderbuffer->configure(_opts.width, _opts.height, Renderbuffer::PixelFormat::Depth);
|
||||
_depthRenderbuffer->unbind();
|
||||
|
||||
|
||||
// Geometry framebuffer
|
||||
|
||||
_geometryColor1 = make_unique<Texture>("geometry_color1", getTextureProperties(TextureUsage::ColorBuffer));
|
||||
|
@ -63,17 +72,11 @@ void WorldRenderPipeline::init() {
|
|||
_geometryColor2->clearPixels(_opts.width, _opts.height, Texture::PixelFormat::RGB);
|
||||
_geometryColor2->unbind();
|
||||
|
||||
_geometryDepth = make_unique<Texture>("geometry_depth", getTextureProperties(TextureUsage::DepthBuffer));
|
||||
_geometryDepth->init();
|
||||
_geometryDepth->bind();
|
||||
_geometryDepth->clearPixels(_opts.width, _opts.height, Texture::PixelFormat::Depth);
|
||||
_geometryDepth->unbind();
|
||||
|
||||
_geometry.init();
|
||||
_geometry.bind();
|
||||
_geometry.attachColor(*_geometryColor1, 0);
|
||||
_geometry.attachColor(*_geometryColor2, 1);
|
||||
_geometry.attachDepth(*_geometryDepth);
|
||||
_geometry.attachDepth(*_depthRenderbuffer);
|
||||
_geometry.checkCompleteness();
|
||||
_geometry.unbind();
|
||||
|
||||
|
@ -86,16 +89,10 @@ void WorldRenderPipeline::init() {
|
|||
_verticalBlurColor->clearPixels(_opts.width, _opts.height, Texture::PixelFormat::RGB);
|
||||
_verticalBlurColor->unbind();
|
||||
|
||||
_verticalBlurDepth = make_unique<Texture>("verticalblur_depth", getTextureProperties(TextureUsage::DepthBuffer));
|
||||
_verticalBlurDepth->init();
|
||||
_verticalBlurDepth->bind();
|
||||
_verticalBlurDepth->clearPixels(_opts.width, _opts.height, Texture::PixelFormat::Depth);
|
||||
_verticalBlurDepth->unbind();
|
||||
|
||||
_verticalBlur.init();
|
||||
_verticalBlur.bind();
|
||||
_verticalBlur.attachColor(*_verticalBlurColor);
|
||||
_verticalBlur.attachDepth(*_verticalBlurDepth);
|
||||
_verticalBlur.attachDepth(*_depthRenderbuffer);
|
||||
_verticalBlur.checkCompleteness();
|
||||
_verticalBlur.unbind();
|
||||
|
||||
|
@ -108,16 +105,10 @@ void WorldRenderPipeline::init() {
|
|||
_horizontalBlurColor->clearPixels(_opts.width, _opts.height, Texture::PixelFormat::RGB);
|
||||
_horizontalBlurColor->unbind();
|
||||
|
||||
_horizontalBlurDepth = make_unique<Texture>("horizontalblur_depth", getTextureProperties(TextureUsage::DepthBuffer));
|
||||
_horizontalBlurDepth->init();
|
||||
_horizontalBlurDepth->bind();
|
||||
_horizontalBlurDepth->clearPixels(_opts.width, _opts.height, Texture::PixelFormat::Depth);
|
||||
_horizontalBlurDepth->unbind();
|
||||
|
||||
_horizontalBlur.init();
|
||||
_horizontalBlur.bind();
|
||||
_horizontalBlur.attachColor(*_horizontalBlurColor);
|
||||
_horizontalBlur.attachDepth(*_horizontalBlurDepth);
|
||||
_horizontalBlur.attachDepth(*_depthRenderbuffer);
|
||||
_horizontalBlur.checkCompleteness();
|
||||
_horizontalBlur.unbind();
|
||||
|
||||
|
|
|
@ -17,9 +17,13 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
#include "glm/mat4x4.hpp"
|
||||
|
||||
#include "../../render/framebuffer.h"
|
||||
#include "../../render/renderbuffer.h"
|
||||
#include "../../render/texture.h"
|
||||
#include "../../render/types.h"
|
||||
#include "../../scene/scenegraph.h"
|
||||
|
||||
|
@ -27,7 +31,7 @@ namespace reone {
|
|||
|
||||
namespace scene {
|
||||
|
||||
class WorldRenderPipeline {
|
||||
class WorldRenderPipeline : boost::noncopyable {
|
||||
public:
|
||||
WorldRenderPipeline(SceneGraph *scene, const render::GraphicsOptions &opts);
|
||||
|
||||
|
@ -49,20 +53,15 @@ private:
|
|||
|
||||
// Framebuffer targets
|
||||
|
||||
std::unique_ptr<render::Renderbuffer> _depthRenderbuffer;
|
||||
std::unique_ptr<render::Texture> _geometryColor1;
|
||||
std::unique_ptr<render::Texture> _geometryColor2;
|
||||
std::unique_ptr<render::Texture> _geometryDepth;
|
||||
std::unique_ptr<render::Texture> _verticalBlurColor;
|
||||
std::unique_ptr<render::Texture> _verticalBlurDepth;
|
||||
std::unique_ptr<render::Texture> _horizontalBlurColor;
|
||||
std::unique_ptr<render::Texture> _horizontalBlurDepth;
|
||||
std::unique_ptr<render::Texture> _shadowsDepth;
|
||||
|
||||
// END Framebuffers targets
|
||||
|
||||
WorldRenderPipeline(const WorldRenderPipeline &) = delete;
|
||||
WorldRenderPipeline &operator=(const WorldRenderPipeline &) = delete;
|
||||
|
||||
void drawShadows() const;
|
||||
void drawGeometry() const;
|
||||
void applyHorizontalBlur() const;
|
||||
|
|
Loading…
Reference in a new issue