Support for loading texture data on data, rather than loading all known textures on startup.

This was SVN commit r412.
This commit is contained in:
notpete 2004-06-07 19:56:26 +00:00
parent a7d0c194ad
commit 6caf7c7466
3 changed files with 118 additions and 75 deletions

View file

@ -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;
}

View file

@ -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;
};

View file

@ -41,7 +41,7 @@ CTextureEntry* CTextureManager::FindTexture(const char* filename)
for (uint k=0;k<m_TerrainTextures.size();k++) {
STextureType& ttype=m_TerrainTextures[k];
for (uint i=0;i<ttype.m_Textures.size();i++) {
if (strcmp((const char*) ttype.m_Textures[i]->m_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;k<m_TerrainTextures.size();k++) {
STextureType& ttype=m_TerrainTextures[k];
for (uint i=0;i<ttype.m_Textures.size();i++) {
if (handle==ttype.m_Textures[i]->m_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)type<m_TerrainTextures.size());
CStr pathname("art/textures/terrain/types/");
pathname+=m_TerrainTextures[type].m_Name;
pathname+='/';
pathname+=filename;
Handle h=tex_load((const char*) pathname);
if (h <= 0) {
LOG(ERROR, "CTextureManager::AddTexture(): texture %s failed loading\n", pathname.c_str());
return 0;
} else {
int tw;
int th;
tex_info(h, &tw, &th, NULL, NULL, NULL);
tw &= (tw-1);
th &= (th-1);
if (tw || th) {
return 0;
}
}
// create new texture entry
CTextureEntry* texentry=new CTextureEntry;
texentry->m_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<CTextureEntry*>& textures=m_TerrainTextures[entry->m_Type].m_Textures;
std::vector<CTextureEntry*>& textures=m_TerrainTextures[entry->GetType()].m_Textures;
typedef std::vector<CTextureEntry*>::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);
}