#include "precompiled.h" #include #include #include "TextureManager.h" #include "TextureEntry.h" #include "TerrainProperties.h" #include "lib/res/res.h" #include "lib/res/graphics/ogl_tex.h" #include "lib/ogl.h" #include "lib/timer.h" #include "ps/CLogger.h" #include "ps/VFSUtil.h" #define LOG_CATEGORY "graphics" using namespace std; // filter for vfs_next_dirent static const char* SupportedTextureFormats[] = { "*.png", "*.dds", "*.tga", "*.bmp" }; CTextureManager::CTextureManager(): m_LastGroupIndex(0) {} CTextureManager::~CTextureManager() { for (size_t i=0;isecond; ++it; } } CTextureEntry* CTextureManager::FindTexture(CStr tag) { // Strip extension off of tag long pos=tag.ReverseFind("."); if (pos != -1) { tag = tag.GetSubstring(0, pos); } for (uint i=0;iGetTag() == tag) return m_TextureEntries[i]; } LOG(WARNING, LOG_CATEGORY, "TextureManager: Couldn't find terrain %s\n", tag.c_str()); return 0; } CTextureEntry* CTextureManager::FindTexture(Handle handle) { return CTextureEntry::GetByHandle(handle); } CTerrainProperties *CTextureManager::GetPropertiesFromFile(CTerrainProperties *props, const char* path) { return CTerrainProperties::FromXML(props, path); } CTextureEntry *CTextureManager::AddTexture(CTerrainProperties *props, CStr path) { CTextureEntry *entry = new CTextureEntry(props, path); m_TextureEntries.push_back(entry); return entry; } void CTextureManager::DeleteTexture(CTextureEntry* entry) { typedef std::vector::iterator Iter; Iter i=std::find(m_TextureEntries.begin(),m_TextureEntries.end(),entry); if (i!=m_TextureEntries.end()) { m_TextureEntries.erase(i); } delete entry; } // FIXME This could be effectivized by surveying the xml files in the directory // instead of trial-and-error checking for existence of the xml file through // the VFS. // jw: indeed this is inefficient and RecurseDirectory should be implemented // via VFSUtil::EnumFiles, but it works fine and "only" takes 25ms for // typical maps. therefore, we'll leave it for now. void CTextureManager::LoadTextures(CTerrainProperties *props, const char* dir, const char* fileext_filter) { VFSUtil::FileList files; if(!VFSUtil::FindFiles(dir, fileext_filter, files)) // FindFiles has already logged the failure return; for(VFSUtil::FileList::iterator it = files.begin(); it != files.end(); ++it) { const char* texture_name = it->c_str(); // build name of associated xml file (i.e. replace extension) char xml_name[PATH_MAX+5]; // add room for .XML strcpy_s(xml_name, PATH_MAX, texture_name); char* ext = strrchr(xml_name, '.'); if(ext) strcpy(ext, ".xml"); // safe CTerrainProperties *myprops = NULL; // Has XML file -> attempt to load properties if (vfs_exists(xml_name)) { myprops=GetPropertiesFromFile(props, xml_name); if (myprops) LOG(NORMAL, LOG_CATEGORY, "CTextureManager: Successfully loaded override xml %s for texture %s\n", xml_name, texture_name); } // Error or non-existant xml file -> use parent props if (!myprops) myprops = props; AddTexture(myprops, texture_name); } } void CTextureManager::RecurseDirectory(CTerrainProperties *parentProps, const char* cur_dir_path) { //LOG(NORMAL, LOG_CATEGORY, "CTextureManager::RecurseDirectory(%s)", path.c_str()); CTerrainProperties *props=NULL; // Load terrains.xml first, if it exists char fn[PATH_MAX]; snprintf(fn, PATH_MAX, "%s/%s", cur_dir_path, "terrains.xml"); if (vfs_exists(fn)) props=GetPropertiesFromFile(parentProps, fn); // No terrains.xml, or read failures -> use parent props (i.e. if (!props) { LOG(NORMAL, LOG_CATEGORY, "CTextureManager::RecurseDirectory(%s): no terrains.xml (or errors while loading) - using parent properties", cur_dir_path); props = parentProps; } // Recurse once for each subdirectory VFSUtil::FileList subdirs; VFSUtil::FindFiles(cur_dir_path, "/", subdirs); for (uint i=0;isecond; else return m_TerrainGroups[name] = new CTerrainGroup(name, ++m_LastGroupIndex); } /* There was a GetRandomTexture in MainFrm.cpp (sced) previously that gave compile errors... So I thought "better fix it up and put it in CTextureManager instead".. well, it is never used except for one *comment* in MainFrm.cpp - d'oh */ CTextureEntry* CTextureManager::GetRandomTexture() { if (!m_TextureEntries.size()) return NULL; u32 type=rand()%(u32)m_TextureEntries.size(); return m_TextureEntries[type]; } void CTerrainGroup::AddTerrain(CTextureEntry *pTerrain) { m_Terrains.push_back(pTerrain); } void CTerrainGroup::RemoveTerrain(CTextureEntry *pTerrain) { vector::iterator it; it=find(m_Terrains.begin(), m_Terrains.end(), pTerrain); if (it != m_Terrains.end()) m_Terrains.erase(it); }