mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2024-11-29 03:33:48 +00:00
fix tile repeat, works now
This commit is contained in:
parent
9b1c3bba18
commit
1da28ec40a
5 changed files with 142 additions and 19 deletions
|
@ -277,8 +277,11 @@ public:
|
|||
q->setTexturePointer(t.et->tex);
|
||||
q->fhTo(!!(t.flags & TILEFLAG_FH));
|
||||
q->rotation.z = t.rotation;
|
||||
q->repeatToFillScale = Vector(t.texscaleX, t.texscaleY);
|
||||
q->repeatTextureToFill(!!(t.flags & TILEFLAG_REPEAT));
|
||||
if(t.flags & TILEFLAG_REPEAT && t.rep)
|
||||
{
|
||||
q->repeatToFillScale = Vector(t.rep->texscaleX, t.rep->texscaleY);
|
||||
q->repeatTextureToFill(true);
|
||||
}
|
||||
th->addChild(q, PM_POINTER, RBP_ON);
|
||||
th->_quads.push_back(q);
|
||||
}
|
||||
|
@ -1046,7 +1049,9 @@ void SceneEditor::enterAnyStateHelper(EditorStates newstate)
|
|||
if(selectedTiles.size() == 1)
|
||||
{
|
||||
const TileData& t = getCurrentLayerTiles().tiles[selectedTiles[0]];
|
||||
oldRepeatScale = Vector(t.texscaleX, t.texscaleY);
|
||||
oldRepeatScale = Vector(1,1);
|
||||
if(t.flags & TILEFLAG_REPEAT)
|
||||
oldRepeatScale = Vector(t.rep->texscaleX, t.rep->texscaleY);
|
||||
oldScale = Vector(t.scalex, t.scaley);
|
||||
oldRotation = t.rotation;
|
||||
}
|
||||
|
|
|
@ -123,13 +123,11 @@ void TileMgr::createTiles(const TileDef* defs, size_t n)
|
|||
if(d.fh)
|
||||
t->flags |= TILEFLAG_FH;
|
||||
if(d.repeat)
|
||||
t->flags |= TILEFLAG_REPEAT;
|
||||
t->setRepeatOn(d.rsx, d.rsy);
|
||||
|
||||
// FIXME: handle fv
|
||||
|
||||
t->rotation = d.rot;
|
||||
t->texscaleX = d.rsx;
|
||||
t->texscaleY = d.rsy;
|
||||
t->tag = d.tag;
|
||||
t->scalex = d.sx;
|
||||
t->scaley = d.sy;
|
||||
|
@ -183,8 +181,6 @@ TileData* TileMgr::_createTile(unsigned tilesetID, unsigned layer, float x, flo
|
|||
t.x = x;
|
||||
t.y = y;
|
||||
t.rotation = 0;
|
||||
t.texscaleX = 1;
|
||||
t.texscaleY = 1;
|
||||
t.scalex = 1;
|
||||
t.scaley = 1;
|
||||
//t.beforeScaleOffsetX = 0;
|
||||
|
@ -273,6 +269,11 @@ TileDef::TileDef(unsigned lr, const TileData& t)
|
|||
, repeat(!!(t.flags & TILEFLAG_REPEAT))
|
||||
, tag(t.tag)
|
||||
, sx(t.scalex), sy(t.scaley)
|
||||
, rsx(t.texscaleX), rsy(t.texscaleY)
|
||||
, rsx(1), rsy(1)
|
||||
{
|
||||
if(t.flags & TILEFLAG_REPEAT)
|
||||
{
|
||||
rsx = t.rep->texscaleX;
|
||||
rsy = t.rep->texscaleY;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "Tileset.h"
|
||||
#include "Base.h"
|
||||
#include <algorithm>
|
||||
#include "Texture.h"
|
||||
|
||||
TileStorage::TileStorage()
|
||||
{
|
||||
|
@ -133,7 +134,7 @@ size_t TileStorage::moveToOther(TileStorage& other, const size_t *indices, size_
|
|||
return firstNewIdx;
|
||||
}
|
||||
|
||||
static void dropAttachments(TileData& t)
|
||||
static void dropEffect(TileData& t)
|
||||
{
|
||||
if(t.flags & TILEFLAG_OWN_EFFDATA)
|
||||
{
|
||||
|
@ -143,6 +144,23 @@ static void dropAttachments(TileData& t)
|
|||
t.eff = NULL;
|
||||
}
|
||||
|
||||
static void dropRepeat(TileData& t)
|
||||
{
|
||||
if(t.flags & TILEFLAG_OWN_REPEAT)
|
||||
{
|
||||
delete t.rep;
|
||||
t.flags &= ~TILEFLAG_OWN_REPEAT;
|
||||
}
|
||||
t.rep = NULL;
|
||||
}
|
||||
|
||||
static void dropAll(TileData& t)
|
||||
{
|
||||
dropEffect(t);
|
||||
dropRepeat(t);
|
||||
}
|
||||
|
||||
|
||||
void TileStorage::deleteSome(const size_t* indices, size_t n)
|
||||
{
|
||||
std::vector<TileData> tmp;
|
||||
|
@ -154,7 +172,7 @@ void TileStorage::deleteSome(const size_t* indices, size_t n)
|
|||
for(size_t k = 0; k < n; ++i) // not particularly efficient, could be much better by sorting first but eh
|
||||
if(indices[k] == i)
|
||||
{
|
||||
dropAttachments(tmp[i]);
|
||||
dropAll(tmp[i]);
|
||||
goto skip;
|
||||
}
|
||||
|
||||
|
@ -170,7 +188,7 @@ void TileStorage::destroyAll()
|
|||
{
|
||||
const size_t n = tiles.size();
|
||||
for(size_t i = 0; i < n; ++i)
|
||||
dropAttachments(tiles[i]);
|
||||
dropAll(tiles[i]);
|
||||
tiles.clear();
|
||||
indicesToCollide.clear();
|
||||
indicesToUpdate.clear();
|
||||
|
@ -221,6 +239,10 @@ size_t TileStorage::cloneSome(const TileEffectStorage& effstore, const size_t* i
|
|||
t.flags &= TILEFLAG_OWN_EFFDATA;
|
||||
effstore.assignEffect(t, efx); // recreate effect properly
|
||||
}
|
||||
if((t.flags & TILEFLAG_OWN_REPEAT) && t.rep)
|
||||
{
|
||||
t.rep = new TileRepeatData(*t.rep);
|
||||
}
|
||||
}
|
||||
|
||||
refreshAll();
|
||||
|
@ -236,7 +258,8 @@ void TileStorage::refreshAll()
|
|||
const size_t n = tiles.size();
|
||||
for(size_t i = 0; i < n; ++i)
|
||||
{
|
||||
const TileData& t = tiles[i];
|
||||
TileData& t = tiles[i];
|
||||
t.refreshRepeat();
|
||||
if(!(t.flags & TILEFLAG_HIDDEN))
|
||||
{
|
||||
if(const TileEffectData *e = t.eff)
|
||||
|
@ -434,7 +457,7 @@ TileEffectStorage::~TileEffectStorage()
|
|||
|
||||
void TileEffectStorage::assignEffect(TileData& t, int index) const
|
||||
{
|
||||
dropAttachments(t);
|
||||
dropEffect(t);
|
||||
|
||||
if(index < 0)
|
||||
return;
|
||||
|
@ -507,3 +530,65 @@ bool TileData::isCoordinateInside(float cx, float cy, float minsize) const
|
|||
return cx >= x - hw && cx <= x + hw
|
||||
&& cy >= y - hh && cy <= y + hh;
|
||||
}
|
||||
|
||||
void TileRepeatData::refresh(const ElementTemplate& et, float scalex, float scaley)
|
||||
{
|
||||
float tw, th;
|
||||
if(et.tex)
|
||||
{
|
||||
tw = et.tex->width;
|
||||
th = et.tex->height;
|
||||
}
|
||||
else
|
||||
{
|
||||
tw = et.w;
|
||||
th = et.h;
|
||||
}
|
||||
|
||||
const float tu1 = texOffX;
|
||||
const float tv1 = texOffY;
|
||||
const float tu2 = (et.w*scalex*texscaleX)/tw + texOffX;
|
||||
const float tv2 = (et.h*scaley*texscaleY)/th + texOffY;
|
||||
|
||||
this->tu1 = tu1;
|
||||
this->tv1 = tv1;
|
||||
this->tu2 = tu2;
|
||||
this->tv2 = tv2;
|
||||
|
||||
texcoords[0] = tu1;
|
||||
texcoords[1] = 1.0f-tv1;
|
||||
texcoords[2] = tu2;
|
||||
texcoords[3] = 1.0f-tv1;
|
||||
texcoords[4] = tu2;
|
||||
texcoords[5] = 1.0f-tv2;
|
||||
texcoords[6] = tu1;
|
||||
texcoords[7] = 1.0f-tv2;
|
||||
}
|
||||
|
||||
TileRepeatData* TileData::setRepeatOn(float texscalex, float texscaley, float offx, float offy)
|
||||
{
|
||||
if(rep && !(flags & TILEFLAG_OWN_REPEAT))
|
||||
rep = NULL;
|
||||
flags |= (TILEFLAG_OWN_REPEAT | TILEFLAG_REPEAT);
|
||||
if(!rep)
|
||||
rep = new TileRepeatData;
|
||||
rep->texscaleX = texscalex;
|
||||
rep->texscaleY = texscaley;
|
||||
rep->texOffX = offx;
|
||||
rep->texOffY = offy;
|
||||
rep->refresh(*et, scalex, scaley);
|
||||
return rep;
|
||||
}
|
||||
|
||||
void TileData::setRepeatOff()
|
||||
{
|
||||
flags &= ~TILEFLAG_REPEAT;
|
||||
}
|
||||
|
||||
void TileData::refreshRepeat()
|
||||
{
|
||||
if((flags & TILEFLAG_OWN_REPEAT) && rep)
|
||||
{
|
||||
rep->refresh(*et, scalex, scaley);
|
||||
}
|
||||
}
|
||||
|
|
23
BBGE/Tile.h
23
BBGE/Tile.h
|
@ -94,7 +94,8 @@ enum TileFlags
|
|||
TILEFLAG_OWN_EFFDATA = 0x40, // tile owns its TileEffectData, can update, must delete
|
||||
TILEFLAG_HIDDEN = 0x80, // don't render tile
|
||||
TILEFLAG_SELECTED = 0x100, // ephemeral: selected in editor
|
||||
TILEFLAG_EDITOR_HIDDEN = 0x200 // tile is hidden for editor reasons. temporarily set when multi-selecting and moving. doesn't count as hidden externally and is only for rendering.
|
||||
TILEFLAG_EDITOR_HIDDEN = 0x200, // tile is hidden for editor reasons. temporarily set when multi-selecting and moving. doesn't count as hidden externally and is only for rendering.
|
||||
TILEFLAG_OWN_REPEAT = 0x400 // owns TileRepeatData, may update, must delete
|
||||
};
|
||||
|
||||
struct TileData;
|
||||
|
@ -128,23 +129,41 @@ private:
|
|||
TileEffectData(const TileEffectData&); // no-copy
|
||||
};
|
||||
|
||||
struct TileRepeatData
|
||||
{
|
||||
// written via refresh()
|
||||
float texcoords[8];
|
||||
float tu1, tv1, tu2, tv2;
|
||||
|
||||
// set by user
|
||||
float texscaleX, texscaleY;
|
||||
float texOffX, texOffY;
|
||||
|
||||
// pass ET & scale of owning tile
|
||||
void refresh(const ElementTemplate& et, float scalex, float scaley);
|
||||
};
|
||||
|
||||
// POD and as compact as possible. Intended for rendering as quickly as possible.
|
||||
// the idea is that these are linearly adjacent in memory in the order they are rendered,
|
||||
// to maximize cache & prefetch efficiency
|
||||
struct TileData
|
||||
{
|
||||
float x, y, scalex, scaley, texscaleX, texscaleY;
|
||||
float x, y, scalex, scaley;
|
||||
//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
|
||||
const ElementTemplate *et; // never NULL. texture, texcoords, etc is here. // TODO: maybe replace with unsigned tilesetID? but that's an extra indirection or two during rendering...
|
||||
TileEffectData *eff; // mostly NULL
|
||||
TileRepeatData *rep;
|
||||
|
||||
// helpers for external access
|
||||
inline void setVisible(bool on) { if(on) flags &= ~TILEFLAG_HIDDEN; else flags |= TILEFLAG_HIDDEN; }
|
||||
inline bool isVisible() const { return !(flags & TILEFLAG_HIDDEN); }
|
||||
bool isCoordinateInside(float cx, float cy, float minsize = 0) const;
|
||||
TileRepeatData *setRepeatOn(float texscalex = 1, float texscaley = 1, float offx = 0, float offy = 0);
|
||||
void setRepeatOff();
|
||||
void refreshRepeat();
|
||||
};
|
||||
|
||||
class TileEffectStorage
|
||||
|
|
|
@ -155,7 +155,9 @@ void TileRender::onRender(const RenderState& rs) const
|
|||
|
||||
if(!grid)
|
||||
{
|
||||
const float *tcbuf = tile.et->texcoordQuadPtr;
|
||||
const float *tcbuf = (tile.flags & TILEFLAG_REPEAT)
|
||||
? &tile.rep->texcoords[0]
|
||||
: tile.et->texcoordQuadPtr;
|
||||
assert(tcbuf);
|
||||
if(lastTexcoordBuf != tcbuf)
|
||||
{
|
||||
|
@ -167,8 +169,19 @@ void TileRender::onRender(const RenderState& rs) const
|
|||
else
|
||||
{
|
||||
rx.alpha = alpha;
|
||||
const Vector upperLeftTextureCoordinates(et->tu1, et->tv1);
|
||||
const Vector lowerRightTextureCoordinates(et->tu2, et->tv2);
|
||||
|
||||
Vector upperLeftTextureCoordinates, lowerRightTextureCoordinates;
|
||||
if(tile.flags & TILEFLAG_REPEAT)
|
||||
{
|
||||
upperLeftTextureCoordinates = Vector(tile.rep->tu1, tile.rep->tv1);
|
||||
lowerRightTextureCoordinates = Vector(tile.rep->tu2, tile.rep->tv2);
|
||||
}
|
||||
else
|
||||
{
|
||||
upperLeftTextureCoordinates = Vector(et->tu1, et->tv1);
|
||||
lowerRightTextureCoordinates = Vector(et->tu2, et->tv2);
|
||||
}
|
||||
|
||||
grid->render(rx, upperLeftTextureCoordinates, lowerRightTextureCoordinates);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue