post-processing test
This commit is contained in:
@@ -0,0 +1,13 @@
|
|||||||
|
in vec2 v_coord;
|
||||||
|
out vec4 f_color;
|
||||||
|
|
||||||
|
uniform sampler2D u_texture0;
|
||||||
|
uniform float u_timer;
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
vec2 coord = v_coord;
|
||||||
|
coord.x += sin(u_timer*5.0+coord.x*4.0) * 0.02;
|
||||||
|
coord.y += cos(u_timer*5.0+coord.y*4.0) * 0.02;
|
||||||
|
f_color = texture(u_texture0, coord);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
layout (location = 0) in vec2 v_position;
|
||||||
|
|
||||||
|
out vec2 v_coord;
|
||||||
|
|
||||||
|
uniform ivec2 u_screenSize;
|
||||||
|
uniform float u_timer;
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
v_coord = v_position * 0.5 + 0.5;
|
||||||
|
gl_Position = vec4(v_position, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -74,6 +74,7 @@ void AssetsLoader::addDefaults(AssetsLoader& loader, const Content* content) {
|
|||||||
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/gui/cross.png", "gui/cross");
|
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/gui/cross.png", "gui/cross");
|
||||||
if (content) {
|
if (content) {
|
||||||
loader.add(ASSET_SHADER, SHADERS_FOLDER"/ui3d", "ui3d");
|
loader.add(ASSET_SHADER, SHADERS_FOLDER"/ui3d", "ui3d");
|
||||||
|
loader.add(ASSET_SHADER, SHADERS_FOLDER"/screen", "screen");
|
||||||
loader.add(ASSET_SHADER, SHADERS_FOLDER"/background", "background");
|
loader.add(ASSET_SHADER, SHADERS_FOLDER"/background", "background");
|
||||||
loader.add(ASSET_SHADER, SHADERS_FOLDER"/skybox_gen", "skybox_gen");
|
loader.add(ASSET_SHADER, SHADERS_FOLDER"/skybox_gen", "skybox_gen");
|
||||||
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/misc/moon.png", "misc/moon");
|
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/misc/moon.png", "misc/moon");
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include "../graphics/Batch3D.h"
|
#include "../graphics/Batch3D.h"
|
||||||
#include "../graphics/Texture.h"
|
#include "../graphics/Texture.h"
|
||||||
#include "../graphics/LineBatch.h"
|
#include "../graphics/LineBatch.h"
|
||||||
|
#include "../graphics/PostProcessing.h"
|
||||||
#include "../voxels/Chunks.h"
|
#include "../voxels/Chunks.h"
|
||||||
#include "../voxels/Chunk.h"
|
#include "../voxels/Chunk.h"
|
||||||
#include "../voxels/Block.h"
|
#include "../voxels/Block.h"
|
||||||
@@ -39,6 +40,7 @@ WorldRenderer::WorldRenderer(Engine* engine, LevelFrontend* frontend, Player* pl
|
|||||||
level(frontend->getLevel()),
|
level(frontend->getLevel()),
|
||||||
player(player)
|
player(player)
|
||||||
{
|
{
|
||||||
|
postProcessing = std::make_unique<PostProcessing>();
|
||||||
frustumCulling = std::make_unique<Frustum>();
|
frustumCulling = std::make_unique<Frustum>();
|
||||||
lineBatch = std::make_unique<LineBatch>();
|
lineBatch = std::make_unique<LineBatch>();
|
||||||
renderer = std::make_unique<ChunksRenderer>(
|
renderer = std::make_unique<ChunksRenderer>(
|
||||||
@@ -139,8 +141,6 @@ void WorldRenderer::drawChunks(Chunks* chunks, Camera* camera, Shader* shader) {
|
|||||||
|
|
||||||
void WorldRenderer::draw(const GfxContext& pctx, Camera* camera, bool hudVisible){
|
void WorldRenderer::draw(const GfxContext& pctx, Camera* camera, bool hudVisible){
|
||||||
EngineSettings& settings = engine->getSettings();
|
EngineSettings& settings = engine->getSettings();
|
||||||
|
|
||||||
Window::clearDepth();
|
|
||||||
skybox->refresh(pctx, level->world->daytime, 1.0f+fog*2.0f, 4);
|
skybox->refresh(pctx, level->world->daytime, 1.0f+fog*2.0f, 4);
|
||||||
|
|
||||||
const Content* content = level->content;
|
const Content* content = level->content;
|
||||||
@@ -154,12 +154,19 @@ void WorldRenderer::draw(const GfxContext& pctx, Camera* camera, bool hudVisible
|
|||||||
int displayWidth = viewport.getWidth();
|
int displayWidth = viewport.getWidth();
|
||||||
int displayHeight = viewport.getHeight();
|
int displayHeight = viewport.getHeight();
|
||||||
|
|
||||||
|
// World render scope with diegetic HUD included
|
||||||
|
{
|
||||||
|
GfxContext wctx = pctx.sub();
|
||||||
|
postProcessing->use(wctx);
|
||||||
|
|
||||||
|
Window::clearDepth();
|
||||||
|
|
||||||
// Drawing background sky plane
|
// Drawing background sky plane
|
||||||
skybox->draw(pctx, camera, assets, level->getWorld()->daytime, fog);
|
skybox->draw(pctx, camera, assets, level->getWorld()->daytime, fog);
|
||||||
|
|
||||||
// Actually world render with depth buffer on
|
// Actually world render with depth buffer on
|
||||||
{
|
{
|
||||||
GfxContext ctx = pctx.sub();
|
GfxContext ctx = wctx.sub();
|
||||||
ctx.setDepthTest(true);
|
ctx.setDepthTest(true);
|
||||||
ctx.setCullFace(true);
|
ctx.setCullFace(true);
|
||||||
|
|
||||||
@@ -266,6 +273,19 @@ void WorldRenderer::draw(const GfxContext& pctx, Camera* camera, bool hudVisible
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
GfxContext ctx = pctx.sub();
|
||||||
|
ctx.setDepthTest(false);
|
||||||
|
|
||||||
|
auto shader = assets->getShader("screen");
|
||||||
|
shader->use();
|
||||||
|
shader->uniform1f("u_timer", Window::time());
|
||||||
|
shader->uniform1f("u_dayTime", level->world->daytime);
|
||||||
|
|
||||||
|
postProcessing->render(ctx, shader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void WorldRenderer::drawBorders(int sx, int sy, int sz, int ex, int ey, int ez) {
|
void WorldRenderer::drawBorders(int sx, int sy, int sz, int ex, int ey, int ez) {
|
||||||
int ww = ex-sx;
|
int ww = ex-sx;
|
||||||
int dd = ez-sz;
|
int dd = ez-sz;
|
||||||
|
|||||||
@@ -20,17 +20,18 @@ class Batch3D;
|
|||||||
class LineBatch;
|
class LineBatch;
|
||||||
class ChunksRenderer;
|
class ChunksRenderer;
|
||||||
class Shader;
|
class Shader;
|
||||||
class Texture;
|
|
||||||
class Frustum;
|
class Frustum;
|
||||||
class Engine;
|
class Engine;
|
||||||
class Chunks;
|
class Chunks;
|
||||||
class LevelFrontend;
|
class LevelFrontend;
|
||||||
class Skybox;
|
class Skybox;
|
||||||
|
class PostProcessing;
|
||||||
|
|
||||||
class WorldRenderer {
|
class WorldRenderer {
|
||||||
Engine* engine;
|
Engine* engine;
|
||||||
Level* level;
|
Level* level;
|
||||||
Player* player;
|
Player* player;
|
||||||
|
std::unique_ptr<PostProcessing> postProcessing;
|
||||||
std::unique_ptr<Frustum> frustumCulling;
|
std::unique_ptr<Frustum> frustumCulling;
|
||||||
std::unique_ptr<LineBatch> lineBatch;
|
std::unique_ptr<LineBatch> lineBatch;
|
||||||
std::unique_ptr<ChunksRenderer> renderer;
|
std::unique_ptr<ChunksRenderer> renderer;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ Framebuffer::Framebuffer(uint width, uint height, bool alpha)
|
|||||||
|
|
||||||
// Setup color attachment (texture)
|
// Setup color attachment (texture)
|
||||||
GLuint tex;
|
GLuint tex;
|
||||||
GLuint format = alpha ? GL_RGBA : GL_RGB;
|
format = alpha ? GL_RGBA : GL_RGB;
|
||||||
glGenTextures(1, &tex);
|
glGenTextures(1, &tex);
|
||||||
glBindTexture(GL_TEXTURE_2D, tex);
|
glBindTexture(GL_TEXTURE_2D, tex);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, nullptr);
|
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, nullptr);
|
||||||
@@ -55,6 +55,16 @@ void Framebuffer::unbind() {
|
|||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Framebuffer::resize(uint width, uint height) {
|
||||||
|
if (this->width == width && this->height == height) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GLuint texid = texture->getId();
|
||||||
|
texture->bind();
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, nullptr);
|
||||||
|
texture->unbind();
|
||||||
|
}
|
||||||
|
|
||||||
Texture* Framebuffer::getTexture() const {
|
Texture* Framebuffer::getTexture() const {
|
||||||
return texture.get();
|
return texture.get();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,17 +12,30 @@ class Framebuffer {
|
|||||||
uint depth;
|
uint depth;
|
||||||
uint width;
|
uint width;
|
||||||
uint height;
|
uint height;
|
||||||
|
uint format;
|
||||||
std::unique_ptr<Texture> texture;
|
std::unique_ptr<Texture> texture;
|
||||||
public:
|
public:
|
||||||
Framebuffer(uint fbo, uint depth, std::unique_ptr<Texture> texture);
|
Framebuffer(uint fbo, uint depth, std::unique_ptr<Texture> texture);
|
||||||
Framebuffer(uint width, uint height, bool alpha=false);
|
Framebuffer(uint width, uint height, bool alpha=false);
|
||||||
~Framebuffer();
|
~Framebuffer();
|
||||||
|
|
||||||
|
/// @brief Use framebuffer
|
||||||
void bind();
|
void bind();
|
||||||
|
|
||||||
|
/// @brief Stop using framebuffer
|
||||||
void unbind();
|
void unbind();
|
||||||
|
|
||||||
|
/// @brief Update framebuffer texture size
|
||||||
|
/// @param width new width
|
||||||
|
/// @param height new height
|
||||||
|
void resize(uint width, uint height);
|
||||||
|
|
||||||
|
/// @brief Get framebuffer color attachment
|
||||||
Texture* getTexture() const;
|
Texture* getTexture() const;
|
||||||
|
|
||||||
|
/// @brief Get framebuffer width
|
||||||
uint getWidth() const;
|
uint getWidth() const;
|
||||||
|
/// @brief Get framebuffer height
|
||||||
uint getHeight() const;
|
uint getHeight() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ GfxContext::~GfxContext() {
|
|||||||
fbo->unbind();
|
fbo->unbind();
|
||||||
}
|
}
|
||||||
if (parent->fbo) {
|
if (parent->fbo) {
|
||||||
fbo->bind();
|
parent->fbo->bind();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
#include "PostProcessing.h"
|
||||||
|
#include "Mesh.h"
|
||||||
|
#include "Shader.h"
|
||||||
|
#include "Texture.h"
|
||||||
|
#include "Framebuffer.h"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
PostProcessing::PostProcessing() {
|
||||||
|
// Fullscreen quad mesh bulding
|
||||||
|
float vertices[] {
|
||||||
|
-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f,
|
||||||
|
-1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f
|
||||||
|
};
|
||||||
|
vattr attrs[] {{2}, {0}};
|
||||||
|
quadMesh = std::make_unique<Mesh>(vertices, 6, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
PostProcessing::~PostProcessing() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void PostProcessing::use(GfxContext& context) {
|
||||||
|
const auto& vp = context.getViewport();
|
||||||
|
if (fbo) {
|
||||||
|
fbo->resize(vp.getWidth(), vp.getHeight());
|
||||||
|
} else {
|
||||||
|
fbo = std::make_unique<Framebuffer>(vp.getWidth(), vp.getHeight());
|
||||||
|
}
|
||||||
|
context.setFramebuffer(fbo.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
void PostProcessing::render(GfxContext& context, Shader* screenShader) {
|
||||||
|
if (fbo == nullptr) {
|
||||||
|
throw std::runtime_error("'use(...)' was never called");
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& viewport = context.getViewport();
|
||||||
|
screenShader->use();
|
||||||
|
screenShader->uniform2i("u_screenSize", viewport.size());
|
||||||
|
fbo->getTexture()->bind();
|
||||||
|
quadMesh->draw();
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#ifndef GRAPHICS_POST_PROCESSING_H_
|
||||||
|
#define GRAPHICS_POST_PROCESSING_H_
|
||||||
|
|
||||||
|
#include "Viewport.h"
|
||||||
|
#include "GfxContext.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class Mesh;
|
||||||
|
class Shader;
|
||||||
|
class Framebuffer;
|
||||||
|
|
||||||
|
/// @brief Framebuffer with blitting with shaders.
|
||||||
|
/// @attention Current implementation does not support multiple render passes
|
||||||
|
/// for multiple effects. Will be implemented in v0.21
|
||||||
|
class PostProcessing {
|
||||||
|
/// @brief Main framebuffer (lasy field)
|
||||||
|
std::unique_ptr<Framebuffer> fbo;
|
||||||
|
/// @brief Fullscreen quad mesh as the post-processing canvas
|
||||||
|
std::unique_ptr<Mesh> quadMesh;
|
||||||
|
public:
|
||||||
|
PostProcessing();
|
||||||
|
~PostProcessing();
|
||||||
|
|
||||||
|
/// @brief Prepare and bind framebuffer
|
||||||
|
/// @param context graphics context will be modified
|
||||||
|
void use(GfxContext& context);
|
||||||
|
|
||||||
|
/// @brief Render fullscreen quad using the passed shader
|
||||||
|
/// with framebuffer texture bound
|
||||||
|
/// @param context graphics context
|
||||||
|
/// @param screenShader shader used for fullscreen quad
|
||||||
|
/// @throws std::runtime_error if use(...) wasn't called before
|
||||||
|
void render(GfxContext& context, Shader* screenShader);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // GRAPHICS_POST_PROCESSING_H_
|
||||||
@@ -52,6 +52,11 @@ void Shader::uniform2f(std::string name, glm::vec2 xy){
|
|||||||
glUniform2f(transformLoc, xy.x, xy.y);
|
glUniform2f(transformLoc, xy.x, xy.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Shader::uniform2i(std::string name, glm::ivec2 xy){
|
||||||
|
GLuint transformLoc = glGetUniformLocation(id, name.c_str());
|
||||||
|
glUniform2i(transformLoc, xy.x, xy.y);
|
||||||
|
}
|
||||||
|
|
||||||
void Shader::uniform3f(std::string name, float x, float y, float z){
|
void Shader::uniform3f(std::string name, float x, float y, float z){
|
||||||
GLuint transformLoc = glGetUniformLocation(id, name.c_str());
|
GLuint transformLoc = glGetUniformLocation(id, name.c_str());
|
||||||
glUniform3f(transformLoc, x,y,z);
|
glUniform3f(transformLoc, x,y,z);
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ public:
|
|||||||
void uniform1f(std::string name, float x);
|
void uniform1f(std::string name, float x);
|
||||||
void uniform2f(std::string name, float x, float y);
|
void uniform2f(std::string name, float x, float y);
|
||||||
void uniform2f(std::string name, glm::vec2 xy);
|
void uniform2f(std::string name, glm::vec2 xy);
|
||||||
|
void uniform2i(std::string name, glm::ivec2 xy);
|
||||||
void uniform3f(std::string name, float x, float y, float z);
|
void uniform3f(std::string name, float x, float y, float z);
|
||||||
void uniform3f(std::string name, glm::vec3 xyz);
|
void uniform3f(std::string name, glm::vec3 xyz);
|
||||||
|
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ public:
|
|||||||
virtual uint getWidth() const;
|
virtual uint getWidth() const;
|
||||||
virtual uint getHeight() const;
|
virtual uint getHeight() const;
|
||||||
|
|
||||||
glm::vec2 size() const {
|
glm::ivec2 size() const {
|
||||||
return glm::vec2(width, height);
|
return glm::ivec2(width, height);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user