From f0d580d8739053a43f8ee07e3d5337f3049f4bd8 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Tue, 24 Mar 2015 00:06:51 +0100 Subject: [PATCH] Refactor texture loading code; should fix a crash that started appearing recently. --- Aquaria/AquariaMenuItem.cpp | 7 +- Aquaria/AquariaMenuItem.h | 2 +- Aquaria/Avatar.cpp | 3 +- Aquaria/DSQ.cpp | 20 ++-- Aquaria/DSQ.h | 2 +- Aquaria/MiniMapRender.cpp | 16 +-- Aquaria/ModSelector.cpp | 3 +- BBGE/Base.h | 1 + BBGE/BitmapFont.cpp | 7 +- BBGE/BitmapFont.h | 2 +- BBGE/Core.cpp | 204 +++++++++++------------------------- BBGE/Core.h | 25 ++--- BBGE/Quad.cpp | 5 + BBGE/Refcounted.h | 95 +++++++++++++++++ BBGE/RenderObject.cpp | 27 ++--- BBGE/RenderObject.h | 10 +- BBGE/Resource.cpp | 28 ----- BBGE/Resource.h | 57 ---------- BBGE/Texture.cpp | 77 ++++---------- BBGE/Texture.h | 38 ++++--- CMakeLists.txt | 1 - win/vc90/BBGE.vcproj | 12 +-- 22 files changed, 255 insertions(+), 387 deletions(-) create mode 100644 BBGE/Refcounted.h delete mode 100644 BBGE/Resource.cpp delete mode 100644 BBGE/Resource.h diff --git a/Aquaria/AquariaMenuItem.cpp b/Aquaria/AquariaMenuItem.cpp index c288058..9f1383b 100644 --- a/Aquaria/AquariaMenuItem.cpp +++ b/Aquaria/AquariaMenuItem.cpp @@ -847,16 +847,17 @@ void AquariaMenuItem::useSound(const std::string &tex) useSfx = tex; } -void AquariaMenuItem::useQuad(const std::string &tex) +bool AquariaMenuItem::useQuad(const std::string &tex) { if (quad) { debugLog("trying to call useQuad twice on the same object"); - return; + return true; } quad = new Quad; - quad->setTexture(tex); + bool good = quad->setTexture(tex); addChild(quad, PM_POINTER); + return good; } void AquariaMenuItem::useGlow(const std::string &tex, int w, int h) diff --git a/Aquaria/AquariaMenuItem.h b/Aquaria/AquariaMenuItem.h index 95dc797..842ca39 100644 --- a/Aquaria/AquariaMenuItem.h +++ b/Aquaria/AquariaMenuItem.h @@ -81,7 +81,7 @@ public: XMLElement *ability, *xmlItem; int choice; Quad *glow, *quad; - void useQuad(const std::string &tex); + bool useQuad(const std::string &tex); void useGlow(const std::string &tex, int w, int h); void useSound(const std::string &tex); diff --git a/Aquaria/Avatar.cpp b/Aquaria/Avatar.cpp index 2455e20..355f807 100644 --- a/Aquaria/Avatar.cpp +++ b/Aquaria/Avatar.cpp @@ -4115,8 +4115,7 @@ void Avatar::refreshNormalForm() hair->alphaMod = 1.0; if (!c.empty() && c!="Naija") { - hair->setTexture("naija/cape-"+c); - if (Texture::textureError != TEXERR_OK) + if(!hair->setTexture("naija/cape-"+c)) hair->alphaMod = 0; } else diff --git a/Aquaria/DSQ.cpp b/Aquaria/DSQ.cpp index fe26abb..87610af 100644 --- a/Aquaria/DSQ.cpp +++ b/Aquaria/DSQ.cpp @@ -2222,7 +2222,7 @@ void DSQ::refreshResourcesForPatch(const std::string& name) { for(int i = 0; i < dsq->resources.size(); ++i) { - Resource *r = dsq->resources[i]; + Texture *r = dsq->resources[i]; if(files.find(r->name) != files.end()) r->reload(); } @@ -2313,7 +2313,7 @@ void DSQ::shutdown() SkeletalSprite::clearCache(); - cursor->setTexturePointer(0, RenderObject::NO_ADD_REF); + cursor->setTexturePointer(0); UNREFTEX(texCursor); UNREFTEX(texCursorSwim); @@ -2410,7 +2410,7 @@ void DSQ::setTexturePointers() texCursorSing = core->addTexture("cursor-sing"); if (cursor) - cursor->setTexturePointer(texCursor, RenderObject::NO_ADD_REF); + cursor->setTexturePointer(texCursor); } void DSQ::setCursor(CursorType type) @@ -2418,22 +2418,22 @@ void DSQ::setCursor(CursorType type) switch(type) { case CURSOR_NORMAL: - cursor->setTexturePointer(texCursor, RenderObject::NO_ADD_REF); + cursor->setTexturePointer(texCursor); break; case CURSOR_LOOK: - cursor->setTexturePointer(texCursorLook, RenderObject::NO_ADD_REF); + cursor->setTexturePointer(texCursorLook); break; case CURSOR_BURST: - cursor->setTexturePointer(texCursorBurst, RenderObject::NO_ADD_REF); + cursor->setTexturePointer(texCursorBurst); break; case CURSOR_SWIM: - cursor->setTexturePointer(texCursorSwim, RenderObject::NO_ADD_REF); + cursor->setTexturePointer(texCursorSwim); break; case CURSOR_SING: - cursor->setTexturePointer(texCursorSing, RenderObject::NO_ADD_REF); + cursor->setTexturePointer(texCursorSing); break; default: - cursor->setTexturePointer(texCursor, RenderObject::NO_ADD_REF); + cursor->setTexturePointer(texCursor); break; } } @@ -4550,7 +4550,7 @@ void DSQ::onUpdate(float dt) if (isDeveloperKeys() && fpsText && cmDebug && cmDebug->alpha == 1) { std::ostringstream os; - os << "FPS: " << core->fps << " | ROC: " << core->renderObjectCount << " | RC: " << Core::dbg_numRenderCalls; + os << "FPS: " << core->fps << " | ROC: " << core->renderObjectCount << " | RC: " << Core::dbg_numRenderCalls << " | RES: " << core->resources.size(); os << " | p: " << core->processedRenderObjectCount << " | t: " << core->totalRenderObjectCount; os << " | s: " << dsq->continuity.seconds; os << " | evQ: " << core->eventQueue.getSize(); diff --git a/Aquaria/DSQ.h b/Aquaria/DSQ.h index 03b189a..21cded4 100644 --- a/Aquaria/DSQ.h +++ b/Aquaria/DSQ.h @@ -1262,7 +1262,7 @@ public: Quad *bar_left, *bar_right, *bar_up, *bar_down; Quad *barFade_left, *barFade_right; - Texture *texCursor, *texCursorSwim, *texCursorBurst, *texCursorSing, *texCursorLook; + CountedPtr texCursor, texCursorSwim, texCursorBurst, texCursorSing, texCursorLook; void setBlackBarsColor(Vector color); diff --git a/Aquaria/MiniMapRender.cpp b/Aquaria/MiniMapRender.cpp index 5e0d24b..d952e89 100644 --- a/Aquaria/MiniMapRender.cpp +++ b/Aquaria/MiniMapRender.cpp @@ -66,14 +66,14 @@ namespace MiniMapRenderSpace const int healthMarkerSize = 20; - Texture *texCook = 0; - Texture *texWaterBit = 0; - Texture *texMinimapBtm = 0; - Texture *texMinimapTop = 0; - Texture *texRipple = 0; - Texture *texNaija = 0; - Texture *texHealthBar = 0; - Texture *texMarker = 0; + CountedPtr texCook = 0; + CountedPtr texWaterBit = 0; + CountedPtr texMinimapBtm = 0; + CountedPtr texMinimapTop = 0; + CountedPtr texRipple = 0; + CountedPtr texNaija = 0; + CountedPtr texHealthBar = 0; + CountedPtr texMarker = 0; float waterSin = 0; diff --git a/Aquaria/ModSelector.cpp b/Aquaria/ModSelector.cpp index 2a48670..3f95a16 100644 --- a/Aquaria/ModSelector.cpp +++ b/Aquaria/ModSelector.cpp @@ -640,8 +640,7 @@ bool ModIconOnline::fixIcon() quad->setDecayRate(2); quad = 0; } - useQuad(iconfile); - result = Texture::textureError == TEXERR_OK; + result = useQuad(iconfile); } if(!quad) { diff --git a/BBGE/Base.h b/BBGE/Base.h index 7e51583..1f650e3 100644 --- a/BBGE/Base.h +++ b/BBGE/Base.h @@ -144,6 +144,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "ttvfs_stdio.h" #include "tinyxml2.h" +#include "Refcounted.h" #ifdef BBGE_BUILD_LINUX # include diff --git a/BBGE/BitmapFont.cpp b/BBGE/BitmapFont.cpp index e7dc664..277656d 100644 --- a/BBGE/BitmapFont.cpp +++ b/BBGE/BitmapFont.cpp @@ -45,11 +45,8 @@ void BmpFont::destroy() font.Destroy(); loaded = false; } - if (overrideTexture) - { - overrideTexture->removeRef(); - overrideTexture = 0; - } + + overrideTexture = NULL; } void BmpFont::load(const std::string &file, float scale, bool loadTexture) diff --git a/BBGE/BitmapFont.h b/BBGE/BitmapFont.h index cc9f62e..188d4c1 100644 --- a/BBGE/BitmapFont.h +++ b/BBGE/BitmapFont.h @@ -48,7 +48,7 @@ struct BmpFont Vector fontTopColor; Vector fontBtmColor; - Texture *overrideTexture; + CountedPtr overrideTexture; }; class BitmapText : public BaseText diff --git a/BBGE/Core.cpp b/BBGE/Core.cpp index a12c63e..4164be9 100644 --- a/BBGE/Core.cpp +++ b/BBGE/Core.cpp @@ -4240,26 +4240,13 @@ void Core::showBuffer() // when destroy is called on them void Core::clearResources() { - std::vector deletedResources; - int i; - for (i = 0; i < resources.size(); i++) + if(resources.size()) { - int j = 0; - for (j = 0; j < deletedResources.size(); j++) - { - if (deletedResources[j] == resources[i]) - break; - } - if (j == deletedResources.size()) - { - deletedResources.push_back (resources[i]); - Resource *r = resources[i]; - r->destroy(); - delete r; - } + debugLog("Warning: The following resources were not cleared:"); + for(size_t i = 0; i < resources.size(); ++i) + debugLog(resources[i]->name); + resources.clear(); // nothing we can do; refcounting is messed up } - resourceNames.clear(); - resources.clear(); } void Core::shutdownInputLibrary() @@ -4408,20 +4395,7 @@ bool Core::exists(const std::string &filename) return ::exists(filename, false); // defined in Base.cpp } -Resource* Core::findResource(const std::string &name) -{ - for (int i = 0; i < resources.size(); i++) - { - if (resources[i]->name == name) - { - return resources[i]; - } - } - return 0; -} - - -Texture* Core::findTexture(const std::string &name) +CountedPtr Core::findTexture(const std::string &name) { //stringToUpper(name); //std::ofstream out("texturefind.log"); @@ -4432,19 +4406,12 @@ Texture* Core::findTexture(const std::string &name) //NOTE: ensure all names are lowercase before this point if (resources[i]->name == name) { - return (Texture*)resources[i]; + return resources[i]; } } return 0; } -std::string Core::getInternalTextureName(const std::string &name) -{ - std::string n = name; - stringToUpper(n); - return n; -} - // This handles unix/win32 relative paths: ./rel/path // Unix abs paths: /home/user/... // Win32 abs paths: C:/Stuff/.. and also C:\Stuff\... @@ -4462,7 +4429,7 @@ std::string Core::getTextureLoadName(const std::string &texture) return loadName; } -Texture *Core::doTextureAdd(const std::string &texture, const std::string &loadName, std::string internalTextureName) +std::pair, TextureLoadResult> Core::doTextureAdd(const std::string &texture, const std::string &loadName, std::string internalTextureName) { if (texture.empty() || !ISPATHROOT(texture)) { @@ -4479,47 +4446,32 @@ Texture *Core::doTextureAdd(const std::string &texture, const std::string &loadN } stringToLowerUserData(internalTextureName); - Texture *t = core->findTexture(internalTextureName); + CountedPtr t = core->findTexture(internalTextureName); if (t) - { - t->addRef(); - - Texture::textureError = t->failed ? TEXERR_FILENOTFOUND : TEXERR_OK; - - /* - std::ostringstream os; - os << "reference texture: " << internalTextureName << " ref: " << t->getRef(); - debugLog(os.str()); - */ - - //msg ("found texture " + internalTextureName); - return t; - } + return std::make_pair(t, TEX_SUCCESS); t = new Texture; t->name = internalTextureName; - t->load(loadName); - t->addRef(); - //resources.push_back (t); - addResource(t); + unsigned res = TEX_FAILED; - if (debugLogTextures) + if(t->load(loadName)) + res |= (TEX_LOADED | TEX_SUCCESS); + else { - std::ostringstream os; - os << "LOADED TEXTURE FROM DISK: [" << internalTextureName << "] ref: " << t->getRef() << " idx: " << resources.size()-1; - debugLog(os.str()); + t->width = 64; + t->height = 64; } - return t; + return std::make_pair(t, (TextureLoadResult)res); } -Texture* Core::addTexture(const std::string &textureName) +CountedPtr Core::addTexture(const std::string &textureName) { - if (textureName.empty()) return 0; + if (textureName.empty()) return NULL; BBGE_PROF(Core_addTexture); - Texture *texPointer = 0; + std::pair, TextureLoadResult> texResult; std::string texture = textureName; stringToLowerUserData(texture); @@ -4537,30 +4489,34 @@ Texture* Core::addTexture(const std::string &textureName) std::string ln = loadName; texture = secondaryTexturePath + texture; loadName = texture; - texPointer = doTextureAdd(texture, loadName, internalTextureName); - if (Texture::textureError != TEXERR_OK) - { - if (texPointer) - { - texPointer->destroy(); - texPointer = 0; - } - texPointer = doTextureAdd(t, ln, internalTextureName); - } + texResult = doTextureAdd(texture, loadName, internalTextureName); + if (!texResult.second) + texResult = doTextureAdd(t, ln, internalTextureName); } else - texPointer = doTextureAdd(texture, loadName, internalTextureName); + texResult = doTextureAdd(texture, loadName, internalTextureName); - return texPointer; + addTexture(texResult.first.content()); + + if(debugLogTextures) + { + if (texResult.second & TEX_LOADED) + { + std::ostringstream os; + os << "LOADED TEXTURE FROM DISK: [" << internalTextureName << "] idx: " << resources.size()-1; + debugLog(os.str()); + } + else if(!(texResult.second & TEX_SUCCESS)) + { + std::ostringstream os; + os << "FAILED TO LOAD TEXTURE: [" << internalTextureName << "] idx: " << resources.size()-1; + debugLog(os.str()); + } + } + + return texResult.first; } -void Core::removeTexture(std::string texture) -{ - //std::string internalName = baseTextureDirectory + texture; - removeResource(texture, DESTROY); -} - - void Core::addRenderObject(RenderObject *o, int layer) { if (!o) return; @@ -4603,59 +4559,36 @@ void Core::reloadResources() onReloadResources(); } -void Core::addResource(Resource *r) +void Core::addTexture(Texture *r) { + for(size_t i = 0; i < resources.size(); ++i) + if(resources[i] == r) + return; + resources.push_back(r); - resourceNames.push_back(r->name); if (r->name.empty()) { debugLog("Empty name resource added"); } } -void Core::removeResource(std::string name, RemoveResource removeFlag) +void Core::removeTexture(Texture *res) { - //Resource *r = findResource(name); - //int idx = 0; - int i = 0; - std::vectorcopy; - copy = resources; - resources.clear(); + std::vector copy; + copy.swap(resources); - - std::vector copyNames; - copyNames = resourceNames; - resourceNames.clear(); - - bool isDestroyed = false; - - - for (i = 0; i < copy.size(); i++) + for (size_t i = 0; i < copy.size(); ++i) { -#ifdef _DEBUG - std::string s = copy[i]->name; -#endif - if (!isDestroyed && copy[i]->name == name) + if (copy[i] == res) { - if (removeFlag == DESTROY) - { - copy[i]->destroy(); - delete copy[i]; - isDestroyed = true; - } - continue; - } - // also remove other entries of the same resource - else if (isDestroyed && copyNames[i] == name) - { - continue; - } - else - { - resources.push_back(copy[i]); - resourceNames.push_back(copy[i]->name); + copy[i]->destroy(); + copy[i] = copy.back(); + copy.pop_back(); + break; } } + + resources.swap(copy); } void Core::deleteRenderObjectMemory(RenderObject *r) @@ -4709,25 +4642,6 @@ void Core::clearGarbage() } garbage.clear(); - - // to clear resources - for (std::vector::iterator i = resources.begin(); i != resources.end(); ) - { - if ((*i)->getRef() == 0) - { - clearedGarbageFlag = true; - delete (*i); - i = resources.erase(i); - continue; - } - - if ((*i)->getRef() < 0) - { - errorLog("Texture ref < 0"); - } - - i++; - } } bool Core::canChangeState() diff --git a/BBGE/Core.h b/BBGE/Core.h index 55d2233..2f0cd99 100644 --- a/BBGE/Core.h +++ b/BBGE/Core.h @@ -964,11 +964,6 @@ class Core : public ActionMapper, public StateManager { public: - enum RemoveResource - { - DESTROY = 0, - NO_DESTROY - }; // init Core(const std::string &filesystem, const std::string& extraDataDir, int numRenderLayers, const std::string &appName="BBGE", int particleSize=1024, std::string userDataSubFolder=""); void initPlatform(const std::string &filesystem); @@ -1023,13 +1018,12 @@ public: void enable2D(int pixelScaleX=0, int pixelScaleY=0, bool forcePixelScale=false); void addRenderObject(RenderObject *o, int layer=0); void switchRenderObjectLayer(RenderObject *o, int toLayer); - void addResource(Resource *r); - Resource *findResource(const std::string &name); - Texture *findTexture(const std::string &name); - void removeResource(std::string name, RemoveResource removeFlag); + void addTexture(Texture *r); + CountedPtr findTexture(const std::string &name); + void removeTexture(Texture *res); + void clearResources(); - Texture *addTexture(const std::string &texture); - void removeTexture(std::string texture); + CountedPtr addTexture(const std::string &texture); PostProcessingFX postProcessingFx; @@ -1047,7 +1041,6 @@ public: void enqueueRenderObjectDeletion(RenderObject *object); void clearGarbage(); - void clearResources(); bool isNested() { return nestedMains > 1; } @@ -1103,8 +1096,7 @@ public: HINSTANCE hInstance; // Holds The Instance Of The Application #endif - std::vectorresources; - std::vector resourceNames; + std::vector resources; RenderObjectLayer *getRenderObjectLayer(int i); std::vector renderObjectLayerOrder; @@ -1247,7 +1239,6 @@ public: Joystick joystick; - std::string getInternalTextureName(const std::string &name); void setClearColor(const Vector &c); Vector getClearColor(); int flipMouseButtons; @@ -1337,7 +1328,7 @@ protected: virtual void onReloadResources(); - Texture* doTextureAdd(const std::string &texture, const std::string &name, std::string internalTextureName); + std::pair, TextureLoadResult> doTextureAdd(const std::string &texture, const std::string &name, std::string internalTextureName); void deleteRenderObjectMemory(RenderObject *r); bool _hasFocus; @@ -1398,6 +1389,8 @@ protected: int numSavedScreenshots; + CountedPtr texError; + //unsigned int windowWidth, windowHeight; diff --git a/BBGE/Quad.cpp b/BBGE/Quad.cpp index ae32b08..a8c8f41 100644 --- a/BBGE/Quad.cpp +++ b/BBGE/Quad.cpp @@ -798,6 +798,11 @@ void Quad::onSetTexture() width = this->texture->width; height = this->texture->height; } + else + { + width = 64; + height = 64; + } } PauseQuad::PauseQuad() : Quad(), pauseLevel(0) diff --git a/BBGE/Refcounted.h b/BBGE/Refcounted.h new file mode 100644 index 0000000..f79fa1b --- /dev/null +++ b/BBGE/Refcounted.h @@ -0,0 +1,95 @@ +#ifndef CG_CORE_REFCOUNTED_H +#define CG_CORE_REFCOUNTED_H + +#include +#include +#include + + +class Refcounted +{ +protected: + + Refcounted() : _refcount(0) + { + } + virtual ~Refcounted() + { + assert(_refcount == 0 && "Object was deleted with refcount != 0"); + } + +public: + + inline void incref() + { + ++_refcount; + } + inline void decref() + { + if (!--_refcount) + delete this; + } + +private: + unsigned _refcount; +}; + + +template class CountedPtr +{ +public: + inline ~CountedPtr() + { + if(_p) + _p->decref(); + } + inline CountedPtr() : _p(NULL) + {} + inline CountedPtr(T* p) : _p(p) + { + if(p) + p->incref(); + } + inline CountedPtr(const CountedPtr& ref) : _p(ref._p) + { + if (_p) + _p->incref(); + } + + // intentionally not a reference -- see http://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom + CountedPtr& operator=(CountedPtr ref) + { + CountedPtr::swap(*this, ref); + return *this; + } + + const T* operator->() const { return _p; } + T* operator->() { return _p; } + + bool operator!() const { return !_p; } + + // Safe for use in if statements + operator bool() const { return !!_p; } + + T* content () { return _p; } + const T* content () const { return _p; } + + bool operator<(const CountedPtr& ref) const { return _p < ref._p; } + bool operator<=(const CountedPtr& ref) const { return _p <= ref._p; } + bool operator==(const CountedPtr& ref) const { return _p == ref._p; } + bool operator!=(const CountedPtr& ref) const { return _p != ref._p; } + bool operator>=(const CountedPtr& ref) const { return _p >= ref._p; } + bool operator>(const CountedPtr& ref) const { return _p > ref._p; } + + inline static void swap(CountedPtr& a, CountedPtr& b) + { + std::swap(a._p, b._p); + } + +private: + + T *_p; +}; + + +#endif diff --git a/BBGE/RenderObject.cpp b/BBGE/RenderObject.cpp index b66d817..6d833cb 100644 --- a/BBGE/RenderObject.cpp +++ b/BBGE/RenderObject.cpp @@ -416,11 +416,8 @@ void RenderObject::destroy() parent->removeChild(this); parent = 0; } - if (texture) - { - texture->removeRef(); - texture = 0; - } + + texture = NULL; } void RenderObject::copyProperties(RenderObject *target) @@ -1320,26 +1317,20 @@ void RenderObject::reloadDevice() } } -void RenderObject::setTexture(const std::string &n) +bool RenderObject::setTexture(const std::string &n) { std::string name = n; stringToLowerUserData(name); if (name.empty()) - return; + return false; - if(texture && !texture->failed && texture->name == core->getInternalTextureName(name)) - { - Texture::textureError = TEXERR_OK; - return; // no texture change - } + if(texture && name == texture->name) + return true; // no texture change - Texture *oldtex = texture; - Texture *t = core->addTexture(name); - setTexturePointer(t, NO_ADD_REF); - - if (oldtex) - oldtex->removeRef(); + CountedPtr tex = core->addTexture(name); + setTexturePointer(tex); + return !!tex; } float RenderObject::getSortDepth() diff --git a/BBGE/RenderObject.h b/BBGE/RenderObject.h index 2542c1f..a86672a 100644 --- a/BBGE/RenderObject.h +++ b/BBGE/RenderObject.h @@ -83,18 +83,14 @@ public: static RenderObjectLayer *rlayer; - enum AddRefChoice { NO_ADD_REF = 0, ADD_REF = 1}; - - void setTexturePointer(Texture *t, AddRefChoice addRefChoice) + void setTexturePointer(CountedPtr t) { this->texture = t; - if (addRefChoice == ADD_REF) - texture->addRef(); onSetTexture(); } void setStateDataObject(StateData *state); - void setTexture(const std::string &name); + bool setTexture(const std::string &name); void toggleAlpha(float t = 0.2); void matrixChain(); @@ -239,7 +235,7 @@ public: InterpolatedVector offset, rotationOffset, internalOffset, beforeScaleOffset; InterpolatedVector velocity, gravity; - Texture *texture; + CountedPtr texture; //int mode; diff --git a/BBGE/Resource.cpp b/BBGE/Resource.cpp deleted file mode 100644 index eea6ac3..0000000 --- a/BBGE/Resource.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/* -Copyright (C) 2007, 2010 - Bit-Blot - -This file is part of Aquaria. - -Aquaria is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -#include "Resource.h" -#include "Core.h" - - -void Resource::destroy() -{ - core->removeResource(this->name, Core::NO_DESTROY); -} diff --git a/BBGE/Resource.h b/BBGE/Resource.h deleted file mode 100644 index 5ea7f6d..0000000 --- a/BBGE/Resource.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright (C) 2007, 2010 - Bit-Blot - -This file is part of Aquaria. - -Aquaria is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -#ifndef __resource__ -#define __resource__ - -#include "Base.h" - -class Resource -{ -public: - Resource() - { - ref = 0; - } - ~Resource() - { - destroy(); - } - virtual void destroy(); - - void addRef() - { - ref++; - } - void removeRef() - { - ref--; - if (ref == 0) - destroy(); - } - int getRef() { return ref; } - std::string name; - virtual void reload() {} - virtual void unload() {} -protected: - int ref; -}; - -#endif diff --git a/BBGE/Texture.cpp b/BBGE/Texture.cpp index 29336b9..f9b898c 100644 --- a/BBGE/Texture.cpp +++ b/BBGE/Texture.cpp @@ -54,9 +54,8 @@ bool Texture::useMipMaps = true; #endif */ -TexErr Texture::textureError = TEXERR_OK; -Texture::Texture() : Resource() +Texture::Texture() { #ifdef BBGE_BUILD_OPENGL textures[0] = 0; @@ -68,9 +67,7 @@ Texture::Texture() : Resource() repeat = false; repeating = false; - failed = false; pngSetStandardOrientation(0); - ow = oh = -1; } @@ -152,7 +149,6 @@ void Texture::write(int tx, int ty, int w, int h, const unsigned char *pixels) void Texture::unload() { - Resource::unload(); #ifdef BBGE_BUILD_OPENGL if (textures[0]) { @@ -167,8 +163,6 @@ void Texture::unload() glDeleteTextures(1, &textures[0]); textures[0] = 0; - - //removeRef(); } #endif } @@ -186,10 +180,7 @@ void Texture::destroy() } #endif - if (!core->isShuttingDown()) - core->removeTexture(this->name); - -// Resource::destroy(); + core->removeTexture(this); } int Texture::getPixelWidth() @@ -256,8 +247,6 @@ int Texture::getPixelHeight() void Texture::reload() { - Resource::reload(); - debugLog("RELOADING TEXTURE: " + name + " with loadName " + loadName + "..."); unload(); @@ -271,17 +260,12 @@ void Texture::reload() debugLog("DONE"); } -void Texture::load(std::string file) +bool Texture::load(std::string file) { - Texture::textureError = TEXERR_OK; - failed = false; - if (file.size()<4) { errorLog("Texture Name is Empty or Too Short"); - Texture::textureError = TEXERR_FILENOTFOUND; - failed = true; - return; + return false; } stringToLowerUserData(file); @@ -335,7 +319,7 @@ void Texture::load(std::string file) { #ifdef BBGE_BUILD_OPENGL - loadPNG(file); + return loadPNG(file); #endif #ifdef BBGE_BUILD_DIRECTX @@ -356,19 +340,15 @@ void Texture::load(std::string file) } else if (post == "zga") { - loadZGA(file); + return loadZGA(file); } else if (post == "tga") { - loadTGA(file); + return loadTGA(file); } else { debugLog("unknown image file type: " + file); - Texture::textureError = TEXERR_FILENOTFOUND; - width = 64; - height = 64; - failed = true; } } else @@ -376,11 +356,8 @@ void Texture::load(std::string file) // load default image / leave white if (core->debugLogTextures) debugLog("***Could not find texture: " + file); - Texture::textureError = TEXERR_FILENOTFOUND; - width = 64; - height = 64; - failed = true; } + return false; } void Texture::apply(bool repeatOverride) @@ -416,18 +393,10 @@ void Texture::unbind() { } -#ifdef BBGE_BUILD_OPENGL - -void Texture::setID(int id) +bool Texture::loadPNG(const std::string &file) { - textures[0] = id; -} - -#endif - -void Texture::loadPNG(const std::string &file) -{ - if (file.empty()) return; + if (file.empty()) return false; + bool good = false; #ifdef BBGE_BUILD_OPENGL @@ -435,7 +404,7 @@ void Texture::loadPNG(const std::string &file) pngInfo info; int pngType = PNG_ALPHA; - + if (format != 0) { if (format == GL_LUMINANCE_ALPHA) @@ -460,31 +429,29 @@ void Texture::loadPNG(const std::string &file) { width = info.Width; height = info.Height; + good = true; } else { fail: debugLog("Can't load PNG file: " + file); - width = 64; - height = 64; - Texture::textureError = TEXERR_FILENOTFOUND; - failed = true; } if(memptr) delete [] memptr; #endif + return good; } // internal load functions -void Texture::loadTGA(const std::string &file) +bool Texture::loadTGA(const std::string &file) { - loadTGA(TGAload(file.c_str())); + return loadTGA(TGAload(file.c_str())); } -void Texture::loadZGA(const std::string &file) +bool Texture::loadZGA(const std::string &file) { unsigned long size = 0; char *buf = readCompressedFile(file, &size); @@ -492,15 +459,15 @@ void Texture::loadZGA(const std::string &file) if (!tga) { debugLog("Can't load ZGA File: " + file); - return; + return false; } - loadTGA(tga); + return loadTGA(tga); } -void Texture::loadTGA(ImageTGA *imageTGA) +bool Texture::loadTGA(ImageTGA *imageTGA) { if (!imageTGA) - return; + return false; glGenTextures(1, &textures[0]); glBindTexture(GL_TEXTURE_2D, textures[0]); @@ -518,6 +485,8 @@ void Texture::loadTGA(ImageTGA *imageTGA) if (imageTGA->data) delete[] (imageTGA->data); free (imageTGA); + + return true; } diff --git a/BBGE/Texture.h b/BBGE/Texture.h index e27c242..a32a5ee 100644 --- a/BBGE/Texture.h +++ b/BBGE/Texture.h @@ -21,7 +21,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef __texture__ #define __texture__ -#include "Resource.h" +#include "Base.h" + +enum TextureLoadResult +{ + TEX_FAILED = 0x00, + TEX_SUCCESS = 0x01, + TEX_LOADED = 0x02, +}; struct ImageTGA { @@ -31,24 +38,16 @@ struct ImageTGA unsigned char *data; // The image pixel data }; -enum TexErr -{ - TEXERR_OK = 0, - TEXERR_FILENOTFOUND = 1, - TEXERR_MAX -}; - -class Texture : public Resource +class Texture : public Refcounted { public: Texture(); ~Texture(); - void load(std::string file); + bool load(std::string file); void apply(bool repeatOverride=false); void unbind(); void unload(); - void setLayer(int layer); int getPixelWidth(); int getPixelHeight(); @@ -62,12 +61,11 @@ public: static ImageTGA *TGAloadMem(void *mem, int size); static bool useMipMaps; - bool repeat, repeating, failed; + bool repeat, repeating; #ifdef BBGE_BUILD_OPENGL static GLint filter; static GLint format; - void setID (int id); GLuint textures[1]; #endif #ifdef BBGE_BUILD_DIRECTX @@ -76,26 +74,26 @@ public: void reload(); - static TexErr textureError; - void write(int tx, int ty, int w, int h, const unsigned char *pixels); void read(int tx, int ty, int w, int h, unsigned char *pixels); unsigned char *getBufferAndSize(int *w, int *h, unsigned int *size); // returned memory must be free()'d + std::string name; + protected: std::string loadName; // internal load functions - void loadPNG(const std::string &file); - void loadTGA(const std::string &file); - void loadZGA(const std::string &file); - void loadTGA(ImageTGA *tga); + bool loadPNG(const std::string &file); + bool loadTGA(const std::string &file); + bool loadZGA(const std::string &file); + bool loadTGA(ImageTGA *tga); int ow, oh; }; -#define UNREFTEX(x) if (x) {x->removeRef(); x=0;} +#define UNREFTEX(x) if (x) {x = NULL;} #endif diff --git a/CMakeLists.txt b/CMakeLists.txt index 82e1f8f..71f8de3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -482,7 +482,6 @@ SET(BBGE_SRCS ${BBGEDIR}/RenderObject.cpp ${BBGEDIR}/RenderObjectLayer.cpp ${BBGEDIR}/RenderRect.cpp - ${BBGEDIR}/Resource.cpp ${BBGEDIR}/RoundedRect.cpp ${BBGEDIR}/ScreenTransition.cpp ${BBGEDIR}/ScriptObject.cpp diff --git a/win/vc90/BBGE.vcproj b/win/vc90/BBGE.vcproj index 0d3d68d..c701762 100644 --- a/win/vc90/BBGE.vcproj +++ b/win/vc90/BBGE.vcproj @@ -396,6 +396,10 @@ RelativePath="..\..\BBGE\Rect.h" > + + @@ -416,14 +420,6 @@ RelativePath="..\..\BBGE\RenderRect.cpp" > - - - -