diff --git a/Bin/VC10/VC10.vcxproj b/Bin/VC10/VC10.vcxproj index a236387..d949fcd 100644 --- a/Bin/VC10/VC10.vcxproj +++ b/Bin/VC10/VC10.vcxproj @@ -98,6 +98,7 @@ + diff --git a/Bin/VC10/VC10.vcxproj.filters b/Bin/VC10/VC10.vcxproj.filters index 639e230..c397de8 100644 --- a/Bin/VC10/VC10.vcxproj.filters +++ b/Bin/VC10/VC10.vcxproj.filters @@ -126,6 +126,9 @@ TMXParser + + System + diff --git a/src/Actor/Player.cpp b/src/Actor/Player.cpp index 5b95168..b0918d3 100644 --- a/src/Actor/Player.cpp +++ b/src/Actor/Player.cpp @@ -6,17 +6,12 @@ Player::Player(void) { } Player::~Player(void) { - delete _player->GetTexture(); delete _player; } void Player::Prepare(void) { _player = new Sprite(); - _playerTexture = new Texture(); - _playerTexture->Load("../Data/Img/Player.png"); - _player->SetTexture(_playerTexture); - _player->SetPosition(Vec2(800/2, 600/2)); - _player->SetScale(Vec2(4.5f, 4.5f)); + _player->LoadSprite("../Data/Img/Player.png"); } void Player::Render(void) { diff --git a/src/Actor/Player.h b/src/Actor/Player.h index 382f0aa..5ee44a2 100644 --- a/src/Actor/Player.h +++ b/src/Actor/Player.h @@ -1,4 +1,4 @@ -#include "../Texture/Texture.h" +#pragma once #include "../Sprite/Sprite.h" #include "../Global/Globals.h" #include "../System/Debug.h" @@ -19,6 +19,5 @@ public: private: float PLAYER_SPEED; Sprite* _player; - Texture* _playerTexture; float _rotationAngle; }; diff --git a/src/Sprite/Sprite.cpp b/src/Sprite/Sprite.cpp index f0e4f88..35a711a 100644 --- a/src/Sprite/Sprite.cpp +++ b/src/Sprite/Sprite.cpp @@ -10,6 +10,10 @@ Sprite::Sprite() { } Sprite::~Sprite() { + if(texture) { + textureManager.Destroy(texture); + texture = NULL; + } } void Sprite::Update(float dt) { @@ -20,10 +24,10 @@ void Sprite::Draw() const { } void Sprite::DrawRegion(const Rect& src) const { - const float uvX = src.x / (float)texture->GetWidth(); - const float uvY = src.y / (float)texture->GetHeight(); - const float uvW = src.w / (float)texture->GetWidth(); - const float uvH = src.h / (float)texture->GetHeight(); + const float uvX = src.x / (float)texture->GetWidth(); + const float uvY = src.y / (float)texture->GetHeight(); + const float uvW = src.w / (float)texture->GetWidth(); + const float uvH = src.h / (float)texture->GetHeight(); // Awesome artwork to describe this: // 0---------1 @@ -74,6 +78,20 @@ void Sprite::DrawRegion(const Rect& src) const { glPopMatrix(); } +bool Sprite::LoadSprite(const std::string& filename) { + Texture* newTexture = textureManager.Load(filename); + if(newTexture) { + if(texture) { + textureManager.Destroy(texture); + } + size.x = (float)newTexture->GetWidth(); + size.y = (float)newTexture->GetHeight(); + texture = newTexture; + return true; + } + return false; +} + void Sprite::SetTexture(Texture* texture) { this->texture = texture; this->size = Vec2((float)texture->GetWidth(), (float)texture->GetHeight()); diff --git a/src/Sprite/Sprite.h b/src/Sprite/Sprite.h index 6e87cd3..174a947 100644 --- a/src/Sprite/Sprite.h +++ b/src/Sprite/Sprite.h @@ -14,10 +14,14 @@ public: virtual void Draw() const; virtual void DrawRegion(const Rect& src) const; + virtual bool LoadSprite(const std::string& filename); + const Vec2& GetPosition() const { return position; } float GetX(void) { return position.x; } float GetY(void) { return position.y; } const Vec2& GetSize() const { return size; } + float GetWidth() const { return size.x; } + float GetHeight() const { return size.y; } const Vec2& GetScale() const { return scale; } float GetRotation() const { return rotation; } Texture* GetTexture() { return texture; } diff --git a/src/System/ResourceManager.h b/src/System/ResourceManager.h new file mode 100644 index 0000000..decf664 --- /dev/null +++ b/src/System/ResourceManager.h @@ -0,0 +1,96 @@ +#pragma once + +#include +#include + +class Resource { +public: + virtual bool Load(const std::string& filename) = 0; + +protected: + Resource() : refs(0) {} + int refs; +}; + +template +class ResourceManager +{ +public: + ResourceManager() { } + + typedef std::map ResourceMap; + + T* Load(const std::string& name) { + ResourceMap::iterator i = m_resources.find(name); + if(i == m_resources.end()) { + T* resource = new T(); + + if(!resource->Load(name)) { + delete resource; + return NULL; + } + + resource->refs = 1; + + m_resources.insert(std::pair(name, resource)); + + return resource; + } + + i->second->refs++; + + return i->second; + } + + T* Find(const std::string& name) { + ResourceMap::iterator i = m_resources.find(name); + if(i != m_resources.end()) { + return i->second; + } + return NULL; + } + + void Add(const std::string& name, T* resource) { + ResourceMap::iterator i = m_resources.find(name); + if(i == m_resources.end()) { + resource->refs++; + m_resources.insert(std::pair(name, resource)); + } else { + i->second->refs++; + } + } + + void Destroy(const std::string& name) { + if(name.empty()) + return; + + ResourceMap::iterator i = m_resources.find(name); + if(i != m_resources.end()) { + T* resource = i->second; + + resource->refs--; + + if(resource->m_refs < 1) { + delete resource; + m_resources.erase(i); + } + } + } + + void Destroy(T* resource) { + ResourceMap::iterator i; + for(i = m_resources.begin(); i != m_resources.end(); ++i) { + if(i->second == resource){ + resource->refs--; + if(resource->refs < 1) { + m_resources.erase(i); + delete resource; + } + return; + } + } + } + +private: + ResourceMap m_resources; +}; diff --git a/src/Texture/Texture.cpp b/src/Texture/Texture.cpp index 3e9a871..513db79 100644 --- a/src/Texture/Texture.cpp +++ b/src/Texture/Texture.cpp @@ -3,6 +3,8 @@ #include using namespace std; +ResourceManager textureManager; + static GLuint boundTexture = 0; static bool IsBGR(SDL_Surface* surf) { @@ -239,8 +241,8 @@ Texture::~Texture() { } } -bool Texture::Load(const char* filename) { - if(BuildTexture(filename, &texID, GL_CLAMP, false)) { +bool Texture::Load(const std::string& filename) { + if(BuildTexture(filename.c_str(), &texID, GL_CLAMP, false)) { glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height); return true; diff --git a/src/Texture/Texture.h b/src/Texture/Texture.h index 0d33df4..9b22a6b 100644 --- a/src/Texture/Texture.h +++ b/src/Texture/Texture.h @@ -25,12 +25,16 @@ int LoadTGAFile(const char* filename, TGAFILE* tgaFile); int WriteTGAFile(const char* filename, short int width, short int height, unsigned char* textureData); void BindTexture(GLuint texID); -class Texture { +#include "../System/ResourceManager.h" + +class Texture : public Resource { + template friend class ResourceManager; + public: Texture(); ~Texture(); - bool Load(const char* filename); + bool Load(const std::string& filename); GLuint GetTexID() const { return texID; } int GetWidth() const { return width; } @@ -41,3 +45,5 @@ private: int width; int height; }; + +extern ResourceManager textureManager;