mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2024-12-28 07:45:49 +00:00
Refactor texture loading code; should fix a crash that started appearing recently.
This commit is contained in:
parent
66cf20ffa9
commit
f0d580d873
22 changed files with 254 additions and 386 deletions
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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<Texture> texCursor, texCursorSwim, texCursorBurst, texCursorSing, texCursorLook;
|
||||
|
||||
void setBlackBarsColor(Vector color);
|
||||
|
||||
|
|
|
@ -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<Texture> texCook = 0;
|
||||
CountedPtr<Texture> texWaterBit = 0;
|
||||
CountedPtr<Texture> texMinimapBtm = 0;
|
||||
CountedPtr<Texture> texMinimapTop = 0;
|
||||
CountedPtr<Texture> texRipple = 0;
|
||||
CountedPtr<Texture> texNaija = 0;
|
||||
CountedPtr<Texture> texHealthBar = 0;
|
||||
CountedPtr<Texture> texMarker = 0;
|
||||
|
||||
float waterSin = 0;
|
||||
|
||||
|
|
|
@ -640,8 +640,7 @@ bool ModIconOnline::fixIcon()
|
|||
quad->setDecayRate(2);
|
||||
quad = 0;
|
||||
}
|
||||
useQuad(iconfile);
|
||||
result = Texture::textureError == TEXERR_OK;
|
||||
result = useQuad(iconfile);
|
||||
}
|
||||
if(!quad)
|
||||
{
|
||||
|
|
|
@ -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 <sys/types.h>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -48,7 +48,7 @@ struct BmpFont
|
|||
Vector fontTopColor;
|
||||
Vector fontBtmColor;
|
||||
|
||||
Texture *overrideTexture;
|
||||
CountedPtr<Texture> overrideTexture;
|
||||
};
|
||||
|
||||
class BitmapText : public BaseText
|
||||
|
|
202
BBGE/Core.cpp
202
BBGE/Core.cpp
|
@ -4240,26 +4240,13 @@ void Core::showBuffer()
|
|||
// when destroy is called on them
|
||||
void Core::clearResources()
|
||||
{
|
||||
std::vector<Resource*> 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<Texture> 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<CountedPtr<Texture>, 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<Texture> 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<Texture> 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<CountedPtr<Texture>, TextureLoadResult> texResult;
|
||||
|
||||
std::string texture = textureName;
|
||||
stringToLowerUserData(texture);
|
||||
|
@ -4537,29 +4489,33 @@ 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());
|
||||
|
||||
void Core::removeTexture(std::string texture)
|
||||
{
|
||||
//std::string internalName = baseTextureDirectory + texture;
|
||||
removeResource(texture, DESTROY);
|
||||
}
|
||||
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::addRenderObject(RenderObject *o, int layer)
|
||||
{
|
||||
|
@ -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::vector<Resource*>copy;
|
||||
copy = resources;
|
||||
resources.clear();
|
||||
|
||||
|
||||
std::vector <std::string> copyNames;
|
||||
copyNames = resourceNames;
|
||||
resourceNames.clear();
|
||||
std::vector<Texture*> copy;
|
||||
copy.swap(resources);
|
||||
|
||||
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 (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
|
||||
if (copy[i] == res)
|
||||
{
|
||||
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<Resource*>::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()
|
||||
|
|
25
BBGE/Core.h
25
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<Texture> findTexture(const std::string &name);
|
||||
void removeTexture(Texture *res);
|
||||
void clearResources();
|
||||
|
||||
Texture *addTexture(const std::string &texture);
|
||||
void removeTexture(std::string texture);
|
||||
CountedPtr<Texture> 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::vector<Resource*>resources;
|
||||
std::vector<std::string> resourceNames;
|
||||
std::vector<Texture*> resources;
|
||||
|
||||
RenderObjectLayer *getRenderObjectLayer(int i);
|
||||
std::vector <int> 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<CountedPtr<Texture>, 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<Texture> texError;
|
||||
|
||||
//unsigned int windowWidth, windowHeight;
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
95
BBGE/Refcounted.h
Normal file
95
BBGE/Refcounted.h
Normal file
|
@ -0,0 +1,95 @@
|
|||
#ifndef CG_CORE_REFCOUNTED_H
|
||||
#define CG_CORE_REFCOUNTED_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <assert.h>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
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<typename T> 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
|
|
@ -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;
|
||||
|
||||
if(texture && !texture->failed && texture->name == core->getInternalTextureName(name))
|
||||
{
|
||||
Texture::textureError = TEXERR_OK;
|
||||
return; // no texture change
|
||||
}
|
||||
return false;
|
||||
|
||||
Texture *oldtex = texture;
|
||||
Texture *t = core->addTexture(name);
|
||||
setTexturePointer(t, NO_ADD_REF);
|
||||
if(texture && name == texture->name)
|
||||
return true; // no texture change
|
||||
|
||||
if (oldtex)
|
||||
oldtex->removeRef();
|
||||
CountedPtr<Texture> tex = core->addTexture(name);
|
||||
setTexturePointer(tex);
|
||||
return !!tex;
|
||||
}
|
||||
|
||||
float RenderObject::getSortDepth()
|
||||
|
|
|
@ -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<Texture> 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> texture;
|
||||
|
||||
//int mode;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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)
|
||||
{
|
||||
textures[0] = id;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void Texture::loadPNG(const std::string &file)
|
||||
bool 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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -396,6 +396,10 @@
|
|||
RelativePath="..\..\BBGE\Rect.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\BBGE\Refcounted.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\BBGE\RenderObject.cpp"
|
||||
>
|
||||
|
@ -416,14 +420,6 @@
|
|||
RelativePath="..\..\BBGE\RenderRect.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\BBGE\Resource.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\BBGE\Resource.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\BBGE\RoundedRect.cpp"
|
||||
>
|
||||
|
|
Loading…
Reference in a new issue