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:
parent
ab218ceca6
commit
9b1c3bba18
8 changed files with 171 additions and 140 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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),)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,104 +125,92 @@ 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)
|
if(eff != prevEff) // effects between tiles are often shared so this works not only for NULL
|
||||||
{
|
{
|
||||||
grid = eff->grid;
|
prevEff = eff;
|
||||||
alpha *= eff->alpha.x;
|
BlendType blend = BLEND_DEFAULT;
|
||||||
blend = eff->blend;
|
alpha = rs.alpha;
|
||||||
|
grid = NULL;
|
||||||
|
|
||||||
|
if(eff)
|
||||||
|
{
|
||||||
|
grid = eff->grid;
|
||||||
|
alpha *= eff->alpha.x;
|
||||||
|
blend = eff->blend;
|
||||||
|
}
|
||||||
|
|
||||||
|
rs.gpu.setBlend(blend);
|
||||||
|
glColor4f(rs.color.x, rs.color.y, rs.color.z, alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
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)
|
}
|
||||||
|
|
||||||
|
if(renderExtras)
|
||||||
|
{
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
lastTexId = 0;
|
||||||
|
prevEff = ((TileEffectData*)NULL)+1;
|
||||||
|
|
||||||
|
if(grid && RenderObject::renderCollisionShape)
|
||||||
{
|
{
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
grid->renderDebugPoints(rs);
|
grid->renderDebugPoints(rs);
|
||||||
lastTexId = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glPopMatrix();
|
if(renderBorders)
|
||||||
|
{
|
||||||
|
float c = (tile.flags & TILEFLAG_SELECTED) ? 1.0f : 0.5f;
|
||||||
|
Vector color(c,c,c);
|
||||||
|
color *= getTagColor(tile.tag);
|
||||||
|
|
||||||
|
glColor4f(color.x, color.y, color.z, 1.0f);
|
||||||
|
glPointSize(16);
|
||||||
|
glBegin(GL_POINTS);
|
||||||
|
glVertex2f(0,0);
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
glLineWidth(2);
|
||||||
|
glBegin(GL_LINE_STRIP);
|
||||||
|
glVertex2f(0.5f, 0.5f);
|
||||||
|
glVertex2f(0.5f, -0.5f);
|
||||||
|
glVertex2f(-0.5f, -0.5f);
|
||||||
|
glVertex2f(-0.5f, 0.5f);
|
||||||
|
glVertex2f(0.5f, 0.5f);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(renderBorders)
|
|
||||||
{
|
|
||||||
lastTexId = 0;
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
|
|
||||||
float c = (tile.flags & TILEFLAG_SELECTED) ? 1.0f : 0.5f;
|
|
||||||
Vector color(c,c,c);
|
|
||||||
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);
|
|
||||||
glPointSize(16);
|
|
||||||
glBegin(GL_POINTS);
|
|
||||||
glVertex2f(0,0);
|
|
||||||
glEnd();
|
|
||||||
|
|
||||||
glLineWidth(2);
|
|
||||||
glBegin(GL_LINE_STRIP);
|
|
||||||
glVertex2f(_w2, _h2);
|
|
||||||
glVertex2f(_w2, -_h2);
|
|
||||||
glVertex2f(-_w2, -_h2);
|
|
||||||
glVertex2f(-_w2, _h2);
|
|
||||||
glVertex2f(_w2, _h2);
|
|
||||||
glEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glPopClientAttrib();
|
||||||
|
|
||||||
RenderObject::lastTextureApplied = lastTexId;
|
RenderObject::lastTextureApplied = lastTexId;
|
||||||
RenderObject::lastTextureRepeat = !!lastTexRepeat;
|
RenderObject::lastTextureRepeat = !!lastTexRepeat;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,17 +165,22 @@ 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()
|
||||||
tex = core->getTexture(gfx); // may end up NULL
|
{
|
||||||
|
if(!gfx.empty())
|
||||||
|
tex = core->getTexture(gfx); // may end up NULL
|
||||||
if(tex)
|
if(tex)
|
||||||
{
|
{
|
||||||
if(!w)
|
if(!w)
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Reference in a new issue