SDL2 游戏开发日记(六) 纹理缓存
功能:图片名字相同的纹理只加载一次,重复使用。
纹理缓存类采用单例模式。支持从文件或者从SDL_RWops中加载纹理
纹理缓存类
#pragma once
#include <SDL.h>
#include <map>
using namespace std;
struct TextureInfo{
int width;
int height;
SDL_Texture *texture;
TextureInfo(int w, int h, SDL_Texture *tex){
texture = tex;
width = w;
height = h;
}
~TextureInfo(){
if (texture != NULL){
SDL_DestroyTexture(texture);
texture = NULL;
}
}
};
typedef map<string, TextureInfo*> TextureList;
#define TexCache TextureCache::Instance()
class TextureCache{
private:
TextureList mTextureList;
TextureCache(){}
TextureCache(const TextureCache &){}
void operator=(const TextureCache &){}
public:
static TextureCache& Instance(){
static TextureCache instance;
return instance;
}
~TextureCache(){
TextureList::iterator iter = mTextureList.begin();
while (iter != mTextureList.end()){
delete (iter->second);
iter++;
}
mTextureList.clear();
}
TextureInfo* GetTexture(string fileName,SDL_RWops * rwOps = NULL);
//
bool AddTexture(string fileName, TextureInfo *textureInfo){
TextureList::iterator iter = mTextureList.find(fileName);
if (iter != mTextureList.end()){
return false;
}
mTextureList.insert(make_pair(fileName, textureInfo));
return true;
}
//从缓存中移除
void RemoveTexture(string fileName){
TextureList::iterator iter = mTextureList.find(fileName);
if (iter != mTextureList.end()){
delete iter->second;
mTextureList.erase(iter);
}
}
};
//TextureCache.cpp
#include "stdafx.h"
#include "TextureCache.h"
#include "SDLGame.h"
TextureInfo* TextureCache::GetTexture(string fileName, SDL_RWops * rwOps){
TextureInfo *info = NULL;
TextureList::iterator iter = mTextureList.find(fileName);
if (iter != mTextureList.end()){
//缓存中有资源
info = iter->second;
}
else{
//缓存中没有资源,重新加载。
SDL_Surface *surface = NULL;
if (rwOps != NULL){
surface = IMG_Load_RW(rwOps, 1);
}
else{
surface = IMG_Load(fileName.c_str());
}
if (surface != NULL){
SDL_Texture *texture = SDL_CreateTextureFromSurface(theGame.getRenderer(), surface);
if (texture != NULL){
info = new TextureInfo(surface->w, surface->h, texture);
//加载成功,放如缓存
mTextureList.insert(make_pair(fileName, info));
}
SDL_FreeSurface(surface);
}
}
return info;
}
更新Renderable类
Renderable释放时不再释放mTexture。由TextrueCache统一释放。
bool Renderable::LoadTexture(string fileName,SDL_RWops *rwOps){
bool bResult = false;
TextureInfo *texInfo = TexCache.GetTexture(fileName, rwOps);
if (texInfo != NULL){
mTexture = texInfo->texture;
if (mTexture != NULL){
if (mRenderRect == NULL)
mRenderRect = new SDL_Rect();
mRenderRect->w = texInfo->width;
mRenderRect->h = texInfo->height;
mTextureWidth = texInfo->width;
mTextureHeight = texInfo->height;
bResult = true;
}
}
return bResult;
}