1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2025-02-27 08:34:02 +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;
for (int i = 0; i < 27; i++)
{
ElementTemplate t;
t.idx = 1024+i;
t.tex = aqtex;
t.loaded = true;
ElementTemplate *et = new ElementTemplate;
et->idx = 1024+i;
et->tex = aqtex;
int x = i,y=0;
while (x >= 6)
{
@ -3523,19 +3522,20 @@ bool DSQ::loadTileset(std::string pack, const unsigned char *usedIdx, size_t use
y++;
}
t.tu1 = x*cell;
t.tv1 = y*cell;
t.tu2 = t.tu1 + cell;
t.tv2 = t.tv1 + cell;
et->tu1 = x*cell;
et->tv1 = y*cell;
et->tu2 = et->tu1 + cell;
et->tv2 = et->tv1 + cell;
t.tv2 = 1 - t.tv2;
t.tv1 = 1 - t.tv1;
std::swap(t.tv1,t.tv2);
et->tv2 = 1 - et->tv2;
et->tv1 = 1 - et->tv1;
std::swap(et->tv1,et->tv2);
t.w = 512*cell;
t.h = 512*cell;
et->w = 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())
{
placer->setTexture(dsq->tilemgr.tileset.elementTemplates[curElement].gfx);
placer->setTexture(dsq->tilemgr.tileset.elementTemplates[curElement]->gfx);
placer->scale = Vector(1,1);
}
else
@ -888,7 +888,7 @@ void SceneEditor::editModeElements()
editType = ET_ELEMENTS;
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->alpha = 0.5;
@ -2002,7 +2002,6 @@ void SceneEditor::cycleSelectedTiles(int direction)
const int maxn = (int)dsq->tilemgr.tileset.elementTemplates.size();
if(!maxn)
return;
const ElementTemplate * const base = &dsq->tilemgr.tileset.elementTemplates[0];
for(size_t i = 0; i < n; ++i)
{
TileData& t = ts.tiles[selectedTiles[i]];
@ -2093,9 +2092,9 @@ void SceneEditor::cyclePlacer(int direction)
if(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;
}
}
@ -2108,7 +2107,7 @@ void SceneEditor::selectZero()
{
if (dsq->tilemgr.tileset.elementTemplates.empty()) return;
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;
for (size_t i = 0; i < dsq->tilemgr.tileset.elementTemplates.size(); i++)
{
ElementTemplate et = dsq->tilemgr.tileset.elementTemplates[i];
if (et.idx < 1024 && i > largest)
ElementTemplate *et = dsq->tilemgr.tileset.elementTemplates[i];
if (et->idx < 1024 && i > largest)
{
largest = i;
}
}
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))
{
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);
// FIXME: need to update grid or no?
updateText();

View file

@ -187,8 +187,8 @@ TileData* TileMgr::_createTile(unsigned tilesetID, unsigned layer, float x, flo
t.texscaleY = 1;
t.scalex = 1;
t.scaley = 1;
t.beforeScaleOffsetX = 0;
t.beforeScaleOffsetY = 0;
//t.beforeScaleOffsetX = 0;
//t.beforeScaleOffsetY = 0;
t.flags = GetTileFlags(ef);
t.tag = 0;
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,glColor3f,(GLfloat r,GLfloat g,GLfloat b),(r,g,b),)
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(GLuint,glGenLists,(GLsizei range),(range),return)
GL_FUNC(void,glNewList,(GLuint list, GLenum mode),(list,mode),)

View file

@ -134,7 +134,7 @@ private:
struct TileData
{
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;
unsigned flags; // TileFlags
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
{
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
const RenderObjectLayer& rl = core->renderObjectLayers[this->layer];
const Vector M = rl.followCameraMult; // affected by parallaxLock
@ -58,8 +75,10 @@ void TileRender::onRender(const RenderState& rs) const
unsigned lastTexRepeat = false;
unsigned lastTexId = 0;
const bool renderBorders = this->renderBorders;
//bool mustSetColor = false;
const bool renderExtras = renderBorders || RenderObject::renderCollisionShape;
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)
{
@ -75,13 +94,12 @@ void TileRender::onRender(const RenderState& rs) const
}
const ElementTemplate * const et = tile.et;
const float sw = et->w * tile.scalex;
const float sh = et->h * tile.scaley;
// adapted from RenderObject::isOnScreen()
{
const float cw = et->w * tile.scalex;
const float ch = et->h * tile.scaley;
const float cullRadiusSqr = ((cw*cw + ch*ch) * core->invGlobalScaleSqr) + core->cullRadiusSqr;
const float cullRadiusSqr = ((sw*sw + sh*sh) * core->invGlobalScaleSqr) + core->cullRadiusSqr;
if ((pos - core->cullCenter).getSquaredLength2D() >= cullRadiusSqr)
continue;
}
@ -107,19 +125,23 @@ void TileRender::onRender(const RenderState& rs) const
glTranslatef(pos.x, pos.y, pos.z);
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);
// 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(tile.scalex * et->w, tile.scaley * et->h, 1); // TODO use this + fixed verts
glScalef(sw, sh, 1);
BlendType blend = BLEND_DEFAULT;
float alpha = rs.alpha;
RenderGrid *grid = NULL;
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)
{
grid = eff->grid;
@ -128,62 +150,44 @@ void TileRender::onRender(const RenderState& rs) const
}
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)
{
const float _w2 = et->w * 0.5f;
const float _h2 = et->h * 0.5f;
glBegin(GL_QUADS);
const float *tcbuf = tile.et->texcoordQuadPtr;
assert(tcbuf);
if(lastTexcoordBuf != tcbuf)
{
glTexCoord2f(upperLeftTextureCoordinates.x, 1.0f-upperLeftTextureCoordinates.y);
glVertex2f(-_w2, +_h2);
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);
lastTexcoordBuf = tcbuf;
glTexCoordPointer(2, GL_FLOAT, 0, tcbuf);
}
glEnd();
glDrawArrays(GL_QUADS, 0, 4);
}
else
{
glPushMatrix();
glScalef(et->w, et->h, 1);
RenderState rx(rs);
rx.alpha = alpha;
const Vector upperLeftTextureCoordinates(et->tu1, et->tv1);
const Vector lowerRightTextureCoordinates(et->tu2, et->tv2);
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)
{
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);
@ -193,18 +197,20 @@ void TileRender::onRender(const RenderState& rs) const
glLineWidth(2);
glBegin(GL_LINE_STRIP);
glVertex2f(_w2, _h2);
glVertex2f(_w2, -_h2);
glVertex2f(-_w2, -_h2);
glVertex2f(-_w2, _h2);
glVertex2f(_w2, _h2);
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();
}
}
glPopMatrix();
}
glPopClientAttrib();
RenderObject::lastTextureApplied = lastTexId;
RenderObject::lastTextureRepeat = !!lastTexRepeat;
}

View file

@ -16,7 +16,7 @@ Tileset::~Tileset()
bool Tileset::loadFile(const char *fn, const unsigned char *usedIdx, size_t usedIdxLen)
{
elementTemplates.clear();
clear();
InStream in(fn);
if(!in)
@ -34,12 +34,12 @@ bool Tileset::loadFile(const char *fn, const unsigned char *usedIdx, size_t used
{
if(idx < 1024)
{
ElementTemplate t;
t.idx = idx;
t.gfx = gfx;
t.w = w;
t.h = h;
elementTemplates.push_back(t);
ElementTemplate *et = new ElementTemplate;
et->idx = idx;
et->gfx = gfx;
et->w = w;
et->h = h;
elementTemplates.push_back(et);
}
else
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++)
{
size_t idx = elementTemplates[i].idx;
size_t idx = elementTemplates[i]->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());
// drop duplicates
@ -90,15 +90,16 @@ bool Tileset::loadFile(const char *fn, const unsigned char *usedIdx, size_t used
std::ostringstream failed;
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
// 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;
failed << et.gfx << " ";
failed << et->gfx << " ";
}
}
}
@ -119,6 +120,9 @@ void Tileset::clear()
for(size_t i = 0; i < dummies.size(); ++i)
delete dummies[i];
dummies.clear();
for(size_t i = 0; i < elementTemplates.size(); ++i)
delete elementTemplates[i];
elementTemplates.clear();
}
@ -126,11 +130,11 @@ const ElementTemplate *Tileset::getByIdx(size_t idx)
{
for (size_t i = 0; i < elementTemplates.size(); i++)
{
ElementTemplate& et = elementTemplates[i];
if (et.idx == idx)
ElementTemplate *et = elementTemplates[i];
if (et->idx == idx)
{
et.getTexture(); // HACK: make sure the texture is loaded before this gets used
return &et;
et->finalize(); // HACK: make sure the texture is loaded before this gets used
return et;
}
}
@ -151,6 +155,7 @@ const ElementTemplate *Tileset::getByIdx(size_t idx)
ElementTemplate *dummy = new ElementTemplate;
dummy->idx = idx;
dummy->finalize();
dummies.push_back(dummy);
return dummy;
@ -160,16 +165,21 @@ const ElementTemplate* Tileset::getAdjacent(size_t idx, int direction, bool wrap
{
ElementTemplate *et = _getAdjacent(idx, direction, wraparound);
if(et)
et->getTexture(); // load just in case
et->finalize(); // load just in case
return et;
}
Texture* ElementTemplate::getTexture()
static const float s_defaultTexcoordBuf[] =
{
if(loaded)
return tex.content();
0, 1,
1, 1,
1, 0,
0, 0
};
loaded = true;
void ElementTemplate::finalize()
{
if(!gfx.empty())
tex = core->getTexture(gfx); // may end up NULL
if(tex)
{
@ -186,8 +196,20 @@ Texture* ElementTemplate::getTexture()
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)
@ -198,21 +220,21 @@ ElementTemplate * Tileset::_getAdjacent(size_t idx, int direction, bool wraparou
int mindiff = 0;
for (size_t i = 0; i < maxn; i++)
{
if (elementTemplates[i].idx == idx)
if (elementTemplates[i]->idx == idx)
{
if(wraparound)
{
if(!i && direction < 0)
return &elementTemplates.back();
return elementTemplates.back();
if(i + direction >= maxn)
return &elementTemplates[0];
return elementTemplates[0];
}
else
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)
{
mindiff = diff;
@ -230,11 +252,11 @@ ElementTemplate * Tileset::_getAdjacent(size_t idx, int direction, bool wraparou
else if(wraparound)
{
if(!closest && direction < 0)
return &elementTemplates.back();
return elementTemplates.back();
if(closest + direction >= maxn)
return &elementTemplates[0];
return elementTemplates[0];
}
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
{
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; }
Texture *getTexture(); // loads if not already loaded
void finalize(); // call after settings params
// lazily assigned when tex is loaded
CountedPtr<Texture> tex; // NULL if failed to load or not yet loaded
float w,h; // custom size if used, otherwise texture size
const float *texcoordQuadPtr;
float texcoordQuadBuffer[8];
// fixed
float tu1, tu2, tv1, tv2; // texcoords
size_t idx;
std::string gfx;
bool loaded;
private:
ElementTemplate(const ElementTemplate&); // no copy
};
class Tileset
@ -43,7 +46,7 @@ public:
// never returns dummy ET. May return NULL.
const ElementTemplate *getAdjacent(size_t idx, int direction, bool wraparound);
std::vector<ElementTemplate> elementTemplates;
std::vector<ElementTemplate*> elementTemplates;
private:
ElementTemplate *_getAdjacent(size_t idx, int direction, bool wraparound);