Fix relief mapping issues
authorRealBadAngel <maciej.kasatkin@o2.pl>
Thu, 16 Jul 2015 13:36:48 +0000 (15:36 +0200)
committerRealBadAngel <maciej.kasatkin@o2.pl>
Thu, 16 Jul 2015 13:36:48 +0000 (15:36 +0200)
15 files changed:
client/shaders/nodes_shader/opengl_fragment.glsl
client/shaders/nodes_shader/opengl_vertex.glsl
client/shaders/water_surface_shader/opengl_fragment.glsl
doc/lua_api.txt
games/minimal/mods/default/init.lua
src/client/tile.cpp
src/client/tile.h
src/game.cpp
src/mapblock_mesh.cpp
src/network/networkprotocol.h
src/nodedef.cpp
src/nodedef.h
src/script/common/c_content.cpp
textures/base/pack/disable_img.png [deleted file]
textures/base/pack/enable_img.png [deleted file]

index 8dc3a5683b4fb368758c24f1180750e13c318a53..02bf2c124f5df53594129920caff2239b0b3ea2e 100644 (file)
@@ -1,6 +1,6 @@
 uniform sampler2D baseTexture;
 uniform sampler2D normalTexture;
-uniform sampler2D useNormalmap;
+uniform sampler2D textureFlags;
 
 uniform vec4 skyBgColor;
 uniform float fogDistance;
@@ -15,19 +15,73 @@ varying vec3 tsEyeVec;
 varying vec3 lightVec;
 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 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;
 }
 
-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)
@@ -50,7 +104,8 @@ float find_intersection(vec2 dp, vec2 ds)
        return depth;
 }
 
-float find_intersectionRGB(vec2 dp, vec2 ds) {
+float find_intersectionRGB(vec2 dp, vec2 ds)
+{
        const float depth_step = 1.0 / 24.0;
        float depth = 1.0;
        for (int i = 0 ; i < 24 ; i++) {
@@ -62,24 +117,19 @@ float find_intersectionRGB(vec2 dp, vec2 ds) {
        return depth;
 }
 
-void main (void)
+void main(void)
 {
        vec3 color;
        vec4 bump;
        vec2 uv = gl_TexCoord[0].st;
        bool use_normalmap = false;
-
-#if USE_NORMALMAPS == 1
-       if (texture2D(useNormalmap,vec2(1.0, 1.0)).r > 0.0) {
-               normalTexturePresent = true;
-       }
-#endif
+       get_texture_flags();
 
 #ifdef ENABLE_PARALLAX_OCCLUSION
        vec2 eyeRay = vec2 (tsEyeVec.x, -tsEyeVec.y);
        const float scale = PARALLAX_OCCLUSION_SCALE / PARALLAX_OCCLUSION_ITERATIONS;
        const float bias = PARALLAX_OCCLUSION_BIAS / PARALLAX_OCCLUSION_ITERATIONS;
-               
+
 #if PARALLAX_OCCLUSION_MODE == 0
        // Parallax occlusion with slope information
        if (normalTexturePresent && area_enable_parallax > 0.0) {
@@ -89,17 +139,23 @@ void main (void)
                        uv += h * normal.z * eyeRay;
                }
 #endif
+
 #if PARALLAX_OCCLUSION_MODE == 1
        // Relief mapping
        if (normalTexturePresent && area_enable_parallax > 0.0) {
                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);
-               uv += dist * ds;
+               uv = validate_displacement(uv, ds, dist);
+
 #endif
        } else if (GENERATE_NORMALMAPS == 1 && area_enable_parallax > 0.0) {
                vec2 ds = eyeRay * PARALLAX_OCCLUSION_SCALE;
+               uv -= ds;
                float dist = find_intersectionRGB(uv, ds);
-               uv += dist * ds;
+               uv = validate_displacement(uv, ds, dist);
        }
 #endif
 
@@ -107,10 +163,10 @@ void main (void)
        if (normalTexturePresent) {
                bump = get_normal_map(uv);
                use_normalmap = true;
-       } 
+       }
 #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 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));
index 9f8210d12dfed402c0915b5928d58b86eacdb04a..acdaa47d195e44beaf439504f902901a395a9e60 100644 (file)
@@ -94,7 +94,7 @@ void main(void)
 
        // Don't generate heightmaps when too far from the eye
        float dist = distance (vec3(0.0, 0.0 ,0.0), vPosition);
-       if (dist > 120.0) {
+       if (dist > 300.0) {
                area_enable_parallax = 0.0;
        }
 
index 386f7748650381641766cd0e3904e5e4fbad8709..75751e243edade3ac46822a75412a3624bc1052e 100644 (file)
@@ -1,6 +1,6 @@
 uniform sampler2D baseTexture;
 uniform sampler2D normalTexture;
-uniform sampler2D useNormalmap;
+uniform sampler2D textureFlags;
 
 uniform vec4 skyBgColor;
 uniform float fogDistance;
@@ -15,37 +15,55 @@ varying vec3 lightVec;
 varying vec3 tsLightVec;
 
 bool normalTexturePresent = false;
+bool texTileableHorizontal = false;
+bool texTileableVertical = false;
+bool texSeamless = false;
 
 const float e = 2.718281828459;
 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;
 }
 
-float get_rgb_height (vec2 uv){
+float get_rgb_height(vec2 uv)
+{
        return intensity(texture2D(baseTexture,uv).rgb);
 }
 
-vec4 get_normal_map(vec2 uv){
+vec4 get_normal_map(vec2 uv)
+{
        vec4 bump = texture2D(normalTexture, uv).rgba;
        bump.xyz = normalize(bump.xyz * 2.0 -1.0);
        bump.y = -bump.y;
        return bump;
 }
 
-void main (void)
+void main(void)
 {
        vec3 color;
        vec4 bump;
        vec2 uv = gl_TexCoord[0].st;
        bool use_normalmap = false;
-
-#ifdef USE_NORMALMAPS
-       if (texture2D(useNormalmap,vec2(1.0,1.0)).r > 0.0) {
-               normalTexturePresent = true;
-       }
-#endif
+       get_texture_flags();
 
 #ifdef ENABLE_PARALLAX_OCCLUSION
        if (normalTexturePresent) {
index 49292d2b480774da830c38805f8c51226a59e443..34d22cdb8c4e933a69e558b119b89ff0eb3d61f8 100644 (file)
@@ -3058,8 +3058,13 @@ Definition tables
 ### Tile definition
 * `"image.png"`
 * `{name="image.png", animation={Tile Animation definition}}`
-* `{name="image.png", backface_culling=bool}`
-    * backface culling only supported in special tiles
+* `{name="image.png", backface_culling=bool, tileable_vertical=bool,
+    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:
     * `image` (name)
 
index dd3d7bbf6a2fd0787180a490fcaefb646cf195ce..bff7860e36f54d9d4cda9893525b20fa53c683a6 100644 (file)
@@ -722,7 +722,9 @@ minetest.register_node("default:stone_with_iron", {
 
 minetest.register_node("default: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},
        drop = 'default:dirt',
        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", {
        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},
        drop = 'default:dirt',
        sounds = default.node_sound_dirt_defaults({
index cf8061982d6af77955dc5637632b2ed28f7b9d54..5ad564b651c93aa0ea70d4e768e3f2ba84cbcba5 100644 (file)
@@ -35,6 +35,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "util/string.h" // for parseColorString()
 #include "imagefilters.h"
 #include "guiscalingfilter.h"
+#include "nodedef.h"
+
 
 #ifdef __ANDROID__
 #include <GLES/gl.h>
@@ -330,7 +332,7 @@ public:
        */
        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
@@ -383,6 +385,7 @@ public:
 
        video::ITexture* getNormalTexture(const std::string &name);
        video::SColor getTextureAverageColor(const std::string &name);
+       video::ITexture *getShaderFlagsTexture(TileDef *tiledef, TileSpec *tile);
 
 private:
 
@@ -1992,9 +1995,8 @@ void imageTransform(u32 transform, video::IImage *src, video::IImage *dst)
 
 video::ITexture* TextureSource::getNormalTexture(const std::string &name)
 {
-       u32 id;
        if (isKnownSourceImage("override_normal.png"))
-               return getTexture("override_normal.png", &id);
+               return getTexture("override_normal.png");
        std::string fname_base = name;
        std::string normal_ext = "_normal.png";
        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);
                        i += normal_ext.length();
                }
-               return getTexture(fname_base, &id);
+               return getTexture(fname_base);
                }
        return NULL;
 }
@@ -2015,8 +2017,7 @@ video::SColor TextureSource::getTextureAverageColor(const std::string &name)
 {
        video::IVideoDriver *driver = m_device->getVideoDriver();
        video::SColor c(0, 0, 0, 0);
-       u32 id;
-       video::ITexture *texture = getTexture(name, &id);
+       video::ITexture *texture = getTexture(name);
        video::IImage *image = driver->createImage(texture,
                core::position2d<s32>(0, 0),
                texture->getOriginalSize());
@@ -2048,3 +2049,31 @@ video::SColor TextureSource::getTextureAverageColor(const std::string &name)
        c.setAlpha(255);
        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);
+       }
+}
index 674da66f22903a3d1836f860f1392c3a1cbb8ce8..13f1a8b349d08a381a36e37402609ec03634f6b0 100644 (file)
@@ -31,6 +31,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "util/numeric.h"
 
 class IGameDef;
+struct TileSpec;
+struct TileDef;
 
 /*
        tile.{h,cpp}: Texture handling stuff.
@@ -111,6 +113,7 @@ public:
                        const TextureFromMeshParams &params)=0;
        virtual video::ITexture* getNormalTexture(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
@@ -133,6 +136,7 @@ public:
        virtual void rebuildImagesAndTextures()=0;
        virtual video::ITexture* getNormalTexture(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);
@@ -172,12 +176,14 @@ struct FrameSpec
        FrameSpec():
                texture_id(0),
                texture(NULL),
-               normal_texture(NULL)
+               normal_texture(NULL),
+               flags_texture(NULL)
        {
        }
        u32 texture_id;
        video::ITexture *texture;
        video::ITexture *normal_texture;
+       video::ITexture *flags_texture;
 };
 
 struct TileSpec
@@ -186,6 +192,7 @@ struct TileSpec
                texture_id(0),
                texture(NULL),
                normal_texture(NULL),
+               flags_texture(NULL),
                alpha(255),
                material_type(TILE_MATERIAL_BASIC),
                material_flags(
@@ -252,6 +259,7 @@ struct TileSpec
        u32 texture_id;
        video::ITexture *texture;
        video::ITexture *normal_texture;
+       video::ITexture *flags_texture;
        
        // Vertex alpha (when MATERIAL_ALPHA_VERTEX is used)
        u8 alpha;
@@ -266,5 +274,4 @@ struct TileSpec
 
        u8 rotation;
 };
-
 #endif
index d5819f78aa46a2b0f54707917cf9d3a6eb54271d..e3d6b0bc6fb395fe3d627e11dd395e5cbdf9325c 100644 (file)
@@ -878,11 +878,11 @@ public:
 #if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
                services->setPixelShaderConstant("baseTexture" , (irr::f32 *)&layer0, 1);
                services->setPixelShaderConstant("normalTexture" , (irr::f32 *)&layer1, 1);
-               services->setPixelShaderConstant("useNormalmap" , (irr::f32 *)&layer2, 1);
+               services->setPixelShaderConstant("textureFlags" , (irr::f32 *)&layer2, 1);
 #else
                services->setPixelShaderConstant("baseTexture" , (irr::s32 *)&layer0, 1);
                services->setPixelShaderConstant("normalTexture" , (irr::s32 *)&layer1, 1);
-               services->setPixelShaderConstant("useNormalmap" , (irr::s32 *)&layer2, 1);
+               services->setPixelShaderConstant("textureFlags" , (irr::s32 *)&layer2, 1);
 #endif
        }
 };
@@ -4352,13 +4352,9 @@ void the_game(bool *kill,
                }
 
        } catch (SerializationError &e) {
-               error_message = strgettext("A serialization error occurred:")
-                               + "\n" + e.what();
-               if (!simple_singleplayer_mode) {
-                       error_message += "\n\n"
-                                       + strgettext("The server is probably running a different version of")
-                                       + " " PROJECT_NAME_C ".";
-               }
+               error_message = std::string("A serialization error occurred:\n")
+                               + e.what() + "\n\nThe server is probably "
+                               " running a different version of " PROJECT_NAME_C ".";
                errorstream << error_message << std::endl;
        } catch (ServerError &e) {
                error_message = e.what();
index 145ab40c253fb51a10f03ba93757ce8d2560a4a5..32f6e659a4957fc4d6f34ea064a0dd5384b4a679 100644 (file)
@@ -1213,10 +1213,8 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
                                p.tile.applyMaterialOptionsWithShaders(material);
                                if (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 {
                                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 (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);
                }
        }
 
index 852f2ee0390c880bce058873fc556dd99ea20106..e4b5667409fbdc4bacb82ab9ef31cc09caa3a2a4 100644 (file)
@@ -130,6 +130,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
                        presentation
                Add TOCLIENT_AUTH_ACCEPT to accept connection from client
                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
index ccafd45984c6e95d39f55e20f73b15ddd6b1c91d..bb4f102da224298ec2b38253843ae0bcd356a411 100644 (file)
@@ -120,7 +120,9 @@ void NodeBox::deSerialize(std::istream &is)
 
 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);
        else
                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_h);
        writeF1000(os, animation.length);
-       if(protocol_version >= 17)
+       if (protocol_version >= 17)
                writeU8(os, backface_culling);
+       if (protocol_version >= 26) {
+               writeU8(os, tileable_horizontal);
+               writeU8(os, tileable_vertical);
+       }
 }
 
 void TileDef::deSerialize(std::istream &is)
@@ -141,10 +147,15 @@ void TileDef::deSerialize(std::istream &is)
        animation.aspect_w = readU16(is);
        animation.aspect_h = readU16(is);
        animation.length = readF1000(is);
-       if(version >= 1)
+       if (version >= 1)
                backface_culling = readU8(is);
+       if (version >= 2) {
+               tileable_horizontal = readU8(is);
+               tileable_vertical = readU8(is);
+       }
 }
 
+
 /*
        SimpleSoundSpec serialization
 */
@@ -183,6 +194,7 @@ void ContentFeatures::reset()
        solidness = 2;
        visual_solidness = 0;
        backface_culling = true;
+
 #endif
        has_on_construct = false;
        has_on_destruct = false;
@@ -996,9 +1008,11 @@ void CNodeDefManager::fillTileAttribs(ITextureSource *tsrc, TileSpec *tile,
        tile->alpha         = alpha;
        tile->material_type = material_type;
 
-       // Normal texture
-       if (use_normal_texture)
+       // Normal texture and shader flags texture
+       if (use_normal_texture) {
                tile->normal_texture = tsrc->getNormalTexture(tiledef->name);
+       }
+       tile->flags_texture = tsrc->getShaderFlagsTexture(tiledef, tile);
 
        // Material flags
        tile->material_flags = 0;
@@ -1038,6 +1052,7 @@ void CNodeDefManager::fillTileAttribs(ITextureSource *tsrc, TileSpec *tile,
                        frame.texture = tsrc->getTextureForMesh(os.str(), &frame.texture_id);
                        if (tile->normal_texture)
                                frame.normal_texture = tsrc->getNormalTexture(os.str());
+                       frame.flags_texture = tile->flags_texture;
                        tile->frames[i] = frame;
                }
        }
index bbce6ba3ef5ac0965c13fc0b6044a6693279922c..a4a7b6e41b9d8cd6ee7bb7deadeeacc697d587e5 100644 (file)
@@ -113,6 +113,8 @@ struct TileDef
 {
        std::string name;
        bool backface_culling; // Takes effect only in special cases
+       bool tileable_horizontal;
+       bool tileable_vertical;
        struct{
                enum TileAnimationType type;
                int aspect_w; // width for aspect ratio
@@ -124,6 +126,8 @@ struct TileDef
        {
                name = "";
                backface_culling = true;
+               tileable_horizontal = true;
+               tileable_vertical = true;
                animation.type = TAT_NONE;
                animation.aspect_w = 1;
                animation.aspect_h = 1;
index 4db92190b89fcb20b301bf0c13585d9b84c48fd3..42c6889d893b816f7b5321c6633f186aa0d6a991 100644 (file)
@@ -277,20 +277,24 @@ TileDef read_tiledef(lua_State *L, int index)
                getstringfield(L, index, "name", tiledef.name);
                getstringfield(L, index, "image", tiledef.name); // MaterialSpec compat.
                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 = {}
                lua_getfield(L, index, "animation");
                if(lua_istable(L, -1)){
                        // {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}
                        tiledef.animation.type = (TileAnimationType)
-                                       getenumfield(L, -1, "type", es_TileAnimationType,
-                                       TAT_NONE);
+                               getenumfield(L, -1, "type", es_TileAnimationType,
+                               TAT_NONE);
                        tiledef.animation.aspect_w =
-                                       getintfield_default(L, -1, "aspect_w", 16);
+                               getintfield_default(L, -1, "aspect_w", 16);
                        tiledef.animation.aspect_h =
-                                       getintfield_default(L, -1, "aspect_h", 16);
+                               getintfield_default(L, -1, "aspect_h", 16);
                        tiledef.animation.length =
-                                       getfloatfield_default(L, -1, "length", 1.0);
+                               getfloatfield_default(L, -1, "length", 1.0);
                }
                lua_pop(L, 1);
        }
diff --git a/textures/base/pack/disable_img.png b/textures/base/pack/disable_img.png
deleted file mode 100644 (file)
index 4d3a1b4..0000000
Binary files a/textures/base/pack/disable_img.png and /dev/null differ
diff --git a/textures/base/pack/enable_img.png b/textures/base/pack/enable_img.png
deleted file mode 100644 (file)
index e07f4e9..0000000
Binary files a/textures/base/pack/enable_img.png and /dev/null differ