initial commit
This commit is contained in:
@@ -100,7 +100,7 @@ void DrawContext::setViewport(const glm::uvec2& viewport) {
|
||||
glViewport(0, 0, viewport.x, viewport.y);
|
||||
}
|
||||
|
||||
void DrawContext::setFramebuffer(Framebuffer* fbo) {
|
||||
void DrawContext::setFramebuffer(Bindable* fbo) {
|
||||
if (this->fbo == fbo)
|
||||
return;
|
||||
this->fbo = fbo;
|
||||
|
||||
@@ -16,7 +16,7 @@ class DrawContext {
|
||||
glm::uvec2 viewport;
|
||||
Batch2D* g2d;
|
||||
Flushable* flushable = nullptr;
|
||||
Framebuffer* fbo = nullptr;
|
||||
Bindable* fbo = nullptr;
|
||||
bool depthMask = true;
|
||||
bool depthTest = false;
|
||||
bool cullFace = false;
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
DrawContext sub(Flushable* flushable=nullptr) const;
|
||||
|
||||
void setViewport(const glm::uvec2& viewport);
|
||||
void setFramebuffer(Framebuffer* fbo);
|
||||
void setFramebuffer(Bindable* fbo);
|
||||
void setDepthMask(bool flag);
|
||||
void setDepthTest(bool flag);
|
||||
void setCullFace(bool flag);
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
#include <GL/glew.h>
|
||||
#include "Texture.hpp"
|
||||
#include "debug/Logger.hpp"
|
||||
|
||||
static debug::Logger logger("gl-framebuffer");
|
||||
|
||||
Framebuffer::Framebuffer(uint fbo, uint depth, std::unique_ptr<Texture> texture)
|
||||
: fbo(fbo), depth(depth), texture(std::move(texture))
|
||||
@@ -38,18 +41,41 @@ Framebuffer::Framebuffer(uint width, uint height, bool alpha)
|
||||
|
||||
// Setup color attachment (texture)
|
||||
texture = create_texture(width, height, format);
|
||||
|
||||
|
||||
glGenTextures(1, &positions);
|
||||
glBindTexture(GL_TEXTURE_2D, positions);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_FLOAT, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, positions, 0);
|
||||
|
||||
glGenTextures(1, &normals);
|
||||
glBindTexture(GL_TEXTURE_2D, normals);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_FLOAT, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, normals, 0);
|
||||
|
||||
unsigned int attachments[3] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };
|
||||
glDrawBuffers(3, attachments);
|
||||
|
||||
// Setup depth attachment
|
||||
glGenRenderbuffers(1, &depth);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, depth);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth);
|
||||
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||
logger.error() << "framebuffer is not complete!";
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
Framebuffer::~Framebuffer() {
|
||||
glDeleteFramebuffers(1, &fbo);
|
||||
glDeleteRenderbuffers(1, &depth);
|
||||
glDeleteTextures(1, &normals);
|
||||
glDeleteTextures(1, &depth);
|
||||
}
|
||||
|
||||
void Framebuffer::bind() {
|
||||
@@ -60,6 +86,19 @@ void Framebuffer::unbind() {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void Framebuffer::bindBuffers() {
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture->getId());
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, positions);
|
||||
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_2D, normals);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
void Framebuffer::resize(uint width, uint height) {
|
||||
if (this->width == width && this->height == height) {
|
||||
return;
|
||||
@@ -67,11 +106,22 @@ void Framebuffer::resize(uint width, uint height) {
|
||||
this->width = width;
|
||||
this->height = height;
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, depth);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
glBindTexture(GL_TEXTURE_2D, positions);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, NULL);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, positions, 0);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, normals);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, NULL);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, normals, 0);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
texture = create_texture(width, height, format);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "typedefs.hpp"
|
||||
#include "commons.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
class Texture;
|
||||
|
||||
class Framebuffer {
|
||||
class Framebuffer : public Bindable {
|
||||
uint fbo;
|
||||
uint depth;
|
||||
uint positions;
|
||||
uint normals;
|
||||
uint width;
|
||||
uint height;
|
||||
uint format;
|
||||
@@ -19,10 +22,12 @@ public:
|
||||
~Framebuffer();
|
||||
|
||||
/// @brief Use framebuffer
|
||||
void bind();
|
||||
void bind() override;
|
||||
|
||||
/// @brief Stop using framebuffer
|
||||
void unbind();
|
||||
void unbind() override;
|
||||
|
||||
void bindBuffers();
|
||||
|
||||
/// @brief Update framebuffer texture size
|
||||
/// @param width new width
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
#include "GBuffer.hpp"
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include "debug/Logger.hpp"
|
||||
|
||||
static debug::Logger logger("gl-gbuffer");
|
||||
|
||||
void GBuffer::createColorBuffer() {
|
||||
glGenTextures(1, &colorBuffer);
|
||||
glBindTexture(GL_TEXTURE_2D, colorBuffer);
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_RGB,
|
||||
width,
|
||||
height,
|
||||
0,
|
||||
GL_RGB,
|
||||
GL_UNSIGNED_BYTE,
|
||||
nullptr
|
||||
);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
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, GL_TEXTURE_2D, colorBuffer, 0
|
||||
);
|
||||
}
|
||||
|
||||
void GBuffer::createPositionsBuffer() {
|
||||
glGenTextures(1, &positionsBuffer);
|
||||
glBindTexture(GL_TEXTURE_2D, positionsBuffer);
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_RGBA16F,
|
||||
width,
|
||||
height,
|
||||
0,
|
||||
GL_RGBA,
|
||||
GL_FLOAT,
|
||||
nullptr
|
||||
);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glFramebufferTexture2D(
|
||||
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, positionsBuffer, 0
|
||||
);
|
||||
}
|
||||
|
||||
void GBuffer::createNormalsBuffer() {
|
||||
glGenTextures(1, &normalsBuffer);
|
||||
glBindTexture(GL_TEXTURE_2D, normalsBuffer);
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_RGBA16F,
|
||||
width,
|
||||
height,
|
||||
0,
|
||||
GL_RGBA,
|
||||
GL_FLOAT,
|
||||
nullptr
|
||||
);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glFramebufferTexture2D(
|
||||
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, normalsBuffer, 0
|
||||
);
|
||||
}
|
||||
|
||||
void GBuffer::createDepthBuffer() {
|
||||
glGenRenderbuffers(1, &depthBuffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
|
||||
glFramebufferRenderbuffer(
|
||||
GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer
|
||||
);
|
||||
}
|
||||
|
||||
GBuffer::GBuffer(uint width, uint height) : width(width), height(height) {
|
||||
glGenFramebuffers(1, &fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
|
||||
createColorBuffer();
|
||||
createPositionsBuffer();
|
||||
createNormalsBuffer();
|
||||
|
||||
GLenum attachments[3] = {
|
||||
GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2
|
||||
};
|
||||
glDrawBuffers(3, attachments);
|
||||
|
||||
createDepthBuffer();
|
||||
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||
logger.error() << "framebuffer is not complete!";
|
||||
}
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
GBuffer::~GBuffer() {
|
||||
glDeleteTextures(1, &colorBuffer);
|
||||
glDeleteTextures(1, &positionsBuffer);
|
||||
glDeleteTextures(1, &normalsBuffer);
|
||||
glDeleteRenderbuffers(1, &depthBuffer);
|
||||
glDeleteFramebuffers(1, &fbo);
|
||||
}
|
||||
|
||||
void GBuffer::bind() {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
}
|
||||
|
||||
void GBuffer::unbind() {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void GBuffer::bindBuffers() {
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_2D, normalsBuffer);
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, positionsBuffer);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, colorBuffer);
|
||||
}
|
||||
|
||||
void GBuffer::resize(uint width, uint height) {
|
||||
if (this->width == width && this->height == height) {
|
||||
return;
|
||||
}
|
||||
this->width = width;
|
||||
this->height = height;
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, colorBuffer);
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_RGB,
|
||||
width,
|
||||
height,
|
||||
0,
|
||||
GL_RGB,
|
||||
GL_UNSIGNED_BYTE,
|
||||
nullptr
|
||||
);
|
||||
glFramebufferTexture2D(
|
||||
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBuffer, 0
|
||||
);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, positionsBuffer);
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, nullptr
|
||||
);
|
||||
glFramebufferTexture2D(
|
||||
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, positionsBuffer, 0
|
||||
);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, normalsBuffer);
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, nullptr
|
||||
);
|
||||
glFramebufferTexture2D(
|
||||
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, normalsBuffer, 0
|
||||
);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
uint GBuffer::getWidth() const {
|
||||
return width;
|
||||
}
|
||||
|
||||
uint GBuffer::getHeight() const {
|
||||
return height;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include "typedefs.hpp"
|
||||
#include "commons.hpp"
|
||||
|
||||
class GBuffer : public Bindable{
|
||||
public:
|
||||
GBuffer(uint width, uint height);
|
||||
~GBuffer();
|
||||
|
||||
void bind() override;
|
||||
void unbind() override;
|
||||
|
||||
void bindBuffers();
|
||||
|
||||
void resize(uint width, uint height);
|
||||
|
||||
uint getWidth() const;
|
||||
uint getHeight() const;
|
||||
private:
|
||||
uint width;
|
||||
uint height;
|
||||
|
||||
uint fbo;
|
||||
uint colorBuffer;
|
||||
uint positionsBuffer;
|
||||
uint normalsBuffer;
|
||||
uint depthBuffer;
|
||||
|
||||
void createColorBuffer();
|
||||
void createPositionsBuffer();
|
||||
void createNormalsBuffer();
|
||||
void createDepthBuffer();
|
||||
};
|
||||
@@ -6,22 +6,56 @@
|
||||
#include "DrawContext.hpp"
|
||||
#include "PostEffect.hpp"
|
||||
#include "assets/Assets.hpp"
|
||||
#include "window/Camera.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <random>
|
||||
|
||||
PostProcessing::PostProcessing(size_t effectSlotsCount)
|
||||
: effectSlots(effectSlotsCount) {
|
||||
// Fullscreen quad mesh bulding
|
||||
PostProcessingVertex meshData[]{
|
||||
{{-1.0f, -1.0f}},
|
||||
{{-1.0f, 1.0f}},
|
||||
{{1.0f, 1.0f}},
|
||||
{{-1.0f, -1.0f}},
|
||||
{{1.0f, 1.0f}},
|
||||
{{1.0f, -1.0f}},
|
||||
PostProcessingVertex meshData[] {
|
||||
{{-1.0f, -1.0f}},
|
||||
{{-1.0f, 1.0f}},
|
||||
{{1.0f, 1.0f}},
|
||||
{{-1.0f, -1.0f}},
|
||||
{{1.0f, 1.0f}},
|
||||
{{1.0f, -1.0f}},
|
||||
};
|
||||
|
||||
quadMesh = std::make_unique<Mesh<PostProcessingVertex>>(meshData, 6);
|
||||
|
||||
std::vector<glm::vec3> ssaoNoise;
|
||||
for (unsigned int i = 0; i < 16; i++)
|
||||
{
|
||||
glm::vec3 noise(
|
||||
(rand() / static_cast<float>(RAND_MAX)) * 2.0 - 1.0,
|
||||
(rand() / static_cast<float>(RAND_MAX)) * 2.0 - 1.0,
|
||||
0.0f);
|
||||
ssaoNoise.push_back(noise);
|
||||
}
|
||||
glGenTextures(1, &noiseTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, noiseTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, 4, 4, 0, GL_RGB, GL_FLOAT, ssaoNoise.data());
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
std::uniform_real_distribution<float> randomFloats(0.0, 1.0);
|
||||
std::default_random_engine generator;
|
||||
for (unsigned int i = 0; i < 64; ++i)
|
||||
{
|
||||
glm::vec3 sample(
|
||||
randomFloats(generator) * 2.0 - 1.0,
|
||||
randomFloats(generator) * 2.0 - 1.0,
|
||||
randomFloats(generator)
|
||||
);
|
||||
sample = glm::normalize(sample);
|
||||
sample *= randomFloats(generator);
|
||||
ssaoKernel.push_back(sample);
|
||||
}
|
||||
}
|
||||
|
||||
PostProcessing::~PostProcessing() = default;
|
||||
@@ -39,7 +73,7 @@ void PostProcessing::use(DrawContext& context) {
|
||||
}
|
||||
|
||||
void PostProcessing::render(
|
||||
const DrawContext& context, const Assets& assets, float timer
|
||||
const DrawContext& context, const Assets& assets, float timer, const Camera& camera, uint depthMap
|
||||
) {
|
||||
if (fbo == nullptr) {
|
||||
throw std::runtime_error("'use(...)' was never called");
|
||||
@@ -51,8 +85,38 @@ void PostProcessing::render(
|
||||
|
||||
if (totalPasses == 0) {
|
||||
auto& effect = assets.require<PostEffect>("default");
|
||||
effect.use();
|
||||
fbo->getTexture()->bind();
|
||||
fbo->bindBuffers();
|
||||
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glBindTexture(GL_TEXTURE_2D, noiseTexture);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
glActiveTexture(GL_TEXTURE4);
|
||||
glBindTexture(GL_TEXTURE_2D, depthMap);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
const auto& viewport = context.getViewport();
|
||||
|
||||
auto& shader = effect.use();
|
||||
if (!ssaoConfigured) {
|
||||
for (unsigned int i = 0; i < 64; ++i) {
|
||||
auto name = "samples["+ std::to_string(i) + "]";
|
||||
shader.uniform3f(name, ssaoKernel[i]);
|
||||
}
|
||||
ssaoConfigured = true;
|
||||
}
|
||||
shader.uniform1i("u_screen", 0);
|
||||
shader.uniform1i("u_position", 1);
|
||||
shader.uniform1i("u_normal", 2);
|
||||
shader.uniform1i("u_noise", 3);
|
||||
shader.uniform1i("u_shadows", 4);
|
||||
shader.uniform2i("u_screenSize", viewport);
|
||||
shader.uniform1f("u_timer", timer);
|
||||
shader.uniform1f("near_plane", camera.near);
|
||||
shader.uniform1f("far_plane", camera.far);
|
||||
shader.uniformMatrix("u_projection", camera.getProjection());
|
||||
|
||||
quadMesh->draw();
|
||||
return;
|
||||
}
|
||||
@@ -64,15 +128,25 @@ void PostProcessing::render(
|
||||
}
|
||||
auto& shader = effect->use();
|
||||
|
||||
for (unsigned int i = 0; i < 64; ++i) {
|
||||
shader.uniform3f("samples["+ std::to_string(i) + "]", ssaoKernel[i]);
|
||||
}
|
||||
|
||||
const auto& viewport = context.getViewport();
|
||||
shader.uniform1i("u_screen", 0);
|
||||
shader.uniform1i("u_position", 1);
|
||||
shader.uniform1i("u_normal", 2);
|
||||
shader.uniform1i("u_noise", 3);
|
||||
shader.uniform2i("u_screenSize", viewport);
|
||||
shader.uniform1f("u_timer", timer);
|
||||
|
||||
shader.uniformMatrix("u_projection", camera.getProjView(false));
|
||||
fbo->getTexture()->bind();
|
||||
fbo->bindBuffers();
|
||||
|
||||
if (currentPass < totalPasses) {
|
||||
fboSecond->bind();
|
||||
}
|
||||
|
||||
quadMesh->draw();
|
||||
if (currentPass < totalPasses) {
|
||||
fboSecond->unbind();
|
||||
|
||||
@@ -11,6 +11,7 @@ class Framebuffer;
|
||||
class DrawContext;
|
||||
class ImageData;
|
||||
class PostEffect;
|
||||
class Camera;
|
||||
|
||||
struct PostProcessingVertex {
|
||||
glm::vec2 position;
|
||||
@@ -30,6 +31,10 @@ class PostProcessing {
|
||||
/// @brief Fullscreen quad mesh as the post-processing canvas
|
||||
std::unique_ptr<Mesh<PostProcessingVertex>> quadMesh;
|
||||
std::vector<std::shared_ptr<PostEffect>> effectSlots;
|
||||
|
||||
std::vector<glm::vec3> ssaoKernel;
|
||||
uint noiseTexture;
|
||||
bool ssaoConfigured = false;
|
||||
public:
|
||||
PostProcessing(size_t effectSlotsCount);
|
||||
~PostProcessing();
|
||||
@@ -42,7 +47,7 @@ public:
|
||||
/// with framebuffer texture bound
|
||||
/// @param context graphics context
|
||||
/// @throws std::runtime_error if use(...) wasn't called before
|
||||
void render(const DrawContext& context, const Assets& assets, float timer);
|
||||
void render(const DrawContext& context, const Assets& assets, float timer, const Camera& camera, uint depthMap);
|
||||
|
||||
void setEffect(size_t slot, std::shared_ptr<PostEffect> effect);
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
#include "ShadowMap.hpp"
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
ShadowMap::ShadowMap(int resolution) : resolution(resolution) {
|
||||
glGenTextures(1, &depthMap);
|
||||
glBindTexture(GL_TEXTURE_2D, depthMap);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
|
||||
resolution, resolution, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
|
||||
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_S, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
|
||||
float border[4] {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
glTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_BORDER_COLOR, border);
|
||||
|
||||
glGenFramebuffers(1, &fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthMap, 0);
|
||||
glDrawBuffer(GL_NONE);
|
||||
glReadBuffer(GL_NONE);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
ShadowMap::~ShadowMap() {
|
||||
glDeleteFramebuffers(1, &fbo);
|
||||
glDeleteTextures(1, &depthMap);
|
||||
}
|
||||
|
||||
void ShadowMap::bind() {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void ShadowMap::unbind() {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
uint ShadowMap::getDepthMap() const {
|
||||
return depthMap;
|
||||
}
|
||||
|
||||
int ShadowMap::getResolution() const {
|
||||
return resolution;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "typedefs.hpp"
|
||||
|
||||
class ShadowMap {
|
||||
public:
|
||||
ShadowMap(int resolution);
|
||||
~ShadowMap();
|
||||
|
||||
void bind();
|
||||
void unbind();
|
||||
uint getDepthMap() const;
|
||||
int getResolution() const;
|
||||
private:
|
||||
uint fbo;
|
||||
uint depthMap;
|
||||
int resolution;
|
||||
};
|
||||
@@ -69,3 +69,11 @@ public:
|
||||
|
||||
virtual void flush() = 0;
|
||||
};
|
||||
|
||||
class Bindable {
|
||||
public:
|
||||
virtual ~Bindable() = default;
|
||||
|
||||
virtual void bind() = 0;
|
||||
virtual void unbind() = 0;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user