From abaa7af55c2efe9599f2d8968abcf41e927c1f2f Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Wed, 22 Apr 2009 22:53:06 +0100 Subject: [PATCH] Start adding a texture cache --- src/AnimatedImage.cpp | 14 +++++++------- src/Image.cpp | 10 +++++----- src/Image.hpp | 15 ++++++++++++--- src/Mine.cpp | 17 ++++++----------- src/Mine.hpp | 2 +- src/Missile.cpp | 26 +++++++++++--------------- src/Missile.hpp | 3 ++- src/Surface.cpp | 13 ++++--------- src/Surface.hpp | 2 +- src/Texture.cpp | 25 +++++++++++++++++++++++++ src/Texture.hpp | 4 ++++ 11 files changed, 78 insertions(+), 53 deletions(-) diff --git a/src/AnimatedImage.cpp b/src/AnimatedImage.cpp index 6df6c41..750dd48 100644 --- a/src/AnimatedImage.cpp +++ b/src/AnimatedImage.cpp @@ -23,11 +23,11 @@ AnimatedImage::AnimatedImage(const char* file, int frameWidth, int frameHeight, frameCount(frameCount) { if (frameCount == 0) { - if (Texture::GetWidth() % frameWidth != 0) { + if (Image::GetWidth() % frameWidth != 0) { cerr << "Warning: " << file << " with frame width " << frameWidth << " does not have whole number of frames" << endl; } - if (Texture::GetHeight() % frameHeight != 0) { + if (Image::GetHeight() % frameHeight != 0) { cerr << "Warning: " << file << " with frame height " << frameHeight << " does not have whole number of frames" << endl; } @@ -40,12 +40,12 @@ AnimatedImage::AnimatedImage(const char* file, int frameWidth, int frameHeight, void AnimatedImage::Draw(int x, int y, double rotate, double scale, double alpha, double white) const { - int width = Texture::GetWidth(); - int height = Texture::GetHeight(); + int width = Image::GetWidth(); + int height = Image::GetHeight(); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); - glBindTexture(GL_TEXTURE_2D, GetGLTexture()); + glBindTexture(GL_TEXTURE_2D, GetTexture()->GetGLTexture()); glLoadIdentity(); glTranslated((double)(x + frameWidth/2), (double)(y + frameHeight/2), 0.0); glScaled(scale, scale, 0); @@ -68,12 +68,12 @@ void AnimatedImage::Draw(int x, int y, double rotate, double scale, int AnimatedImage::FramesPerRow() const { - return Texture::GetWidth() / frameWidth; + return Image::GetWidth() / frameWidth; } int AnimatedImage::FramesPerCol() const { - return Texture::GetHeight() / frameHeight; + return Image::GetHeight() / frameHeight; } void AnimatedImage::NextFrame() diff --git a/src/Image.cpp b/src/Image.cpp index 4d33164..61aa7ad 100644 --- a/src/Image.cpp +++ b/src/Image.cpp @@ -1,5 +1,5 @@ // Image.cpp -- Wrapper for loading and displaying images -// Copyright (C) 2008 Nick Gasson +// Copyright (C) 2008-2009 Nick Gasson // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -17,11 +17,11 @@ #include "Image.hpp" #include "OpenGL.hpp" +#include "Texture.hpp" -Image::Image(const char* file) - : Texture(file) +Image::Image(const string& fileName) { - + texture = LoadTexture(fileName); } Image::~Image() @@ -37,7 +37,7 @@ void Image::Draw(int x, int y, double rotate, double scale, glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); - glBindTexture(GL_TEXTURE_2D, GetGLTexture()); + glBindTexture(GL_TEXTURE_2D, texture->GetGLTexture()); glLoadIdentity(); glTranslated((double)(x + width/2), (double)(y + height/2), 0.0); glScaled(scale, scale, 0); diff --git a/src/Image.hpp b/src/Image.hpp index 0db9725..c741ad9 100644 --- a/src/Image.hpp +++ b/src/Image.hpp @@ -1,5 +1,5 @@ // Image.hpp -- Wrapper for loading and displaying images -// Copyright (C) 2008 Nick Gasson +// Copyright (C) 2008-2009 Nick Gasson // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -21,13 +21,22 @@ #include "Platform.hpp" #include "Texture.hpp" -class Image : public Texture { +class Image { public: - Image(const char* file); + Image(const string& fileName); virtual ~Image(); void Draw(int x, int y, double rotate=0.0, double scale=1.0, double alpha=1.0, double white=1.0) const; + + inline int GetWidth() const { return texture->GetWidth(); } + inline int GetHeight() const { return texture->GetHeight(); } + +protected: + inline Texture* GetTexture() const { return texture; } + +private: + Texture* texture; }; #endif diff --git a/src/Mine.cpp b/src/Mine.cpp index 66f42ae..b7294c5 100644 --- a/src/Mine.cpp +++ b/src/Mine.cpp @@ -18,18 +18,12 @@ #include "Mine.hpp" #include "OpenGL.hpp" -#include "LoadOnce.hpp" #include "Ship.hpp" -AnimatedImage* Mine::image = NULL; - Mine::Mine(ObjectGrid* o, Viewport* v, int x, int y) - : objgrid(o), viewport(v) -{ - LOAD_ONCE { - image = new AnimatedImage("images/mine.png", 64, 64, MINE_FRAME_COUNT); - } - + : objgrid(o), viewport(v), + image("images/mine.png", 64, 64, MINE_FRAME_COUNT) +{ current = 0; rotcount = MINE_ROTATION_SPEED; displace_x = 0; @@ -137,6 +131,8 @@ void Mine::Move() current = (current + 1) % MINE_FRAME_COUNT; rotcount = MINE_ROTATION_SPEED; } + + image.SetFrame(current); } bool Mine::CheckCollision(Ship& ship) @@ -154,6 +150,5 @@ void Mine::Draw() const - viewport->GetXAdjust(); int draw_y = ypos*OBJ_GRID_SIZE + displace_y - viewport->GetYAdjust() + OBJ_GRID_TOP; - image->SetFrame(current); - image->Draw(draw_x, draw_y); + image.Draw(draw_x, draw_y); } diff --git a/src/Mine.hpp b/src/Mine.hpp index a46705b..baf03ad 100644 --- a/src/Mine.hpp +++ b/src/Mine.hpp @@ -45,7 +45,7 @@ private: int current, rotcount, movetimeout; int displace_x, displace_y, movedelay; - static AnimatedImage* image; + AnimatedImage image; }; #endif diff --git a/src/Missile.cpp b/src/Missile.cpp index 588101e..5345b98 100644 --- a/src/Missile.cpp +++ b/src/Missile.cpp @@ -25,7 +25,6 @@ #include -Image* Missile::image(NULL); SoundEffect* Missile::fireSound(NULL); const double Missile::ACCEL(0.1); @@ -34,14 +33,11 @@ const int Missile::HORIZ_FIRE_RANGE(600); const int Missile::VERT_FIRE_RANGE(50); Missile::Missile(ObjectGrid* o, Viewport* v, Side s) - : viewport(v), objgrid(o), speed(0.0), state(FIXED) + : viewport(v), objgrid(o), speed(0.0), state(FIXED), + image("images/missile.png") { // This constructor builds a missile attached to the side of the screen - LOAD_ONCE { - image = new Image("images/missile.png"); - } - if (NULL == fireSound) fireSound = new SoundEffect(LocateResource("sounds/missile.wav"), 60); // Volume @@ -63,7 +59,7 @@ void Missile::Draw() const if (viewport->PointInScreen(dx, dy, ObjectGrid::OBJ_GRID_SIZE, ObjectGrid::OBJ_GRID_SIZE) && state != DESTROYED) { - image->Draw(dx - viewport->GetXAdjust(), dy - viewport->GetYAdjust(), angle); + image.Draw(dx - viewport->GetXAdjust(), dy - viewport->GetYAdjust(), angle); } exhaust.Draw((double)viewport->GetXAdjust(), @@ -74,7 +70,7 @@ bool Missile::CheckCollison(const Ship& ship) { // A bounding box collision isn't exactly accurate but should // work OK - bool collided = ship.BoxCollision(dx, dy, image->GetWidth(), image->GetHeight()); + bool collided = ship.BoxCollision(dx, dy, image.GetWidth(), image.GetHeight()); if (collided) state = DESTROYED; return collided; @@ -92,8 +88,8 @@ void Missile::Move(const Ship& ship) void Missile::MoveFixed(const Ship& ship) { // Decide whether to fire or not - int missileMidX = dx + image->GetWidth()/2; - int missileMidY = dy + image->GetHeight()/2; + int missileMidX = dx + image.GetWidth()/2; + int missileMidY = dy + image.GetHeight()/2; int xDistance = abs(static_cast(ship.GetX()) - missileMidX); int yDistance = abs(static_cast(ship.GetY()) - missileMidY); @@ -111,17 +107,17 @@ void Missile::MoveFlying() dx += speed * sin(angle * M_PI/180); dy += speed * cos(angle * M_PI/180); - exhaust.xpos = dx + image->GetWidth()/2 - - (image->GetWidth()/2)*sin(angle*(M_PI/180)); - exhaust.ypos = dy + image->GetHeight()/2 - + (image->GetHeight()/2)*cos(angle*(M_PI/180)); + exhaust.xpos = dx + image.GetWidth()/2 + - (image.GetWidth()/2)*sin(angle*(M_PI/180)); + exhaust.ypos = dy + image.GetHeight()/2 + + (image.GetHeight()/2)*cos(angle*(M_PI/180)); exhaust.Process(true); if (speed < MAX_SPEED) speed += ACCEL; if (dx > viewport->GetLevelWidth() || dy > viewport->GetLevelHeight() - || dx + image->GetWidth() < 0 || dy < 0) + || dx + image.GetWidth() < 0 || dy < 0) state = DESTROYED; } diff --git a/src/Missile.hpp b/src/Missile.hpp index aa7d072..2bd02c7 100644 --- a/src/Missile.hpp +++ b/src/Missile.hpp @@ -23,6 +23,7 @@ #include "GraphicsFwd.hpp" #include "Emitter.hpp" #include "SoundEffect.hpp" +#include "Image.hpp" class Missile { public: @@ -49,7 +50,7 @@ private: OrangeSmokeTrail exhaust; static SoundEffect* fireSound; - static Image* image; + Image image; static const double ACCEL; static const double MAX_SPEED; diff --git a/src/Surface.cpp b/src/Surface.cpp index b2afd35..1f8c1ff 100644 --- a/src/Surface.cpp +++ b/src/Surface.cpp @@ -16,7 +16,6 @@ // #include "Surface.hpp" -#include "LoadOnce.hpp" #include "Ship.hpp" const int Surface::VARIANCE(65); // Bumpyness of landscape @@ -24,17 +23,13 @@ const int Surface::MAX_SURFACE_HEIGHT(300); const int Surface::MIN_SURFACE_HEIGHT(10); const int Surface::SURFACE_SIZE(20); -Texture* Surface::surfTexture[Surface::NUM_SURF_TEX]; - Surface::Surface(Viewport* v) : viewport(v), surface(NULL) { - LOAD_ONCE { - surfTexture[0] = new Texture("images/dirt_surface.png"); - surfTexture[1] = new Texture("images/snow_surface.png"); - surfTexture[2] = new Texture("images/red_rock_surface.png"); - surfTexture[3] = new Texture("images/rock_surface.png"); - } + surfTexture[0] = LoadTexture("images/dirt_surface.png"); + surfTexture[1] = LoadTexture("images/snow_surface.png"); + surfTexture[2] = LoadTexture("images/red_rock_surface.png"); + surfTexture[3] = LoadTexture("images/rock_surface.png"); } Surface::~Surface() diff --git a/src/Surface.hpp b/src/Surface.hpp index 1b82ee7..7968455 100644 --- a/src/Surface.hpp +++ b/src/Surface.hpp @@ -38,7 +38,7 @@ public: static const int VARIANCE; private: - static Texture* surfTexture[NUM_SURF_TEX]; + Texture* surfTexture[NUM_SURF_TEX]; int texidx; Viewport* viewport; diff --git a/src/Texture.cpp b/src/Texture.cpp index 1929f90..cde6e60 100644 --- a/src/Texture.cpp +++ b/src/Texture.cpp @@ -20,6 +20,31 @@ #include +#include + +using namespace std; + +// Cache of loaded textures +namespace { + typedef map TextureCache; + TextureCache theCache; +} + +Texture* LoadTexture(const string& fileName) +{ + TextureCache::iterator it = theCache.find(fileName); + if (it != theCache.end()) { + cout << "Reading from cache: " << fileName << endl; + return (*it).second; + } + else { + cout << "Loading from file: " << fileName << endl; + Texture* tex = new Texture(fileName.c_str()); + theCache[fileName] = tex; + return tex; + } +} + Texture::Texture(const char* file) { SDL_Surface* surface = IMG_Load(LocateResource(file)); diff --git a/src/Texture.hpp b/src/Texture.hpp index f6baa91..a16bd42 100644 --- a/src/Texture.hpp +++ b/src/Texture.hpp @@ -29,6 +29,8 @@ public: int GetWidth() const { return width; } int GetHeight() const { return height; } + + friend Texture* loadTexture(const string& fileName); private: GLuint texture; @@ -37,4 +39,6 @@ private: static bool IsPowerOfTwo(int n); }; +Texture* LoadTexture(const string& fileName); + #endif -- 2.39.2