From 28b77136488d988f7e9eb5311db1ac02f8481c2b Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 12 May 2026 18:41:14 +0300 Subject: [PATCH] move some code there and here --- src/graphics/core/DrawContext.cpp | 22 +++++++++++++ src/graphics/core/DrawContext.hpp | 3 ++ src/graphics/core/Framebuffer.cpp | 4 +-- src/graphics/core/Framebuffer.hpp | 4 +-- src/graphics/core/GBuffer.cpp | 4 +-- src/graphics/core/GBuffer.hpp | 4 +-- src/graphics/core/Texture.hpp | 15 +++++---- src/graphics/core/commons.hpp | 6 ++-- src/graphics/render/HandsRenderer.cpp | 3 ++ src/graphics/render/Skybox.cpp | 46 +++++++++------------------ src/graphics/render/Skybox.hpp | 6 ++-- src/graphics/render/WorldRenderer.cpp | 43 +++++++++++-------------- 12 files changed, 84 insertions(+), 76 deletions(-) diff --git a/src/graphics/core/DrawContext.cpp b/src/graphics/core/DrawContext.cpp index fc37fd46d..86e2131b1 100644 --- a/src/graphics/core/DrawContext.cpp +++ b/src/graphics/core/DrawContext.cpp @@ -74,6 +74,18 @@ DrawContext::~DrawContext() { if (lineWidth != parent->lineWidth) { glLineWidth(parent->lineWidth); } + + for (int i = 0; i < textures.size(); i++) { + auto texture = parent->textures[i]; + if (textures[i] != texture) { + glActiveTexture(GL_TEXTURE0 + i); + if (texture == nullptr) { + glBindTexture(GL_TEXTURE_2D, 0); + } else { + texture->bind(); + } + } + } } const glm::uvec2& DrawContext::getViewport() const { @@ -154,3 +166,13 @@ void DrawContext::setLineWidth(float width) { lineWidth = width; glLineWidth(width); } + +void DrawContext::useTexture(int target, const Bindable* texture) { + glActiveTexture(GL_TEXTURE0 + target); + if (texture == nullptr) { + glBindTexture(GL_TEXTURE_2D, 0); + } else { + texture->bind(); + } + textures.at(target) = texture; +} diff --git a/src/graphics/core/DrawContext.hpp b/src/graphics/core/DrawContext.hpp index b14bf71bc..7e568e337 100644 --- a/src/graphics/core/DrawContext.hpp +++ b/src/graphics/core/DrawContext.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -23,6 +24,7 @@ class DrawContext { BlendMode blendMode = BlendMode::normal; int scissorsCount = 0; float lineWidth = 1.0f; + std::array textures {}; public: DrawContext( const DrawContext* parent, @@ -44,4 +46,5 @@ public: void setBlendMode(BlendMode mode); void setScissors(const glm::vec4& area); void setLineWidth(float width); + void useTexture(int target, const Bindable* texture); }; diff --git a/src/graphics/core/Framebuffer.cpp b/src/graphics/core/Framebuffer.cpp index dde31f6be..1dc677096 100644 --- a/src/graphics/core/Framebuffer.cpp +++ b/src/graphics/core/Framebuffer.cpp @@ -84,11 +84,11 @@ void Framebuffer::setTexture(std::unique_ptr texture) { this->texture = std::move(texture); } -void Framebuffer::bind() { +void Framebuffer::bind() const { glBindFramebuffer(GL_FRAMEBUFFER, fbo); } -void Framebuffer::unbind() { +void Framebuffer::unbind() const { glBindFramebuffer(GL_FRAMEBUFFER, 0); } diff --git a/src/graphics/core/Framebuffer.hpp b/src/graphics/core/Framebuffer.hpp index f64d33f37..5f9dc3491 100644 --- a/src/graphics/core/Framebuffer.hpp +++ b/src/graphics/core/Framebuffer.hpp @@ -21,10 +21,10 @@ public: void setTexture(std::unique_ptr texture); /// @brief Use framebuffer - void bind() override; + void bind() const override; /// @brief Stop using framebuffer - void unbind() override; + void unbind() const override; /// @brief Update framebuffer texture size /// @param width new width diff --git a/src/graphics/core/GBuffer.cpp b/src/graphics/core/GBuffer.cpp index aba3103fc..30b0c817a 100644 --- a/src/graphics/core/GBuffer.cpp +++ b/src/graphics/core/GBuffer.cpp @@ -189,7 +189,7 @@ GBuffer::~GBuffer() { glDeleteFramebuffers(1, &ssaoFbo); } -void GBuffer::bind() { +void GBuffer::bind() const { glBindFramebuffer(GL_FRAMEBUFFER, fbo); glClear(GL_COLOR_BUFFER_BIT); } @@ -198,7 +198,7 @@ void GBuffer::bindSSAO() const { glBindFramebuffer(GL_FRAMEBUFFER, ssaoFbo); } -void GBuffer::unbind() { +void GBuffer::unbind() const { glBindFramebuffer(GL_FRAMEBUFFER, 0); } diff --git a/src/graphics/core/GBuffer.hpp b/src/graphics/core/GBuffer.hpp index ae433c873..a549b720b 100644 --- a/src/graphics/core/GBuffer.hpp +++ b/src/graphics/core/GBuffer.hpp @@ -9,9 +9,9 @@ public: GBuffer(uint width, uint height); ~GBuffer() override; - void bind() override; + void bind() const override; void bindSSAO() const; - void unbind() override; + void unbind() const override; void bindBuffers() const; void bindSSAOBuffer() const; diff --git a/src/graphics/core/Texture.hpp b/src/graphics/core/Texture.hpp index 50734a577..30959ed60 100644 --- a/src/graphics/core/Texture.hpp +++ b/src/graphics/core/Texture.hpp @@ -1,12 +1,13 @@ #pragma once -#include "typedefs.hpp" -#include "maths/UVRegion.hpp" -#include "ImageData.hpp" - #include -class Texture { +#include "ImageData.hpp" +#include "commons.hpp" +#include "maths/UVRegion.hpp" +#include "typedefs.hpp" + +class Texture : public Bindable { protected: uint id; uint width; @@ -17,8 +18,8 @@ public: Texture(const ubyte* data, uint width, uint height, ImageFormat format); virtual ~Texture(); - virtual void bind() const; - virtual void unbind() const; + virtual void bind() const override; + virtual void unbind() const override; virtual void reload(const ubyte* data, uint w, uint h); void reloadPartial(const ImageData& image, uint x, uint y, uint w, uint h); diff --git a/src/graphics/core/commons.hpp b/src/graphics/core/commons.hpp index 8785cec10..0ca5a6470 100644 --- a/src/graphics/core/commons.hpp +++ b/src/graphics/core/commons.hpp @@ -59,6 +59,8 @@ namespace advanced_pipeline { inline constexpr int TARGET_SSAO = 5; inline constexpr int TARGET_SHADOWS0 = 6; inline constexpr int TARGET_SHADOWS1 = 7; + + inline constexpr int TARGETS_COUNT = 8; } VC_ENUM_METADATA(CursorShape) @@ -85,6 +87,6 @@ class Bindable { public: virtual ~Bindable() = default; - virtual void bind() = 0; - virtual void unbind() = 0; + virtual void bind() const = 0; + virtual void unbind() const = 0; }; diff --git a/src/graphics/render/HandsRenderer.cpp b/src/graphics/render/HandsRenderer.cpp index 8e2f757b2..17c38d76d 100644 --- a/src/graphics/render/HandsRenderer.cpp +++ b/src/graphics/render/HandsRenderer.cpp @@ -34,4 +34,7 @@ void HandsRenderer::render(const Camera& camera) { glm::vec3(), glm::vec3(1.0f) ); + + modelBatch.render(); + modelBatch.setLightsOffset(glm::vec3()); } diff --git a/src/graphics/render/Skybox.cpp b/src/graphics/render/Skybox.cpp index 79e5552af..ef34384fc 100644 --- a/src/graphics/render/Skybox.cpp +++ b/src/graphics/render/Skybox.cpp @@ -80,9 +80,11 @@ void Skybox::drawBackground(const Camera& camera, int width, int height) { ); backShader->uniform1f("u_ar", float(width) / float(height)); backShader->uniform1i("u_skybox", 1); - bind(); + + auto texture = fbo->getTexture(); + texture->bind(); mesh->draw(); - unbind(); + texture->unbind(); } void Skybox::drawStars(float angle, float opacity) { @@ -150,9 +152,6 @@ void Skybox::draw( float fog ) { const glm::uvec2& viewport = pctx.getViewport(); - - glActiveTexture(GL_TEXTURE0); - drawBackground(camera, viewport.x, viewport.y); float angle = daytime * glm::pi() * 2.0f; @@ -216,13 +215,12 @@ void Skybox::refresh( ctx.setDepthTest(false); ctx.setFramebuffer(fbo.get()); ctx.setViewport({fbo->getWidth(), fbo->getHeight()}); + ctx.useTexture(advanced_pipeline::TARGET_SKYBOX, fbo->getTexture()); + ctx.useTexture(advanced_pipeline::TARGET_COLOR, nullptr); auto cubemap = dynamic_cast(fbo->getTexture()); assert(cubemap != nullptr); - glActiveTexture(GL_TEXTURE0 + TARGET_SKYBOX); - cubemap->bind(); - for (int face = 0; face < 6; face++) { glFramebufferTexture2D( GL_FRAMEBUFFER, @@ -234,8 +232,6 @@ void Skybox::refresh( glClearColor(tint.r, tint.g, tint.b, 1); glClear(GL_COLOR_BUFFER_BIT); } - - cubemap->unbind(); return; } @@ -245,14 +241,12 @@ void Skybox::refresh( ctx.setDepthTest(false); ctx.setFramebuffer(fbo.get()); ctx.setViewport({fbo->getWidth(), fbo->getHeight()}); + ctx.useTexture(advanced_pipeline::TARGET_SKYBOX, fbo->getTexture()); + ctx.useTexture(advanced_pipeline::TARGET_COLOR, nullptr); auto cubemap = dynamic_cast(fbo->getTexture()); assert(cubemap != nullptr); - glActiveTexture(GL_TEXTURE0 + TARGET_SKYBOX); - cubemap->bind(); - shader.use(); - float t = dayTime * glm::two_pi(); lightDir = glm::normalize(glm::vec3(sin(t), -cos(t), 0.0f)); @@ -266,6 +260,7 @@ void Skybox::refresh( rotation = glm::rotate(rotation, z, glm::vec3(0, 0, 1)); lightDir = glm::vec3(rotation * glm::vec4(0, 0, -1, 1)); + shader.use(); shader.uniform1i("u_quality", quality); shader.uniform1f("u_mie", mie); shader.uniform3f("u_tint", tint); @@ -278,21 +273,18 @@ void Skybox::refresh( glm::abs(prevHighlight.r - hightlight.r) >= 0.01) { for (uint face = 0; face < 6; face++) { - refreshFace(face, cubemap); + refreshFace(face, *cubemap); } } else { uint face = frameid % 6; - refreshFace(face, cubemap); + refreshFace(face, *cubemap); } prevMie = mie; prevT = t; prevHighlight = hightlight; - - cubemap->unbind(); - glActiveTexture(GL_TEXTURE0); } -void Skybox::refreshFace(uint face, Cubemap* cubemap) { +void Skybox::refreshFace(uint face, Cubemap& cubemap) { const glm::vec3 xaxs[] = { {0.0f, 0.0f, -1.0f}, {0.0f, 0.0f, 1.0f}, @@ -325,7 +317,7 @@ void Skybox::refreshFace(uint face, Cubemap* cubemap) { GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, - cubemap->getId(), + cubemap.getId(), 0 ); shader.uniform3f("u_xaxis", xaxs[face]); @@ -334,14 +326,6 @@ void Skybox::refreshFace(uint face, Cubemap* cubemap) { mesh->draw(); } -void Skybox::bind() const { - glActiveTexture(GL_TEXTURE0 + TARGET_SKYBOX); - fbo->getTexture()->bind(); - glActiveTexture(GL_TEXTURE0); -} - -void Skybox::unbind() const { - glActiveTexture(GL_TEXTURE0 + TARGET_SKYBOX); - fbo->getTexture()->unbind(); - glActiveTexture(GL_TEXTURE0); +const Cubemap* Skybox::getCubemap() const { + return dynamic_cast(fbo->getTexture()); } diff --git a/src/graphics/render/Skybox.hpp b/src/graphics/render/Skybox.hpp index 270dc066d..6d6074e6e 100644 --- a/src/graphics/render/Skybox.hpp +++ b/src/graphics/render/Skybox.hpp @@ -59,7 +59,7 @@ class Skybox { void drawStars(float angle, float opacity); void drawBackground(const Camera& camera, int width, int height); void drawSkySprites(float daytime, float angle, float opacity); - void refreshFace(uint face, Cubemap* cubemap); + void refreshFace(uint face, Cubemap& cubemap); public: Skybox(uint size, const Assets& assets); ~Skybox(); @@ -83,8 +83,8 @@ public: const glm::vec3& hightlight, uint quality ); - void bind() const; - void unbind() const; + + const Cubemap* getCubemap() const; const glm::vec3& getLightDir() const { return lightDir; diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index e5d838f7d..57cc90f24 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -1,12 +1,5 @@ #include "WorldRenderer.hpp" -#include - -#include -#include -#include -#include - #include "BlockWrapsRenderer.hpp" #include "ChunksRenderer.hpp" #include "CloudsRenderer.hpp" @@ -39,6 +32,7 @@ #include "graphics/core/PostProcessing.hpp" #include "graphics/core/Shader.hpp" #include "graphics/core/Shadows.hpp" +#include "graphics/core/Cubemap.hpp" #include "graphics/core/Texture.hpp" #include "items/Inventory.hpp" #include "items/ItemDef.hpp" @@ -59,7 +53,11 @@ #include "world/LevelEvents.hpp" #include "world/World.hpp" -using namespace advanced_pipeline; +#include +#include +#include +#include +#include inline constexpr size_t BATCH3D_CAPACITY = 4096; inline constexpr size_t MODEL_BATCH_CAPACITY = 20'000; @@ -160,7 +158,7 @@ void WorldRenderer::setupWorldShader( shader.uniform1i("u_debugNormals", false); shader.uniform1f("u_dayTime", level.getWorld()->getInfo().daytime); shader.uniform2f("u_lightDir", skybox->getLightDir()); - shader.uniform1i("u_skybox", TARGET_SKYBOX); + shader.uniform1i("u_skybox", advanced_pipeline::TARGET_SKYBOX); auto indices = level.content.getIndices(); // Light emission when an emissive item is chosen @@ -196,7 +194,6 @@ void WorldRenderer::renderOpaque( auto& entityShader = assets.require("entity"); setupWorldShader(entityShader, camera, settings, fogFactor); - skybox->bind(); bool culling = engine.getSettings().graphics.frustumCulling.get(); if (culling) { @@ -237,7 +234,6 @@ void WorldRenderer::renderOpaque( auto& linesShader = assets.require("lines"); renderLines(camera, linesShader, ctx); } - skybox->unbind(); } void WorldRenderer::renderBlockSelection() { @@ -378,18 +374,18 @@ void WorldRenderer::renderFrame( { DrawContext wctx = pctx.sub(); postProcessing.use(wctx, gbufferPipeline); - display::clearDepth(); /* Main opaque pass (GBuffer pass) */ { DrawContext ctx = wctx.sub(); ctx.setDepthTest(true); ctx.setCullFace(true); + ctx.useTexture(advanced_pipeline::TARGET_SKYBOX, skybox->getCubemap()); + ctx.useTexture(advanced_pipeline::TARGET_COLOR, nullptr); renderOpaque(ctx, camera, settings, hudVisible); } texts->render(pctx, camera, settings, hudVisible, true); } - skybox->bind(); float fogFactor = calcFogFactor(); if (gbufferPipeline) { deferredShader.use(); @@ -399,6 +395,7 @@ void WorldRenderer::renderFrame( { DrawContext ctx = pctx.sub(); ctx.setDepthTest(true); + ctx.useTexture(advanced_pipeline::TARGET_COLOR, nullptr); if (gbufferPipeline) { postProcessing.bindDepthBuffer(); @@ -421,10 +418,12 @@ void WorldRenderer::renderFrame( linesShader.uniformMatrix("u_projview", projView); lineBatch->flush(); - skybox->bind(); + DrawContext wctx = ctx.sub(); + wctx.useTexture(advanced_pipeline::TARGET_SKYBOX, skybox->getCubemap()); + wctx.useTexture(advanced_pipeline::TARGET_COLOR, nullptr); // Translucent blocks { - auto sctx = ctx.sub(); + auto sctx = wctx.sub(); sctx.setCullFace(true); translucentShader.use(); setupWorldShader(translucentShader, camera, settings, fogFactor); @@ -450,8 +449,6 @@ void WorldRenderer::renderFrame( precipitation->render(camera, *weather); } } - skybox->unbind(); - glBindFramebuffer(GL_FRAMEBUFFER, 0); } postProcessing.render(pctx, assets, timer, camera); @@ -460,6 +457,9 @@ void WorldRenderer::renderFrame( DrawContext ctx = pctx.sub(); ctx.setDepthTest(true); ctx.setCullFace(true); + ctx.useTexture(advanced_pipeline::TARGET_SKYBOX, skybox->getCubemap()); + ctx.useTexture(advanced_pipeline::TARGET_COLOR, nullptr); + display::clearDepth(); // prepare modified HUD camera Camera hudcam = camera; @@ -467,15 +467,8 @@ void WorldRenderer::renderFrame( hudcam.setFov(0.9f); hudcam.position = {}; - hands->render(camera); - - display::clearDepth(); setupWorldShader(entityShader, hudcam, engine.getSettings(), 0.0f); - - skybox->bind(); - modelBatch->render(); - modelBatch->setLightsOffset(glm::vec3()); - skybox->unbind(); + hands->render(camera); } renderBlockOverlay(pctx);