mirror of https://github.com/minetest/minetest.git
119 lines
4.0 KiB
C++
119 lines
4.0 KiB
C++
/*
|
|
Minetest
|
|
Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
|
Copyright (C) 2017 numzero, Lobachevskiy Vitaliy <numzer0@yandex.ru>
|
|
Copyright (C) 2020 appgurueu, Lars Mueller <appgurulars@gmx.de>
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU Lesser General Public License as published by
|
|
the Free Software Foundation; either version 2.1 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License along
|
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*/
|
|
|
|
#include "secondstage.h"
|
|
#include "client/client.h"
|
|
#include "client/shader.h"
|
|
#include "client/tile.h"
|
|
|
|
PostProcessingStep::PostProcessingStep(u32 _shader_id, const std::vector<u8> &_texture_map) :
|
|
shader_id(_shader_id), texture_map(_texture_map)
|
|
{
|
|
assert(texture_map.size() <= video::MATERIAL_MAX_TEXTURES);
|
|
configureMaterial();
|
|
}
|
|
|
|
void PostProcessingStep::configureMaterial()
|
|
{
|
|
material.UseMipMaps = false;
|
|
material.ZBuffer = true;
|
|
material.ZWriteEnable = video::EZW_ON;
|
|
for (u32 k = 0; k < texture_map.size(); ++k) {
|
|
material.TextureLayer[k].AnisotropicFilter = false;
|
|
material.TextureLayer[k].BilinearFilter = false;
|
|
material.TextureLayer[k].TrilinearFilter = false;
|
|
material.TextureLayer[k].TextureWrapU = video::ETC_CLAMP_TO_EDGE;
|
|
material.TextureLayer[k].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
|
|
}
|
|
}
|
|
|
|
void PostProcessingStep::setRenderSource(RenderSource *_source)
|
|
{
|
|
source = _source;
|
|
}
|
|
|
|
void PostProcessingStep::setRenderTarget(RenderTarget *_target)
|
|
{
|
|
target = _target;
|
|
}
|
|
|
|
void PostProcessingStep::reset(PipelineContext &context)
|
|
{
|
|
}
|
|
|
|
void PostProcessingStep::run(PipelineContext &context)
|
|
{
|
|
if (target)
|
|
target->activate(context);
|
|
|
|
// attach the shader
|
|
material.MaterialType = context.client->getShaderSource()->getShaderInfo(shader_id).material;
|
|
|
|
auto driver = context.device->getVideoDriver();
|
|
|
|
for (u32 i = 0; i < texture_map.size(); i++)
|
|
material.TextureLayer[i].Texture = source->getTexture(texture_map[i]);
|
|
|
|
static const video::SColor color = video::SColor(0, 0, 0, 255);
|
|
static const video::S3DVertex vertices[4] = {
|
|
video::S3DVertex(1.0, -1.0, 0.0, 0.0, 0.0, -1.0,
|
|
color, 1.0, 0.0),
|
|
video::S3DVertex(-1.0, -1.0, 0.0, 0.0, 0.0, -1.0,
|
|
color, 0.0, 0.0),
|
|
video::S3DVertex(-1.0, 1.0, 0.0, 0.0, 0.0, -1.0,
|
|
color, 0.0, 1.0),
|
|
video::S3DVertex(1.0, 1.0, 0.0, 0.0, 0.0, -1.0,
|
|
color, 1.0, 1.0),
|
|
};
|
|
static const u16 indices[6] = {0, 1, 2, 2, 3, 0};
|
|
driver->setMaterial(material);
|
|
driver->drawVertexPrimitiveList(&vertices, 4, &indices, 2);
|
|
}
|
|
|
|
RenderStep *addPostProcessing(RenderPipeline *pipeline, RenderStep *previousStep, v2f scale, Client *client)
|
|
{
|
|
auto buffer = pipeline->createOwned<TextureBuffer>();
|
|
static const u8 TEXTURE_COLOR = 0;
|
|
static const u8 TEXTURE_DEPTH = 3;
|
|
|
|
// init post-processing buffer
|
|
buffer->setTexture(TEXTURE_COLOR, scale, "3d_render", video::ECF_A8R8G8B8);
|
|
|
|
video::ECOLOR_FORMAT depth_format = video::ECF_D16; // fallback depth format
|
|
auto driver = client->getSceneManager()->getVideoDriver();
|
|
if (driver->queryTextureFormat(video::ECF_D32))
|
|
depth_format = video::ECF_D32;
|
|
else if (driver->queryTextureFormat(video::ECF_D24S8))
|
|
depth_format = video::ECF_D24S8;
|
|
buffer->setDepthTexture(TEXTURE_DEPTH, scale, "3d_depthmap", depth_format);
|
|
|
|
// attach buffer to the previous step
|
|
previousStep->setRenderTarget(buffer);
|
|
|
|
// post-processing stage
|
|
// set up shader
|
|
u32 shader_id = client->getShaderSource()->getShader("second_stage", TILE_MATERIAL_PLAIN, NDT_MESH);
|
|
|
|
RenderStep *effect = pipeline->addStep<PostProcessingStep>(shader_id, std::vector<u8> { TEXTURE_COLOR });
|
|
effect->setRenderSource(buffer);
|
|
return effect;
|
|
}
|