1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2025-02-27 16:44:00 +00:00

rendering optimizations; work towards making the transition to VBOs eventually

This commit is contained in:
fgenesis 2023-07-14 04:25:59 +02:00
parent ab218ceca6
commit 9b1c3bba18
8 changed files with 171 additions and 140 deletions

View file

@ -3512,10 +3512,9 @@ bool DSQ::loadTileset(std::string pack, const unsigned char *usedIdx, size_t use
const float cell = 64.0f/512.0f; const float cell = 64.0f/512.0f;
for (int i = 0; i < 27; i++) for (int i = 0; i < 27; i++)
{ {
ElementTemplate t; ElementTemplate *et = new ElementTemplate;
t.idx = 1024+i; et->idx = 1024+i;
t.tex = aqtex; et->tex = aqtex;
t.loaded = true;
int x = i,y=0; int x = i,y=0;
while (x >= 6) while (x >= 6)
{ {
@ -3523,19 +3522,20 @@ bool DSQ::loadTileset(std::string pack, const unsigned char *usedIdx, size_t use
y++; y++;
} }
t.tu1 = x*cell; et->tu1 = x*cell;
t.tv1 = y*cell; et->tv1 = y*cell;
t.tu2 = t.tu1 + cell; et->tu2 = et->tu1 + cell;
t.tv2 = t.tv1 + cell; et->tv2 = et->tv1 + cell;
t.tv2 = 1 - t.tv2; et->tv2 = 1 - et->tv2;
t.tv1 = 1 - t.tv1; et->tv1 = 1 - et->tv1;
std::swap(t.tv1,t.tv2); std::swap(et->tv1,et->tv2);
t.w = 512*cell; et->w = 512*cell;
t.h = 512*cell; et->h = 512*cell;
tilemgr.tileset.elementTemplates.push_back(t); et->finalize();
tilemgr.tileset.elementTemplates.push_back(et);
} }
} }

View file

@ -703,7 +703,7 @@ void SceneEditor::init()
if (curElement < dsq->tilemgr.tileset.elementTemplates.size()) if (curElement < dsq->tilemgr.tileset.elementTemplates.size())
{ {
placer->setTexture(dsq->tilemgr.tileset.elementTemplates[curElement].gfx); placer->setTexture(dsq->tilemgr.tileset.elementTemplates[curElement]->gfx);
placer->scale = Vector(1,1); placer->scale = Vector(1,1);
} }
else else
@ -888,7 +888,7 @@ void SceneEditor::editModeElements()
editType = ET_ELEMENTS; editType = ET_ELEMENTS;
if (curElement < dsq->tilemgr.tileset.elementTemplates.size()) if (curElement < dsq->tilemgr.tileset.elementTemplates.size())
{ {
placer->setTexture(dsq->tilemgr.tileset.elementTemplates[curElement].gfx); placer->setTexture(dsq->tilemgr.tileset.elementTemplates[curElement]->gfx);
placer->scale = Vector(1,1); placer->scale = Vector(1,1);
} }
placer->alpha = 0.5; placer->alpha = 0.5;
@ -2002,7 +2002,6 @@ void SceneEditor::cycleSelectedTiles(int direction)
const int maxn = (int)dsq->tilemgr.tileset.elementTemplates.size(); const int maxn = (int)dsq->tilemgr.tileset.elementTemplates.size();
if(!maxn) if(!maxn)
return; return;
const ElementTemplate * const base = &dsq->tilemgr.tileset.elementTemplates[0];
for(size_t i = 0; i < n; ++i) for(size_t i = 0; i < n; ++i)
{ {
TileData& t = ts.tiles[selectedTiles[i]]; TileData& t = ts.tiles[selectedTiles[i]];
@ -2093,9 +2092,9 @@ void SceneEditor::cyclePlacer(int direction)
if(nextidx >= maxn) if(nextidx >= maxn)
nextidx -= maxn; nextidx -= maxn;
if (maxn && dsq->tilemgr.tileset.elementTemplates[curElement].idx < 1024) if (maxn && dsq->tilemgr.tileset.elementTemplates[curElement]->idx < 1024)
{ {
placer->setTexture(dsq->tilemgr.tileset.elementTemplates[curElement].gfx); placer->setTexture(dsq->tilemgr.tileset.elementTemplates[curElement]->gfx);
curElement = nextidx; curElement = nextidx;
} }
} }
@ -2108,7 +2107,7 @@ void SceneEditor::selectZero()
{ {
if (dsq->tilemgr.tileset.elementTemplates.empty()) return; if (dsq->tilemgr.tileset.elementTemplates.empty()) return;
curElement = 0; curElement = 0;
placer->setTexture(dsq->tilemgr.tileset.elementTemplates[curElement].gfx); placer->setTexture(dsq->tilemgr.tileset.elementTemplates[curElement]->gfx);
} }
} }
@ -2122,14 +2121,14 @@ void SceneEditor::selectEnd()
size_t largest = 0; size_t largest = 0;
for (size_t i = 0; i < dsq->tilemgr.tileset.elementTemplates.size(); i++) for (size_t i = 0; i < dsq->tilemgr.tileset.elementTemplates.size(); i++)
{ {
ElementTemplate et = dsq->tilemgr.tileset.elementTemplates[i]; ElementTemplate *et = dsq->tilemgr.tileset.elementTemplates[i];
if (et.idx < 1024 && i > largest) if (et->idx < 1024 && i > largest)
{ {
largest = i; largest = i;
} }
} }
curElement = largest; curElement = largest;
placer->setTexture(dsq->tilemgr.tileset.elementTemplates[curElement].gfx); placer->setTexture(dsq->tilemgr.tileset.elementTemplates[curElement]->gfx);
} }
} }
@ -2139,7 +2138,7 @@ void SceneEditor::placeElement()
{ {
if (!core->getShiftState() && !core->getKeyState(KEY_LALT)) if (!core->getShiftState() && !core->getKeyState(KEY_LALT))
{ {
unsigned tilesetID = dsq->tilemgr.tileset.elementTemplates[curElement].idx; unsigned tilesetID = dsq->tilemgr.tileset.elementTemplates[curElement]->idx;
dsq->tilemgr.createOneTile(tilesetID, bgLayer, placer->position.x, placer->position.y); dsq->tilemgr.createOneTile(tilesetID, bgLayer, placer->position.x, placer->position.y);
// FIXME: need to update grid or no? // FIXME: need to update grid or no?
updateText(); updateText();

View file

@ -187,8 +187,8 @@ TileData* TileMgr::_createTile(unsigned tilesetID, unsigned layer, float x, flo
t.texscaleY = 1; t.texscaleY = 1;
t.scalex = 1; t.scalex = 1;
t.scaley = 1; t.scaley = 1;
t.beforeScaleOffsetX = 0; //t.beforeScaleOffsetX = 0;
t.beforeScaleOffsetY = 0; //t.beforeScaleOffsetY = 0;
t.flags = GetTileFlags(ef); t.flags = GetTileFlags(ef);
t.tag = 0; t.tag = 0;
t.et = tileset.getByIdx(tilesetID); t.et = tileset.getByIdx(tilesetID);

View file

@ -70,6 +70,7 @@ GL_FUNC(void,glCallList,(GLuint list),(list),)
GL_FUNC(void,glClearDepth,(GLclampd x),(x),) GL_FUNC(void,glClearDepth,(GLclampd x),(x),)
GL_FUNC(void,glColor3f,(GLfloat r,GLfloat g,GLfloat b),(r,g,b),) GL_FUNC(void,glColor3f,(GLfloat r,GLfloat g,GLfloat b),(r,g,b),)
GL_FUNC(void,glDeleteLists,(GLuint list, GLsizei range),(list,range),) GL_FUNC(void,glDeleteLists,(GLuint list, GLsizei range),(list,range),)
GL_FUNC(void,glDrawArrays,(GLenum mode, GLint first, GLsizei count), (mode,first,count),)
GL_FUNC(void,glDrawPixels,(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels),(width,height,format,type,pixels),) GL_FUNC(void,glDrawPixels,(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels),(width,height,format,type,pixels),)
GL_FUNC(GLuint,glGenLists,(GLsizei range),(range),return) GL_FUNC(GLuint,glGenLists,(GLsizei range),(range),return)
GL_FUNC(void,glNewList,(GLuint list, GLenum mode),(list,mode),) GL_FUNC(void,glNewList,(GLuint list, GLenum mode),(list,mode),)

View file

@ -134,7 +134,7 @@ private:
struct TileData struct TileData
{ {
float x, y, scalex, scaley, texscaleX, texscaleY; float x, y, scalex, scaley, texscaleX, texscaleY;
float beforeScaleOffsetX, beforeScaleOffsetY; // almost always 0. // TODO: this is nasty, ideally get rid of this //float beforeScaleOffsetX, beforeScaleOffsetY; // almost always 0. // TODO: this is nasty, ideally get rid of this
float rotation; float rotation;
unsigned flags; // TileFlags unsigned flags; // TileFlags
unsigned tag; // FIXME: make this int unsigned tag; // FIXME: make this int

View file

@ -41,9 +41,26 @@ static inline const Vector& getTagColor(int tag)
} }
static const float s_quadVerts[] =
{
-0.5f, +0.5f,
+0.5f, +0.5f,
+0.5f, -0.5f,
-0.5f, -0.5f,
};
void TileRender::onRender(const RenderState& rs) const void TileRender::onRender(const RenderState& rs) const
{ {
if(storage.tiles.empty())
return;
glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, s_quadVerts);
RenderState rx(rs);
// prepare. get parallax scroll factors // prepare. get parallax scroll factors
const RenderObjectLayer& rl = core->renderObjectLayers[this->layer]; const RenderObjectLayer& rl = core->renderObjectLayers[this->layer];
const Vector M = rl.followCameraMult; // affected by parallaxLock const Vector M = rl.followCameraMult; // affected by parallaxLock
@ -58,8 +75,10 @@ void TileRender::onRender(const RenderState& rs) const
unsigned lastTexRepeat = false; unsigned lastTexRepeat = false;
unsigned lastTexId = 0; unsigned lastTexId = 0;
const bool renderBorders = this->renderBorders; const bool renderExtras = renderBorders || RenderObject::renderCollisionShape;
//bool mustSetColor = false; const TileEffectData *prevEff = ((TileEffectData*)NULL)+1; // initial value is different from anything else
const RenderGrid *grid = NULL;
const float *lastTexcoordBuf = NULL;
for(size_t i = 0; i < storage.tiles.size(); ++i) for(size_t i = 0; i < storage.tiles.size(); ++i)
{ {
@ -75,13 +94,12 @@ void TileRender::onRender(const RenderState& rs) const
} }
const ElementTemplate * const et = tile.et; const ElementTemplate * const et = tile.et;
const float sw = et->w * tile.scalex;
const float sh = et->h * tile.scaley;
// adapted from RenderObject::isOnScreen() // adapted from RenderObject::isOnScreen()
{ {
const float cw = et->w * tile.scalex; const float cullRadiusSqr = ((sw*sw + sh*sh) * core->invGlobalScaleSqr) + core->cullRadiusSqr;
const float ch = et->h * tile.scaley;
const float cullRadiusSqr = ((cw*cw + ch*ch) * core->invGlobalScaleSqr) + core->cullRadiusSqr;
if ((pos - core->cullCenter).getSquaredLength2D() >= cullRadiusSqr) if ((pos - core->cullCenter).getSquaredLength2D() >= cullRadiusSqr)
continue; continue;
} }
@ -107,19 +125,23 @@ void TileRender::onRender(const RenderState& rs) const
glTranslatef(pos.x, pos.y, pos.z); glTranslatef(pos.x, pos.y, pos.z);
glRotatef(tile.rotation, 0, 0, 1); glRotatef(tile.rotation, 0, 0, 1);
if(tile.flags & TILEFLAG_FH) // TODO: This is not necessary! Since we have no children, flipped texcoords are fine if(tile.flags & TILEFLAG_FH)
glRotatef(180, 0, 1, 0); glRotatef(180, 0, 1, 0);
// this is only relevant in editor mode and is always 0 otherwise // this is only relevant in editor mode and is always 0 otherwise
glTranslatef(tile.beforeScaleOffsetX, tile.beforeScaleOffsetY, 0); //glTranslatef(tile.beforeScaleOffsetX, tile.beforeScaleOffsetY, 0);
glScalef(tile.scalex, tile.scaley, 1); glScalef(sw, sh, 1);
//glScalef(tile.scalex * et->w, tile.scaley * et->h, 1); // TODO use this + fixed verts
BlendType blend = BLEND_DEFAULT;
float alpha = rs.alpha; float alpha = rs.alpha;
RenderGrid *grid = NULL;
const TileEffectData * const eff = tile.eff; const TileEffectData * const eff = tile.eff;
if(eff != prevEff) // effects between tiles are often shared so this works not only for NULL
{
prevEff = eff;
BlendType blend = BLEND_DEFAULT;
alpha = rs.alpha;
grid = NULL;
if(eff) if(eff)
{ {
grid = eff->grid; grid = eff->grid;
@ -128,62 +150,44 @@ void TileRender::onRender(const RenderState& rs) const
} }
rs.gpu.setBlend(blend); rs.gpu.setBlend(blend);
// TODO: only need to do this when prev. tile had different alpha
glColor4f(rs.color.x, rs.color.y, rs.color.z, alpha); glColor4f(rs.color.x, rs.color.y, rs.color.z, alpha);
}
const Vector upperLeftTextureCoordinates(et->tu1, et->tv1);
const Vector lowerRightTextureCoordinates(et->tu2, et->tv2);
if(!grid) if(!grid)
{ {
const float _w2 = et->w * 0.5f; const float *tcbuf = tile.et->texcoordQuadPtr;
const float _h2 = et->h * 0.5f; assert(tcbuf);
if(lastTexcoordBuf != tcbuf)
glBegin(GL_QUADS);
{ {
glTexCoord2f(upperLeftTextureCoordinates.x, 1.0f-upperLeftTextureCoordinates.y); lastTexcoordBuf = tcbuf;
glVertex2f(-_w2, +_h2); glTexCoordPointer(2, GL_FLOAT, 0, tcbuf);
glTexCoord2f(lowerRightTextureCoordinates.x, 1.0f-upperLeftTextureCoordinates.y);
glVertex2f(+_w2, +_h2);
glTexCoord2f(lowerRightTextureCoordinates.x, 1.0f-lowerRightTextureCoordinates.y);
glVertex2f(+_w2, -_h2);
glTexCoord2f(upperLeftTextureCoordinates.x, 1.0f-lowerRightTextureCoordinates.y);
glVertex2f(-_w2, -_h2);
} }
glEnd(); glDrawArrays(GL_QUADS, 0, 4);
} }
else else
{ {
glPushMatrix();
glScalef(et->w, et->h, 1);
RenderState rx(rs);
rx.alpha = alpha; rx.alpha = alpha;
const Vector upperLeftTextureCoordinates(et->tu1, et->tv1);
const Vector lowerRightTextureCoordinates(et->tu2, et->tv2);
grid->render(rx, upperLeftTextureCoordinates, lowerRightTextureCoordinates); grid->render(rx, upperLeftTextureCoordinates, lowerRightTextureCoordinates);
if (RenderObject::renderCollisionShape)
{
glBindTexture(GL_TEXTURE_2D, 0);
grid->renderDebugPoints(rs);
lastTexId = 0;
} }
glPopMatrix(); if(renderExtras)
{
glBindTexture(GL_TEXTURE_2D, 0);
lastTexId = 0;
prevEff = ((TileEffectData*)NULL)+1;
if(grid && RenderObject::renderCollisionShape)
{
grid->renderDebugPoints(rs);
} }
if(renderBorders) if(renderBorders)
{ {
lastTexId = 0;
glBindTexture(GL_TEXTURE_2D, 0);
float c = (tile.flags & TILEFLAG_SELECTED) ? 1.0f : 0.5f; float c = (tile.flags & TILEFLAG_SELECTED) ? 1.0f : 0.5f;
Vector color(c,c,c); Vector color(c,c,c);
color *= getTagColor(tile.tag); color *= getTagColor(tile.tag);
const float _w2 = et->w * 0.5f;
const float _h2 = et->h * 0.5f;
glColor4f(color.x, color.y, color.z, 1.0f); glColor4f(color.x, color.y, color.z, 1.0f);
glPointSize(16); glPointSize(16);
@ -193,18 +197,20 @@ void TileRender::onRender(const RenderState& rs) const
glLineWidth(2); glLineWidth(2);
glBegin(GL_LINE_STRIP); glBegin(GL_LINE_STRIP);
glVertex2f(_w2, _h2); glVertex2f(0.5f, 0.5f);
glVertex2f(_w2, -_h2); glVertex2f(0.5f, -0.5f);
glVertex2f(-_w2, -_h2); glVertex2f(-0.5f, -0.5f);
glVertex2f(-_w2, _h2); glVertex2f(-0.5f, 0.5f);
glVertex2f(_w2, _h2); glVertex2f(0.5f, 0.5f);
glEnd(); glEnd();
} }
}
glPopMatrix(); glPopMatrix();
} }
glPopClientAttrib();
RenderObject::lastTextureApplied = lastTexId; RenderObject::lastTextureApplied = lastTexId;
RenderObject::lastTextureRepeat = !!lastTexRepeat; RenderObject::lastTextureRepeat = !!lastTexRepeat;
} }

View file

@ -16,7 +16,7 @@ Tileset::~Tileset()
bool Tileset::loadFile(const char *fn, const unsigned char *usedIdx, size_t usedIdxLen) bool Tileset::loadFile(const char *fn, const unsigned char *usedIdx, size_t usedIdxLen)
{ {
elementTemplates.clear(); clear();
InStream in(fn); InStream in(fn);
if(!in) if(!in)
@ -34,12 +34,12 @@ bool Tileset::loadFile(const char *fn, const unsigned char *usedIdx, size_t used
{ {
if(idx < 1024) if(idx < 1024)
{ {
ElementTemplate t; ElementTemplate *et = new ElementTemplate;
t.idx = idx; et->idx = idx;
t.gfx = gfx; et->gfx = gfx;
t.w = w; et->w = w;
t.h = h; et->h = h;
elementTemplates.push_back(t); elementTemplates.push_back(et);
} }
else else
warn = true; warn = true;
@ -59,9 +59,9 @@ bool Tileset::loadFile(const char *fn, const unsigned char *usedIdx, size_t used
for (size_t i = 0; i < elementTemplates.size(); i++) for (size_t i = 0; i < elementTemplates.size(); i++)
{ {
size_t idx = elementTemplates[i].idx; size_t idx = elementTemplates[i]->idx;
if (!usedIdx || (idx < usedIdxLen && usedIdx[idx])) if (!usedIdx || (idx < usedIdxLen && usedIdx[idx]))
usedTex.push_back(elementTemplates[i].gfx); usedTex.push_back(elementTemplates[i]->gfx);
} }
std::sort(usedTex.begin(), usedTex.end()); std::sort(usedTex.begin(), usedTex.end());
// drop duplicates // drop duplicates
@ -90,15 +90,16 @@ bool Tileset::loadFile(const char *fn, const unsigned char *usedIdx, size_t used
std::ostringstream failed; std::ostringstream failed;
for (size_t i = 0; i < elementTemplates.size(); i++) for (size_t i = 0; i < elementTemplates.size(); i++)
{ {
ElementTemplate& et = elementTemplates[i]; ElementTemplate *et = elementTemplates[i];
// only check those that are actualy loaded; otherwise this would load in textures // only check those that are actualy loaded; otherwise this would load in textures
// that we didn't bother to batch-load above // that we didn't bother to batch-load above
if(!usedIdx || (et.idx < usedIdxLen && usedIdx[et.idx])) if(!usedIdx || (et->idx < usedIdxLen && usedIdx[et->idx]))
{ {
if(!et.getTexture()) // assigns width/height and caches texture pointer et->finalize(); // assigns width/height and caches texture pointer
if(!et->tex)
{ {
++nfailed; ++nfailed;
failed << et.gfx << " "; failed << et->gfx << " ";
} }
} }
} }
@ -119,6 +120,9 @@ void Tileset::clear()
for(size_t i = 0; i < dummies.size(); ++i) for(size_t i = 0; i < dummies.size(); ++i)
delete dummies[i]; delete dummies[i];
dummies.clear(); dummies.clear();
for(size_t i = 0; i < elementTemplates.size(); ++i)
delete elementTemplates[i];
elementTemplates.clear(); elementTemplates.clear();
} }
@ -126,11 +130,11 @@ const ElementTemplate *Tileset::getByIdx(size_t idx)
{ {
for (size_t i = 0; i < elementTemplates.size(); i++) for (size_t i = 0; i < elementTemplates.size(); i++)
{ {
ElementTemplate& et = elementTemplates[i]; ElementTemplate *et = elementTemplates[i];
if (et.idx == idx) if (et->idx == idx)
{ {
et.getTexture(); // HACK: make sure the texture is loaded before this gets used et->finalize(); // HACK: make sure the texture is loaded before this gets used
return &et; return et;
} }
} }
@ -151,6 +155,7 @@ const ElementTemplate *Tileset::getByIdx(size_t idx)
ElementTemplate *dummy = new ElementTemplate; ElementTemplate *dummy = new ElementTemplate;
dummy->idx = idx; dummy->idx = idx;
dummy->finalize();
dummies.push_back(dummy); dummies.push_back(dummy);
return dummy; return dummy;
@ -160,16 +165,21 @@ const ElementTemplate* Tileset::getAdjacent(size_t idx, int direction, bool wrap
{ {
ElementTemplate *et = _getAdjacent(idx, direction, wraparound); ElementTemplate *et = _getAdjacent(idx, direction, wraparound);
if(et) if(et)
et->getTexture(); // load just in case et->finalize(); // load just in case
return et; return et;
} }
Texture* ElementTemplate::getTexture() static const float s_defaultTexcoordBuf[] =
{ {
if(loaded) 0, 1,
return tex.content(); 1, 1,
1, 0,
0, 0
};
loaded = true; void ElementTemplate::finalize()
{
if(!gfx.empty())
tex = core->getTexture(gfx); // may end up NULL tex = core->getTexture(gfx); // may end up NULL
if(tex) if(tex)
{ {
@ -186,8 +196,20 @@ Texture* ElementTemplate::getTexture()
h = 64; h = 64;
} }
return tex.content(); if(tu1 == 0 && tv1 == 0 && tu2 == 1 && tv2 == 1)
texcoordQuadPtr = s_defaultTexcoordBuf;
else
{
texcoordQuadPtr = &texcoordQuadBuffer[0];
texcoordQuadBuffer[0] = tu1;
texcoordQuadBuffer[1] = 1.0f-tv1;
texcoordQuadBuffer[2] = tu2;
texcoordQuadBuffer[3] = 1.0f-tv1;
texcoordQuadBuffer[4] = tu2;
texcoordQuadBuffer[5] = 1.0f-tv2;
texcoordQuadBuffer[6] = tu1;
texcoordQuadBuffer[7] = 1.0f-tv2;
}
} }
ElementTemplate * Tileset::_getAdjacent(size_t idx, int direction, bool wraparound) ElementTemplate * Tileset::_getAdjacent(size_t idx, int direction, bool wraparound)
@ -198,21 +220,21 @@ ElementTemplate * Tileset::_getAdjacent(size_t idx, int direction, bool wraparou
int mindiff = 0; int mindiff = 0;
for (size_t i = 0; i < maxn; i++) for (size_t i = 0; i < maxn; i++)
{ {
if (elementTemplates[i].idx == idx) if (elementTemplates[i]->idx == idx)
{ {
if(wraparound) if(wraparound)
{ {
if(!i && direction < 0) if(!i && direction < 0)
return &elementTemplates.back(); return elementTemplates.back();
if(i + direction >= maxn) if(i + direction >= maxn)
return &elementTemplates[0]; return elementTemplates[0];
} }
else else
i += direction; // may underflow i += direction; // may underflow
return i < maxn ? &elementTemplates[i] : NULL; return i < maxn ? elementTemplates[i] : NULL;
} }
int diff = labs((int)elementTemplates[i].idx - (int)idx); int diff = labs((int)elementTemplates[i]->idx - (int)idx);
if(diff < mindiff || !mindiff) if(diff < mindiff || !mindiff)
{ {
mindiff = diff; mindiff = diff;
@ -230,11 +252,11 @@ ElementTemplate * Tileset::_getAdjacent(size_t idx, int direction, bool wraparou
else if(wraparound) else if(wraparound)
{ {
if(!closest && direction < 0) if(!closest && direction < 0)
return &elementTemplates.back(); return elementTemplates.back();
if(closest + direction >= maxn) if(closest + direction >= maxn)
return &elementTemplates[0]; return elementTemplates[0];
} }
size_t i = closest + direction; size_t i = closest + direction;
return i < maxn ? &elementTemplates[i] : NULL; return i < maxn ? elementTemplates[i] : NULL;
} }

View file

@ -8,21 +8,24 @@
class ElementTemplate class ElementTemplate
{ {
public: public:
ElementTemplate() { w=0; h=0; idx=-1; tu1=tv1=0; tu2=tv2=1; loaded=false; } ElementTemplate() { w=0; h=0; idx=-1; tu1=tv1=0; tu2=tv2=1; texcoordQuadPtr=NULL; }
inline bool operator<(const ElementTemplate& o) const { return idx < o.idx; } inline bool operator<(const ElementTemplate& o) const { return idx < o.idx; }
Texture *getTexture(); // loads if not already loaded void finalize(); // call after settings params
// lazily assigned when tex is loaded // lazily assigned when tex is loaded
CountedPtr<Texture> tex; // NULL if failed to load or not yet loaded CountedPtr<Texture> tex; // NULL if failed to load or not yet loaded
float w,h; // custom size if used, otherwise texture size float w,h; // custom size if used, otherwise texture size
const float *texcoordQuadPtr;
float texcoordQuadBuffer[8];
// fixed // fixed
float tu1, tu2, tv1, tv2; // texcoords float tu1, tu2, tv1, tv2; // texcoords
size_t idx; size_t idx;
std::string gfx; std::string gfx;
bool loaded; private:
ElementTemplate(const ElementTemplate&); // no copy
}; };
class Tileset class Tileset
@ -43,7 +46,7 @@ public:
// never returns dummy ET. May return NULL. // never returns dummy ET. May return NULL.
const ElementTemplate *getAdjacent(size_t idx, int direction, bool wraparound); const ElementTemplate *getAdjacent(size_t idx, int direction, bool wraparound);
std::vector<ElementTemplate> elementTemplates; std::vector<ElementTemplate*> elementTemplates;
private: private:
ElementTemplate *_getAdjacent(size_t idx, int direction, bool wraparound); ElementTemplate *_getAdjacent(size_t idx, int direction, bool wraparound);