Compare commits

...

16 Commits

Author SHA1 Message Date
Lars Müller
448083aabc
Merge 7bf61ed9c73681b90f5ea2e46ec8da99038ccefe into 9ab447843be1580e2296db5d27daaf01ab0c0512 2024-06-22 19:53:13 -03:00
Lars Müller
7bf61ed9c7
Explain type vs ID 2024-06-02 20:54:13 +02:00
Lars Mueller
1588eab2f7 More refactoring 2024-06-02 18:31:32 +02:00
Lars Mueller
34bd7dcde1 Remove unnecessary assignments 2024-06-02 18:16:56 +02:00
Lars Mueller
8b11c73994 Fix items glowing with shaders enabled 2024-06-02 17:41:49 +02:00
Lars Mueller
7f1105cd47 More refactoring 2024-06-02 17:16:04 +02:00
Lars Mueller
b74c36961b Remove now unused includes 2024-06-02 17:01:08 +02:00
Lars Mueller
b3d957127c Remove always false use_shaders param 2024-06-02 16:38:42 +02:00
Lars Mueller
c1a76bc7db Make functions static as appropriate 2024-06-02 16:31:38 +02:00
Lars Mueller
ed11b33430 Refactor 2024-06-01 21:18:01 +02:00
Lars Mueller
a509aad6b2 Add translucent test item 2024-06-01 17:49:03 +02:00
Lars Mueller
f06364e6a5 Fix flowing water def in devtest 2024-06-01 17:34:49 +02:00
Lars Mueller
8c11c12c69 Set alpha mode of air to clip 2024-06-01 17:29:34 +02:00
Lars Mueller
67810800ad Register opaque variant of marble 2024-05-25 17:23:52 +02:00
Lars Mueller
9375f66c48 Fix rendering of translucent wield meshes 2024-05-25 17:23:52 +02:00
Lars Mueller
a73b4f27cb Make item alpha rendering consistent with their definition 2024-05-25 17:23:33 +02:00
12 changed files with 274 additions and 227 deletions

@ -157,7 +157,7 @@ minetest.register_node("basenodes:water_flowing", {
"Drowning damage: 1",
drawtype = "flowingliquid",
waving = 3,
tiles = {"default_water_flowing.png"},
tiles = {"default_water_flowing.png"..WATER_ALPHA},
special_tiles = {
{name = "default_water_flowing.png"..WATER_ALPHA,
backface_culling = false},

@ -105,3 +105,9 @@ minetest.register_craftitem("testitems:telescope_stick", {
return itemstack
end,
})
minetest.register_craftitem("testitems:translucent_item", {
description = S("Translucent item (translucent inventory & wield image)"),
inventory_image = "testitems_translucent.png",
wield_image = "testitems_translucent.png",
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

@ -2,29 +2,22 @@
local S = minetest.get_translator("testnodes")
-- Complex mesh
minetest.register_node("testnodes:performance_mesh_clip", {
description = S("Performance Test Node") .. "\n" .. S("Marble with 'clip' transparency"),
drawtype = "mesh",
mesh = "testnodes_marble_glass.obj",
tiles = {"testnodes_marble_glass.png"},
paramtype = "light",
use_texture_alpha = "clip",
for use_texture_alpha, description in pairs({
opaque = S("Marble with 'opaque' transparency"),
clip = S("Marble with 'clip' transparency"),
blend = S("Marble with 'blend' transparency"),
}) do
minetest.register_node("testnodes:performance_mesh_" .. use_texture_alpha, {
description = S("Performance Test Node") .. "\n" .. description,
drawtype = "mesh",
mesh = "testnodes_marble_glass.obj",
tiles = {"testnodes_marble_glass.png"},
paramtype = "light",
use_texture_alpha = use_texture_alpha,
groups = {dig_immediate=3},
})
-- Complex mesh, alpha blending
minetest.register_node("testnodes:performance_mesh_blend", {
description = S("Performance Test Node") .. "\n" .. S("Marble with 'blend' transparency"),
drawtype = "mesh",
mesh = "testnodes_marble_glass.obj",
tiles = {"testnodes_marble_glass.png"},
paramtype = "light",
use_texture_alpha = "blend",
groups = {dig_immediate=3},
})
groups = {dig_immediate=3},
})
end
-- Overlay
minetest.register_node("testnodes:performance_overlay_clip", {

@ -1145,7 +1145,6 @@ void drawItemStack(
}
video::SMaterial &material = buf->getMaterial();
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
material.Lighting = false;
driver->setMaterial(material);
driver->drawMeshBuffer(buf);

@ -526,26 +526,7 @@ ShaderInfo ShaderSource::generateShader(const std::string &name,
shaderinfo.name = name;
shaderinfo.material_type = material_type;
shaderinfo.drawtype = drawtype;
switch (material_type) {
case TILE_MATERIAL_OPAQUE:
case TILE_MATERIAL_LIQUID_OPAQUE:
case TILE_MATERIAL_WAVING_LIQUID_OPAQUE:
shaderinfo.base_material = video::EMT_SOLID;
break;
case TILE_MATERIAL_ALPHA:
case TILE_MATERIAL_PLAIN_ALPHA:
case TILE_MATERIAL_LIQUID_TRANSPARENT:
case TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT:
shaderinfo.base_material = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
break;
case TILE_MATERIAL_BASIC:
case TILE_MATERIAL_PLAIN:
case TILE_MATERIAL_WAVING_LEAVES:
case TILE_MATERIAL_WAVING_PLANTS:
case TILE_MATERIAL_WAVING_LIQUID_BASIC:
shaderinfo.base_material = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
break;
}
shaderinfo.base_material = MaterialType_to_irr(material_type);
shaderinfo.material = shaderinfo.base_material;
bool enable_shaders = g_settings->getBool("enable_shaders");

@ -18,31 +18,54 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/
#include "tile.h"
#include "EMaterialTypes.h"
#include "SMaterial.h"
// Sets everything else except the texture in the material
void TileLayer::applyMaterialOptions(video::SMaterial &material) const
void MaterialType_to_irr(MaterialType material_type,
video::E_MATERIAL_TYPE &irr_mat_type, f32 &irr_mat_param)
{
switch (material_type) {
case TILE_MATERIAL_OPAQUE:
case TILE_MATERIAL_LIQUID_OPAQUE:
case TILE_MATERIAL_WAVING_LIQUID_OPAQUE:
material.MaterialType = video::EMT_SOLID;
irr_mat_type = video::EMT_SOLID;
irr_mat_param = 0.0f;
break;
case TILE_MATERIAL_ALPHA:
case TILE_MATERIAL_PLAIN_ALPHA:
case TILE_MATERIAL_LIQUID_TRANSPARENT:
case TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT:
default:
irr_mat_type = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
irr_mat_param = 0.0f;
break;
case TILE_MATERIAL_BASIC:
case TILE_MATERIAL_PLAIN:
case TILE_MATERIAL_WAVING_LEAVES:
case TILE_MATERIAL_WAVING_PLANTS:
case TILE_MATERIAL_WAVING_LIQUID_BASIC:
material.MaterialTypeParam = 0.5;
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
break;
case TILE_MATERIAL_ALPHA:
case TILE_MATERIAL_LIQUID_TRANSPARENT:
case TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT:
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
break;
default:
irr_mat_type = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
irr_mat_param = 0.5f;
break;
}
}
video::E_MATERIAL_TYPE MaterialType_to_irr(MaterialType material_type) {
video::E_MATERIAL_TYPE res;
f32 unused;
MaterialType_to_irr(material_type, res, unused);
return res;
}
void MaterialType_to_irr(MaterialType material_type, video::SMaterial &material) {
MaterialType_to_irr(material_type,
material.MaterialType, material.MaterialTypeParam);
}
// Sets everything else except the texture in the material
void TileLayer::applyMaterialOptions(video::SMaterial &material) const
{
MaterialType_to_irr(static_cast<MaterialType>(material_type), material);
material.BackfaceCulling = (material_flags & MATERIAL_FLAG_BACKFACE_CULLING) != 0;
if (!(material_flags & MATERIAL_FLAG_TILEABLE_HORIZONTAL)) {
material.TextureLayers[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE;

@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#pragma once
#include "EMaterialTypes.h"
#include "irrlichttypes.h"
#include <ITexture.h>
#include <vector>
@ -39,6 +40,11 @@ enum MaterialType{
TILE_MATERIAL_PLAIN_ALPHA
};
void MaterialType_to_irr(MaterialType material_type,
video::E_MATERIAL_TYPE &irr_mat_type, f32 &irr_mat_param);
video::E_MATERIAL_TYPE MaterialType_to_irr(MaterialType material_type);
void MaterialType_to_irr(MaterialType material_type, video::SMaterial &mat);
// Material flags
// Should backface culling be enabled?
#define MATERIAL_FLAG_BACKFACE_CULLING 0x01

@ -18,8 +18,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/
#include "wieldmesh.h"
#include "EMaterialTypes.h"
#include "SMaterial.h"
#include "settings.h"
#include "shader.h"
#include "inventory.h"
#include "client.h"
#include "itemdef.h"
@ -29,7 +30,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mapblock_mesh.h"
#include "client/meshgen/collector.h"
#include "client/tile.h"
#include "log.h"
#include "util/numeric.h"
#include <map>
#include <IMeshManipulator.h>
@ -41,6 +41,56 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define MIN_EXTRUSION_MESH_RESOLUTION 16
#define MAX_EXTRUSION_MESH_RESOLUTION 512
/*!
* Applies overlays, textures and optionally materials to the given mesh and
* extracts tile colors for colorization.
* \param mattype overrides the buffer's material type, but can also
* be NULL to leave the original material.
* \param colors returns the colors of the mesh buffers in the mesh.
*/
static void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f,
std::vector<ItemPartColor> *colors)
{
const u32 mc = mesh->getMeshBufferCount();
// Allocate colors for existing buffers
colors->clear();
colors->resize(mc);
for (u32 i = 0; i < mc; ++i) {
const TileSpec *tile = &(f.tiles[i]);
scene::IMeshBuffer *buf = mesh->getMeshBuffer(i);
for (int layernum = 0; layernum < MAX_TILE_LAYERS; layernum++) {
const TileLayer *layer = &tile->layers[layernum];
if (layer->texture_id == 0)
continue;
if (layernum != 0) {
scene::IMeshBuffer *copy = cloneMeshBuffer(buf);
copy->getMaterial() = buf->getMaterial();
mesh->addMeshBuffer(copy);
copy->drop();
buf = copy;
colors->emplace_back(layer->has_color, layer->color);
} else {
(*colors)[i] = ItemPartColor(layer->has_color, layer->color);
}
video::SMaterial &material = buf->getMaterial();
if (layer->animation_frame_count > 1) {
const FrameSpec &animation_frame = (*layer->frames)[0];
material.setTexture(0, animation_frame.texture);
} else {
material.setTexture(0, layer->texture);
}
if (tile->world_aligned) {
u32 n = buf->getVertexCount();
for (u32 k = 0; k != n; ++k)
buf->getTCoords(k) /= layer->scale;
}
}
}
}
static scene::IMesh *createExtrusionMesh(int resolution_x, int resolution_y)
{
const f32 r = 0.5;
@ -193,10 +243,55 @@ class ExtrusionMeshCache: public IReferenceCounted
static ExtrusionMeshCache *g_extrusion_mesh_cache = nullptr;
static scene::SMesh *getExtrudedMesh(ITextureSource *tsrc,
const std::string &imagename, const std::string &overlay_name)
{
// check textures
video::ITexture *texture = tsrc->getTextureForMesh(imagename);
if (!texture) {
return NULL;
}
video::ITexture *overlay_texture =
(overlay_name.empty()) ? NULL : tsrc->getTexture(overlay_name);
// get mesh
core::dimension2d<u32> dim = texture->getSize();
scene::IMesh *original = g_extrusion_mesh_cache->create(dim);
scene::SMesh *mesh = cloneMesh(original);
original->drop();
//set texture
mesh->getMeshBuffer(0)->getMaterial().setTexture(0,
tsrc->getTexture(imagename));
if (overlay_texture) {
scene::IMeshBuffer *copy = cloneMeshBuffer(mesh->getMeshBuffer(0));
copy->getMaterial().setTexture(0, overlay_texture);
mesh->addMeshBuffer(copy);
copy->drop();
}
// Customize materials
for (u32 layer = 0; layer < mesh->getMeshBufferCount(); layer++) {
video::SMaterial &material = mesh->getMeshBuffer(layer)->getMaterial();
material.TextureLayers[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE;
material.TextureLayers[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
material.forEachTexture([] (auto &tex) {
tex.MinFilter = video::ETMINF_NEAREST_MIPMAP_NEAREST;
tex.MagFilter = video::ETMAGF_NEAREST;
});
material.BackfaceCulling = true;
material.Lighting = false;
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
material.MaterialTypeParam = 0.0f; // render everything with alpha > 0
material.ZWriteEnable = video::EZW_ON;
}
scaleMesh(mesh, v3f(2.0, 2.0, 2.0));
return mesh;
}
WieldMeshSceneNode::WieldMeshSceneNode(scene::ISceneManager *mgr, s32 id, bool lighting):
scene::ISceneNode(mgr->getRootSceneNode(), mgr, id),
m_material_type(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF),
m_material_type(video::EMT_TRANSPARENT_ALPHA_CHANNEL),
m_lighting(lighting)
{
m_enable_shaders = g_settings->getBool("enable_shaders");
@ -248,7 +343,17 @@ void WieldMeshSceneNode::setCube(const ContentFeatures &f,
scene::IMesh *cubemesh = g_extrusion_mesh_cache->createCube();
scene::SMesh *copy = cloneMesh(cubemesh);
cubemesh->drop();
postProcessNodeMesh(copy, f, false, true, &m_material_type, &m_colors, true);
postProcessNodeMesh(copy, f, &m_colors);
// Customize materials
for (u32 i = 0; i < cubemesh->getMeshBufferCount(); ++i) {
// It suffices to look at the first layer;
// a special overlay layer needs to be consistent with it -
// otherwise we would be overwriting the material options of the fist layer
scene::IMeshBuffer *buf = cubemesh->getMeshBuffer(i);
f.tiles[i].layers[0].applyMaterialOptions(buf->getMaterial());
}
changeToMesh(copy);
copy->drop();
m_meshnode->setScale(wield_scale * WIELD_SCALE_FACTOR);
@ -295,7 +400,8 @@ void WieldMeshSceneNode::setExtruded(const std::string &imagename,
material.TextureLayers[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE;
material.TextureLayers[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
material.MaterialType = m_material_type;
material.MaterialTypeParam = 0.5f;
material.MaterialTypeParam = m_material_type_param;
material.ZWriteEnable = video::EZW_ON;
material.BackfaceCulling = true;
// Enable bi/trilinear filtering only for high resolution textures
bool bilinear_filter = dim.Width > 32 && m_bilinear_filter;
@ -350,13 +456,11 @@ static scene::SMesh *createSpecialNodeMesh(Client *client, MapNode n,
}
scene::SMeshBuffer *buf = new scene::SMeshBuffer();
buf->Material.setTexture(0, p.layer.texture);
p.layer.applyMaterialOptions(buf->Material);
mesh->addMeshBuffer(buf);
buf->append(&p.vertices[0], p.vertices.size(),
&p.indices[0], p.indices.size());
buf->drop();
colors->push_back(
ItemPartColor(p.layer.has_color, p.layer.color));
colors->emplace_back(p.layer.has_color, p.layer.color);
}
return mesh;
}
@ -365,7 +469,6 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client, bool che
{
ITextureSource *tsrc = client->getTextureSource();
IItemDefManager *idef = client->getItemDefManager();
IShaderSource *shdrsrc = client->getShaderSource();
const NodeDefManager *ndef = client->getNodeDefManager();
const ItemDefinition &def = item.getDefinition(idef);
const ContentFeatures &f = ndef->get(def.name);
@ -373,8 +476,16 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client, bool che
scene::SMesh *mesh = nullptr;
const auto material_type = def.type == ITEM_NODE
? f.getMaterialType() : TILE_MATERIAL_ALPHA;
MaterialType_to_irr(material_type, m_material_type, m_material_type_param);
if (m_enable_shaders) {
u32 shader_id = shdrsrc->getShader("object_shader", TILE_MATERIAL_BASIC, NDT_NORMAL);
IShaderSource *shdrsrc = client->getShaderSource();
u32 shader_id = shdrsrc->getShader("object_shader",
material_type, def.type == ITEM_NODE ? f.drawtype : NDT_MESH);
// The shader gives a material ID (different from our material type) back.
// Strictly speaking, "m_material type" is a misnomer,
// since either a material type or ID is stored.
m_material_type = shdrsrc->getShaderInfo(shader_id).material;
}
@ -463,7 +574,8 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client, bool che
for (u32 i = 0; i < material_count; ++i) {
video::SMaterial &material = m_meshnode->getMaterial(i);
material.MaterialType = m_material_type;
material.MaterialTypeParam = 0.5f;
material.MaterialTypeParam = m_material_type_param;
material.ZWriteEnable = video::EZW_ON;
material.BackfaceCulling = cull_backface;
material.forEachTexture([this] (auto &tex) {
setMaterialFilters(tex, m_bilinear_filter, m_trilinear_filter,
@ -624,8 +736,7 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result)
} else
scaleMesh(mesh, v3f(1.2, 1.2, 1.2));
// add overlays
postProcessNodeMesh(mesh, f, false, false, nullptr,
&result->buffer_colors, true);
postProcessNodeMesh(mesh, f, &result->buffer_colors);
if (f.drawtype == NDT_ALLFACES)
scaleMesh(mesh, v3f(f.visual_scale));
break;
@ -664,14 +775,17 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result)
for (u32 i = 0; i < mesh->getMeshBufferCount(); ++i) {
scene::IMeshBuffer *buf = mesh->getMeshBuffer(i);
video::SMaterial &material = buf->getMaterial();
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
material.MaterialTypeParam = 0.5f;
// Note: This overwrites material types / type params
// of plantlike extrusion meshes for alpha blending consistency.
// It suffices to look at the first layer; overlays need to be consistent.
f.tiles[i].layers[0].applyMaterialOptions(material);
material.ZWriteEnable = video::EZW_ON;
material.forEachTexture([] (auto &tex) {
tex.MinFilter = video::ETMINF_NEAREST_MIPMAP_NEAREST;
tex.MagFilter = video::ETMAGF_NEAREST;
});
material.BackfaceCulling = cull_backface;
material.Lighting = false;
material.Lighting = false; // no lighting in the inventory
}
rotateMeshXZby(mesh, -45);
@ -685,109 +799,3 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result)
}
result->mesh = mesh;
}
scene::SMesh *getExtrudedMesh(ITextureSource *tsrc,
const std::string &imagename, const std::string &overlay_name)
{
// check textures
video::ITexture *texture = tsrc->getTextureForMesh(imagename);
if (!texture) {
return NULL;
}
video::ITexture *overlay_texture =
(overlay_name.empty()) ? NULL : tsrc->getTexture(overlay_name);
// get mesh
core::dimension2d<u32> dim = texture->getSize();
scene::IMesh *original = g_extrusion_mesh_cache->create(dim);
scene::SMesh *mesh = cloneMesh(original);
original->drop();
//set texture
mesh->getMeshBuffer(0)->getMaterial().setTexture(0,
tsrc->getTexture(imagename));
if (overlay_texture) {
scene::IMeshBuffer *copy = cloneMeshBuffer(mesh->getMeshBuffer(0));
copy->getMaterial().setTexture(0, overlay_texture);
mesh->addMeshBuffer(copy);
copy->drop();
}
// Customize materials
for (u32 layer = 0; layer < mesh->getMeshBufferCount(); layer++) {
video::SMaterial &material = mesh->getMeshBuffer(layer)->getMaterial();
material.TextureLayers[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE;
material.TextureLayers[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
material.forEachTexture([] (auto &tex) {
tex.MinFilter = video::ETMINF_NEAREST_MIPMAP_NEAREST;
tex.MagFilter = video::ETMAGF_NEAREST;
});
material.BackfaceCulling = true;
material.Lighting = false;
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
material.MaterialTypeParam = 0.5f;
}
scaleMesh(mesh, v3f(2.0, 2.0, 2.0));
return mesh;
}
void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f,
bool use_shaders, bool set_material, const video::E_MATERIAL_TYPE *mattype,
std::vector<ItemPartColor> *colors, bool apply_scale)
{
const u32 mc = mesh->getMeshBufferCount();
// Allocate colors for existing buffers
colors->clear();
colors->resize(mc);
for (u32 i = 0; i < mc; ++i) {
const TileSpec *tile = &(f.tiles[i]);
scene::IMeshBuffer *buf = mesh->getMeshBuffer(i);
for (int layernum = 0; layernum < MAX_TILE_LAYERS; layernum++) {
const TileLayer *layer = &tile->layers[layernum];
if (layer->texture_id == 0)
continue;
if (layernum != 0) {
scene::IMeshBuffer *copy = cloneMeshBuffer(buf);
copy->getMaterial() = buf->getMaterial();
mesh->addMeshBuffer(copy);
copy->drop();
buf = copy;
colors->emplace_back(layer->has_color, layer->color);
} else {
(*colors)[i] = ItemPartColor(layer->has_color, layer->color);
}
video::SMaterial &material = buf->getMaterial();
if (set_material)
layer->applyMaterialOptions(material);
if (mattype) {
material.MaterialType = *mattype;
}
if (layer->animation_frame_count > 1) {
const FrameSpec &animation_frame = (*layer->frames)[0];
material.setTexture(0, animation_frame.texture);
} else {
material.setTexture(0, layer->texture);
}
if (use_shaders) {
if (layer->normal_texture) {
if (layer->animation_frame_count > 1) {
const FrameSpec &animation_frame = (*layer->frames)[0];
material.setTexture(1, animation_frame.normal_texture);
} else
material.setTexture(1, layer->normal_texture);
}
material.setTexture(2, layer->flags_texture);
}
if (apply_scale && tile->world_aligned) {
u32 n = buf->getVertexCount();
for (u32 k = 0; k != n; ++k)
buf->getTCoords(k) /= layer->scale;
}
}
}
}

@ -118,6 +118,7 @@ class WieldMeshSceneNode : public scene::ISceneNode
// Child scene node with the current wield mesh
scene::IMeshSceneNode *m_meshnode = nullptr;
video::E_MATERIAL_TYPE m_material_type;
f32 m_material_type_param = 0.0f;
// True if SMaterial::Lighting should be enabled.
bool m_lighting;
@ -146,17 +147,3 @@ class WieldMeshSceneNode : public scene::ISceneNode
};
void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result);
scene::SMesh *getExtrudedMesh(ITextureSource *tsrc, const std::string &imagename,
const std::string &overlay_name);
/*!
* Applies overlays, textures and optionally materials to the given mesh and
* extracts tile colors for colorization.
* \param mattype overrides the buffer's material type, but can also
* be NULL to leave the original material.
* \param colors returns the colors of the mesh buffers in the mesh.
*/
void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f, bool use_shaders,
bool set_material, const video::E_MATERIAL_TYPE *mattype,
std::vector<ItemPartColor> *colors, bool apply_scale = false);

@ -784,6 +784,80 @@ bool isWorldAligned(AlignStyle style, WorldAlignMode mode, NodeDrawType drawtype
return false;
}
void ContentFeatures::updateAlpha(bool translucent_liquids) {
if ((drawtype == NDT_LIQUID || drawtype == NDT_FLOWINGLIQUID) &&
!translucent_liquids)
alpha = ALPHAMODE_OPAQUE;
}
MaterialType ContentFeatures::getMaterialType() const
{
MaterialType material_type;
switch (alpha) {
case ALPHAMODE_OPAQUE:
material_type = TILE_MATERIAL_OPAQUE;
break;
case ALPHAMODE_CLIP:
material_type = TILE_MATERIAL_BASIC;
break;
case ALPHAMODE_BLEND:
default:
material_type = TILE_MATERIAL_ALPHA;
break;
}
switch (drawtype) {
case NDT_LIQUID:
case NDT_FLOWINGLIQUID:
switch (alpha) {
case ALPHAMODE_OPAQUE:
return (waving == 3)
? TILE_MATERIAL_WAVING_LIQUID_OPAQUE
: TILE_MATERIAL_LIQUID_OPAQUE;
case ALPHAMODE_CLIP:
return (waving == 3)
? TILE_MATERIAL_WAVING_LIQUID_BASIC
: TILE_MATERIAL_LIQUID_TRANSPARENT;
case ALPHAMODE_BLEND:
default:
return (waving == 3)
? TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT
: TILE_MATERIAL_LIQUID_TRANSPARENT;
}
break;
case NDT_ALLFACES_OPTIONAL:
if (waving >= 1)
return TILE_MATERIAL_WAVING_LEAVES;
break;
case NDT_PLANTLIKE:
if (waving >= 1)
return TILE_MATERIAL_WAVING_PLANTS;
break;
case NDT_MESH:
case NDT_NODEBOX:
switch (waving) {
case 1:
return TILE_MATERIAL_WAVING_PLANTS;
case 2:
return TILE_MATERIAL_WAVING_LEAVES;
case 3:
switch (alpha) {
case ALPHAMODE_OPAQUE:
return TILE_MATERIAL_WAVING_LIQUID_OPAQUE;
case ALPHAMODE_CLIP:
return TILE_MATERIAL_WAVING_LIQUID_BASIC;
case ALPHAMODE_BLEND:
return TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT;
default:
assert(false);
}
break;
}
break;
default: break;
}
return material_type;
}
void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc,
scene::IMeshManipulator *meshmanip, Client *client, const TextureSettings &tsettings)
{
@ -810,11 +884,8 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc
tdef_spec[j] = tiledef_special[j];
}
bool is_liquid = false;
MaterialType material_type = alpha == ALPHAMODE_OPAQUE ?
TILE_MATERIAL_OPAQUE : (alpha == ALPHAMODE_CLIP ? TILE_MATERIAL_BASIC :
TILE_MATERIAL_ALPHA);
updateAlpha(tsettings.translucent_liquids);
MaterialType material_type = getMaterialType();
switch (drawtype) {
default:
@ -825,16 +896,10 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc
solidness = 0;
break;
case NDT_LIQUID:
if (!tsettings.translucent_liquids)
alpha = ALPHAMODE_OPAQUE;
solidness = 1;
is_liquid = true;
break;
case NDT_FLOWINGLIQUID:
solidness = 0;
if (!tsettings.translucent_liquids)
alpha = ALPHAMODE_OPAQUE;
is_liquid = true;
break;
case NDT_GLASSLIKE:
solidness = 0;
@ -879,13 +944,9 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc
for (TileDef &td : tdef)
td.name += std::string("^[noalpha");
}
if (waving >= 1)
material_type = TILE_MATERIAL_WAVING_LEAVES;
break;
case NDT_PLANTLIKE:
solidness = 0;
if (waving >= 1)
material_type = TILE_MATERIAL_WAVING_PLANTS;
break;
case NDT_FIRELIKE:
solidness = 0;
@ -893,15 +954,6 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc
case NDT_MESH:
case NDT_NODEBOX:
solidness = 0;
if (waving == 1) {
material_type = TILE_MATERIAL_WAVING_PLANTS;
} else if (waving == 2) {
material_type = TILE_MATERIAL_WAVING_LEAVES;
} else if (waving == 3) {
material_type = alpha == ALPHAMODE_OPAQUE ?
TILE_MATERIAL_WAVING_LIQUID_OPAQUE : (alpha == ALPHAMODE_CLIP ?
TILE_MATERIAL_WAVING_LIQUID_BASIC : TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT);
}
break;
case NDT_TORCHLIKE:
case NDT_SIGNLIKE:
@ -914,17 +966,6 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc
break;
}
if (is_liquid) {
if (waving == 3) {
material_type = alpha == ALPHAMODE_OPAQUE ?
TILE_MATERIAL_WAVING_LIQUID_OPAQUE : (alpha == ALPHAMODE_CLIP ?
TILE_MATERIAL_WAVING_LIQUID_BASIC : TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT);
} else {
material_type = alpha == ALPHAMODE_OPAQUE ? TILE_MATERIAL_LIQUID_OPAQUE :
TILE_MATERIAL_LIQUID_TRANSPARENT;
}
}
u32 tile_shader = shdsrc->getShader("nodes_shader", material_type, drawtype);
MaterialType overlay_material = material_type;
@ -1082,6 +1123,7 @@ void NodeDefManager::clear()
f.name = "air";
f.drawtype = NDT_AIRLIKE;
f.param_type = CPT_LIGHT;
f.alpha = ALPHAMODE_CLIP;
f.light_propagates = true;
f.sunlight_propagates = true;
f.walkable = false;

@ -531,6 +531,8 @@ struct ContentFeatures
}
#ifndef SERVER
void updateAlpha(bool translucent_liquids);
MaterialType getMaterialType() const;
void updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc,
scene::IMeshManipulator *meshmanip, Client *client, const TextureSettings &tsettings);
#endif