⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 texturemanager.cpp

📁 一个自己写的游戏引擎,用DirectX 写成
💻 CPP
字号:
//--------------------------------------------------
//  Desc: Texture Manager
//  Author: artsylee/2006.10.27
//--------------------------------------------------
#include "../stdafx.h"
#include <stdio.h>
#include <string>
#include "TextureManager.h"
#include "Log.h"

CTextureManager::CTextureManager()
{
	m_CurHandle = BASEHANDLE;
	m_UpdateTime = 0;
}

CTextureManager::~CTextureManager()
{
	DestroyAll();
}

//---------------------------------------------------
// 加载共享纹理
//---------------------------------------------------
TextureHandle CTextureManager::LoadTexture(const char *szFilename, MemoryMode mode /* = MM_AUTO */, int mipLevel /* = 1 */)
{
	if(szFilename == NULL || szFilename[0] == 0)
	{
		return INVALID_HANDLE;
	}

	TextureHandle hTex = QueryHandle(szFilename);
	if(hTex == INVALID_HANDLE)
	{
		CTexture * pTexture = new CTexture;
		if(!pTexture->LoadTexture(szFilename, mipLevel))
		{
			delete (pTexture);
			return INVALID_HANDLE;
		}
		pTexture->SetMemMode(mode);
		hTex = CreateHandle();
		m_TextureMap.insert(std::map<TextureHandle, CTexture*>::value_type(hTex, pTexture));
	}
	return hTex;
}

//---------------------------------------------------
// 加载共享纹理(从AMF文件)
//---------------------------------------------------
TextureHandle CTextureManager::LoadAMFTexture(const char *szFilename, DWORD index /* = 0 */, 
											  MemoryMode mode /* = MM_AUTO */, int mipLevel /* = 1 */)
{
	if(szFilename == NULL || szFilename[0] == 0)
	{
		return INVALID_HANDLE;
	}

	TextureHandle hTex = QueryHandle(szFilename, index);
	if(hTex == INVALID_HANDLE)
	{
		CTexture * pTexture = new CTexture;
		if(!pTexture->LoadAMFTexture(szFilename, index, mipLevel))
		{
			delete (pTexture);
			return INVALID_HANDLE;
		}
		pTexture->SetMemMode(mode);
		hTex = CreateHandle();
		m_TextureMap.insert(std::map<TextureHandle, CTexture*>::value_type(hTex, pTexture));
	}
	return hTex;
}

//---------------------------------------------------
// 加载共享纹理描述
//---------------------------------------------------
TextureHandle CTextureManager::LoadTextureDesc(const char *szFilename, int mipLevel /* = 1 */)
{
	if(szFilename == NULL || szFilename[0] == 0)
	{
		return INVALID_HANDLE;
	}

	TextureHandle hTex = QueryHandle(szFilename);
	if(hTex == INVALID_HANDLE)
	{
		CTexture * pTexture = new CTexture;
		if(!pTexture->LoadTextureDesc(szFilename, mipLevel))
		{
			delete (pTexture);
			return INVALID_HANDLE;
		}
		hTex = CreateHandle();
		m_TextureMap.insert(std::map<TextureHandle, CTexture*>::value_type(hTex, pTexture));
	}
	return hTex;
}

//---------------------------------------------------
// 加载共享纹理描述(AMF)
//---------------------------------------------------
TextureHandle CTextureManager::LoadAMFTextureDesc(const char *szFilename, DWORD index /* = 0 */, int mipLevel /* = 1 */)
{
	if(szFilename == NULL || szFilename[0] == 0)
	{
		return INVALID_HANDLE;
	}

	TextureHandle hTex = QueryHandle(szFilename, index);
	if(hTex == INVALID_HANDLE)
	{
		CTexture * pTexture = new CTexture;
		if(!pTexture->LoadAMFTextureDesc(szFilename, index, mipLevel))
		{
			delete (pTexture);
			return INVALID_HANDLE;
		}
		hTex = CreateHandle();
		m_TextureMap.insert(std::map<TextureHandle, CTexture*>::value_type(hTex, pTexture));
	}
	return hTex;
}

//---------------------------------------------------
// 加载指定句柄的非共享纹理
//---------------------------------------------------
bool CTextureManager::LoadTexture(TextureHandle hTex, const char *szFilename, 
								  MemoryMode mode /* = MM_AUTO */, int mipLevel /* = 1 */)
{
	if(szFilename == NULL || szFilename[0] == 0 || hTex>BASEHANDLE)
	{
		WriteLog(INFO_ERROR, "Invalidate parameter!");
		return false;
	}
	if(m_TextureMap.find(hTex) != m_TextureMap.end())
	{
		WriteLog(INFO_WARNING, "Texture Handle has been used![%s]", szFilename);
		return false;
	}
	CTexture * pTexture = new CTexture;
	if(!pTexture->LoadTexture(szFilename, mipLevel))
	{
		delete (pTexture);
		return false;
	}
	pTexture->SetMemMode(mode);
	m_TextureMap.insert(std::map<TextureHandle, CTexture*>::value_type(hTex, pTexture));
	return true;
}

//---------------------------------------------------
// 加载指定句柄的非共享纹理(AMF文件)
//---------------------------------------------------
bool CTextureManager::LoadAMFTexture(TextureHandle hTex, const char *szFilename, DWORD index /* = 0 */, 
									 MemoryMode mode /* = MM_AUTO */, int mipLevel /* = 1 */)
{
	if(szFilename == NULL || szFilename[0] == 0 || hTex>BASEHANDLE)
	{
		WriteLog(INFO_ERROR, "Invalidate parameter!");
		return false;
	}
	if(m_TextureMap.find(hTex) != m_TextureMap.end())
	{
		CTexture *pTex = GetTexture(hTex);
		if(pTex)
		{
			if(pTex->GetIndex() == index)
			{
				WriteLog(INFO_WARNING, "Texture Handle has been used![%s]", szFilename);
				return false;
			}
			else
			{
				pTex->Release();
				if(pTex->LoadAMFTexture(szFilename, index, mipLevel))
				{
					pTex->SetMemMode(mode);
					return true;
				}
			}
		}
		return false;
	}
	CTexture * pTexture = new CTexture;
	if(!pTexture->LoadAMFTexture(szFilename, index, mipLevel))
	{
		delete (pTexture);
		return false;
	}
	pTexture->SetMemMode(mode);
	m_TextureMap.insert(std::map<TextureHandle, CTexture*>::value_type(hTex, pTexture));
	return true;
}

//---------------------------------------------------
// 加载非共享纹理的描述
//---------------------------------------------------
bool CTextureManager::LoadTextureDesc(TextureHandle hTex, const char *szFilename, int mipLevel /* = 1 */)
{
	if(szFilename == NULL || szFilename[0] == 0 || hTex>BASEHANDLE)
	{
		WriteLog(INFO_ERROR, "Invalidate parameter!");
		return false;
	}
	if(m_TextureMap.find(hTex) != m_TextureMap.end())
	{
		WriteLog(INFO_WARNING, "Texture Handle has been used![%s]", szFilename);
		return false;
	}
	CTexture * pTexture = new CTexture;
	if(!pTexture->LoadTextureDesc(szFilename, mipLevel))
	{
		delete (pTexture);
		return false;
	}
	m_TextureMap.insert(std::map<TextureHandle, CTexture*>::value_type(hTex, pTexture));
	return true;
}

//---------------------------------------------------
// 加载非共享纹理的描述(AMF)
//---------------------------------------------------
bool CTextureManager::LoadAMFTextureDesc(TextureHandle hTex, const char *szFilename, 
										 DWORD index /* = 0 */, int mipLevel /* = 1 */)
{
	if(szFilename == NULL || szFilename[0] == 0 || hTex>BASEHANDLE)
	{
		WriteLog(INFO_ERROR, "Invalidate parameter!");
		return false;
	}
	if(m_TextureMap.find(hTex) != m_TextureMap.end())
	{
		WriteLog(INFO_WARNING, "Texture Handle has been used![%s]", szFilename);
		return false;
	}
	CTexture * pTexture = new CTexture;
	if(!pTexture->LoadAMFTextureDesc(szFilename, index, mipLevel))
	{
		delete (pTexture);
		return false;
	}
	m_TextureMap.insert(std::map<TextureHandle, CTexture*>::value_type(hTex, pTexture));
	return true;
}

//---------------------------------------------------
// 从INI文件批加载非共享纹理
//---------------------------------------------------
bool CTextureManager::BatchLoad(const char *szIniFile)
{
	if(szIniFile == NULL || szIniFile[0] == 0)
	{
		return false;
	}
	FILE * fp = fopen(szIniFile, "r");
	if(!fp)
	{
		WriteLog(INFO_ERROR, "Can't open file[%s]!", szIniFile);
		return false;
	}

	int		nHandle, nInMem, nDesc, nIndex, nMipmap;
	char	*TOKEN = " \t\n\r";
	char	*temp, szTemp[256];
	char    *szFilename;
	std::string strFileName;

	while(!feof(fp))
	{
		fgets(szTemp, 256, fp);
		if(szTemp[0] != '#')
		{
			szTemp[0]	= 0;
			continue;
		}
		temp = szTemp;
		++temp;
		nHandle	= atoi(strtok(temp, TOKEN));
		nInMem = atoi(strtok(0, TOKEN));
		nDesc = atoi(strtok(0, TOKEN));
		nIndex = atoi(strtok(0, TOKEN));
		nMipmap = atoi(strtok(0, TOKEN));
		szFilename	= strtok(0, TOKEN);
		_strlwr(szFilename);
		strFileName = szFilename;

		bool bAMF = false;
		std::string::size_type pos;
		pos = strFileName.find('.');
		if(pos == std::string::npos)
		{
			return false;
		}
		else
		{
			std::string strext = strFileName.substr(pos, strFileName.length()-pos);
			if(strext == ".amf")
			{
				bAMF = true;
			}
		}

		if(nInMem)
		{
			if(bAMF)
			{
				LoadAMFTexture(nHandle, szFilename, nIndex, MM_KEEPINMEMORY, nMipmap);
			}
			else
			{
				LoadTexture(nHandle, szFilename, MM_KEEPINMEMORY, nMipmap);
			}
		}
		else
		{
			if(bAMF)
			{
				if(nDesc)	LoadAMFTextureDesc(nHandle, szFilename, nIndex, nMipmap);
				else		LoadAMFTexture(nHandle, szFilename, nIndex, MM_AUTO, nMipmap);
			}
			else
			{
				if(nDesc)	LoadTextureDesc(nHandle, szFilename, nMipmap);
				else		LoadTexture(nHandle, szFilename, MM_AUTO, nMipmap);
			}
		}
	}
	fclose(fp);

	return true;
}

//---------------------------------------------------
// 插入共享纹理(未加载后的纹理也可以,最好使用MM_KEEPINMEMORY)
//---------------------------------------------------
TextureHandle CTextureManager::InsertTexture(CTexture *pTexture, MemoryMode mode)
{
	if(pTexture == NULL)
	{
		return INVALID_HANDLE;
	}
	pTexture->SetMemMode(mode);
	TextureHandle hTex = CreateHandle();
	m_TextureMap.insert(std::map<TextureHandle, CTexture*>::value_type(hTex, pTexture));
	return hTex;
}

//---------------------------------------------------
// 由内存生成纹理(支持mipmap, 必须为A8R8G8B8的数据, 长宽必须为2次方)
//---------------------------------------------------
TextureHandle CTextureManager::LoadTextureFromMem(int width, int height, const DWORD *pData)
{
	if(pData == NULL)	return INVALID_HANDLE;

	CTexture * pCTexture = new CTexture;
	if(!pCTexture->CreateMipTexture(width, height, D3DFMT_A8R8G8B8))
	{
		delete (pCTexture);
		return INVALID_HANDLE;
	}
		
	IDirect3DTexture9 *pTexture = pCTexture->GetTexture();
	D3DLOCKED_RECT lrDst;
	pTexture->LockRect(0, &lrDst, 0, 0);
	DWORD* pDst = (DWORD*)(lrDst.pBits);
	for(int i=0; i<height; i++)
	{
		for(int j=0; j<width; j++)
		{
			pDst[i*(lrDst.Pitch/4)+j] = pData[i*width+j];
		}
	}
	pTexture->UnlockRect(0);
	D3DXFilterTexture(pTexture, 0, 0, D3DX_DEFAULT);

	DWORD hTex = CreateHandle();
	m_TextureMap.insert(std::map<TextureHandle, CTexture*>::value_type(hTex, pCTexture));
	return hTex;
}

//---------------------------------------------------
// 获取纹理
//---------------------------------------------------
CTexture* CTextureManager::GetTexture(TextureHandle texHandle)
{
	if(texHandle==INVALID_HANDLE)
		return NULL;
	std::map<TextureHandle, CTexture*>::iterator itor = m_TextureMap.find(texHandle);
	if(itor != m_TextureMap.end())
	{
		(*itor).second->SetLastUseTime(::timeGetTime());
		return (*itor).second;
	}
	return NULL;
}

//---------------------------------------------------
// 释放纹理
//---------------------------------------------------
void CTextureManager::ReleaseTexture(TextureHandle texHandle)
{
	if(texHandle==INVALID_HANDLE)
		return;
	std::map<TextureHandle, CTexture*>::iterator itor = m_TextureMap.find(texHandle);
	if(itor != m_TextureMap.end())
	{
		if((*itor).second->Release()<=0)
		{
			delete ((*itor).second);
			m_TextureMap.erase(itor);
			return;
		}
	}
}

//---------------------------------------------------
// 删除纹理
//---------------------------------------------------
void CTextureManager::DestroyTexture(TextureHandle texHandle)
{
	if(texHandle==INVALID_HANDLE)
		return;
	std::map<TextureHandle, CTexture*>::iterator itor = m_TextureMap.find(texHandle);
	if(itor != m_TextureMap.end())
	{
		delete ((*itor).second);
		m_TextureMap.erase(itor);
		return;
	}
}

//---------------------------------------------------
// 删除所有纹理
//---------------------------------------------------
void CTextureManager::DestroyAll(void)
{
	std::map<TextureHandle, CTexture*>::iterator itor = m_TextureMap.begin();
	while(itor!=m_TextureMap.end())
	{
		// 调用析构函数Destroy释放m_pTexture
		delete ((*itor).second);
		itor++;
	}
	m_TextureMap.clear();
}

//---------------------------------------------------
// 自动管理纹理
//---------------------------------------------------
void CTextureManager::Update(void)
{
	DWORD tm = ::timeGetTime();
	if(tm - m_UpdateTime>UPDATETIME)
	{
		std::map<TextureHandle, CTexture*>::iterator itor = m_TextureMap.begin();
		while(itor != m_TextureMap.end())
		{
			if((tm-(*itor).second->GetLastUseTime())>MAXEXIST 
				&& !((*itor).second->IsRelease())
				&& (*itor).second->GetMemMode()==MM_AUTO)
			{
				(*itor).second->AutoRemove();
			}
			itor++;
		}
		m_UpdateTime = tm;
	}
}

//---------------------------------------------------
// 查询共享句柄(5000+)
// 5000以下不参与共享
//---------------------------------------------------
TextureHandle CTextureManager::QueryHandle(const char *szFilename, DWORD index /* = 0 */)
{
	std::map<TextureHandle, CTexture*>::iterator itor = m_TextureMap.begin();
	while(itor!=m_TextureMap.end())
	{
		if((*itor).second->GetName() == szFilename && (*itor).first>BASEHANDLE &&
		   (*itor).second->GetIndex() == index)
		{
			(*itor).second->AddRef();
			return (*itor).first;
		}
		itor++;
	}
	return INVALID_HANDLE;
}

//---------------------------------------------------
// 创建唯一的共享句柄(5000+)
//---------------------------------------------------
TextureHandle CTextureManager::CreateHandle(void)
{
	m_CurHandle++;
	while(m_TextureMap.end() != m_TextureMap.find(m_CurHandle))
	{
		m_CurHandle++;
	}
	if(m_CurHandle==INVALID_HANDLE)
	{
		m_CurHandle = BASEHANDLE;
	}
	return m_CurHandle;
}

//---------------------------------------------------
// 锁定
//---------------------------------------------------
bool CTextureManager::LockTexture(TextureHandle texHandle, D3DLOCKED_RECT *pLockedRect, RECT *pRc)
{
	CTexture *pTex = GetTexture(texHandle);
	if(!pTex)
		return false;
	if(pTex->AutoLoad())
	{
		return SUCCEEDED(pTex->GetTexture()->LockRect(0, pLockedRect, pRc, 0));
	}
	return false;
}

//---------------------------------------------------
// 解锁
//---------------------------------------------------
void CTextureManager::UnLockTexture(TextureHandle texHandle)
{
	CTexture *pTex = GetTexture(texHandle);
	if(!pTex)
		return;
	if(pTex->AutoLoad())
	{
		pTex->GetTexture()->UnlockRect(0);
	}
}

// end of this file 2006.10.27 artsylee

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -