mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-07-04 05:55:47 -07:00
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:
parent
a7d0c194ad
commit
6caf7c7466
3 changed files with 118 additions and 75 deletions
62
source/graphics/TextureEntry.cpp
Executable file
62
source/graphics/TextureEntry.cpp
Executable 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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue