Fix relief mapping issues
parent
b30e8d8ec6
commit
655fc6010f
|
@ -1,6 +1,6 @@
|
||||||
uniform sampler2D baseTexture;
|
uniform sampler2D baseTexture;
|
||||||
uniform sampler2D normalTexture;
|
uniform sampler2D normalTexture;
|
||||||
uniform sampler2D useNormalmap;
|
uniform sampler2D textureFlags;
|
||||||
|
|
||||||
uniform vec4 skyBgColor;
|
uniform vec4 skyBgColor;
|
||||||
uniform float fogDistance;
|
uniform float fogDistance;
|
||||||
|
@ -15,19 +15,73 @@ varying vec3 tsEyeVec;
|
||||||
varying vec3 lightVec;
|
varying vec3 lightVec;
|
||||||
varying vec3 tsLightVec;
|
varying vec3 tsLightVec;
|
||||||
|
|
||||||
bool normalTexturePresent = false;
|
bool normalTexturePresent = false;
|
||||||
|
bool texTileableHorizontal = false;
|
||||||
|
bool texTileableVertical = false;
|
||||||
|
bool texSeamless = false;
|
||||||
|
|
||||||
const float e = 2.718281828459;
|
const float e = 2.718281828459;
|
||||||
const float BS = 10.0;
|
const float BS = 10.0;
|
||||||
|
|
||||||
float intensity (vec3 color)
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 validate_displacement(vec2 uv, vec2 ds, float dist)
|
||||||
|
{
|
||||||
|
if (texSeamless) {
|
||||||
|
uv += dist * ds;
|
||||||
|
} else if (texTileableVertical == false) {
|
||||||
|
vec2 uv2 = uv + dist * ds;
|
||||||
|
// limit vertical texure displacement
|
||||||
|
if ((uv.y + uv2.y) < 0.0) {
|
||||||
|
uv.y = 0.0;
|
||||||
|
} else if ((uv.y + uv2.y) > 1.999) {
|
||||||
|
uv.y = 0.999;
|
||||||
|
} else {
|
||||||
|
uv.y = uv2.y;
|
||||||
|
}
|
||||||
|
uv.x = uv2.x;
|
||||||
|
} else {
|
||||||
|
vec2 uv2 = uv + dist * ds;
|
||||||
|
// limit horizontal texure displacement
|
||||||
|
if ((uv.x + uv2.x) < 0.0) {
|
||||||
|
uv.x = 0.0;
|
||||||
|
} else if ((uv.x + uv2.x) > 1.999) {
|
||||||
|
uv.x = 0.999;
|
||||||
|
} else {
|
||||||
|
uv.x = uv2.x;
|
||||||
|
}
|
||||||
|
uv.y = uv2.y;
|
||||||
|
}
|
||||||
|
return uv;
|
||||||
|
}
|
||||||
|
|
||||||
|
float intensity(vec3 color)
|
||||||
{
|
{
|
||||||
return (color.r + color.g + color.b) / 3.0;
|
return (color.r + color.g + color.b) / 3.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
float get_rgb_height (vec2 uv)
|
float get_rgb_height(vec2 uv)
|
||||||
{
|
{
|
||||||
return intensity(texture2D(baseTexture,uv).rgb);
|
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 get_normal_map(vec2 uv)
|
||||||
|
@ -50,7 +104,8 @@ float find_intersection(vec2 dp, vec2 ds)
|
||||||
return depth;
|
return depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
float find_intersectionRGB(vec2 dp, vec2 ds) {
|
float find_intersectionRGB(vec2 dp, vec2 ds)
|
||||||
|
{
|
||||||
const float depth_step = 1.0 / 24.0;
|
const float depth_step = 1.0 / 24.0;
|
||||||
float depth = 1.0;
|
float depth = 1.0;
|
||||||
for (int i = 0 ; i < 24 ; i++) {
|
for (int i = 0 ; i < 24 ; i++) {
|
||||||
|
@ -62,24 +117,19 @@ float find_intersectionRGB(vec2 dp, vec2 ds) {
|
||||||
return depth;
|
return depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
void main (void)
|
void main(void)
|
||||||
{
|
{
|
||||||
vec3 color;
|
vec3 color;
|
||||||
vec4 bump;
|
vec4 bump;
|
||||||
vec2 uv = gl_TexCoord[0].st;
|
vec2 uv = gl_TexCoord[0].st;
|
||||||
bool use_normalmap = false;
|
bool use_normalmap = false;
|
||||||
|
get_texture_flags();
|
||||||
#if USE_NORMALMAPS == 1
|
|
||||||
if (texture2D(useNormalmap,vec2(1.0, 1.0)).r > 0.0) {
|
|
||||||
normalTexturePresent = true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_PARALLAX_OCCLUSION
|
#ifdef ENABLE_PARALLAX_OCCLUSION
|
||||||
vec2 eyeRay = vec2 (tsEyeVec.x, -tsEyeVec.y);
|
vec2 eyeRay = vec2 (tsEyeVec.x, -tsEyeVec.y);
|
||||||
const float scale = PARALLAX_OCCLUSION_SCALE / PARALLAX_OCCLUSION_ITERATIONS;
|
const float scale = PARALLAX_OCCLUSION_SCALE / PARALLAX_OCCLUSION_ITERATIONS;
|
||||||
const float bias = PARALLAX_OCCLUSION_BIAS / PARALLAX_OCCLUSION_ITERATIONS;
|
const float bias = PARALLAX_OCCLUSION_BIAS / PARALLAX_OCCLUSION_ITERATIONS;
|
||||||
|
|
||||||
#if PARALLAX_OCCLUSION_MODE == 0
|
#if PARALLAX_OCCLUSION_MODE == 0
|
||||||
// Parallax occlusion with slope information
|
// Parallax occlusion with slope information
|
||||||
if (normalTexturePresent && area_enable_parallax > 0.0) {
|
if (normalTexturePresent && area_enable_parallax > 0.0) {
|
||||||
|
@ -89,17 +139,23 @@ void main (void)
|
||||||
uv += h * normal.z * eyeRay;
|
uv += h * normal.z * eyeRay;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if PARALLAX_OCCLUSION_MODE == 1
|
#if PARALLAX_OCCLUSION_MODE == 1
|
||||||
// Relief mapping
|
// Relief mapping
|
||||||
if (normalTexturePresent && area_enable_parallax > 0.0) {
|
if (normalTexturePresent && area_enable_parallax > 0.0) {
|
||||||
vec2 ds = eyeRay * PARALLAX_OCCLUSION_SCALE;
|
vec2 ds = eyeRay * PARALLAX_OCCLUSION_SCALE;
|
||||||
|
// offset the texture by maximum possible displacement,
|
||||||
|
// this will help align seamless and non seamless textures
|
||||||
|
uv -= ds;
|
||||||
float dist = find_intersection(uv, ds);
|
float dist = find_intersection(uv, ds);
|
||||||
uv += dist * ds;
|
uv = validate_displacement(uv, ds, dist);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
} else if (GENERATE_NORMALMAPS == 1 && area_enable_parallax > 0.0) {
|
} else if (GENERATE_NORMALMAPS == 1 && area_enable_parallax > 0.0) {
|
||||||
vec2 ds = eyeRay * PARALLAX_OCCLUSION_SCALE;
|
vec2 ds = eyeRay * PARALLAX_OCCLUSION_SCALE;
|
||||||
|
uv -= ds;
|
||||||
float dist = find_intersectionRGB(uv, ds);
|
float dist = find_intersectionRGB(uv, ds);
|
||||||
uv += dist * ds;
|
uv = validate_displacement(uv, ds, dist);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -107,10 +163,10 @@ void main (void)
|
||||||
if (normalTexturePresent) {
|
if (normalTexturePresent) {
|
||||||
bump = get_normal_map(uv);
|
bump = get_normal_map(uv);
|
||||||
use_normalmap = true;
|
use_normalmap = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (GENERATE_NORMALMAPS == 1 && use_normalmap == false) {
|
if (GENERATE_NORMALMAPS == 1 && normalTexturePresent == false) {
|
||||||
float tl = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y + SAMPLE_STEP));
|
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 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 tr = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y + SAMPLE_STEP));
|
||||||
|
|
|
@ -94,7 +94,7 @@ void main(void)
|
||||||
|
|
||||||
// Don't generate heightmaps when too far from the eye
|
// Don't generate heightmaps when too far from the eye
|
||||||
float dist = distance (vec3(0.0, 0.0 ,0.0), vPosition);
|
float dist = distance (vec3(0.0, 0.0 ,0.0), vPosition);
|
||||||
if (dist > 120.0) {
|
if (dist > 300.0) {
|
||||||
area_enable_parallax = 0.0;
|
area_enable_parallax = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
uniform sampler2D baseTexture;
|
uniform sampler2D baseTexture;
|
||||||
uniform sampler2D normalTexture;
|
uniform sampler2D normalTexture;
|
||||||
uniform sampler2D useNormalmap;
|
uniform sampler2D textureFlags;
|
||||||
|
|
||||||
uniform vec4 skyBgColor;
|
uniform vec4 skyBgColor;
|
||||||
uniform float fogDistance;
|
uniform float fogDistance;
|
||||||
|
@ -15,37 +15,55 @@ varying vec3 lightVec;
|
||||||
varying vec3 tsLightVec;
|
varying vec3 tsLightVec;
|
||||||
|
|
||||||
bool normalTexturePresent = false;
|
bool normalTexturePresent = false;
|
||||||
|
bool texTileableHorizontal = false;
|
||||||
|
bool texTileableVertical = false;
|
||||||
|
bool texSeamless = false;
|
||||||
|
|
||||||
const float e = 2.718281828459;
|
const float e = 2.718281828459;
|
||||||
const float BS = 10.0;
|
const float BS = 10.0;
|
||||||
|
|
||||||
float intensity (vec3 color){
|
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;
|
return (color.r + color.g + color.b) / 3.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
float get_rgb_height (vec2 uv){
|
float get_rgb_height(vec2 uv)
|
||||||
|
{
|
||||||
return intensity(texture2D(baseTexture,uv).rgb);
|
return intensity(texture2D(baseTexture,uv).rgb);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 get_normal_map(vec2 uv){
|
vec4 get_normal_map(vec2 uv)
|
||||||
|
{
|
||||||
vec4 bump = texture2D(normalTexture, uv).rgba;
|
vec4 bump = texture2D(normalTexture, uv).rgba;
|
||||||
bump.xyz = normalize(bump.xyz * 2.0 -1.0);
|
bump.xyz = normalize(bump.xyz * 2.0 -1.0);
|
||||||
bump.y = -bump.y;
|
bump.y = -bump.y;
|
||||||
return bump;
|
return bump;
|
||||||
}
|
}
|
||||||
|
|
||||||
void main (void)
|
void main(void)
|
||||||
{
|
{
|
||||||
vec3 color;
|
vec3 color;
|
||||||
vec4 bump;
|
vec4 bump;
|
||||||
vec2 uv = gl_TexCoord[0].st;
|
vec2 uv = gl_TexCoord[0].st;
|
||||||
bool use_normalmap = false;
|
bool use_normalmap = false;
|
||||||
|
get_texture_flags();
|
||||||
#ifdef USE_NORMALMAPS
|
|
||||||
if (texture2D(useNormalmap,vec2(1.0,1.0)).r > 0.0) {
|
|
||||||
normalTexturePresent = true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_PARALLAX_OCCLUSION
|
#ifdef ENABLE_PARALLAX_OCCLUSION
|
||||||
if (normalTexturePresent) {
|
if (normalTexturePresent) {
|
||||||
|
|
|
@ -3058,8 +3058,13 @@ Definition tables
|
||||||
### Tile definition
|
### Tile definition
|
||||||
* `"image.png"`
|
* `"image.png"`
|
||||||
* `{name="image.png", animation={Tile Animation definition}}`
|
* `{name="image.png", animation={Tile Animation definition}}`
|
||||||
* `{name="image.png", backface_culling=bool}`
|
* `{name="image.png", backface_culling=bool, tileable_vertical=bool,
|
||||||
* backface culling only supported in special tiles
|
tileable_horizontal=bool}`
|
||||||
|
* backface culling only supported in special tiles.
|
||||||
|
* tileable flags are info for shaders, how they should treat texture
|
||||||
|
when displacement mapping is used
|
||||||
|
Directions are from the point of view of the tile texture,
|
||||||
|
not the node it's on
|
||||||
* deprecated, yet still supported field names:
|
* deprecated, yet still supported field names:
|
||||||
* `image` (name)
|
* `image` (name)
|
||||||
|
|
||||||
|
|
|
@ -722,7 +722,9 @@ minetest.register_node("default:stone_with_iron", {
|
||||||
|
|
||||||
minetest.register_node("default:dirt_with_grass", {
|
minetest.register_node("default:dirt_with_grass", {
|
||||||
description = "Dirt with grass",
|
description = "Dirt with grass",
|
||||||
tiles ={"default_grass.png", "default_dirt.png", "default_dirt.png^default_grass_side.png"},
|
tiles ={"default_grass.png", "default_dirt.png",
|
||||||
|
{name = "default_dirt.png^default_grass_side.png",
|
||||||
|
tileable_vertical = false}},
|
||||||
groups = {crumbly=3, soil=1},
|
groups = {crumbly=3, soil=1},
|
||||||
drop = 'default:dirt',
|
drop = 'default:dirt',
|
||||||
sounds = default.node_sound_dirt_defaults({
|
sounds = default.node_sound_dirt_defaults({
|
||||||
|
@ -732,7 +734,9 @@ minetest.register_node("default:dirt_with_grass", {
|
||||||
|
|
||||||
minetest.register_node("default:dirt_with_grass_footsteps", {
|
minetest.register_node("default:dirt_with_grass_footsteps", {
|
||||||
description = "Dirt with grass and footsteps",
|
description = "Dirt with grass and footsteps",
|
||||||
tiles ={"default_grass_footsteps.png", "default_dirt.png", "default_dirt.png^default_grass_side.png"},
|
tiles ={"default_grass_footsteps.png", "default_dirt.png",
|
||||||
|
{name = "default_dirt.png^default_grass_side.png",
|
||||||
|
tileable_vertical = false}},
|
||||||
groups = {crumbly=3, soil=1},
|
groups = {crumbly=3, soil=1},
|
||||||
drop = 'default:dirt',
|
drop = 'default:dirt',
|
||||||
sounds = default.node_sound_dirt_defaults({
|
sounds = default.node_sound_dirt_defaults({
|
||||||
|
|
|
@ -35,6 +35,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "util/string.h" // for parseColorString()
|
#include "util/string.h" // for parseColorString()
|
||||||
#include "imagefilters.h"
|
#include "imagefilters.h"
|
||||||
#include "guiscalingfilter.h"
|
#include "guiscalingfilter.h"
|
||||||
|
#include "nodedef.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
#include <GLES/gl.h>
|
#include <GLES/gl.h>
|
||||||
|
@ -330,7 +332,7 @@ public:
|
||||||
*/
|
*/
|
||||||
video::ITexture* getTexture(u32 id);
|
video::ITexture* getTexture(u32 id);
|
||||||
|
|
||||||
video::ITexture* getTexture(const std::string &name, u32 *id);
|
video::ITexture* getTexture(const std::string &name, u32 *id = NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get a texture specifically intended for mesh
|
Get a texture specifically intended for mesh
|
||||||
|
@ -383,6 +385,7 @@ public:
|
||||||
|
|
||||||
video::ITexture* getNormalTexture(const std::string &name);
|
video::ITexture* getNormalTexture(const std::string &name);
|
||||||
video::SColor getTextureAverageColor(const std::string &name);
|
video::SColor getTextureAverageColor(const std::string &name);
|
||||||
|
video::ITexture *getShaderFlagsTexture(TileDef *tiledef, TileSpec *tile);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -1992,9 +1995,8 @@ void imageTransform(u32 transform, video::IImage *src, video::IImage *dst)
|
||||||
|
|
||||||
video::ITexture* TextureSource::getNormalTexture(const std::string &name)
|
video::ITexture* TextureSource::getNormalTexture(const std::string &name)
|
||||||
{
|
{
|
||||||
u32 id;
|
|
||||||
if (isKnownSourceImage("override_normal.png"))
|
if (isKnownSourceImage("override_normal.png"))
|
||||||
return getTexture("override_normal.png", &id);
|
return getTexture("override_normal.png");
|
||||||
std::string fname_base = name;
|
std::string fname_base = name;
|
||||||
std::string normal_ext = "_normal.png";
|
std::string normal_ext = "_normal.png";
|
||||||
size_t pos = fname_base.find(".");
|
size_t pos = fname_base.find(".");
|
||||||
|
@ -2006,7 +2008,7 @@ video::ITexture* TextureSource::getNormalTexture(const std::string &name)
|
||||||
fname_base.replace(i, 4, normal_ext);
|
fname_base.replace(i, 4, normal_ext);
|
||||||
i += normal_ext.length();
|
i += normal_ext.length();
|
||||||
}
|
}
|
||||||
return getTexture(fname_base, &id);
|
return getTexture(fname_base);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -2015,8 +2017,7 @@ video::SColor TextureSource::getTextureAverageColor(const std::string &name)
|
||||||
{
|
{
|
||||||
video::IVideoDriver *driver = m_device->getVideoDriver();
|
video::IVideoDriver *driver = m_device->getVideoDriver();
|
||||||
video::SColor c(0, 0, 0, 0);
|
video::SColor c(0, 0, 0, 0);
|
||||||
u32 id;
|
video::ITexture *texture = getTexture(name);
|
||||||
video::ITexture *texture = getTexture(name, &id);
|
|
||||||
video::IImage *image = driver->createImage(texture,
|
video::IImage *image = driver->createImage(texture,
|
||||||
core::position2d<s32>(0, 0),
|
core::position2d<s32>(0, 0),
|
||||||
texture->getOriginalSize());
|
texture->getOriginalSize());
|
||||||
|
@ -2048,3 +2049,31 @@ video::SColor TextureSource::getTextureAverageColor(const std::string &name)
|
||||||
c.setAlpha(255);
|
c.setAlpha(255);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
video::ITexture *TextureSource::getShaderFlagsTexture(TileDef *tiledef, TileSpec *tile)
|
||||||
|
{
|
||||||
|
std::string tname = "__shaderFlagsTexture";
|
||||||
|
|
||||||
|
bool normalmap_present = tile->normal_texture ? true : false;
|
||||||
|
tname += normalmap_present ? "1" : "0";
|
||||||
|
tname += tiledef->tileable_horizontal ? "1" : "0";
|
||||||
|
tname += tiledef->tileable_vertical ? "1" : "0";
|
||||||
|
|
||||||
|
if (isKnownSourceImage(tname)) {
|
||||||
|
return getTexture(tname);
|
||||||
|
} else {
|
||||||
|
video::IVideoDriver *driver = m_device->getVideoDriver();
|
||||||
|
video::IImage *flags_image = driver->createImage(
|
||||||
|
video::ECF_A8R8G8B8, core::dimension2d<u32>(1, 1));
|
||||||
|
sanity_check(flags_image != NULL);
|
||||||
|
video::SColor c(
|
||||||
|
255,
|
||||||
|
normalmap_present ? 255 : 0,
|
||||||
|
tiledef->tileable_horizontal ? 255 : 0,
|
||||||
|
tiledef->tileable_vertical ? 255 : 0);
|
||||||
|
flags_image->setPixel(0, 0, c);
|
||||||
|
insertSourceImage(tname, flags_image);
|
||||||
|
flags_image->drop();
|
||||||
|
return getTexture(tname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -31,6 +31,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "util/numeric.h"
|
#include "util/numeric.h"
|
||||||
|
|
||||||
class IGameDef;
|
class IGameDef;
|
||||||
|
struct TileSpec;
|
||||||
|
struct TileDef;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
tile.{h,cpp}: Texture handling stuff.
|
tile.{h,cpp}: Texture handling stuff.
|
||||||
|
@ -111,6 +113,7 @@ public:
|
||||||
const TextureFromMeshParams ¶ms)=0;
|
const TextureFromMeshParams ¶ms)=0;
|
||||||
virtual video::ITexture* getNormalTexture(const std::string &name)=0;
|
virtual video::ITexture* getNormalTexture(const std::string &name)=0;
|
||||||
virtual video::SColor getTextureAverageColor(const std::string &name)=0;
|
virtual video::SColor getTextureAverageColor(const std::string &name)=0;
|
||||||
|
virtual video::ITexture *getShaderFlagsTexture(TileDef *tiledef, TileSpec *tile)=0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IWritableTextureSource : public ITextureSource
|
class IWritableTextureSource : public ITextureSource
|
||||||
|
@ -133,6 +136,7 @@ public:
|
||||||
virtual void rebuildImagesAndTextures()=0;
|
virtual void rebuildImagesAndTextures()=0;
|
||||||
virtual video::ITexture* getNormalTexture(const std::string &name)=0;
|
virtual video::ITexture* getNormalTexture(const std::string &name)=0;
|
||||||
virtual video::SColor getTextureAverageColor(const std::string &name)=0;
|
virtual video::SColor getTextureAverageColor(const std::string &name)=0;
|
||||||
|
virtual video::ITexture *getShaderFlagsTexture(TileDef *tiledef, TileSpec *tile)=0;
|
||||||
};
|
};
|
||||||
|
|
||||||
IWritableTextureSource* createTextureSource(IrrlichtDevice *device);
|
IWritableTextureSource* createTextureSource(IrrlichtDevice *device);
|
||||||
|
@ -172,12 +176,14 @@ struct FrameSpec
|
||||||
FrameSpec():
|
FrameSpec():
|
||||||
texture_id(0),
|
texture_id(0),
|
||||||
texture(NULL),
|
texture(NULL),
|
||||||
normal_texture(NULL)
|
normal_texture(NULL),
|
||||||
|
flags_texture(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
u32 texture_id;
|
u32 texture_id;
|
||||||
video::ITexture *texture;
|
video::ITexture *texture;
|
||||||
video::ITexture *normal_texture;
|
video::ITexture *normal_texture;
|
||||||
|
video::ITexture *flags_texture;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TileSpec
|
struct TileSpec
|
||||||
|
@ -186,6 +192,7 @@ struct TileSpec
|
||||||
texture_id(0),
|
texture_id(0),
|
||||||
texture(NULL),
|
texture(NULL),
|
||||||
normal_texture(NULL),
|
normal_texture(NULL),
|
||||||
|
flags_texture(NULL),
|
||||||
alpha(255),
|
alpha(255),
|
||||||
material_type(TILE_MATERIAL_BASIC),
|
material_type(TILE_MATERIAL_BASIC),
|
||||||
material_flags(
|
material_flags(
|
||||||
|
@ -252,6 +259,7 @@ struct TileSpec
|
||||||
u32 texture_id;
|
u32 texture_id;
|
||||||
video::ITexture *texture;
|
video::ITexture *texture;
|
||||||
video::ITexture *normal_texture;
|
video::ITexture *normal_texture;
|
||||||
|
video::ITexture *flags_texture;
|
||||||
|
|
||||||
// Vertex alpha (when MATERIAL_ALPHA_VERTEX is used)
|
// Vertex alpha (when MATERIAL_ALPHA_VERTEX is used)
|
||||||
u8 alpha;
|
u8 alpha;
|
||||||
|
@ -266,5 +274,4 @@ struct TileSpec
|
||||||
|
|
||||||
u8 rotation;
|
u8 rotation;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
14
src/game.cpp
14
src/game.cpp
|
@ -878,11 +878,11 @@ public:
|
||||||
#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
|
#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
|
||||||
services->setPixelShaderConstant("baseTexture" , (irr::f32 *)&layer0, 1);
|
services->setPixelShaderConstant("baseTexture" , (irr::f32 *)&layer0, 1);
|
||||||
services->setPixelShaderConstant("normalTexture" , (irr::f32 *)&layer1, 1);
|
services->setPixelShaderConstant("normalTexture" , (irr::f32 *)&layer1, 1);
|
||||||
services->setPixelShaderConstant("useNormalmap" , (irr::f32 *)&layer2, 1);
|
services->setPixelShaderConstant("textureFlags" , (irr::f32 *)&layer2, 1);
|
||||||
#else
|
#else
|
||||||
services->setPixelShaderConstant("baseTexture" , (irr::s32 *)&layer0, 1);
|
services->setPixelShaderConstant("baseTexture" , (irr::s32 *)&layer0, 1);
|
||||||
services->setPixelShaderConstant("normalTexture" , (irr::s32 *)&layer1, 1);
|
services->setPixelShaderConstant("normalTexture" , (irr::s32 *)&layer1, 1);
|
||||||
services->setPixelShaderConstant("useNormalmap" , (irr::s32 *)&layer2, 1);
|
services->setPixelShaderConstant("textureFlags" , (irr::s32 *)&layer2, 1);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -4352,13 +4352,9 @@ void the_game(bool *kill,
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (SerializationError &e) {
|
} catch (SerializationError &e) {
|
||||||
error_message = strgettext("A serialization error occurred:")
|
error_message = std::string("A serialization error occurred:\n")
|
||||||
+ "\n" + e.what();
|
+ e.what() + "\n\nThe server is probably "
|
||||||
if (!simple_singleplayer_mode) {
|
" running a different version of " PROJECT_NAME_C ".";
|
||||||
error_message += "\n\n"
|
|
||||||
+ strgettext("The server is probably running a different version of")
|
|
||||||
+ " " PROJECT_NAME_C ".";
|
|
||||||
}
|
|
||||||
errorstream << error_message << std::endl;
|
errorstream << error_message << std::endl;
|
||||||
} catch (ServerError &e) {
|
} catch (ServerError &e) {
|
||||||
error_message = e.what();
|
error_message = e.what();
|
||||||
|
|
|
@ -1213,10 +1213,8 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
|
||||||
p.tile.applyMaterialOptionsWithShaders(material);
|
p.tile.applyMaterialOptionsWithShaders(material);
|
||||||
if (p.tile.normal_texture) {
|
if (p.tile.normal_texture) {
|
||||||
material.setTexture(1, p.tile.normal_texture);
|
material.setTexture(1, p.tile.normal_texture);
|
||||||
material.setTexture(2, m_tsrc->getTextureForMesh("enable_img.png"));
|
|
||||||
} else {
|
|
||||||
material.setTexture(2, m_tsrc->getTextureForMesh("disable_img.png"));
|
|
||||||
}
|
}
|
||||||
|
material.setTexture(2, p.tile.flags_texture);
|
||||||
} else {
|
} else {
|
||||||
p.tile.applyMaterialOptions(material);
|
p.tile.applyMaterialOptions(material);
|
||||||
}
|
}
|
||||||
|
@ -1349,10 +1347,8 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_rat
|
||||||
if (m_enable_shaders) {
|
if (m_enable_shaders) {
|
||||||
if (animation_frame.normal_texture) {
|
if (animation_frame.normal_texture) {
|
||||||
buf->getMaterial().setTexture(1, animation_frame.normal_texture);
|
buf->getMaterial().setTexture(1, animation_frame.normal_texture);
|
||||||
buf->getMaterial().setTexture(2, m_tsrc->getTextureForMesh("enable_img.png"));
|
|
||||||
} else {
|
|
||||||
buf->getMaterial().setTexture(2, m_tsrc->getTextureForMesh("disable_img.png"));
|
|
||||||
}
|
}
|
||||||
|
buf->getMaterial().setTexture(2, animation_frame.flags_texture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -130,6 +130,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
presentation
|
presentation
|
||||||
Add TOCLIENT_AUTH_ACCEPT to accept connection from client
|
Add TOCLIENT_AUTH_ACCEPT to accept connection from client
|
||||||
Rename GENERIC_CMD_SET_ATTACHMENT to GENERIC_CMD_ATTACH_TO
|
Rename GENERIC_CMD_SET_ATTACHMENT to GENERIC_CMD_ATTACH_TO
|
||||||
|
PROTOCOL_VERSION 26:
|
||||||
|
Add TileDef tileable_horizontal, tileable_vertical flags
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define LATEST_PROTOCOL_VERSION 25
|
#define LATEST_PROTOCOL_VERSION 25
|
||||||
|
|
|
@ -120,7 +120,9 @@ void NodeBox::deSerialize(std::istream &is)
|
||||||
|
|
||||||
void TileDef::serialize(std::ostream &os, u16 protocol_version) const
|
void TileDef::serialize(std::ostream &os, u16 protocol_version) const
|
||||||
{
|
{
|
||||||
if(protocol_version >= 17)
|
if (protocol_version >= 26)
|
||||||
|
writeU8(os, 2);
|
||||||
|
else if (protocol_version >= 17)
|
||||||
writeU8(os, 1);
|
writeU8(os, 1);
|
||||||
else
|
else
|
||||||
writeU8(os, 0);
|
writeU8(os, 0);
|
||||||
|
@ -129,8 +131,12 @@ void TileDef::serialize(std::ostream &os, u16 protocol_version) const
|
||||||
writeU16(os, animation.aspect_w);
|
writeU16(os, animation.aspect_w);
|
||||||
writeU16(os, animation.aspect_h);
|
writeU16(os, animation.aspect_h);
|
||||||
writeF1000(os, animation.length);
|
writeF1000(os, animation.length);
|
||||||
if(protocol_version >= 17)
|
if (protocol_version >= 17)
|
||||||
writeU8(os, backface_culling);
|
writeU8(os, backface_culling);
|
||||||
|
if (protocol_version >= 26) {
|
||||||
|
writeU8(os, tileable_horizontal);
|
||||||
|
writeU8(os, tileable_vertical);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileDef::deSerialize(std::istream &is)
|
void TileDef::deSerialize(std::istream &is)
|
||||||
|
@ -141,10 +147,15 @@ void TileDef::deSerialize(std::istream &is)
|
||||||
animation.aspect_w = readU16(is);
|
animation.aspect_w = readU16(is);
|
||||||
animation.aspect_h = readU16(is);
|
animation.aspect_h = readU16(is);
|
||||||
animation.length = readF1000(is);
|
animation.length = readF1000(is);
|
||||||
if(version >= 1)
|
if (version >= 1)
|
||||||
backface_culling = readU8(is);
|
backface_culling = readU8(is);
|
||||||
|
if (version >= 2) {
|
||||||
|
tileable_horizontal = readU8(is);
|
||||||
|
tileable_vertical = readU8(is);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SimpleSoundSpec serialization
|
SimpleSoundSpec serialization
|
||||||
*/
|
*/
|
||||||
|
@ -183,6 +194,7 @@ void ContentFeatures::reset()
|
||||||
solidness = 2;
|
solidness = 2;
|
||||||
visual_solidness = 0;
|
visual_solidness = 0;
|
||||||
backface_culling = true;
|
backface_culling = true;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
has_on_construct = false;
|
has_on_construct = false;
|
||||||
has_on_destruct = false;
|
has_on_destruct = false;
|
||||||
|
@ -996,9 +1008,11 @@ void CNodeDefManager::fillTileAttribs(ITextureSource *tsrc, TileSpec *tile,
|
||||||
tile->alpha = alpha;
|
tile->alpha = alpha;
|
||||||
tile->material_type = material_type;
|
tile->material_type = material_type;
|
||||||
|
|
||||||
// Normal texture
|
// Normal texture and shader flags texture
|
||||||
if (use_normal_texture)
|
if (use_normal_texture) {
|
||||||
tile->normal_texture = tsrc->getNormalTexture(tiledef->name);
|
tile->normal_texture = tsrc->getNormalTexture(tiledef->name);
|
||||||
|
}
|
||||||
|
tile->flags_texture = tsrc->getShaderFlagsTexture(tiledef, tile);
|
||||||
|
|
||||||
// Material flags
|
// Material flags
|
||||||
tile->material_flags = 0;
|
tile->material_flags = 0;
|
||||||
|
@ -1038,6 +1052,7 @@ void CNodeDefManager::fillTileAttribs(ITextureSource *tsrc, TileSpec *tile,
|
||||||
frame.texture = tsrc->getTextureForMesh(os.str(), &frame.texture_id);
|
frame.texture = tsrc->getTextureForMesh(os.str(), &frame.texture_id);
|
||||||
if (tile->normal_texture)
|
if (tile->normal_texture)
|
||||||
frame.normal_texture = tsrc->getNormalTexture(os.str());
|
frame.normal_texture = tsrc->getNormalTexture(os.str());
|
||||||
|
frame.flags_texture = tile->flags_texture;
|
||||||
tile->frames[i] = frame;
|
tile->frames[i] = frame;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,6 +113,8 @@ struct TileDef
|
||||||
{
|
{
|
||||||
std::string name;
|
std::string name;
|
||||||
bool backface_culling; // Takes effect only in special cases
|
bool backface_culling; // Takes effect only in special cases
|
||||||
|
bool tileable_horizontal;
|
||||||
|
bool tileable_vertical;
|
||||||
struct{
|
struct{
|
||||||
enum TileAnimationType type;
|
enum TileAnimationType type;
|
||||||
int aspect_w; // width for aspect ratio
|
int aspect_w; // width for aspect ratio
|
||||||
|
@ -124,6 +126,8 @@ struct TileDef
|
||||||
{
|
{
|
||||||
name = "";
|
name = "";
|
||||||
backface_culling = true;
|
backface_culling = true;
|
||||||
|
tileable_horizontal = true;
|
||||||
|
tileable_vertical = true;
|
||||||
animation.type = TAT_NONE;
|
animation.type = TAT_NONE;
|
||||||
animation.aspect_w = 1;
|
animation.aspect_w = 1;
|
||||||
animation.aspect_h = 1;
|
animation.aspect_h = 1;
|
||||||
|
|
|
@ -277,20 +277,24 @@ TileDef read_tiledef(lua_State *L, int index)
|
||||||
getstringfield(L, index, "name", tiledef.name);
|
getstringfield(L, index, "name", tiledef.name);
|
||||||
getstringfield(L, index, "image", tiledef.name); // MaterialSpec compat.
|
getstringfield(L, index, "image", tiledef.name); // MaterialSpec compat.
|
||||||
tiledef.backface_culling = getboolfield_default(
|
tiledef.backface_culling = getboolfield_default(
|
||||||
L, index, "backface_culling", true);
|
L, index, "backface_culling", true);
|
||||||
|
tiledef.tileable_horizontal = getboolfield_default(
|
||||||
|
L, index, "tileable_horizontal", true);
|
||||||
|
tiledef.tileable_vertical = getboolfield_default(
|
||||||
|
L, index, "tileable_vertical", true);
|
||||||
// animation = {}
|
// animation = {}
|
||||||
lua_getfield(L, index, "animation");
|
lua_getfield(L, index, "animation");
|
||||||
if(lua_istable(L, -1)){
|
if(lua_istable(L, -1)){
|
||||||
// {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}
|
// {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}
|
||||||
tiledef.animation.type = (TileAnimationType)
|
tiledef.animation.type = (TileAnimationType)
|
||||||
getenumfield(L, -1, "type", es_TileAnimationType,
|
getenumfield(L, -1, "type", es_TileAnimationType,
|
||||||
TAT_NONE);
|
TAT_NONE);
|
||||||
tiledef.animation.aspect_w =
|
tiledef.animation.aspect_w =
|
||||||
getintfield_default(L, -1, "aspect_w", 16);
|
getintfield_default(L, -1, "aspect_w", 16);
|
||||||
tiledef.animation.aspect_h =
|
tiledef.animation.aspect_h =
|
||||||
getintfield_default(L, -1, "aspect_h", 16);
|
getintfield_default(L, -1, "aspect_h", 16);
|
||||||
tiledef.animation.length =
|
tiledef.animation.length =
|
||||||
getfloatfield_default(L, -1, "length", 1.0);
|
getfloatfield_default(L, -1, "length", 1.0);
|
||||||
}
|
}
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 150 B |
Binary file not shown.
Before Width: | Height: | Size: 160 B |
Loading…
Reference in New Issue