diff --git a/source/graphics/TextureEntry.cpp b/source/graphics/TextureEntry.cpp new file mode 100755 index 0000000000..574b644535 --- /dev/null +++ b/source/graphics/TextureEntry.cpp @@ -0,0 +1,62 @@ +#include "ogl.h" +#include "res/tex.h" +#include "TextureEntry.h" +#include "TextureManager.h" +#include "Texture.h" +#include "CLogger.h" +#include "Renderer.h" + + +///////////////////////////////////////////////////////////////////////////////////// +// CTextureEntry constructor +CTextureEntry::CTextureEntry(const char* name,int type) + : m_Name(name), m_Bitmap(0), m_Handle(0xffffffff), m_BaseColor(0), m_Type(type), m_BaseColorValid(false) +{ +} + +///////////////////////////////////////////////////////////////////////////////////// +// LoadTexture: actually load the texture resource from file +void CTextureEntry::LoadTexture() +{ + CStr pathname("art/textures/terrain/types/"); + pathname+=g_TexMan.m_TerrainTextures[m_Type].m_Name; + pathname+='/'; + pathname+=m_Name; + + CTexture texture; + texture.SetName(pathname); + if (g_Renderer.LoadTexture(&texture,GL_REPEAT)) { + m_Handle=texture.GetHandle(); + } else { + m_Handle=0; + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////// +// BuildBaseColor: calculate the root color of the texture, used for coloring minimap, and store +// in m_BaseColor member +void CTextureEntry::BuildBaseColor() +{ + Handle handle=GetHandle(); + g_Renderer.BindTexture(0,tex_id(handle)); + + // get root color for coloring minimap by querying root level of the texture + // (this should decompress any compressed textures for us), + // then scaling it down to a 1x1 size + // - an alternative approach of just grabbing the top level of the mipmap tree fails + // (or gives an incorrect colour) in some cases: + // - suspect bug on Radeon cards when SGIS_generate_mipmap is used + // - any textures without mipmaps + // we'll just take the basic approach here: + int width,height; + glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_WIDTH,&width); + glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_HEIGHT,&height); + + unsigned char* buf=new unsigned char[width*height*4]; + glGetTexImage(GL_TEXTURE_2D,0,GL_BGRA_EXT,GL_UNSIGNED_BYTE,buf); + gluScaleImage(GL_BGRA_EXT,width,height,GL_UNSIGNED_BYTE,buf, + 1,1,GL_UNSIGNED_BYTE,&m_BaseColor); + delete[] buf; + + m_BaseColorValid=true; +} \ No newline at end of file diff --git a/source/graphics/TextureEntry.h b/source/graphics/TextureEntry.h index e827eecdc6..9a7466315c 100755 --- a/source/graphics/TextureEntry.h +++ b/source/graphics/TextureEntry.h @@ -3,20 +3,52 @@ #include "res/res.h" #include "CStr.h" - + +////////////////////////////////////////////////////////////////////////////////////////////////////////// +// CTextureEntry: class wrapping a terrain texture object; contains various other required +// elements - color of minimap, terrain "group" it belongs to, etc class CTextureEntry { public: - CTextureEntry() : m_Bitmap(0), m_Handle(0), m_BaseColor(0), m_Type(0) {} - - // filename - CStr m_Name; - // UI bitmap object - void* m_Bitmap; + CTextureEntry(const char* name,int type); + + // accessor - return texture name + const char* GetName() const { return (const char*) m_Name; } + + // accessor - get UI bitmap object + void* GetBitmap() const { return m_Bitmap; } + // accessor - set UI bitmap object + void SetBitmap(void* bmp) { m_Bitmap=bmp; } + + // accessor - get texture handle + Handle GetHandle() { + if (m_Handle==0xffffffff) LoadTexture(); + return m_Handle; + } + // accessor - get mipmap color + u32 GetBaseColor() { + if (!m_BaseColorValid) BuildBaseColor(); + return m_BaseColor; + } + // accessor - return texture type + int GetType() const { return m_Type; } + +private: + // load texture from file + void LoadTexture(); + // calculate the root color of the texture, used for coloring minimap + void BuildBaseColor(); + + // filename + CStr m_Name; + // UI bitmap object + void* m_Bitmap; // handle to GL texture data Handle m_Handle; // BGRA color of topmost mipmap level, for coloring minimap - unsigned int m_BaseColor; + u32 m_BaseColor; + // above color valid? + bool m_BaseColorValid; // "type" of texture - index into TextureManager texturetypes array int m_Type; }; diff --git a/source/graphics/TextureManager.cpp b/source/graphics/TextureManager.cpp index 017e8e71de..570fc77dd1 100755 --- a/source/graphics/TextureManager.cpp +++ b/source/graphics/TextureManager.cpp @@ -41,7 +41,7 @@ CTextureEntry* CTextureManager::FindTexture(const char* filename) for (uint k=0;km_Name,filename)==0) { + if (strcmp((const char*) ttype.m_Textures[i]->GetName(),filename)==0) { return ttype.m_Textures[i]; } } @@ -55,7 +55,7 @@ CTextureEntry* CTextureManager::FindTexture(Handle handle) for (uint k=0;km_Handle) { + if (handle==ttype.m_Textures[i]->GetHandle()) { return ttype.m_Textures[i]; } } @@ -67,72 +67,21 @@ CTextureEntry* CTextureManager::FindTexture(Handle handle) CTextureEntry* CTextureManager::AddTexture(const char* filename,int type) { assert((uint)typem_Name=filename; - texentry->m_Handle=h; - texentry->m_Type=type; - - // upload texture for future GL use - tex_upload(h,GL_LINEAR_MIPMAP_LINEAR); - - // setup texture to repeat - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - - // get root color for coloring minimap by querying root level of the texture - // (this should decompress any compressed textures for us), - // then scaling it down to a 1x1 size - // - an alternative approach of just grabbing the top level of the mipmap tree fails - // (or gives an incorrect colour) in some cases: - // - suspect bug on Radeon cards when SGIS_generate_mipmap is used - // - any textures without mipmaps - // we'll just take the basic approach here: - int width,height; - glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_WIDTH,&width); - glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_HEIGHT,&height); - - unsigned char* buf=new unsigned char[width*height*4]; - glGetTexImage(GL_TEXTURE_2D,0,GL_BGRA_EXT,GL_UNSIGNED_BYTE,buf); - gluScaleImage(GL_BGRA_EXT,width,height,GL_UNSIGNED_BYTE,buf, - 1,1,GL_UNSIGNED_BYTE,&texentry->m_BaseColor); - delete[] buf; - - // add entry to list .. - m_TerrainTextures[type].m_Textures.push_back(texentry); - - // .. and return it - return texentry; + // create new texture entry + CTextureEntry* texentry=new CTextureEntry(filename,type); + + // add entry to list .. + m_TerrainTextures[type].m_Textures.push_back(texentry); + + return texentry; } void CTextureManager::DeleteTexture(CTextureEntry* entry) { // find entry in list - std::vector& textures=m_TerrainTextures[entry->m_Type].m_Textures; - + std::vector& textures=m_TerrainTextures[entry->GetType()].m_Textures; + typedef std::vector::iterator Iter; Iter i=std::find(textures.begin(),textures.end(),entry); if (i!=textures.end()) { @@ -146,10 +95,10 @@ void CTextureManager::LoadTerrainTextures(int terraintype,const char* fileext) CStr pathname("art/textures/terrain/types/"); pathname+=m_TerrainTextures[terraintype].m_Name; pathname+="/"; - + Handle dir=vfs_open_dir(pathname.c_str()); vfsDirEnt dent; - + if (dir > 0) { while (vfs_next_dirent(dir, &dent, fileext) == 0) @@ -157,7 +106,7 @@ void CTextureManager::LoadTerrainTextures(int terraintype,const char* fileext) LOG(NORMAL, "CTextureManager::LoadTerrainTextures(): texture %s added to type %s\n", dent.name, m_TerrainTextures[terraintype].m_Name.c_str()); AddTexture(dent.name, terraintype); } - + vfs_close_dir(dir); } } @@ -166,14 +115,14 @@ void CTextureManager::BuildTerrainTypes() { Handle dir=vfs_open_dir("art/textures/terrain/types/"); vfsDirEnt dent; - + if (dir > 0) { while (vfs_next_dirent(dir, &dent, "/") == 0) { AddTextureType(dent.name); } - + vfs_close_dir(dir); }