forked from Mirrorlandia_minetest/minetest
Basic model shading (#9374)
This commit is contained in:
parent
478e753298
commit
6958071f49
131
client/shaders/object_shader/opengl_fragment.glsl
Normal file
131
client/shaders/object_shader/opengl_fragment.glsl
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
uniform sampler2D baseTexture;
|
||||||
|
uniform sampler2D normalTexture;
|
||||||
|
uniform sampler2D textureFlags;
|
||||||
|
|
||||||
|
uniform vec4 emissiveColor;
|
||||||
|
uniform vec4 skyBgColor;
|
||||||
|
uniform float fogDistance;
|
||||||
|
uniform vec3 eyePosition;
|
||||||
|
|
||||||
|
varying vec3 vNormal;
|
||||||
|
varying vec3 vPosition;
|
||||||
|
varying vec3 worldPosition;
|
||||||
|
|
||||||
|
varying vec3 eyeVec;
|
||||||
|
varying vec3 lightVec;
|
||||||
|
varying float vIDiff;
|
||||||
|
|
||||||
|
bool normalTexturePresent = false;
|
||||||
|
bool texTileableHorizontal = false;
|
||||||
|
bool texTileableVertical = false;
|
||||||
|
bool texSeamless = false;
|
||||||
|
|
||||||
|
const float e = 2.718281828459;
|
||||||
|
const float BS = 10.0;
|
||||||
|
const float fogStart = FOG_START;
|
||||||
|
const float fogShadingParameter = 1 / ( 1 - fogStart);
|
||||||
|
|
||||||
|
void get_texture_flags()
|
||||||
|
{
|
||||||
|
vec4 flags = texture2D(textureFlags, vec2(0.0, 0.0));
|
||||||
|
if (flags.r > 0.5) {
|
||||||
|
normalTexturePresent = true;
|
||||||
|
}
|
||||||
|
if (flags.g > 0.5) {
|
||||||
|
texTileableHorizontal = true;
|
||||||
|
}
|
||||||
|
if (flags.b > 0.5) {
|
||||||
|
texTileableVertical = true;
|
||||||
|
}
|
||||||
|
if (texTileableHorizontal && texTileableVertical) {
|
||||||
|
texSeamless = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float intensity(vec3 color)
|
||||||
|
{
|
||||||
|
return (color.r + color.g + color.b) / 3.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
float get_rgb_height(vec2 uv)
|
||||||
|
{
|
||||||
|
if (texSeamless) {
|
||||||
|
return intensity(texture2D(baseTexture, uv).rgb);
|
||||||
|
} else {
|
||||||
|
return intensity(texture2D(baseTexture, clamp(uv, 0.0, 0.999)).rgb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 get_normal_map(vec2 uv)
|
||||||
|
{
|
||||||
|
vec4 bump = texture2D(normalTexture, uv).rgba;
|
||||||
|
bump.xyz = normalize(bump.xyz * 2.0 - 1.0);
|
||||||
|
return bump;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
vec3 color;
|
||||||
|
vec4 bump;
|
||||||
|
vec2 uv = gl_TexCoord[0].st;
|
||||||
|
bool use_normalmap = false;
|
||||||
|
get_texture_flags();
|
||||||
|
|
||||||
|
#if USE_NORMALMAPS == 1
|
||||||
|
if (normalTexturePresent) {
|
||||||
|
bump = get_normal_map(uv);
|
||||||
|
use_normalmap = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if GENERATE_NORMALMAPS == 1
|
||||||
|
if (normalTexturePresent == false) {
|
||||||
|
float tl = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y + SAMPLE_STEP));
|
||||||
|
float t = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y - SAMPLE_STEP));
|
||||||
|
float tr = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y + SAMPLE_STEP));
|
||||||
|
float r = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y));
|
||||||
|
float br = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y - SAMPLE_STEP));
|
||||||
|
float b = get_rgb_height(vec2(uv.x, uv.y - SAMPLE_STEP));
|
||||||
|
float bl = get_rgb_height(vec2(uv.x -SAMPLE_STEP, uv.y - SAMPLE_STEP));
|
||||||
|
float l = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y));
|
||||||
|
float dX = (tr + 2.0 * r + br) - (tl + 2.0 * l + bl);
|
||||||
|
float dY = (bl + 2.0 * b + br) - (tl + 2.0 * t + tr);
|
||||||
|
bump = vec4(normalize(vec3 (dX, dY, NORMALMAPS_STRENGTH)), 1.0);
|
||||||
|
use_normalmap = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vec4 base = texture2D(baseTexture, uv).rgba;
|
||||||
|
|
||||||
|
#ifdef ENABLE_BUMPMAPPING
|
||||||
|
if (use_normalmap) {
|
||||||
|
vec3 L = normalize(lightVec);
|
||||||
|
vec3 E = normalize(eyeVec);
|
||||||
|
float specular = pow(clamp(dot(reflect(L, bump.xyz), E), 0.0, 1.0), 1.0);
|
||||||
|
float diffuse = dot(-E,bump.xyz);
|
||||||
|
color = (diffuse + 0.1 * specular) * base.rgb;
|
||||||
|
} else {
|
||||||
|
color = base.rgb;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
color = base.rgb;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vec4 col = vec4(color.rgb, base.a);
|
||||||
|
|
||||||
|
col.rgb *= emissiveColor.rgb * vIDiff;
|
||||||
|
// Due to a bug in some (older ?) graphics stacks (possibly in the glsl compiler ?),
|
||||||
|
// the fog will only be rendered correctly if the last operation before the
|
||||||
|
// clamp() is an addition. Else, the clamp() seems to be ignored.
|
||||||
|
// E.g. the following won't work:
|
||||||
|
// float clarity = clamp(fogShadingParameter
|
||||||
|
// * (fogDistance - length(eyeVec)) / fogDistance), 0.0, 1.0);
|
||||||
|
// As additions usually come for free following a multiplication, the new formula
|
||||||
|
// should be more efficient as well.
|
||||||
|
// Note: clarity = (1 - fogginess)
|
||||||
|
float clarity = clamp(fogShadingParameter
|
||||||
|
- fogShadingParameter * length(eyeVec) / fogDistance, 0.0, 1.0);
|
||||||
|
col = mix(skyBgColor, col, clarity);
|
||||||
|
|
||||||
|
gl_FragColor = vec4(col.rgb, base.a);
|
||||||
|
}
|
44
client/shaders/object_shader/opengl_vertex.glsl
Normal file
44
client/shaders/object_shader/opengl_vertex.glsl
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
uniform mat4 mWorldViewProj;
|
||||||
|
uniform mat4 mWorld;
|
||||||
|
|
||||||
|
uniform vec3 eyePosition;
|
||||||
|
uniform float animationTimer;
|
||||||
|
|
||||||
|
varying vec3 vNormal;
|
||||||
|
varying vec3 vPosition;
|
||||||
|
varying vec3 worldPosition;
|
||||||
|
|
||||||
|
varying vec3 eyeVec;
|
||||||
|
varying vec3 lightVec;
|
||||||
|
varying float vIDiff;
|
||||||
|
|
||||||
|
const float e = 2.718281828459;
|
||||||
|
const float BS = 10.0;
|
||||||
|
|
||||||
|
float directional_ambient(vec3 normal)
|
||||||
|
{
|
||||||
|
vec3 v = normal * normal;
|
||||||
|
|
||||||
|
if (normal.y < 0)
|
||||||
|
return dot(v, vec3(0.670820f, 0.447213f, 0.836660f));
|
||||||
|
|
||||||
|
return dot(v, vec3(0.670820f, 1.000000f, 0.836660f));
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||||
|
gl_Position = mWorldViewProj * gl_Vertex;
|
||||||
|
|
||||||
|
vPosition = gl_Position.xyz;
|
||||||
|
vNormal = gl_Normal;
|
||||||
|
worldPosition = (mWorld * gl_Vertex).xyz;
|
||||||
|
|
||||||
|
vec3 sunPosition = vec3 (0.0, eyePosition.y * BS + 900.0, 0.0);
|
||||||
|
|
||||||
|
lightVec = sunPosition - worldPosition;
|
||||||
|
eyeVec = -(gl_ModelViewMatrix * gl_Vertex).xyz;
|
||||||
|
vIDiff = directional_ambient(normalize(gl_Normal));
|
||||||
|
|
||||||
|
gl_FrontColor = gl_BackColor = gl_Color;
|
||||||
|
}
|
@ -1860,7 +1860,7 @@ ITextureSource* Client::getTextureSource()
|
|||||||
{
|
{
|
||||||
return m_tsrc;
|
return m_tsrc;
|
||||||
}
|
}
|
||||||
IShaderSource* Client::getShaderSource()
|
IWritableShaderSource* Client::getShaderSource()
|
||||||
{
|
{
|
||||||
return m_shsrc;
|
return m_shsrc;
|
||||||
}
|
}
|
||||||
|
@ -367,7 +367,7 @@ public:
|
|||||||
const NodeDefManager* getNodeDefManager() override;
|
const NodeDefManager* getNodeDefManager() override;
|
||||||
ICraftDefManager* getCraftDefManager() override;
|
ICraftDefManager* getCraftDefManager() override;
|
||||||
ITextureSource* getTextureSource();
|
ITextureSource* getTextureSource();
|
||||||
virtual IShaderSource* getShaderSource();
|
virtual IWritableShaderSource* getShaderSource();
|
||||||
u16 allocateUnknownNodeId(const std::string &name) override;
|
u16 allocateUnknownNodeId(const std::string &name) override;
|
||||||
virtual ISoundManager* getSoundManager();
|
virtual ISoundManager* getSoundManager();
|
||||||
MtEventManager* getEventManager();
|
MtEventManager* getEventManager();
|
||||||
|
@ -32,10 +32,65 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "raycast.h"
|
#include "raycast.h"
|
||||||
#include "voxelalgorithms.h"
|
#include "voxelalgorithms.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
#include "shader.h"
|
||||||
#include "content_cao.h"
|
#include "content_cao.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "client/renderingengine.h"
|
#include "client/renderingengine.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
CAOShaderConstantSetter
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! Shader constant setter for passing material emissive color to the CAO object_shader
|
||||||
|
class CAOShaderConstantSetter : public IShaderConstantSetter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CAOShaderConstantSetter():
|
||||||
|
m_emissive_color_setting("emissiveColor")
|
||||||
|
{}
|
||||||
|
|
||||||
|
~CAOShaderConstantSetter() override = default;
|
||||||
|
|
||||||
|
void onSetConstants(video::IMaterialRendererServices *services,
|
||||||
|
bool is_highlevel) override
|
||||||
|
{
|
||||||
|
if (!is_highlevel)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Ambient color
|
||||||
|
video::SColorf emissive_color(m_emissive_color);
|
||||||
|
|
||||||
|
float as_array[4] = {
|
||||||
|
emissive_color.r,
|
||||||
|
emissive_color.g,
|
||||||
|
emissive_color.b,
|
||||||
|
emissive_color.a,
|
||||||
|
};
|
||||||
|
m_emissive_color_setting.set(as_array, services);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onSetMaterial(const video::SMaterial& material) override
|
||||||
|
{
|
||||||
|
m_emissive_color = material.EmissiveColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
video::SColor m_emissive_color;
|
||||||
|
CachedPixelShaderSetting<float, 4> m_emissive_color_setting;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CAOShaderConstantSetterFactory : public IShaderConstantSetterFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CAOShaderConstantSetterFactory()
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual IShaderConstantSetter* create()
|
||||||
|
{
|
||||||
|
return new CAOShaderConstantSetter();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ClientEnvironment
|
ClientEnvironment
|
||||||
*/
|
*/
|
||||||
@ -47,6 +102,8 @@ ClientEnvironment::ClientEnvironment(ClientMap *map,
|
|||||||
m_texturesource(texturesource),
|
m_texturesource(texturesource),
|
||||||
m_client(client)
|
m_client(client)
|
||||||
{
|
{
|
||||||
|
auto *shdrsrc = m_client->getShaderSource();
|
||||||
|
shdrsrc->addShaderConstantSetterFactory(new CAOShaderConstantSetterFactory());
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientEnvironment::~ClientEnvironment()
|
ClientEnvironment::~ClientEnvironment()
|
||||||
|
@ -46,6 +46,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "wieldmesh.h"
|
#include "wieldmesh.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include "client/shader.h"
|
||||||
|
|
||||||
class Settings;
|
class Settings;
|
||||||
struct ToolCapabilities;
|
struct ToolCapabilities;
|
||||||
@ -352,6 +353,8 @@ void GenericCAO::initialize(const std::string &data)
|
|||||||
player->setCAO(this);
|
player->setCAO(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_enable_shaders = g_settings->getBool("enable_shaders");
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenericCAO::processInitData(const std::string &data)
|
void GenericCAO::processInitData(const std::string &data)
|
||||||
@ -577,8 +580,17 @@ void GenericCAO::addToScene(ITextureSource *tsrc)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
video::E_MATERIAL_TYPE material_type = (m_prop.use_texture_alpha) ?
|
if (m_enable_shaders) {
|
||||||
|
IShaderSource *shader_source = m_client->getShaderSource();
|
||||||
|
u32 shader_id = shader_source->getShader(
|
||||||
|
"object_shader",
|
||||||
|
TILE_MATERIAL_BASIC,
|
||||||
|
NDT_NORMAL);
|
||||||
|
m_material_type = shader_source->getShaderInfo(shader_id).material;
|
||||||
|
} else {
|
||||||
|
m_material_type = (m_prop.use_texture_alpha) ?
|
||||||
video::EMT_TRANSPARENT_ALPHA_CHANNEL : video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
video::EMT_TRANSPARENT_ALPHA_CHANNEL : video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
||||||
|
}
|
||||||
|
|
||||||
auto grabMatrixNode = [this] {
|
auto grabMatrixNode = [this] {
|
||||||
infostream << "GenericCAO::addToScene(): " << m_prop.visual << std::endl;
|
infostream << "GenericCAO::addToScene(): " << m_prop.visual << std::endl;
|
||||||
@ -587,6 +599,18 @@ void GenericCAO::addToScene(ITextureSource *tsrc)
|
|||||||
m_matrixnode->grab();
|
m_matrixnode->grab();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto setSceneNodeMaterial = [this] (scene::ISceneNode *node) {
|
||||||
|
node->setMaterialFlag(video::EMF_LIGHTING, false);
|
||||||
|
node->setMaterialFlag(video::EMF_BILINEAR_FILTER, false);
|
||||||
|
node->setMaterialFlag(video::EMF_FOG_ENABLE, true);
|
||||||
|
node->setMaterialType(m_material_type);
|
||||||
|
|
||||||
|
if (m_enable_shaders) {
|
||||||
|
node->setMaterialFlag(video::EMF_GOURAUD_SHADING, false);
|
||||||
|
node->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (m_prop.visual == "sprite") {
|
if (m_prop.visual == "sprite") {
|
||||||
grabMatrixNode();
|
grabMatrixNode();
|
||||||
m_spritenode = RenderingEngine::get_scene_manager()->addBillboardSceneNode(
|
m_spritenode = RenderingEngine::get_scene_manager()->addBillboardSceneNode(
|
||||||
@ -594,10 +618,9 @@ void GenericCAO::addToScene(ITextureSource *tsrc)
|
|||||||
m_spritenode->grab();
|
m_spritenode->grab();
|
||||||
m_spritenode->setMaterialTexture(0,
|
m_spritenode->setMaterialTexture(0,
|
||||||
tsrc->getTextureForMesh("unknown_node.png"));
|
tsrc->getTextureForMesh("unknown_node.png"));
|
||||||
m_spritenode->setMaterialFlag(video::EMF_LIGHTING, false);
|
|
||||||
m_spritenode->setMaterialFlag(video::EMF_BILINEAR_FILTER, false);
|
setSceneNodeMaterial(m_spritenode);
|
||||||
m_spritenode->setMaterialType(material_type);
|
|
||||||
m_spritenode->setMaterialFlag(video::EMF_FOG_ENABLE, true);
|
|
||||||
u8 li = m_last_light;
|
u8 li = m_last_light;
|
||||||
m_spritenode->setColor(video::SColor(255,li,li,li));
|
m_spritenode->setColor(video::SColor(255,li,li,li));
|
||||||
m_spritenode->setSize(v2f(m_prop.visual_size.X,
|
m_spritenode->setSize(v2f(m_prop.visual_size.X,
|
||||||
@ -619,10 +642,10 @@ void GenericCAO::addToScene(ITextureSource *tsrc)
|
|||||||
{ // Front
|
{ // Front
|
||||||
scene::IMeshBuffer *buf = new scene::SMeshBuffer();
|
scene::IMeshBuffer *buf = new scene::SMeshBuffer();
|
||||||
video::S3DVertex vertices[4] = {
|
video::S3DVertex vertices[4] = {
|
||||||
video::S3DVertex(-dx, -dy, 0, 0,0,0, c, 1,1),
|
video::S3DVertex(-dx, -dy, 0, 0,0,1, c, 1,1),
|
||||||
video::S3DVertex( dx, -dy, 0, 0,0,0, c, 0,1),
|
video::S3DVertex( dx, -dy, 0, 0,0,1, c, 0,1),
|
||||||
video::S3DVertex( dx, dy, 0, 0,0,0, c, 0,0),
|
video::S3DVertex( dx, dy, 0, 0,0,1, c, 0,0),
|
||||||
video::S3DVertex(-dx, dy, 0, 0,0,0, c, 1,0),
|
video::S3DVertex(-dx, dy, 0, 0,0,1, c, 1,0),
|
||||||
};
|
};
|
||||||
if (m_is_player) {
|
if (m_is_player) {
|
||||||
// Move minimal Y position to 0 (feet position)
|
// Move minimal Y position to 0 (feet position)
|
||||||
@ -635,7 +658,14 @@ void GenericCAO::addToScene(ITextureSource *tsrc)
|
|||||||
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
|
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
|
||||||
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
|
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
|
||||||
buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
|
buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
|
||||||
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
|
buf->getMaterial().MaterialType = m_material_type;
|
||||||
|
|
||||||
|
if (m_enable_shaders) {
|
||||||
|
buf->getMaterial().EmissiveColor = c;
|
||||||
|
buf->getMaterial().setFlag(video::EMF_GOURAUD_SHADING, false);
|
||||||
|
buf->getMaterial().setFlag(video::EMF_NORMALIZE_NORMALS, true);
|
||||||
|
}
|
||||||
|
|
||||||
// Add to mesh
|
// Add to mesh
|
||||||
mesh->addMeshBuffer(buf);
|
mesh->addMeshBuffer(buf);
|
||||||
buf->drop();
|
buf->drop();
|
||||||
@ -643,10 +673,10 @@ void GenericCAO::addToScene(ITextureSource *tsrc)
|
|||||||
{ // Back
|
{ // Back
|
||||||
scene::IMeshBuffer *buf = new scene::SMeshBuffer();
|
scene::IMeshBuffer *buf = new scene::SMeshBuffer();
|
||||||
video::S3DVertex vertices[4] = {
|
video::S3DVertex vertices[4] = {
|
||||||
video::S3DVertex( dx,-dy, 0, 0,0,0, c, 1,1),
|
video::S3DVertex( dx,-dy, 0, 0,0,-1, c, 1,1),
|
||||||
video::S3DVertex(-dx,-dy, 0, 0,0,0, c, 0,1),
|
video::S3DVertex(-dx,-dy, 0, 0,0,-1, c, 0,1),
|
||||||
video::S3DVertex(-dx, dy, 0, 0,0,0, c, 0,0),
|
video::S3DVertex(-dx, dy, 0, 0,0,-1, c, 0,0),
|
||||||
video::S3DVertex( dx, dy, 0, 0,0,0, c, 1,0),
|
video::S3DVertex( dx, dy, 0, 0,0,-1, c, 1,0),
|
||||||
};
|
};
|
||||||
if (m_is_player) {
|
if (m_is_player) {
|
||||||
// Move minimal Y position to 0 (feet position)
|
// Move minimal Y position to 0 (feet position)
|
||||||
@ -659,7 +689,14 @@ void GenericCAO::addToScene(ITextureSource *tsrc)
|
|||||||
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
|
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
|
||||||
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
|
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
|
||||||
buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
|
buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
|
||||||
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
buf->getMaterial().MaterialType = m_material_type;
|
||||||
|
|
||||||
|
if (m_enable_shaders) {
|
||||||
|
buf->getMaterial().EmissiveColor = c;
|
||||||
|
buf->getMaterial().setFlag(video::EMF_GOURAUD_SHADING, false);
|
||||||
|
buf->getMaterial().setFlag(video::EMF_NORMALIZE_NORMALS, true);
|
||||||
|
}
|
||||||
|
|
||||||
// Add to mesh
|
// Add to mesh
|
||||||
mesh->addMeshBuffer(buf);
|
mesh->addMeshBuffer(buf);
|
||||||
buf->drop();
|
buf->drop();
|
||||||
@ -683,10 +720,7 @@ void GenericCAO::addToScene(ITextureSource *tsrc)
|
|||||||
u8 li = m_last_light;
|
u8 li = m_last_light;
|
||||||
setMeshColor(m_meshnode->getMesh(), video::SColor(255,li,li,li));
|
setMeshColor(m_meshnode->getMesh(), video::SColor(255,li,li,li));
|
||||||
|
|
||||||
m_meshnode->setMaterialFlag(video::EMF_LIGHTING, false);
|
setSceneNodeMaterial(m_meshnode);
|
||||||
m_meshnode->setMaterialFlag(video::EMF_BILINEAR_FILTER, false);
|
|
||||||
m_meshnode->setMaterialType(material_type);
|
|
||||||
m_meshnode->setMaterialFlag(video::EMF_FOG_ENABLE, true);
|
|
||||||
} else if (m_prop.visual == "mesh") {
|
} else if (m_prop.visual == "mesh") {
|
||||||
grabMatrixNode();
|
grabMatrixNode();
|
||||||
scene::IAnimatedMesh *mesh = m_client->getMesh(m_prop.mesh, true);
|
scene::IAnimatedMesh *mesh = m_client->getMesh(m_prop.mesh, true);
|
||||||
@ -704,10 +738,8 @@ void GenericCAO::addToScene(ITextureSource *tsrc)
|
|||||||
|
|
||||||
setAnimatedMeshColor(m_animated_meshnode, video::SColor(255,li,li,li));
|
setAnimatedMeshColor(m_animated_meshnode, video::SColor(255,li,li,li));
|
||||||
|
|
||||||
m_animated_meshnode->setMaterialFlag(video::EMF_LIGHTING, true);
|
setSceneNodeMaterial(m_animated_meshnode);
|
||||||
m_animated_meshnode->setMaterialFlag(video::EMF_BILINEAR_FILTER, false);
|
|
||||||
m_animated_meshnode->setMaterialType(material_type);
|
|
||||||
m_animated_meshnode->setMaterialFlag(video::EMF_FOG_ENABLE, true);
|
|
||||||
m_animated_meshnode->setMaterialFlag(video::EMF_BACK_FACE_CULLING,
|
m_animated_meshnode->setMaterialFlag(video::EMF_BACK_FACE_CULLING,
|
||||||
m_prop.backface_culling);
|
m_prop.backface_culling);
|
||||||
} else
|
} else
|
||||||
@ -789,9 +821,32 @@ void GenericCAO::updateLightNoCheck(u8 light_at_pos)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
u8 li = decode_light(light_at_pos + m_glow);
|
u8 li = decode_light(light_at_pos + m_glow);
|
||||||
|
|
||||||
if (li != m_last_light) {
|
if (li != m_last_light) {
|
||||||
m_last_light = li;
|
m_last_light = li;
|
||||||
video::SColor color(255,li,li,li);
|
video::SColor color(255,li,li,li);
|
||||||
|
|
||||||
|
if (m_enable_shaders) {
|
||||||
|
scene::ISceneNode *node = getSceneNode();
|
||||||
|
|
||||||
|
if (node == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_prop.visual == "upright_sprite") {
|
||||||
|
scene::IMesh *mesh = m_meshnode->getMesh();
|
||||||
|
for (u32 i = 0; i < mesh->getMeshBufferCount(); ++i) {
|
||||||
|
scene::IMeshBuffer* buf = mesh->getMeshBuffer(i);
|
||||||
|
video::SMaterial& material = buf->getMaterial();
|
||||||
|
material.EmissiveColor = color;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (u32 i = 0; i < node->getMaterialCount(); ++i) {
|
||||||
|
video::SMaterial& material = node->getMaterial(i);
|
||||||
|
material.EmissiveColor = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (m_meshnode) {
|
if (m_meshnode) {
|
||||||
setMeshColor(m_meshnode->getMesh(), color);
|
setMeshColor(m_meshnode->getMesh(), color);
|
||||||
} else if (m_animated_meshnode) {
|
} else if (m_animated_meshnode) {
|
||||||
@ -802,6 +857,7 @@ void GenericCAO::updateLightNoCheck(u8 light_at_pos)
|
|||||||
m_spritenode->setColor(color);
|
m_spritenode->setColor(color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
v3s16 GenericCAO::getLightPosition()
|
v3s16 GenericCAO::getLightPosition()
|
||||||
@ -1101,16 +1157,13 @@ void GenericCAO::updateTextures(std::string mod)
|
|||||||
m_current_texture_modifier = mod;
|
m_current_texture_modifier = mod;
|
||||||
m_glow = m_prop.glow;
|
m_glow = m_prop.glow;
|
||||||
|
|
||||||
video::E_MATERIAL_TYPE material_type = (m_prop.use_texture_alpha) ?
|
|
||||||
video::EMT_TRANSPARENT_ALPHA_CHANNEL : video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
|
||||||
|
|
||||||
if (m_spritenode) {
|
if (m_spritenode) {
|
||||||
if (m_prop.visual == "sprite") {
|
if (m_prop.visual == "sprite") {
|
||||||
std::string texturestring = "unknown_node.png";
|
std::string texturestring = "unknown_node.png";
|
||||||
if (!m_prop.textures.empty())
|
if (!m_prop.textures.empty())
|
||||||
texturestring = m_prop.textures[0];
|
texturestring = m_prop.textures[0];
|
||||||
texturestring += mod;
|
texturestring += mod;
|
||||||
m_spritenode->getMaterial(0).MaterialType = material_type;
|
m_spritenode->getMaterial(0).MaterialType = m_material_type;
|
||||||
m_spritenode->getMaterial(0).MaterialTypeParam = 0.5f;
|
m_spritenode->getMaterial(0).MaterialTypeParam = 0.5f;
|
||||||
m_spritenode->setMaterialTexture(0,
|
m_spritenode->setMaterialTexture(0,
|
||||||
tsrc->getTextureForMesh(texturestring));
|
tsrc->getTextureForMesh(texturestring));
|
||||||
@ -1146,7 +1199,7 @@ void GenericCAO::updateTextures(std::string mod)
|
|||||||
|
|
||||||
// Set material flags and texture
|
// Set material flags and texture
|
||||||
video::SMaterial& material = m_animated_meshnode->getMaterial(i);
|
video::SMaterial& material = m_animated_meshnode->getMaterial(i);
|
||||||
material.MaterialType = material_type;
|
material.MaterialType = m_material_type;
|
||||||
material.MaterialTypeParam = 0.5f;
|
material.MaterialTypeParam = 0.5f;
|
||||||
material.TextureLayer[0].Texture = texture;
|
material.TextureLayer[0].Texture = texture;
|
||||||
material.setFlag(video::EMF_LIGHTING, true);
|
material.setFlag(video::EMF_LIGHTING, true);
|
||||||
@ -1193,7 +1246,7 @@ void GenericCAO::updateTextures(std::string mod)
|
|||||||
|
|
||||||
// Set material flags and texture
|
// Set material flags and texture
|
||||||
video::SMaterial& material = m_meshnode->getMaterial(i);
|
video::SMaterial& material = m_meshnode->getMaterial(i);
|
||||||
material.MaterialType = material_type;
|
material.MaterialType = m_material_type;
|
||||||
material.MaterialTypeParam = 0.5f;
|
material.MaterialTypeParam = 0.5f;
|
||||||
material.setFlag(video::EMF_LIGHTING, false);
|
material.setFlag(video::EMF_LIGHTING, false);
|
||||||
material.setFlag(video::EMF_BILINEAR_FILTER, false);
|
material.setFlag(video::EMF_BILINEAR_FILTER, false);
|
||||||
|
@ -125,6 +125,10 @@ private:
|
|||||||
u8 m_last_light = 255;
|
u8 m_last_light = 255;
|
||||||
bool m_is_visible = false;
|
bool m_is_visible = false;
|
||||||
s8 m_glow = 0;
|
s8 m_glow = 0;
|
||||||
|
// Material
|
||||||
|
video::E_MATERIAL_TYPE m_material_type;
|
||||||
|
// Settings
|
||||||
|
bool m_enable_shaders = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GenericCAO(Client *client, ClientEnvironment *env);
|
GenericCAO(Client *client, ClientEnvironment *env);
|
||||||
|
@ -188,7 +188,7 @@ public:
|
|||||||
delete setter;
|
delete setter;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnSetConstants(video::IMaterialRendererServices *services, s32 userData)
|
virtual void OnSetConstants(video::IMaterialRendererServices *services, s32 userData) override
|
||||||
{
|
{
|
||||||
video::IVideoDriver *driver = services->getVideoDriver();
|
video::IVideoDriver *driver = services->getVideoDriver();
|
||||||
sanity_check(driver != NULL);
|
sanity_check(driver != NULL);
|
||||||
@ -198,6 +198,12 @@ public:
|
|||||||
for (IShaderConstantSetter *setter : m_setters)
|
for (IShaderConstantSetter *setter : m_setters)
|
||||||
setter->onSetConstants(services, is_highlevel);
|
setter->onSetConstants(services, is_highlevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void OnSetMaterial(const video::SMaterial& material) override
|
||||||
|
{
|
||||||
|
for (IShaderConstantSetter *setter : m_setters)
|
||||||
|
setter->onSetMaterial(material);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -67,6 +67,8 @@ public:
|
|||||||
virtual ~IShaderConstantSetter() = default;
|
virtual ~IShaderConstantSetter() = default;
|
||||||
virtual void onSetConstants(video::IMaterialRendererServices *services,
|
virtual void onSetConstants(video::IMaterialRendererServices *services,
|
||||||
bool is_highlevel) = 0;
|
bool is_highlevel) = 0;
|
||||||
|
virtual void onSetMaterial(const video::SMaterial& material)
|
||||||
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user