我写过一个2d游戏。写2d游戏时大部分的精力花在gui的撰写和写脚本的接口上了。之前写gui的时候,new一个button的时候就load一个texture,如果频繁切换gui,texture就会频繁地load和release。
所以把纹理的加载管理与gui写在一块是很浪费效率的。最好的方法是纹理的加载与释放与gui无关。
感谢饭中淹教会了我这个思路:给纹理设置一个重要度,初始值1,当有gui使用到这个纹理的时候,每帧都增加这个纹理的重要度,当没有任何程序使用这个纹理的时候,每帧减少纹理的重要度,当重要度减少到0以下,就释放这个纹理。
这样做的好处是,经常调用的纹理在内存中的时间比较长,这样程序调用纹理时很容易命中。而且可以让多个gui调用同一个纹理。
以下是代码。我用hge的,所以调用纹理的函数是hge的函数。(*^__^*) 嘻嘻……
存储纹理用的是数组,但是用哈希表会更好。(*^__^*) 嘻嘻……
使用方法:
先调用Init()初始化
然后要用纹理的时候:
HTEXTURE = kResourceSystem::Instance().GetTexture("aaa.bmp");
释放纹理的时候:
kResourceSystem::Instance().ThrowTexture("aaa.bmp");
每帧便忘了在主循环函数里调用
kResourceSystem::Instance().Upadate();
- #pragma once
- #include "hge.h"
- #include "Singleton.h"
- #define MAXRESOURCENUM 200
- struct sResourceList
- {
- char* FileName;
- HTEXTURE tex;
- int Importance;//重要度
- int iRendered;//记录有几处引用
- sResourceList(){
- FileName = NULL;
- tex = NULL;
- Importance = 0;
- iRendered = 0;
- }
- };
- class kResourceSystem:public Pattern::Singleton<kResourceSystem>
- {
- public:
- kResourceSystem(){;}
- ~kResourceSystem();
- void Init(HGE* Hge){hge = Hge;}
- HTEXTURE GetTexture(const char* FileName);//从列表中返回一个纹理
- void ThrowTexture(const char* FileName);//通知有一个纹理在某处不用了
- void ThrowTexture(HTEXTURE tex);
- void Update();//逻辑更新
- protected:
- private:
- sResourceList m_list[MAXRESOURCENUM];
- HTEXTURE CreateTexture(const char* FileName);//新建一个纹理
- void ReleaseTexture(int index);//释放纹理
- int GetIndex(const char* FileName);//返回纹理在数组中的位置
- HGE* hge;
- };
- #include "ResourceSystem.h"
- #include "iostream"
- using namespace std;
- int kResourceSystem::GetIndex(const char *FileName)
- {
- for (int i = 0;i < MAXRESOURCENUM;i++)
- {
- if (m_list[i].FileName != NULL)
- {
- //cout << "第" << i << "个元素是:" << m_list[i].FileName << endl;
- if (strcmp(m_list[i].FileName,FileName) == 0)
- {
- //cout << FileName << "与第" << i << "个元素匹配!" << endl;
- return i;
- }
- }
- }
- return -1;
- }
- HTEXTURE kResourceSystem::GetTexture(const char *FileName)
- {
- //cout << "GetTexture:" << FileName << endl;
- int nTemp;
- nTemp = GetIndex(FileName);
- if (nTemp == -1)
- {
- return CreateTexture(FileName);
- }
- else
- {
- m_list[nTemp].iRendered++;
- return m_list[nTemp].tex;
- }
- return NULL;
- }
- void kResourceSystem::ThrowTexture(const char* FileName)
- {
- //printf("ThrowTexture,调用函数%s文件的%u行/n",__FILE__,__LINE__);
- int nTemp;
- nTemp = GetIndex(FileName);
- if (nTemp == -1)
- {
- return;
- }
- else{
- m_list[nTemp].iRendered--;
- if (m_list[nTemp].iRendered < 0)
- {
- m_list[nTemp].iRendered = 0;
- }
- }
- }
- void kResourceSystem::ReleaseTexture(int index)
- {
- //printf("ReleaseTexture,调用函数%s文件的%u行/n",__FILE__,__LINE__);
- printf("ReleaseTexture:释放文件名:%s/n",m_list[index].FileName);
- if (m_list[index].tex)
- {
- hge->Texture_Free(m_list[index].tex);
- m_list[index].tex = NULL;
- }
- delete [] m_list[index].FileName;
- m_list[index].FileName = NULL;
- m_list[index].iRendered = 0;
- m_list[index].Importance = 0;
- }
- HTEXTURE kResourceSystem::CreateTexture(const char* FileName)
- {
- //printf("CreateTexture,调用函数%s文件的%u行",__FILE__,__LINE__);
- for (int i = 0;i < MAXRESOURCENUM;i++)
- {
- if (m_list[i].FileName == NULL)
- {
- m_list[i].FileName = new char[256];
- strcpy(m_list[i].FileName,FileName);
- m_list[i].tex = hge->Texture_Load(FileName);
- m_list[i].Importance = 1;
- m_list[i].iRendered = 1;
- return m_list[i].tex;
- break;
- }
- }
- return NULL;
- }
- void kResourceSystem::Update()
- {
- for (int i = 0;i < MAXRESOURCENUM;i++)
- {
- if (m_list[i].iRendered <= 0 && m_list[i].FileName !=NULL)
- {
- m_list[i].Importance--;
- if (m_list[i].Importance <= 0)
- {
- ReleaseTexture(i);
- }
- }
- else if(m_list[i].iRendered > 0 && m_list[i].FileName != NULL)
- {
- m_list[i].Importance++;
- }
- }
- }
- void kResourceSystem::ThrowTexture(HTEXTURE tex)
- {
- //printf("ThrowTexture,调用函数%s文件的%u行/n",__FILE__,__LINE__);
- for (int i = 0;i < MAXRESOURCENUM;i++)
- {
- if (m_list[i].tex == tex)
- {
- m_list[i].iRendered--;
- //cout << "第" << i << "个元素,iRendered = " << m_list[i].iRendered << endl;
- return;
- break;
- }
- }
- }
- kResourceSystem::~kResourceSystem()
- {
- /*for (int i = 0;i < MAXRESOURCENUM;i++)
- {
- if (m_list[i].FileName != NULL)
- {
- ReleaseTexture(i);
- }
- }*/
- }