Use smaller textures when HD textures option is disabled. Generate them if they are not already in the cache directory.

This commit is contained in:
Guillaume P 2014-05-01 19:09:10 +02:00
parent fac9cafa96
commit 7a3ba812d7
4 changed files with 112 additions and 4 deletions

View File

@ -544,12 +544,12 @@ B3D, MS3D or X meshes */
#endif
//! Define _IRR_COMPILE_WITH_BMP_WRITER_ if you want to write .bmp files
//#define _IRR_COMPILE_WITH_BMP_WRITER_
#define _IRR_COMPILE_WITH_BMP_WRITER_
#ifdef NO_IRR_COMPILE_WITH_BMP_WRITER_
#undef _IRR_COMPILE_WITH_BMP_WRITER_
#endif
//! Define _IRR_COMPILE_WITH_JPG_WRITER_ if you want to write .jpg files
//#define _IRR_COMPILE_WITH_JPG_WRITER_
#define _IRR_COMPILE_WITH_JPG_WRITER_
#ifdef NO_IRR_COMPILE_WITH_JPG_WRITER_
#undef _IRR_COMPILE_WITH_JPG_WRITER_
#endif

View File

@ -1239,6 +1239,76 @@ void IrrDriver::unsetTextureErrorMessage()
m_texture_error_message = "";
} // unsetTextureErrorMessage
// ----------------------------------------------------------------------------
/** Retrieve all textures in the specified directory, generate a smaller
* version for each of them and save them in the cache. Smaller textures are
* generated only if they do not already exist or if their original version
* is newer than the cached one.
* \param dir Directory from where textures will be retrieve.
* \return Directory where smaller textures were cached.
*/
std::string IrrDriver::generateSmallerTextures(const std::string& dir)
{
std::set<std::string> files;
file_manager->listFiles(files, dir, true);
std::set<std::string>::const_iterator it;
for (it = files.cbegin(); it != files.cend(); ++it)
{
std::string ext = StringUtils::toLowerCase(StringUtils::getExtension(*it));
if (ext == "png" || ext == "jpg" || ext == "jpeg" || ext == "bmp")
{
getSmallerTexture(*it);
}
} // for it in files
return file_manager->getCachedTexturesDir();
} // generateSmallerTextures
// ----------------------------------------------------------------------------
/** Return the filename for the cached smaller version of the texture. Also,
* generate the smaller version of the texture if it does not already
* exist or if the original version is newer than the cached one.
* \param filename File name of the original texture.
* \return File name of the cached texture.
*
* \todo Regenerate the texture if the original version is newer than the
* cached one.
*/
std::string IrrDriver::getSmallerTexture(const std::string& filename)
{
// Retrieve the filename of the cached texture
std::string file = StringUtils::getBasename(filename);
std::string cached_file =
file_manager->getCachedTexturesDir() + file;
// If the cached texture does not exist, we generate it.
if (!file_manager->fileExists(cached_file))
{
video::IVideoDriver* video_driver = irr_driver->getVideoDriver();
video::IImage* img =
video_driver->createImageFromFile(filename.c_str());
if (img != NULL)
{
core::dimension2d<u32> dim = img->getDimension();
core::dimension2d<u32> new_dim; // Dimension of the cached texture
const int scale_factor = 2;
// Resize the texture only if it can be done properly
if (dim.Width < scale_factor || dim.Height < scale_factor)
new_dim = dim;
else
new_dim = dim / scale_factor;
video::IImage* scaled =
video_driver->createImage(img->getColorFormat(), new_dim);
img->copyToScaling(scaled);
video_driver->writeImageToFile(scaled, cached_file.c_str());
} // if img != NULL
} // if !file_manager->fileExists(cached_file)
return cached_file;
} // getSmallerTexture
// ----------------------------------------------------------------------------
/** Loads a texture from a file and returns the texture object. This is just
* a convenient wrapper which loads the texture from a STK asset directory.

View File

@ -290,6 +290,8 @@ public:
void displayFPS();
bool OnEvent(const irr::SEvent &event);
void setAmbientLight(const video::SColor &light);
std::string generateSmallerTextures(const std::string& dir);
std::string getSmallerTexture(const std::string& texture);
video::ITexture *getTexture(FileManager::AssetType type,
const std::string &filename,
bool is_premul=false,

View File

@ -829,7 +829,31 @@ bool Track::loadMainTrack(const XMLNode &root)
std::string model_name;
track_node->get("model", &model_name);
std::string full_path = m_root+model_name;
scene::IMesh *mesh = irr_driver->getMesh(full_path);
scene::IMesh *mesh;
// If the hd texture option is disabled, we generate smaller textures
// and configure the path to them before loading the mesh.
if (!UserConfigParams::m_high_definition_textures)
{
std::string cached_textures_dir =
irr_driver->generateSmallerTextures(m_root);
irr::io::IAttributes* scene_params =
irr_driver->getSceneManager()->getParameters();
// Before changing the texture path, we retrieve the older one to restore it later
std::string texture_default_path =
scene_params->getAttributeAsString(scene::B3D_TEXTURE_PATH).c_str();
scene_params->setAttribute(scene::B3D_TEXTURE_PATH, cached_textures_dir.c_str());
mesh = irr_driver->getMesh(full_path);
scene_params->setAttribute(scene::B3D_TEXTURE_PATH, texture_default_path.c_str());
}
else // Load mesh with default (hd) textures
{
mesh = irr_driver->getMesh(full_path);
}
if(!mesh)
{
Log::fatal("track",
@ -1471,6 +1495,15 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
file_manager->pushTextureSearchPath(m_root);
file_manager->pushModelSearchPath (m_root);
// If the hd texture option is disabled, we generate smaller textures
// and we also add the cache directory to the texture search path
if (!UserConfigParams::m_high_definition_textures)
{
std::string cached_textures_dir =
irr_driver->generateSmallerTextures(m_root);
file_manager->pushTextureSearchPath(cached_textures_dir);
}
// First read the temporary materials.xml file if it exists
try
{
@ -1663,7 +1696,10 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
World::getWorld()->setClearbackBufferColor(m_sky_color);
}
if (!UserConfigParams::m_high_definition_textures)
{
file_manager->popTextureSearchPath();
}
file_manager->popTextureSearchPath();
file_manager->popModelSearchPath ();