move some code there and here

This commit is contained in:
MihailRis 2026-05-12 18:41:14 +03:00
parent a7ad219261
commit 28b7713648
12 changed files with 84 additions and 76 deletions

View file

@ -74,6 +74,18 @@ DrawContext::~DrawContext() {
if (lineWidth != parent->lineWidth) { if (lineWidth != parent->lineWidth) {
glLineWidth(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 { const glm::uvec2& DrawContext::getViewport() const {
@ -154,3 +166,13 @@ void DrawContext::setLineWidth(float width) {
lineWidth = width; lineWidth = width;
glLineWidth(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;
}

View file

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <array>
#include <glm/vec2.hpp> #include <glm/vec2.hpp>
#include <glm/vec4.hpp> #include <glm/vec4.hpp>
@ -23,6 +24,7 @@ class DrawContext {
BlendMode blendMode = BlendMode::normal; BlendMode blendMode = BlendMode::normal;
int scissorsCount = 0; int scissorsCount = 0;
float lineWidth = 1.0f; float lineWidth = 1.0f;
std::array<const Bindable*, advanced_pipeline::TARGETS_COUNT> textures {};
public: public:
DrawContext( DrawContext(
const DrawContext* parent, const DrawContext* parent,
@ -44,4 +46,5 @@ public:
void setBlendMode(BlendMode mode); void setBlendMode(BlendMode mode);
void setScissors(const glm::vec4& area); void setScissors(const glm::vec4& area);
void setLineWidth(float width); void setLineWidth(float width);
void useTexture(int target, const Bindable* texture);
}; };

View file

@ -84,11 +84,11 @@ void Framebuffer::setTexture(std::unique_ptr<Texture> texture) {
this->texture = std::move(texture); this->texture = std::move(texture);
} }
void Framebuffer::bind() { void Framebuffer::bind() const {
glBindFramebuffer(GL_FRAMEBUFFER, fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo);
} }
void Framebuffer::unbind() { void Framebuffer::unbind() const {
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
} }

View file

@ -21,10 +21,10 @@ public:
void setTexture(std::unique_ptr<Texture> texture); void setTexture(std::unique_ptr<Texture> texture);
/// @brief Use framebuffer /// @brief Use framebuffer
void bind() override; void bind() const override;
/// @brief Stop using framebuffer /// @brief Stop using framebuffer
void unbind() override; void unbind() const override;
/// @brief Update framebuffer texture size /// @brief Update framebuffer texture size
/// @param width new width /// @param width new width

View file

@ -189,7 +189,7 @@ GBuffer::~GBuffer() {
glDeleteFramebuffers(1, &ssaoFbo); glDeleteFramebuffers(1, &ssaoFbo);
} }
void GBuffer::bind() { void GBuffer::bind() const {
glBindFramebuffer(GL_FRAMEBUFFER, fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
} }
@ -198,7 +198,7 @@ void GBuffer::bindSSAO() const {
glBindFramebuffer(GL_FRAMEBUFFER, ssaoFbo); glBindFramebuffer(GL_FRAMEBUFFER, ssaoFbo);
} }
void GBuffer::unbind() { void GBuffer::unbind() const {
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
} }

View file

@ -9,9 +9,9 @@ public:
GBuffer(uint width, uint height); GBuffer(uint width, uint height);
~GBuffer() override; ~GBuffer() override;
void bind() override; void bind() const override;
void bindSSAO() const; void bindSSAO() const;
void unbind() override; void unbind() const override;
void bindBuffers() const; void bindBuffers() const;
void bindSSAOBuffer() const; void bindSSAOBuffer() const;

View file

@ -1,12 +1,13 @@
#pragma once #pragma once
#include "typedefs.hpp"
#include "maths/UVRegion.hpp"
#include "ImageData.hpp"
#include <memory> #include <memory>
class Texture { #include "ImageData.hpp"
#include "commons.hpp"
#include "maths/UVRegion.hpp"
#include "typedefs.hpp"
class Texture : public Bindable {
protected: protected:
uint id; uint id;
uint width; uint width;
@ -17,8 +18,8 @@ public:
Texture(const ubyte* data, uint width, uint height, ImageFormat format); Texture(const ubyte* data, uint width, uint height, ImageFormat format);
virtual ~Texture(); virtual ~Texture();
virtual void bind() const; virtual void bind() const override;
virtual void unbind() const; virtual void unbind() const override;
virtual void reload(const ubyte* data, uint w, uint h); virtual void reload(const ubyte* data, uint w, uint h);
void reloadPartial(const ImageData& image, uint x, uint y, uint w, uint h); void reloadPartial(const ImageData& image, uint x, uint y, uint w, uint h);

View file

@ -59,6 +59,8 @@ namespace advanced_pipeline {
inline constexpr int TARGET_SSAO = 5; inline constexpr int TARGET_SSAO = 5;
inline constexpr int TARGET_SHADOWS0 = 6; inline constexpr int TARGET_SHADOWS0 = 6;
inline constexpr int TARGET_SHADOWS1 = 7; inline constexpr int TARGET_SHADOWS1 = 7;
inline constexpr int TARGETS_COUNT = 8;
} }
VC_ENUM_METADATA(CursorShape) VC_ENUM_METADATA(CursorShape)
@ -85,6 +87,6 @@ class Bindable {
public: public:
virtual ~Bindable() = default; virtual ~Bindable() = default;
virtual void bind() = 0; virtual void bind() const = 0;
virtual void unbind() = 0; virtual void unbind() const = 0;
}; };

View file

@ -34,4 +34,7 @@ void HandsRenderer::render(const Camera& camera) {
glm::vec3(), glm::vec3(),
glm::vec3(1.0f) glm::vec3(1.0f)
); );
modelBatch.render();
modelBatch.setLightsOffset(glm::vec3());
} }

View file

@ -80,9 +80,11 @@ void Skybox::drawBackground(const Camera& camera, int width, int height) {
); );
backShader->uniform1f("u_ar", float(width) / float(height)); backShader->uniform1f("u_ar", float(width) / float(height));
backShader->uniform1i("u_skybox", 1); backShader->uniform1i("u_skybox", 1);
bind();
auto texture = fbo->getTexture();
texture->bind();
mesh->draw(); mesh->draw();
unbind(); texture->unbind();
} }
void Skybox::drawStars(float angle, float opacity) { void Skybox::drawStars(float angle, float opacity) {
@ -150,9 +152,6 @@ void Skybox::draw(
float fog float fog
) { ) {
const glm::uvec2& viewport = pctx.getViewport(); const glm::uvec2& viewport = pctx.getViewport();
glActiveTexture(GL_TEXTURE0);
drawBackground(camera, viewport.x, viewport.y); drawBackground(camera, viewport.x, viewport.y);
float angle = daytime * glm::pi<float>() * 2.0f; float angle = daytime * glm::pi<float>() * 2.0f;
@ -216,13 +215,12 @@ void Skybox::refresh(
ctx.setDepthTest(false); ctx.setDepthTest(false);
ctx.setFramebuffer(fbo.get()); ctx.setFramebuffer(fbo.get());
ctx.setViewport({fbo->getWidth(), fbo->getHeight()}); 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<Cubemap*>(fbo->getTexture()); auto cubemap = dynamic_cast<Cubemap*>(fbo->getTexture());
assert(cubemap != nullptr); assert(cubemap != nullptr);
glActiveTexture(GL_TEXTURE0 + TARGET_SKYBOX);
cubemap->bind();
for (int face = 0; face < 6; face++) { for (int face = 0; face < 6; face++) {
glFramebufferTexture2D( glFramebufferTexture2D(
GL_FRAMEBUFFER, GL_FRAMEBUFFER,
@ -234,8 +232,6 @@ void Skybox::refresh(
glClearColor(tint.r, tint.g, tint.b, 1); glClearColor(tint.r, tint.g, tint.b, 1);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
} }
cubemap->unbind();
return; return;
} }
@ -245,14 +241,12 @@ void Skybox::refresh(
ctx.setDepthTest(false); ctx.setDepthTest(false);
ctx.setFramebuffer(fbo.get()); ctx.setFramebuffer(fbo.get());
ctx.setViewport({fbo->getWidth(), fbo->getHeight()}); 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<Cubemap*>(fbo->getTexture()); auto cubemap = dynamic_cast<Cubemap*>(fbo->getTexture());
assert(cubemap != nullptr); assert(cubemap != nullptr);
glActiveTexture(GL_TEXTURE0 + TARGET_SKYBOX);
cubemap->bind();
shader.use();
float t = dayTime * glm::two_pi<float>(); float t = dayTime * glm::two_pi<float>();
lightDir = glm::normalize(glm::vec3(sin(t), -cos(t), 0.0f)); 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)); rotation = glm::rotate(rotation, z, glm::vec3(0, 0, 1));
lightDir = glm::vec3(rotation * glm::vec4(0, 0, -1, 1)); lightDir = glm::vec3(rotation * glm::vec4(0, 0, -1, 1));
shader.use();
shader.uniform1i("u_quality", quality); shader.uniform1i("u_quality", quality);
shader.uniform1f("u_mie", mie); shader.uniform1f("u_mie", mie);
shader.uniform3f("u_tint", tint); shader.uniform3f("u_tint", tint);
@ -278,21 +273,18 @@ void Skybox::refresh(
glm::abs(prevHighlight.r - hightlight.r) >= glm::abs(prevHighlight.r - hightlight.r) >=
0.01) { 0.01) {
for (uint face = 0; face < 6; face++) { for (uint face = 0; face < 6; face++) {
refreshFace(face, cubemap); refreshFace(face, *cubemap);
} }
} else { } else {
uint face = frameid % 6; uint face = frameid % 6;
refreshFace(face, cubemap); refreshFace(face, *cubemap);
} }
prevMie = mie; prevMie = mie;
prevT = t; prevT = t;
prevHighlight = hightlight; 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[] = { const glm::vec3 xaxs[] = {
{0.0f, 0.0f, -1.0f}, {0.0f, 0.0f, -1.0f},
{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_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face,
cubemap->getId(), cubemap.getId(),
0 0
); );
shader.uniform3f("u_xaxis", xaxs[face]); shader.uniform3f("u_xaxis", xaxs[face]);
@ -334,14 +326,6 @@ void Skybox::refreshFace(uint face, Cubemap* cubemap) {
mesh->draw(); mesh->draw();
} }
void Skybox::bind() const { const Cubemap* Skybox::getCubemap() const {
glActiveTexture(GL_TEXTURE0 + TARGET_SKYBOX); return dynamic_cast<const Cubemap*>(fbo->getTexture());
fbo->getTexture()->bind();
glActiveTexture(GL_TEXTURE0);
}
void Skybox::unbind() const {
glActiveTexture(GL_TEXTURE0 + TARGET_SKYBOX);
fbo->getTexture()->unbind();
glActiveTexture(GL_TEXTURE0);
} }

View file

@ -59,7 +59,7 @@ class Skybox {
void drawStars(float angle, float opacity); void drawStars(float angle, float opacity);
void drawBackground(const Camera& camera, int width, int height); void drawBackground(const Camera& camera, int width, int height);
void drawSkySprites(float daytime, float angle, float opacity); void drawSkySprites(float daytime, float angle, float opacity);
void refreshFace(uint face, Cubemap* cubemap); void refreshFace(uint face, Cubemap& cubemap);
public: public:
Skybox(uint size, const Assets& assets); Skybox(uint size, const Assets& assets);
~Skybox(); ~Skybox();
@ -83,8 +83,8 @@ public:
const glm::vec3& hightlight, const glm::vec3& hightlight,
uint quality uint quality
); );
void bind() const;
void unbind() const; const Cubemap* getCubemap() const;
const glm::vec3& getLightDir() const { const glm::vec3& getLightDir() const {
return lightDir; return lightDir;

View file

@ -1,12 +1,5 @@
#include "WorldRenderer.hpp" #include "WorldRenderer.hpp"
#include <assert.h>
#include <algorithm>
#include <glm/ext.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <memory>
#include "BlockWrapsRenderer.hpp" #include "BlockWrapsRenderer.hpp"
#include "ChunksRenderer.hpp" #include "ChunksRenderer.hpp"
#include "CloudsRenderer.hpp" #include "CloudsRenderer.hpp"
@ -39,6 +32,7 @@
#include "graphics/core/PostProcessing.hpp" #include "graphics/core/PostProcessing.hpp"
#include "graphics/core/Shader.hpp" #include "graphics/core/Shader.hpp"
#include "graphics/core/Shadows.hpp" #include "graphics/core/Shadows.hpp"
#include "graphics/core/Cubemap.hpp"
#include "graphics/core/Texture.hpp" #include "graphics/core/Texture.hpp"
#include "items/Inventory.hpp" #include "items/Inventory.hpp"
#include "items/ItemDef.hpp" #include "items/ItemDef.hpp"
@ -59,7 +53,11 @@
#include "world/LevelEvents.hpp" #include "world/LevelEvents.hpp"
#include "world/World.hpp" #include "world/World.hpp"
using namespace advanced_pipeline; #include <assert.h>
#include <algorithm>
#include <glm/ext.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <memory>
inline constexpr size_t BATCH3D_CAPACITY = 4096; inline constexpr size_t BATCH3D_CAPACITY = 4096;
inline constexpr size_t MODEL_BATCH_CAPACITY = 20'000; inline constexpr size_t MODEL_BATCH_CAPACITY = 20'000;
@ -160,7 +158,7 @@ void WorldRenderer::setupWorldShader(
shader.uniform1i("u_debugNormals", false); shader.uniform1i("u_debugNormals", false);
shader.uniform1f("u_dayTime", level.getWorld()->getInfo().daytime); shader.uniform1f("u_dayTime", level.getWorld()->getInfo().daytime);
shader.uniform2f("u_lightDir", skybox->getLightDir()); 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(); auto indices = level.content.getIndices();
// Light emission when an emissive item is chosen // Light emission when an emissive item is chosen
@ -196,7 +194,6 @@ void WorldRenderer::renderOpaque(
auto& entityShader = assets.require<Shader>("entity"); auto& entityShader = assets.require<Shader>("entity");
setupWorldShader(entityShader, camera, settings, fogFactor); setupWorldShader(entityShader, camera, settings, fogFactor);
skybox->bind();
bool culling = engine.getSettings().graphics.frustumCulling.get(); bool culling = engine.getSettings().graphics.frustumCulling.get();
if (culling) { if (culling) {
@ -237,7 +234,6 @@ void WorldRenderer::renderOpaque(
auto& linesShader = assets.require<Shader>("lines"); auto& linesShader = assets.require<Shader>("lines");
renderLines(camera, linesShader, ctx); renderLines(camera, linesShader, ctx);
} }
skybox->unbind();
} }
void WorldRenderer::renderBlockSelection() { void WorldRenderer::renderBlockSelection() {
@ -378,18 +374,18 @@ void WorldRenderer::renderFrame(
{ {
DrawContext wctx = pctx.sub(); DrawContext wctx = pctx.sub();
postProcessing.use(wctx, gbufferPipeline); postProcessing.use(wctx, gbufferPipeline);
display::clearDepth(); display::clearDepth();
/* Main opaque pass (GBuffer pass) */ { /* Main opaque pass (GBuffer pass) */ {
DrawContext ctx = wctx.sub(); DrawContext ctx = wctx.sub();
ctx.setDepthTest(true); ctx.setDepthTest(true);
ctx.setCullFace(true); ctx.setCullFace(true);
ctx.useTexture(advanced_pipeline::TARGET_SKYBOX, skybox->getCubemap());
ctx.useTexture(advanced_pipeline::TARGET_COLOR, nullptr);
renderOpaque(ctx, camera, settings, hudVisible); renderOpaque(ctx, camera, settings, hudVisible);
} }
texts->render(pctx, camera, settings, hudVisible, true); texts->render(pctx, camera, settings, hudVisible, true);
} }
skybox->bind();
float fogFactor = calcFogFactor(); float fogFactor = calcFogFactor();
if (gbufferPipeline) { if (gbufferPipeline) {
deferredShader.use(); deferredShader.use();
@ -399,6 +395,7 @@ void WorldRenderer::renderFrame(
{ {
DrawContext ctx = pctx.sub(); DrawContext ctx = pctx.sub();
ctx.setDepthTest(true); ctx.setDepthTest(true);
ctx.useTexture(advanced_pipeline::TARGET_COLOR, nullptr);
if (gbufferPipeline) { if (gbufferPipeline) {
postProcessing.bindDepthBuffer(); postProcessing.bindDepthBuffer();
@ -421,10 +418,12 @@ void WorldRenderer::renderFrame(
linesShader.uniformMatrix("u_projview", projView); linesShader.uniformMatrix("u_projview", projView);
lineBatch->flush(); 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 // Translucent blocks
{ {
auto sctx = ctx.sub(); auto sctx = wctx.sub();
sctx.setCullFace(true); sctx.setCullFace(true);
translucentShader.use(); translucentShader.use();
setupWorldShader(translucentShader, camera, settings, fogFactor); setupWorldShader(translucentShader, camera, settings, fogFactor);
@ -450,8 +449,6 @@ void WorldRenderer::renderFrame(
precipitation->render(camera, *weather); precipitation->render(camera, *weather);
} }
} }
skybox->unbind();
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
} }
postProcessing.render(pctx, assets, timer, camera); postProcessing.render(pctx, assets, timer, camera);
@ -460,6 +457,9 @@ void WorldRenderer::renderFrame(
DrawContext ctx = pctx.sub(); DrawContext ctx = pctx.sub();
ctx.setDepthTest(true); ctx.setDepthTest(true);
ctx.setCullFace(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 // prepare modified HUD camera
Camera hudcam = camera; Camera hudcam = camera;
@ -467,15 +467,8 @@ void WorldRenderer::renderFrame(
hudcam.setFov(0.9f); hudcam.setFov(0.9f);
hudcam.position = {}; hudcam.position = {};
hands->render(camera);
display::clearDepth();
setupWorldShader(entityShader, hudcam, engine.getSettings(), 0.0f); setupWorldShader(entityShader, hudcam, engine.getSettings(), 0.0f);
hands->render(camera);
skybox->bind();
modelBatch->render();
modelBatch->setLightsOffset(glm::vec3());
skybox->unbind();
} }
renderBlockOverlay(pctx); renderBlockOverlay(pctx);