diff options
author | x2048 <codeforsmile@gmail.com> | 2022-09-06 08:25:18 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-06 08:25:18 +0200 |
commit | ff6dcfea82974df6db5a557e31aaddb6bdb7a71f (patch) | |
tree | 18bafaedcfdff36a0c0719653b99370b7434b344 /src/client/render/plain.cpp | |
parent | 464043b8abdbd936640757604ecb21662592043b (diff) | |
download | minetest-ff6dcfea82974df6db5a557e31aaddb6bdb7a71f.tar.xz |
Implement rendering pipeline and post-processing (#12465)
Co-authored-by: Lars Mueller <appgurulars@gmx.de>
Co-authored-by: sfan5 <sfan5@live.de>
Co-authored-by: lhofhansl <lhofhansl@yahoo.com>
Diffstat (limited to 'src/client/render/plain.cpp')
-rw-r--r-- | src/client/render/plain.cpp | 144 |
1 files changed, 110 insertions, 34 deletions
diff --git a/src/client/render/plain.cpp b/src/client/render/plain.cpp index a130a14eb..88d2f9b19 100644 --- a/src/client/render/plain.cpp +++ b/src/client/render/plain.cpp @@ -19,58 +19,134 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include "plain.h" -#include "settings.h" +#include "secondstage.h" +#include "client/camera.h" +#include "client/client.h" +#include "client/clientmap.h" +#include "client/hud.h" +#include "client/minimap.h" +#include "client/shadows/dynamicshadowsrender.h" -inline u32 scaledown(u32 coef, u32 size) +/// Draw3D pipeline step +void Draw3D::run(PipelineContext &context) { - return (size + coef - 1) / coef; + if (m_target) + m_target->activate(context); + + context.device->getSceneManager()->drawAll(); + context.device->getVideoDriver()->setTransform(video::ETS_WORLD, core::IdentityMatrix); + if (!context.show_hud) + return; + context.hud->drawBlockBounds(); + context.hud->drawSelectionMesh(); + if (context.draw_wield_tool) + context.client->getCamera()->drawWieldedTool(); } -RenderingCorePlain::RenderingCorePlain( - IrrlichtDevice *_device, Client *_client, Hud *_hud) - : RenderingCore(_device, _client, _hud) +void DrawHUD::run(PipelineContext &context) { - scale = g_settings->getU16("undersampling"); + if (context.show_hud) { + if (context.shadow_renderer) + context.shadow_renderer->drawDebug(); + + if (context.draw_crosshair) + context.hud->drawCrosshair(); + + context.hud->drawHotbar(context.client->getEnv().getLocalPlayer()->getWieldIndex()); + context.hud->drawLuaElements(context.client->getCamera()->getOffset()); + context.client->getCamera()->drawNametags(); + auto mapper = context.client->getMinimap(); + if (mapper && context.show_minimap) + mapper->drawMinimap(); + } + context.device->getGUIEnvironment()->drawAll(); } -void RenderingCorePlain::initTextures() + +void MapPostFxStep::setRenderTarget(RenderTarget * _target) { - if (scale <= 1) - return; - v2u32 size{scaledown(scale, screensize.X), scaledown(scale, screensize.Y)}; - lowres = driver->addRenderTargetTexture( - size, "render_lowres", video::ECF_A8R8G8B8); + target = _target; } -void RenderingCorePlain::clearTextures() +void MapPostFxStep::run(PipelineContext &context) { - if (scale <= 1) - return; - driver->removeTexture(lowres); + if (target) + target->activate(context); + + context.client->getEnv().getClientMap().renderPostFx(context.client->getCamera()->getCameraMode()); } -void RenderingCorePlain::beforeDraw() +void RenderShadowMapStep::run(PipelineContext &context) { - if (scale <= 1) - return; - driver->setRenderTarget(lowres, true, true, skycolor); + // This is necessary to render shadows for animations correctly + context.device->getSceneManager()->getRootSceneNode()->OnAnimate(context.device->getTimer()->getTime()); + context.shadow_renderer->update(); } -void RenderingCorePlain::upscale() +// class UpscaleStep + +void UpscaleStep::run(PipelineContext &context) { - if (scale <= 1) - return; - driver->setRenderTarget(0, true, true); - v2u32 size{scaledown(scale, screensize.X), scaledown(scale, screensize.Y)}; - v2u32 dest_size{scale * size.X, scale * size.Y}; - driver->draw2DImage(lowres, core::rect<s32>(0, 0, dest_size.X, dest_size.Y), - core::rect<s32>(0, 0, size.X, size.Y)); + video::ITexture *lowres = m_source->getTexture(0); + m_target->activate(context); + context.device->getVideoDriver()->draw2DImage(lowres, + core::rect<s32>(0, 0, context.target_size.X, context.target_size.Y), + core::rect<s32>(0, 0, lowres->getSize().Width, lowres->getSize().Height)); +} + +std::unique_ptr<RenderStep> create3DStage(Client *client, v2f scale) +{ + RenderStep *step = new Draw3D(); + if (g_settings->getBool("enable_shaders")) { + RenderPipeline *pipeline = new RenderPipeline(); + pipeline->addStep(pipeline->own(std::unique_ptr<RenderStep>(step))); + + auto effect = addPostProcessing(pipeline, step, scale, client); + effect->setRenderTarget(pipeline->getOutput()); + step = pipeline; + } + return std::unique_ptr<RenderStep>(step); } -void RenderingCorePlain::drawAll() +static v2f getDownscaleFactor() { - draw3D(); - drawPostFx(); - upscale(); - drawHUD(); + u16 undersampling = MYMAX(g_settings->getU16("undersampling"), 1); + return v2f(1.0f / undersampling); +} + +RenderStep* addUpscaling(RenderPipeline *pipeline, RenderStep *previousStep, v2f downscale_factor) +{ + const int TEXTURE_UPSCALE = 0; + + if (downscale_factor.X == 1.0f && downscale_factor.Y == 1.0f) + return previousStep; + + // Initialize buffer + TextureBuffer *buffer = pipeline->createOwned<TextureBuffer>(); + buffer->setTexture(TEXTURE_UPSCALE, downscale_factor, "upscale", video::ECF_A8R8G8B8); + + // Attach previous step to the buffer + TextureBufferOutput *buffer_output = pipeline->createOwned<TextureBufferOutput>(buffer, TEXTURE_UPSCALE); + previousStep->setRenderTarget(buffer_output); + + // Add upscaling step + RenderStep *upscale = pipeline->createOwned<UpscaleStep>(); + upscale->setRenderSource(buffer); + pipeline->addStep(upscale); + + return upscale; +} + +void populatePlainPipeline(RenderPipeline *pipeline, Client *client) +{ + auto downscale_factor = getDownscaleFactor(); + auto step3D = pipeline->own(create3DStage(client, downscale_factor)); + pipeline->addStep(step3D); + pipeline->addStep<MapPostFxStep>(); + + step3D = addUpscaling(pipeline, step3D, downscale_factor); + + step3D->setRenderTarget(pipeline->createOwned<ScreenTarget>()); + + pipeline->addStep<DrawHUD>(); } |