diff options
-rw-r--r-- | cwd/assets/altcraft/shaders/frag/face.fs | 10 | ||||
-rw-r--r-- | cwd/assets/altcraft/shaders/frag/light.fs | 16 | ||||
-rw-r--r-- | cwd/assets/altcraft/shaders/vert/light.vs | 11 | ||||
-rw-r--r-- | src/GalOgl.cpp | 7 | ||||
-rw-r--r-- | src/Render.cpp | 34 | ||||
-rw-r--r-- | src/Render.hpp | 5 | ||||
-rw-r--r-- | src/RenderConfigs.cpp | 75 | ||||
-rw-r--r-- | src/RenderConfigs.hpp | 38 |
8 files changed, 165 insertions, 31 deletions
diff --git a/cwd/assets/altcraft/shaders/frag/face.fs b/cwd/assets/altcraft/shaders/frag/face.fs index 30d44d2..0eb5a21 100644 --- a/cwd/assets/altcraft/shaders/frag/face.fs +++ b/cwd/assets/altcraft/shaders/frag/face.fs @@ -5,14 +5,16 @@ in VS_OUT { vec3 Color; } fs_in; -out vec4 fragColor; +layout (location = 0) out vec4 color; +layout (location = 1) out vec4 normal; uniform sampler2DArray textureAtlas; void main() { - vec4 color = texture(textureAtlas,fs_in.Texture); - if (color.a < 0.3) + vec4 col = texture(textureAtlas, fs_in.Texture); + if (col.a < 0.3) discard; - fragColor = vec4(color.rgb * fs_in.Color, 1.0); + color = vec4(col.rgb * fs_in.Color, 1.0f); + normal = vec4(1.0f - color.r, 1.0f - color.b, 1.0f, 1.0f); } diff --git a/cwd/assets/altcraft/shaders/frag/light.fs b/cwd/assets/altcraft/shaders/frag/light.fs new file mode 100644 index 0000000..480e265 --- /dev/null +++ b/cwd/assets/altcraft/shaders/frag/light.fs @@ -0,0 +1,16 @@ +#version 330 core + +out vec4 fragColor; + +in vec2 uv; + +uniform sampler2D color; +uniform sampler2D normal; +uniform sampler2D depthStencil; + +void main() { + vec4 c = texture(color, uv); + vec4 n = texture(normal, uv); + float d = texture(depthStencil, uv).r; + fragColor = vec4(c.r, n.r, d - 0.3f, 1.0f); +} diff --git a/cwd/assets/altcraft/shaders/vert/light.vs b/cwd/assets/altcraft/shaders/vert/light.vs new file mode 100644 index 0000000..f837ebe --- /dev/null +++ b/cwd/assets/altcraft/shaders/vert/light.vs @@ -0,0 +1,11 @@ +#version 330 core + +in vec2 pos; +in vec2 uvPos; + +out vec2 uv; + +void main() { + gl_Position = vec4(pos.x, pos.y, 0.0, 1.0); + uv = uvPos; +} diff --git a/src/GalOgl.cpp b/src/GalOgl.cpp index 29e7fc0..c250539 100644 --- a/src/GalOgl.cpp +++ b/src/GalOgl.cpp @@ -137,6 +137,7 @@ public: if (activeTexture[textureUnit] != texture) { SetTextureUnit(textureUnit); glBindTexture(type, texture); + activeTexture[textureUnit] = texture; } glCheckError(); } @@ -690,6 +691,7 @@ struct FramebufferOgl : public Framebuffer { size_t vpX = 0, vpY = 0, vpW = 1, vpH = 1; std::shared_ptr<TextureOgl> depthStencil; std::vector<std::shared_ptr<TextureOgl>> colors; + std::vector<GLenum> attachments; GlResource fbo; @@ -853,6 +855,8 @@ struct PipelineOgl : public Pipeline { oglState.UseProgram(program); oglState.BindFbo(target->fbo); oglState.SetViewport(target->vpX, target->vpY, target->vpW, target->vpH); + if (target->fbo) + glDrawBuffers(target->attachments.size(), target->attachments.data()); for (size_t i = 0; i < staticTextures.size(); i++) { oglState.BindTexture(staticTextures[i]->type, staticTextures[i]->texture, i); @@ -1226,6 +1230,7 @@ struct ImplOgl : public Impl { glUniform1i(location, usedTextureBlocks); pipeline->staticTextures.push_back(texture); + usedTextureBlocks++; } glCheckError(); @@ -1299,6 +1304,7 @@ struct ImplOgl : public Impl { for (auto&& [location, texture] : conf->colors) { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + location, texture->type, texture->texture, 0); fb->colors.emplace_back(std::move(texture)); + fb->attachments.push_back(GL_COLOR_ATTACHMENT0 + location); } if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { @@ -1315,6 +1321,7 @@ struct ImplOgl : public Impl { if (!fbDefault) fbDefault = std::make_shared<FramebufferOgl>(); fbDefault->fbo = GlResource(0, GlResourceType::None); + fbDefault->attachments.push_back(GL_COLOR_ATTACHMENT0); return std::static_pointer_cast<Framebuffer, FramebufferOgl>(fbDefault); } diff --git a/src/Render.cpp b/src/Render.cpp index 02f56ff..96c1ed8 100644 --- a/src/Render.cpp +++ b/src/Render.cpp @@ -17,6 +17,7 @@ #include "Plugin.hpp" #include "Rml.hpp" #include "Gal.hpp" +#include "RenderConfigs.hpp" const std::map<SDL_Keycode, Rml::Input::KeyIdentifier> keyMapping = { {SDLK_BACKSPACE, Rml::Input::KI_BACK}, @@ -77,9 +78,8 @@ Render::~Render() { rmlRender.reset(); rmlSystem.reset(); - PluginSystem::Init(); + PluginSystem::Init(); - framebuffer.reset(); SDL_GL_DeleteContext(glContext); SDL_DestroyWindow(window); SDL_Quit(); @@ -137,28 +137,12 @@ void Render::PrepareToRendering() { float resolutionScale = Settings::ReadDouble("resolutionScale", 1.0f); size_t scaledW = width * resolutionScale, scaledH = height * resolutionScale; + gbuffer = std::make_unique<Gbuffer>(scaledW, scaledH, scaledW, scaledH); + auto gal = Gal::GetImplementation(); gal->GetDefaultFramebuffer()->SetViewport(0, 0, width, height); - auto dsTexConf = gal->CreateTexture2DConfig(scaledW, scaledH, Gal::Format::D24S8); - dsTexConf->SetMinFilter(Gal::Filtering::Bilinear); - dsTexConf->SetMaxFilter(Gal::Filtering::Bilinear); - fbDepthStencil = gal->BuildTexture(dsTexConf); - - auto texConf = gal->CreateTexture2DConfig(scaledW, scaledH, Gal::Format::R8G8B8A8); - texConf->SetMinFilter(Gal::Filtering::Bilinear); - texConf->SetMaxFilter(Gal::Filtering::Bilinear); - fbColor = gal->BuildTexture(texConf); - - auto fbConf = gal->CreateFramebufferConfig(); - fbConf->SetTexture(0, fbColor); - fbConf->SetDepthStencil(fbDepthStencil); - - framebuffer = gal->BuildFramebuffer(fbConf); - framebuffer->SetViewport(0, 0, scaledW, scaledH); - framebuffer->Clear(); - std::string vertexSource, pixelSource; { auto vertAsset = AssetManager::GetAssetByAssetName("/altcraft/shaders/vert/fbo"); @@ -184,7 +168,7 @@ void Render::PrepareToRendering() { fbPPC->SetTarget(gal->GetDefaultFramebuffer()); fbPPC->SetVertexShader(gal->LoadVertexShader(vertexSource)); fbPPC->SetPixelShader(gal->LoadPixelShader(pixelSource)); - fbPPC->AddStaticTexture("inputTexture", fbColor); + fbPPC->AddStaticTexture("inputTexture", gbuffer->GetFinalTexture()); auto fbColorBB = fbPPC->BindVertexBuffer({ {"Pos", Gal::Type::Vec2}, {"TextureCoords", Gal::Type::Vec2} @@ -196,7 +180,7 @@ void Render::PrepareToRendering() { }); if (world) - world->PrepareRender(framebuffer); + world->PrepareRender(gbuffer->GetGeometryTarget()); } void Render::UpdateKeyboard() { @@ -221,7 +205,7 @@ void Render::RenderFrame() { OPTICK_EVENT(); Gal::GetImplementation()->GetDefaultFramebuffer()->Clear(); - framebuffer->Clear(); + gbuffer->Clear(); if (isWireframe) Gal::GetImplementation()->SetWireframe(true); @@ -230,6 +214,8 @@ void Render::RenderFrame() { if (isWireframe) Gal::GetImplementation()->SetWireframe(false); + gbuffer->Render(); + fbPipeline->Activate(); fbPipelineInstance->Activate(); fbPipelineInstance->Render(0, 6); @@ -487,7 +473,7 @@ void Render::InitEvents() { listener.RegisterHandler("PlayerConnected", [this](const Event&) { stateString = "Loading terrain..."; - world = std::make_unique<RendererWorld>(framebuffer); + world = std::make_unique<RendererWorld>(gbuffer->GetGeometryTarget()); world->MaxRenderingDistance = Settings::ReadDouble("renderDistance", 2.0f); PUSH_EVENT("UpdateSectionsRender", 0); }); diff --git a/src/Render.hpp b/src/Render.hpp index 87494fa..379ca66 100644 --- a/src/Render.hpp +++ b/src/Render.hpp @@ -11,6 +11,7 @@ #include "Event.hpp" #include "Gal.hpp" +class Gbuffer; class RendererWorld; class RmlRenderInterface; class RmlSystemInterface; @@ -35,12 +36,10 @@ class Render { bool HasFocus=true; float sensetivity = 0.1f; bool isWireframe = false; - std::shared_ptr<Gal::Framebuffer> framebuffer; - std::shared_ptr<Gal::Texture> fbDepthStencil; - std::shared_ptr<Gal::Texture> fbColor; std::shared_ptr<Gal::Pipeline> fbPipeline; std::shared_ptr<Gal::PipelineInstance> fbPipelineInstance; std::shared_ptr<Gal::Buffer> fbBuffer; + std::unique_ptr<Gbuffer> gbuffer; EventListener listener; std::string stateString; std::unique_ptr<RmlRenderInterface> rmlRender; diff --git a/src/RenderConfigs.cpp b/src/RenderConfigs.cpp new file mode 100644 index 0000000..ebdbaef --- /dev/null +++ b/src/RenderConfigs.cpp @@ -0,0 +1,75 @@ +#include "RenderConfigs.hpp" + +#include "AssetManager.hpp" + +Gbuffer::Gbuffer(size_t geomW, size_t geomH, size_t lightW, size_t lightH) { + auto gal = Gal::GetImplementation(); + + auto colorConf = gal->CreateTexture2DConfig(geomW, geomH, Gal::Format::R8G8B8A8); + color = gal->BuildTexture(colorConf); + + auto normalConf = gal->CreateTexture2DConfig(geomW, geomH, Gal::Format::R8G8B8A8); + normal = gal->BuildTexture(normalConf); + + auto dsConf = gal->CreateTexture2DConfig(geomW, geomH, Gal::Format::D24S8); + depthStencil = gal->BuildTexture(dsConf); + + auto geomFbConf = gal->CreateFramebufferConfig(); + geomFbConf->SetTexture(0, color); + geomFbConf->SetTexture(1, normal); + geomFbConf->SetDepthStencil(depthStencil); + + geomFramebuffer = gal->BuildFramebuffer(geomFbConf); + geomFramebuffer->SetViewport(0, 0, geomW, geomH); + + auto finalColorConf = gal->CreateTexture2DConfig(lightW, lightH, Gal::Format::R8G8B8A8); + finalColor = gal->BuildTexture(finalColorConf); + + auto lightFbConf = gal->CreateFramebufferConfig(); + lightFbConf->SetTexture(0, finalColor); + + lightFramebuffer = gal->BuildFramebuffer(lightFbConf); + lightFramebuffer->SetViewport(0, 0, lightW, lightH); + + std::string vertexSource, pixelSource; + { + auto vertAsset = AssetManager::GetAssetByAssetName("/altcraft/shaders/vert/light"); + vertexSource = std::string((char*)vertAsset->data.data(), (char*)vertAsset->data.data() + vertAsset->data.size()); + + auto pixelAsset = AssetManager::GetAssetByAssetName("/altcraft/shaders/frag/light"); + pixelSource = std::string((char*)pixelAsset->data.data(), (char*)pixelAsset->data.data() + pixelAsset->data.size()); + } + + auto lightPPC = gal->CreatePipelineConfig(); + lightPPC->SetTarget(lightFramebuffer); + lightPPC->AddStaticTexture("color", color); + lightPPC->AddStaticTexture("normal", normal); + lightPPC->AddStaticTexture("depthStencil", depthStencil); + + lightPPC->SetVertexShader(gal->LoadVertexShader(vertexSource)); + lightPPC->SetPixelShader(gal->LoadPixelShader(pixelSource)); + + auto lightBB = lightPPC->BindVertexBuffer({ + {"pos", Gal::Type::Vec2}, + {"uvPos", Gal::Type::Vec2} + }); + + lightPipeline = gal->BuildPipeline(lightPPC); + + constexpr float quadVertices[] = { + // pos // uv + -1.0f, 1.0f, 0.0f, 1.0f, + -1.0f, -1.0f, 0.0f, 0.0f, + 1.0f, -1.0f, 1.0f, 0.0f, + + -1.0f, 1.0f, 0.0f, 1.0f, + 1.0f, -1.0f, 1.0f, 0.0f, + 1.0f, 1.0f, 1.0f, 1.0f + }; + lightBuffer = gal->CreateBuffer(); + lightBuffer->SetData({ reinterpret_cast<const std::byte*>(quadVertices), reinterpret_cast<const std::byte*>(quadVertices) + sizeof(quadVertices) }); + + lightPipelineInstance = lightPipeline->CreateInstance({ + {lightBB, lightBuffer} + }); +} diff --git a/src/RenderConfigs.hpp b/src/RenderConfigs.hpp new file mode 100644 index 0000000..6279169 --- /dev/null +++ b/src/RenderConfigs.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include "Gal.hpp" + +class Gbuffer { + std::shared_ptr<Gal::Framebuffer> lightFramebuffer; + std::shared_ptr<Gal::Buffer> lightBuffer; + std::shared_ptr<Gal::Pipeline> lightPipeline; + std::shared_ptr<Gal::PipelineInstance> lightPipelineInstance; + std::shared_ptr<Gal::Texture> color; + std::shared_ptr<Gal::Texture> normal; + std::shared_ptr<Gal::Texture> depthStencil; + std::shared_ptr<Gal::Framebuffer> geomFramebuffer; + + std::shared_ptr<Gal::Texture> finalColor; + +public: + Gbuffer(size_t geomW, size_t geomH, size_t lightW, size_t lightH); + + std::shared_ptr<Gal::Framebuffer> GetGeometryTarget() { + return geomFramebuffer; + } + + std::shared_ptr<Gal::Texture> GetFinalTexture() { + return finalColor; + } + + void Render() { + lightPipeline->Activate(); + lightPipelineInstance->Activate(); + lightPipelineInstance->Render(0, 6); + } + + void Clear() { + geomFramebuffer->Clear(); + lightFramebuffer->Clear(); + } +}; |