All textures are are now searched first from the directory specified by the texture_path setting.

This commit is contained in:
Perttu Ahola 2011-05-21 11:07:03 +03:00
parent a8acf3c391
commit 969fbb189d
12 changed files with 108 additions and 190 deletions

@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "constants.h"
#include "utility.h"
#include "environment.h"
#include "tile.h"
/*
ClientActiveObject
@ -114,7 +115,7 @@ void TestCAO::addToScene(scene::ISceneManager *smgr)
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
buf->getMaterial().setTexture
(0, driver->getTexture(porting::getDataPath("rat.png").c_str()));
(0, driver->getTexture(getTexturePath("rat.png").c_str()));
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
@ -237,7 +238,7 @@ void ItemCAO::addToScene(scene::ISceneManager *smgr)
//buf->getMaterial().setTexture(0, NULL);
// Initialize with the stick texture
buf->getMaterial().setTexture
(0, driver->getTexture(porting::getDataPath("stick.png").c_str()));
(0, driver->getTexture(getTexturePath("stick.png").c_str()));
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
@ -443,7 +444,7 @@ void RatCAO::addToScene(scene::ISceneManager *smgr)
buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
//buf->getMaterial().setTexture(0, NULL);
buf->getMaterial().setTexture
(0, driver->getTexture(porting::getDataPath("rat.png").c_str()));
(0, driver->getTexture(getTexturePath("rat.png").c_str()));
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
@ -604,7 +605,7 @@ void Oerkki1CAO::addToScene(scene::ISceneManager *smgr)
buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
//buf->getMaterial().setTexture(0, NULL);
buf->getMaterial().setTexture
(0, driver->getTexture(porting::getDataPath("oerkki1.png").c_str()));
(0, driver->getTexture(getTexturePath("oerkki1.png").c_str()));
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;

@ -345,7 +345,7 @@ void draw_hotbar(video::IVideoDriver *driver, gui::IGUIFont *font,
*/
{
video::ITexture *heart_texture =
driver->getTexture(porting::getDataPath("heart.png").c_str());
driver->getTexture(getTexturePath("heart.png").c_str());
v2s32 p = pos + v2s32(0, -20);
for(s32 i=0; i<halfheartcount/2; i++)
{
@ -597,32 +597,32 @@ void update_skybox(video::IVideoDriver* driver,
if(brightness >= 0.5)
{
skybox = smgr->addSkyBoxSceneNode(
driver->getTexture(porting::getDataPath("skybox2.png").c_str()),
driver->getTexture(porting::getDataPath("skybox3.png").c_str()),
driver->getTexture(porting::getDataPath("skybox1.png").c_str()),
driver->getTexture(porting::getDataPath("skybox1.png").c_str()),
driver->getTexture(porting::getDataPath("skybox1.png").c_str()),
driver->getTexture(porting::getDataPath("skybox1.png").c_str()));
driver->getTexture(getTexturePath("skybox2.png").c_str()),
driver->getTexture(getTexturePath("skybox3.png").c_str()),
driver->getTexture(getTexturePath("skybox1.png").c_str()),
driver->getTexture(getTexturePath("skybox1.png").c_str()),
driver->getTexture(getTexturePath("skybox1.png").c_str()),
driver->getTexture(getTexturePath("skybox1.png").c_str()));
}
else if(brightness >= 0.2)
{
skybox = smgr->addSkyBoxSceneNode(
driver->getTexture(porting::getDataPath("skybox2_dawn.png").c_str()),
driver->getTexture(porting::getDataPath("skybox3_dawn.png").c_str()),
driver->getTexture(porting::getDataPath("skybox1_dawn.png").c_str()),
driver->getTexture(porting::getDataPath("skybox1_dawn.png").c_str()),
driver->getTexture(porting::getDataPath("skybox1_dawn.png").c_str()),
driver->getTexture(porting::getDataPath("skybox1_dawn.png").c_str()));
driver->getTexture(getTexturePath("skybox2_dawn.png").c_str()),
driver->getTexture(getTexturePath("skybox3_dawn.png").c_str()),
driver->getTexture(getTexturePath("skybox1_dawn.png").c_str()),
driver->getTexture(getTexturePath("skybox1_dawn.png").c_str()),
driver->getTexture(getTexturePath("skybox1_dawn.png").c_str()),
driver->getTexture(getTexturePath("skybox1_dawn.png").c_str()));
}
else
{
skybox = smgr->addSkyBoxSceneNode(
driver->getTexture(porting::getDataPath("skybox2_night.png").c_str()),
driver->getTexture(porting::getDataPath("skybox3_night.png").c_str()),
driver->getTexture(porting::getDataPath("skybox1_night.png").c_str()),
driver->getTexture(porting::getDataPath("skybox1_night.png").c_str()),
driver->getTexture(porting::getDataPath("skybox1_night.png").c_str()),
driver->getTexture(porting::getDataPath("skybox1_night.png").c_str()));
driver->getTexture(getTexturePath("skybox2_night.png").c_str()),
driver->getTexture(getTexturePath("skybox3_night.png").c_str()),
driver->getTexture(getTexturePath("skybox1_night.png").c_str()),
driver->getTexture(getTexturePath("skybox1_night.png").c_str()),
driver->getTexture(getTexturePath("skybox1_night.png").c_str()),
driver->getTexture(getTexturePath("skybox1_night.png").c_str()));
}
}

@ -913,7 +913,7 @@ void drawMenuBackground(video::IVideoDriver* driver)
core::dimension2d<u32> screensize = driver->getScreenSize();
video::ITexture *bgtexture =
driver->getTexture(porting::getDataPath("mud.png").c_str());
driver->getTexture(getTexturePath("mud.png").c_str());
if(bgtexture)
{
s32 texturesize = 128;
@ -933,7 +933,7 @@ void drawMenuBackground(video::IVideoDriver* driver)
}
video::ITexture *logotexture =
driver->getTexture(porting::getDataPath("menulogo.png").c_str());
driver->getTexture(getTexturePath("menulogo.png").c_str());
if(logotexture)
{
v2s32 logosize(logotexture->getOriginalSize().Width,
@ -1288,7 +1288,7 @@ int main(int argc, char *argv[])
guienv = device->getGUIEnvironment();
gui::IGUISkin* skin = guienv->getSkin();
gui::IGUIFont* font = guienv->getFont(porting::getDataPath("fontlucida.png").c_str());
gui::IGUIFont* font = guienv->getFont(getTexturePath("fontlucida.png").c_str());
if(font)
skin->setFont(font);
else

@ -283,7 +283,7 @@ void RatObject::addToScene(scene::ISceneManager *smgr)
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
buf->getMaterial().setTexture
(0, driver->getTexture(porting::getDataPath("rat.png").c_str()));
(0, driver->getTexture(getTexturePath("rat.png").c_str()));
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
@ -413,7 +413,7 @@ void PlayerObject::addToScene(scene::ISceneManager *smgr)
// Set material
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
//buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
buf->getMaterial().setTexture(0, driver->getTexture(porting::getDataPath("player.png").c_str()));
buf->getMaterial().setTexture(0, driver->getTexture(getTexturePath("player.png").c_str()));
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
//buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
@ -437,7 +437,7 @@ void PlayerObject::addToScene(scene::ISceneManager *smgr)
// Set material
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
//buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
buf->getMaterial().setTexture(0, driver->getTexture(porting::getDataPath("player_back.png").c_str()));
buf->getMaterial().setTexture(0, driver->getTexture(getTexturePath("player_back.png").c_str()));
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;

@ -432,7 +432,7 @@ public:
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
//buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
buf->getMaterial().setTexture
(0, driver->getTexture(porting::getDataPath("sign.png").c_str()));
(0, driver->getTexture(getTexturePath("sign.png").c_str()));
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
@ -456,7 +456,7 @@ public:
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
//buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
buf->getMaterial().setTexture
(0, driver->getTexture(porting::getDataPath("sign_back.png").c_str()));
(0, driver->getTexture(getTexturePath("sign_back.png").c_str()));
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;

@ -27,7 +27,6 @@ const char *mineral_filenames[MINERAL_COUNT] =
"mineral_iron.png"
};
//textureid_t mineral_textures[MINERAL_COUNT] = {0};
std::string mineral_textures[MINERAL_COUNT];
void init_mineral()
@ -40,7 +39,6 @@ void init_mineral()
}
}
//textureid_t mineral_block_texture(u8 mineral)
std::string mineral_block_texture(u8 mineral)
{
if(mineral >= MINERAL_COUNT)

@ -21,7 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define MINERAL_HEADER
#include "inventory.h"
#include "texture.h"
#include "tile.h"
/*
Minerals
@ -39,7 +39,6 @@ void init_mineral();
#define MINERAL_COUNT 3
//textureid_t mineral_block_texture(u8 mineral);
std::string mineral_block_texture(u8 mineral);
inline CraftItem * getDiggedMineralItem(u8 mineral)

@ -261,7 +261,7 @@ RemotePlayer::RemotePlayer(
// Set material
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
//buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
buf->getMaterial().setTexture(0, driver->getTexture(porting::getDataPath("player.png").c_str()));
buf->getMaterial().setTexture(0, driver->getTexture(getTexturePath("player.png").c_str()));
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
//buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
@ -285,7 +285,7 @@ RemotePlayer::RemotePlayer(
// Set material
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
//buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
buf->getMaterial().setTexture(0, driver->getTexture(porting::getDataPath("player_back.png").c_str()));
buf->getMaterial().setTexture(0, driver->getTexture(getTexturePath("player_back.png").c_str()));
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;

@ -1,134 +0,0 @@
/*
Minetest-c55
Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef TEXTURE_HEADER
#define TEXTURE_HEADER
// This file now contains all that was here
#include "tile.h"
// TODO: Remove this
typedef u16 textureid_t;
#if 0
#include "common_irrlicht.h"
//#include "utility.h"
#include "debug.h"
/*
All textures are given a "texture id".
0 = nothing (a NULL pointer texture)
*/
typedef u16 textureid_t;
/*
Every texture in the game can be specified by this.
It exists instead of specification strings because arbitary
texture combinations for map nodes are handled using this,
and strings are too slow for that purpose.
Plain texture pointers are not used because they don't contain
content information by themselves. A texture can be completely
reconstructed by just looking at this, while this also is a
fast unique key to containers.
*/
#define TEXTURE_SPEC_TEXTURE_COUNT 4
struct TextureSpec
{
TextureSpec()
{
clear();
}
TextureSpec(textureid_t id0)
{
clear();
tids[0] = id0;
}
TextureSpec(textureid_t id0, textureid_t id1)
{
clear();
tids[0] = id0;
tids[1] = id1;
}
void clear()
{
for(u32 i=0; i<TEXTURE_SPEC_TEXTURE_COUNT; i++)
{
tids[i] = 0;
}
}
bool empty() const
{
for(u32 i=0; i<TEXTURE_SPEC_TEXTURE_COUNT; i++)
{
if(tids[i] != 0)
return false;
}
return true;
}
void addTid(textureid_t tid)
{
for(u32 i=0; i<TEXTURE_SPEC_TEXTURE_COUNT; i++)
{
if(tids[i] == 0)
{
tids[i] = tid;
return;
}
}
// Too many textures
assert(0);
}
bool operator==(const TextureSpec &other) const
{
for(u32 i=0; i<TEXTURE_SPEC_TEXTURE_COUNT; i++)
{
if(tids[i] != other.tids[i])
return false;
}
return true;
}
bool operator<(const TextureSpec &other) const
{
for(u32 i=0; i<TEXTURE_SPEC_TEXTURE_COUNT; i++)
{
if(tids[i] >= other.tids[i])
return false;
}
return true;
}
// Ids of textures. They are blit on each other.
textureid_t tids[TEXTURE_SPEC_TEXTURE_COUNT];
};
#endif
#endif

@ -1,6 +1,6 @@
/*
Minetest-c55
Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -21,6 +21,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "debug.h"
#include "main.h" // for g_settings
#include "filesys.h"
#include "utility.h"
/*
A cache from texture name to texture path
*/
MutexedMap<std::string, std::string> g_texturename_to_path_cache;
/*
Replaces the filename extension.
@ -30,7 +36,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
-> image = "a/image.jpg"
Returns true on success.
*/
inline bool replace_ext(std::string &path, const char *ext)
static bool replace_ext(std::string &path, const char *ext)
{
if(ext == NULL)
return false;
@ -61,7 +67,7 @@ inline bool replace_ext(std::string &path, const char *ext)
If failed, return "".
*/
inline std::string getImagePath(std::string path)
static std::string getImagePath(std::string path)
{
// A NULL-ended list of possible image extensions
const char *extensions[] = {
@ -86,25 +92,55 @@ inline std::string getImagePath(std::string path)
/*
Gets the path to a texture by first checking if the texture exists
in texture_path and if not, using the data path.
Checks all supported extensions by replacing the original extension.
If not found, returns "".
Utilizes a thread-safe cache.
*/
inline std::string getTexturePath(std::string filename)
std::string getTexturePath(const std::string &filename)
{
std::string fullpath = "";
/*
Check from cache
*/
bool incache = g_texturename_to_path_cache.get(filename, &fullpath);
if(incache)
return fullpath;
/*
Check from texture_path
*/
std::string texture_path = g_settings.get("texture_path");
if(texture_path != "")
{
std::string fullpath = texture_path + '/' + filename;
// Check all filename extensions
fullpath = getImagePath(fullpath);
// If found, return it
if(fullpath != "")
return fullpath;
std::string testpath = texture_path + '/' + filename;
// Check all filename extensions. Returns "" if not found.
fullpath = getImagePath(testpath);
}
std::string fullpath = porting::getDataPath(filename.c_str());
// Check all filename extensions
fullpath = getImagePath(fullpath);
/*
Check from default data directory
*/
if(fullpath == "")
{
std::string testpath = porting::getDataPath(filename.c_str());
// Check all filename extensions. Returns "" if not found.
fullpath = getImagePath(testpath);
}
// Add to cache (also an empty result is cached)
g_texturename_to_path_cache.set(filename, fullpath);
// Finally return it
return fullpath;
}
/*
TextureSource
*/
TextureSource::TextureSource(IrrlichtDevice *device):
m_device(device),
m_main_atlas_image(NULL),

@ -1,6 +1,6 @@
/*
Minetest-c55
Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -25,6 +25,22 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "utility.h"
#include <string>
/*
tile.{h,cpp}: Texture handling stuff.
*/
/*
Gets the path to a texture by first checking if the texture exists
in texture_path and if not, using the data path.
Checks all supported extensions by replacing the original extension.
If not found, returns "".
Utilizes a thread-safe cache.
*/
std::string getTexturePath(const std::string &filename);
/*
Specifies a texture in an atlas.

@ -1766,12 +1766,12 @@ private:
core::list<Value> m_list;
};
#if 0
#if 1
template<typename Key, typename Value>
class MutexedCache
class MutexedMap
{
public:
MutexedCache()
MutexedMap()
{
m_mutex.Init();
assert(m_mutex.IsInitialized());
@ -1794,7 +1794,9 @@ public:
if(n == NULL)
return false;
*result = n->getValue();
if(result != NULL)
*result = n->getValue();
return true;
}