mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2024-11-25 09:44:02 +00:00
wip towards Element draw refactor; still using old render path
This commit is contained in:
parent
578c8ecc45
commit
c09098e13c
12 changed files with 444 additions and 151 deletions
169
Aquaria/Game.cpp
169
Aquaria/Game.cpp
|
@ -318,14 +318,7 @@ void Game::transitionToScene(std::string scene)
|
|||
|
||||
ElementTemplate *Game::getElementTemplateByIdx(size_t idx)
|
||||
{
|
||||
for (size_t i = 0; i < elementTemplates.size(); i++)
|
||||
{
|
||||
if (elementTemplates[i].idx == idx)
|
||||
{
|
||||
return &elementTemplates[i];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return tileset.getByIdx(idx);
|
||||
}
|
||||
|
||||
Element* Game::createElement(size_t idx, Vector position, size_t bgLayer, RenderObject *copy, ElementTemplate *et)
|
||||
|
@ -338,8 +331,7 @@ Element* Game::createElement(size_t idx, Vector position, size_t bgLayer, Render
|
|||
Element *element = new Element();
|
||||
if (et)
|
||||
{
|
||||
element->setTexture(et->gfx);
|
||||
element->alpha = et->alpha;
|
||||
element->setTexturePointer(et->getTexture());
|
||||
}
|
||||
|
||||
element->position = position;
|
||||
|
@ -377,7 +369,6 @@ Element* Game::createElement(size_t idx, Vector position, size_t bgLayer, Render
|
|||
}
|
||||
addRenderObject(element, LR_ELEMENTS1+bgLayer);
|
||||
dsq->addElement(element);
|
||||
//element->updateCullVariables();
|
||||
|
||||
return element;
|
||||
}
|
||||
|
@ -1335,6 +1326,8 @@ bool Game::loadSceneXML(std::string scene)
|
|||
}
|
||||
clearObsRows();
|
||||
|
||||
std::string tilesetToLoad;
|
||||
|
||||
XMLElement *level = doc.FirstChildElement("Level");
|
||||
if (level)
|
||||
{
|
||||
|
@ -1344,7 +1337,7 @@ bool Game::loadSceneXML(std::string scene)
|
|||
tileset = level->Attribute("elementTemplatePack"); // legacy, still present in some very old maps
|
||||
if (tileset)
|
||||
{
|
||||
loadElementTemplates(tileset);
|
||||
tilesetToLoad = tileset;
|
||||
levelSF->SetAttribute("tileset", tileset);
|
||||
}
|
||||
else
|
||||
|
@ -1756,6 +1749,7 @@ bool Game::loadSceneXML(std::string scene)
|
|||
if(fullTilesetReload)
|
||||
{
|
||||
fullTilesetReload = false;
|
||||
tileset.clear();
|
||||
// used by SceneEditor
|
||||
// no elements exist right now -> textures will be cleared and reloaded
|
||||
dsq->texmgr.clearUnused();
|
||||
|
@ -1763,6 +1757,10 @@ bool Game::loadSceneXML(std::string scene)
|
|||
|
||||
// figure out which textures in the tileset are used and preload those that are actually used
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "Scene has " << elemsDefs.size() << " elements";
|
||||
debugLog(os.str());
|
||||
|
||||
unsigned char usedIdx[1024] = {0};
|
||||
for(size_t i = 0; i < elemsDefs.size(); ++i)
|
||||
{
|
||||
|
@ -1770,27 +1768,8 @@ bool Game::loadSceneXML(std::string scene)
|
|||
if(idx < Countof(usedIdx))
|
||||
usedIdx[idx] = 1;
|
||||
}
|
||||
std::vector<std::string> usedTex;
|
||||
usedTex.reserve(elementTemplates.size()); // optimistically assume all textures in the tileset are used
|
||||
|
||||
for (size_t i = 0; i < elementTemplates.size(); i++)
|
||||
{
|
||||
unsigned idx = elementTemplates[i].idx;
|
||||
if (idx < Countof(usedIdx) && usedIdx[idx])
|
||||
usedTex.push_back(elementTemplates[i].gfx);
|
||||
}
|
||||
std::sort(usedTex.begin(), usedTex.end());
|
||||
// drop duplicates
|
||||
usedTex.resize(std::distance(usedTex.begin(), std::unique(usedTex.begin(), usedTex.end())));
|
||||
|
||||
std::ostringstream os;
|
||||
os << "Scene has " << elemsDefs.size() << " elements that use " << usedTex.size()
|
||||
<< " distinct textures out of the " << elementTemplates.size() << " entries in the tileset";
|
||||
debugLog(os.str());
|
||||
|
||||
// preload all used textures
|
||||
if(usedTex.size())
|
||||
dsq->texmgr.loadBatch(NULL, &usedTex[0], usedTex.size());
|
||||
loadElementTemplates(tilesetToLoad, &usedIdx[0], Countof(usedIdx));
|
||||
}
|
||||
|
||||
// Now that all SE tags have been processed, spawn them
|
||||
|
@ -4690,79 +4669,55 @@ void Game::snapCam()
|
|||
warpCameraTo(*cameraFollow);
|
||||
}
|
||||
|
||||
ElementTemplate Game::getElementTemplateForLetter(int i)
|
||||
{
|
||||
float cell = 64.0f/512.0f;
|
||||
//for (int i = 0; i < 27; i++)
|
||||
ElementTemplate t;
|
||||
t.idx = 1024+i;
|
||||
t.gfx = "Aquarian";
|
||||
int x = i,y=0;
|
||||
while (x >= 6)
|
||||
{
|
||||
x -= 6;
|
||||
y++;
|
||||
}
|
||||
|
||||
t.tu1 = x*cell;
|
||||
t.tv1 = y*cell;
|
||||
t.tu2 = t.tu1 + cell;
|
||||
t.tv2 = t.tv1 + cell;
|
||||
|
||||
t.tv2 = 1 - t.tv2;
|
||||
t.tv1 = 1 - t.tv1;
|
||||
std::swap(t.tv1,t.tv2);
|
||||
|
||||
t.w = 512*cell;
|
||||
t.h = 512*cell;
|
||||
//elementTemplates.push_back(t);
|
||||
return t;
|
||||
}
|
||||
|
||||
void Game::loadElementTemplates(std::string pack)
|
||||
bool Game::loadElementTemplates(std::string pack, const unsigned char *usedIdx, size_t usedIdxLen)
|
||||
{
|
||||
stringToLower(pack);
|
||||
|
||||
elementTemplates.clear();
|
||||
|
||||
std::string fn;
|
||||
if (dsq->mod.isActive())
|
||||
fn = dsq->mod.getPath() + "tilesets/" + pack + ".txt";
|
||||
else
|
||||
fn = "data/tilesets/" + pack + ".txt";
|
||||
|
||||
if (!exists(fn))
|
||||
if(!tileset.loadFile(fn.c_str(), usedIdx, usedIdxLen))
|
||||
{
|
||||
errorLog ("Could not open tileset [" + fn + "]");
|
||||
return;
|
||||
errorLog ("Could not load tileset [" + fn + "]");
|
||||
return false;
|
||||
}
|
||||
|
||||
InStream in(fn.c_str());
|
||||
std::string line;
|
||||
while (std::getline(in, line))
|
||||
// Aquarian alphabet letters
|
||||
if(const CountedPtr<Texture> aqtex = dsq->getTexture("aquarian"))
|
||||
{
|
||||
int idx=-1, w=-1, h=-1;
|
||||
std::string gfx;
|
||||
std::istringstream is(line);
|
||||
is >> idx >> gfx >> w >> h;
|
||||
ElementTemplate t;
|
||||
t.idx = idx;
|
||||
t.gfx = gfx;
|
||||
if (w==0) w=-1;
|
||||
if (h==0) h=-1;
|
||||
t.w = w;
|
||||
t.h = h;
|
||||
elementTemplates.push_back(t);
|
||||
const float cell = 64.0f/512.0f;
|
||||
for (int i = 0; i < 27; i++)
|
||||
{
|
||||
ElementTemplate t;
|
||||
t.idx = 1024+i;
|
||||
t.tex = aqtex;
|
||||
int x = i,y=0;
|
||||
while (x >= 6)
|
||||
{
|
||||
x -= 6;
|
||||
y++;
|
||||
}
|
||||
|
||||
t.tu1 = x*cell;
|
||||
t.tv1 = y*cell;
|
||||
t.tu2 = t.tu1 + cell;
|
||||
t.tv2 = t.tv1 + cell;
|
||||
|
||||
t.tv2 = 1 - t.tv2;
|
||||
t.tv1 = 1 - t.tv1;
|
||||
std::swap(t.tv1,t.tv2);
|
||||
|
||||
t.w = 512*cell;
|
||||
t.h = 512*cell;
|
||||
|
||||
tileset.elementTemplates.push_back(t);
|
||||
}
|
||||
}
|
||||
in.close();
|
||||
|
||||
|
||||
std::sort(elementTemplates.begin(), elementTemplates.end());
|
||||
|
||||
for (int i = 0; i < 27; i++)
|
||||
{
|
||||
elementTemplates.push_back(getElementTemplateForLetter(i));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Game::clearGrid(int v)
|
||||
|
@ -4778,40 +4733,6 @@ void Game::resetFromTitle()
|
|||
overrideMusic = "";
|
||||
}
|
||||
|
||||
void Game::setGrid(ElementTemplate *et, Vector position, float rot360)
|
||||
{
|
||||
for (size_t i = 0; i < et->grid.size(); i++)
|
||||
{
|
||||
TileVector t(position);
|
||||
int x = et->grid[i].x;
|
||||
int y = et->grid[i].y;
|
||||
if (rot360 >= 0 && rot360 < 90)
|
||||
{
|
||||
}
|
||||
else if (rot360 >= 90 && rot360 < 180)
|
||||
{
|
||||
int swap = y;
|
||||
y = x;
|
||||
x = swap;
|
||||
x = -x;
|
||||
}
|
||||
else if (rot360 >= 180 && rot360 < 270)
|
||||
{
|
||||
x = -x;
|
||||
y = -y;
|
||||
}
|
||||
else if (rot360 >= 270 && rot360 < 360)
|
||||
{
|
||||
int swap = y;
|
||||
y = x;
|
||||
x = swap;
|
||||
y = -y;
|
||||
}
|
||||
TileVector s(t.x+x, t.y+y);
|
||||
setGrid(s, OT_INVISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
void Game::removeState()
|
||||
{
|
||||
const float fadeTime = 0.25;
|
||||
|
|
|
@ -28,6 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "ScriptedEntity.h"
|
||||
#include "TileVector.h"
|
||||
#include "SceneEditor.h"
|
||||
#include "Tileset.h"
|
||||
|
||||
#include <tinyxml2.h>
|
||||
using namespace tinyxml2;
|
||||
|
@ -84,20 +85,6 @@ struct MinimapIcon
|
|||
|
||||
typedef std::list<Ingredient*> Ingredients;
|
||||
|
||||
class ElementTemplate
|
||||
{
|
||||
public:
|
||||
ElementTemplate() { alpha = 1; cull = true; w=-1; h=-1; idx=-1; tu1=tu2=tv1=tv2=0; }
|
||||
inline bool operator<(const ElementTemplate& o) const { return idx < o.idx; }
|
||||
std::string gfx;
|
||||
std::vector <TileVector> grid;
|
||||
int w,h;
|
||||
float tu1, tu2, tv1, tv2;
|
||||
bool cull;
|
||||
float alpha;
|
||||
size_t idx;
|
||||
};
|
||||
|
||||
class ObsRow
|
||||
{
|
||||
public:
|
||||
|
@ -171,9 +158,10 @@ public:
|
|||
|
||||
InGameMenu *getInGameMenu() { return themenu; }
|
||||
|
||||
void loadElementTemplates(std::string pack);
|
||||
// pass usedIdx == NULL to preload all textures from tileset
|
||||
// pass usedIdx != NULL to preload only textures where usedIdx[i] != 0
|
||||
bool loadElementTemplates(std::string pack, const unsigned char *usedIdx, size_t usedIdxLen);
|
||||
Element* createElement(size_t etidx, Vector position, size_t bgLayer=0, RenderObject *copy=0, ElementTemplate *et=0);
|
||||
void setGrid(ElementTemplate *et, Vector position, float rot360=0);
|
||||
|
||||
void updateParticlePause();
|
||||
|
||||
|
@ -196,7 +184,7 @@ public:
|
|||
void handleShotCollisionsSkeletal(Entity *e);
|
||||
void handleShotCollisionsHair(Entity *e, int num = 0, float perc = 0);
|
||||
|
||||
std::vector<ElementTemplate> elementTemplates;
|
||||
Tileset tileset;
|
||||
std::string sceneName, sceneDisplayName;
|
||||
|
||||
ElementTemplate *getElementTemplateByIdx(size_t idx);
|
||||
|
@ -362,7 +350,6 @@ public:
|
|||
void setMusicToPlay(const std::string &musicToPlay);
|
||||
Vector lastCollidePosition;
|
||||
void switchBgLoop(int v);
|
||||
ElementTemplate getElementTemplateForLetter(int i);
|
||||
CurrentRender *currentRender;
|
||||
SteamRender *steamRender;
|
||||
SongLineRender *songLineRender;
|
||||
|
|
|
@ -23,7 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#include "../BBGE/Vector.h"
|
||||
|
||||
const int TILE_SIZE = 20;
|
||||
enum { TILE_SIZE = 20 };
|
||||
|
||||
class TileVector
|
||||
{
|
||||
|
|
|
@ -109,6 +109,12 @@ set(BBGE_SRCS
|
|||
TextureMgr.h
|
||||
TTFFont.cpp
|
||||
TTFFont.h
|
||||
Tile.cpp
|
||||
Tile.h
|
||||
TileRender.cpp
|
||||
TileRender.h
|
||||
Tileset.cpp
|
||||
Tileset.h
|
||||
Vector.cpp
|
||||
Vector.h
|
||||
Window.cpp
|
||||
|
|
|
@ -205,6 +205,7 @@ public:
|
|||
|
||||
// Defined in RenderObject_inline.h
|
||||
inline Vector getFollowCameraPosition() const;
|
||||
inline Vector getFollowCameraPosition(const Vector& pos) const;
|
||||
|
||||
void lookAt(const Vector &pos, float t, float minAngle, float maxAngle, float offset=0);
|
||||
inline RenderObject *getParent() const {return parent;}
|
||||
|
|
|
@ -33,19 +33,42 @@ inline bool RenderObject::isOnScreen() const
|
|||
}
|
||||
|
||||
Vector RenderObject::getFollowCameraPosition() const
|
||||
{
|
||||
return getFollowCameraPosition(position);
|
||||
}
|
||||
|
||||
Vector RenderObject::getFollowCameraPosition(const Vector& v) const
|
||||
{
|
||||
assert(layer != LR_NONE);
|
||||
assert(!parent); // this makes no sense when we're not a root object
|
||||
const RenderObjectLayer &rl = core->renderObjectLayers[layer];
|
||||
Vector mul = rl.followCameraMult;
|
||||
float f = followCamera;
|
||||
if(!f)
|
||||
f = rl.followCamera;
|
||||
if (f <= 0)
|
||||
return position;
|
||||
Vector M = rl.followCameraMult;
|
||||
float F = followCamera;
|
||||
if(!F)
|
||||
F = rl.followCamera;
|
||||
if (F <= 0)
|
||||
return v;
|
||||
|
||||
const Vector pos = (position - core->screenCenter) * f + core->screenCenter;
|
||||
return position * (Vector(1,1) - mul) + (pos * mul); // lerp
|
||||
/* Originally, not accounting for parallax lock on an axis, this was:
|
||||
pos = v - core->screenCenter;
|
||||
pos *= F;
|
||||
pos = core->screenCenter + pos;
|
||||
*/
|
||||
|
||||
// uppercase are effectively constants that are not per-object
|
||||
// lowercase are per-object
|
||||
|
||||
// more concise math:
|
||||
//const Vector pos = (v - core->screenCenter) * F + core->screenCenter;
|
||||
//return v * (Vector(1,1) - M) + (pos * M); // lerp
|
||||
|
||||
// optimized and rearranged
|
||||
const Vector C = core->screenCenter;
|
||||
const Vector M1 = Vector(1,1) - M;
|
||||
const Vector T = C * (1 - F);
|
||||
|
||||
const Vector pos = T + (F * v);
|
||||
return v * M1 + (pos * M); // lerp, used to select whether to use original v or parallax-corrected v
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
2
BBGE/Tile.cpp
Normal file
2
BBGE/Tile.cpp
Normal file
|
@ -0,0 +1,2 @@
|
|||
#include "Tile.h"
|
||||
|
60
BBGE/Tile.h
Normal file
60
BBGE/Tile.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
#ifndef BBGE_TILE_H
|
||||
#define BBGE_TILE_H
|
||||
|
||||
#include <vector>
|
||||
#include "Vector.h"
|
||||
|
||||
class ElementTemplate;
|
||||
class Texture;
|
||||
|
||||
// A Tile is a very stripped down RenderObject that bypasses the default
|
||||
// rendering pipeline for efficiency reasons.
|
||||
// Use a TileRender to draw a list of Tiles.
|
||||
|
||||
/* Properties of tiles:
|
||||
- Lots of these exist. Need to store & render efficiently
|
||||
- Usually no dynamic behavior, BUT:
|
||||
* can have a TileEffect that requires updating (sometimes)
|
||||
* can react to entities nearby (rare)
|
||||
* may have a draw grid (wobbly plants etc)
|
||||
- Only modified in the editor -> Can be slow to modify or reorder
|
||||
- Render order must be strictly followed to get the correct visual overlapping
|
||||
- Never part of a parent/child hierarchy, all tiles are standalone
|
||||
- Does not have offset, internalOffset, gravity, etc etc that RenderObject has
|
||||
- Parallax scroll factor is solely influenced by layer, not individually
|
||||
- RGB is never tinted, alpha may come from efx
|
||||
*/
|
||||
|
||||
enum TileFlags
|
||||
{
|
||||
TILEFLAG_NONE = 0,
|
||||
TILEFLAG_REPEAT = 0x01, // texture repeats and uses texscale for the repeat factor
|
||||
TILEFLAG_SOLID = 0x02, // generates OT_INVISIBLE
|
||||
TILEFLAG_SOLID_THICK = 0x04, // generates more OT_INVISIBLE
|
||||
TILEFLAG_SOLID_IN = 0x08, // instead of OT_INVISIBLE, generate OT_INVISIBLEIN
|
||||
TILEFLAG_HURT = 0x10, // always generate OT_HURT
|
||||
TILEFLAG_FH = 0x20, // flipped horizontally
|
||||
};
|
||||
|
||||
// sort-of-POD
|
||||
struct TileData
|
||||
{
|
||||
float x, y, rotation, texscale;
|
||||
Vector scale, beforeScaleOffset;
|
||||
int efx;
|
||||
unsigned flags; // TileFlags
|
||||
unsigned tag;
|
||||
ElementTemplate *et;
|
||||
};
|
||||
|
||||
|
||||
class TileStorage
|
||||
{
|
||||
public:
|
||||
std::vector<TileData> tiles;
|
||||
void refresh(); // call when adding/removing/reordering tiles or changing efx
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // BBGE_TILE_H
|
135
BBGE/TileRender.cpp
Normal file
135
BBGE/TileRender.cpp
Normal file
|
@ -0,0 +1,135 @@
|
|||
#include "TileRender.h"
|
||||
#include "RenderBase.h"
|
||||
#include "Core.h"
|
||||
#include "Tileset.h"
|
||||
|
||||
TileRender::TileRender(const TileStorage& tiles)
|
||||
: storage(tiles)
|
||||
{
|
||||
}
|
||||
|
||||
TileRender::~TileRender()
|
||||
{
|
||||
}
|
||||
|
||||
void TileRender::onRender(const RenderState& rs) const
|
||||
{
|
||||
// prepare. get parallax scroll factors
|
||||
const RenderObjectLayer& rl = core->renderObjectLayers[this->layer];
|
||||
Vector M = rl.followCameraMult; // affected by parallaxLock
|
||||
const float F = rl.followCamera;
|
||||
|
||||
// Formula from RenderObject::getFollowCameraPosition() and optimized for speed
|
||||
const Vector C = core->screenCenter;
|
||||
const Vector M1 = Vector(1,1) - M;
|
||||
const Vector T = C * (1 - F);
|
||||
|
||||
unsigned lastTexRepeat = false;
|
||||
unsigned lastTexId = 0;
|
||||
BlendType blend = BLEND_DEFAULT; // TODO: influenced by efx
|
||||
const bool renderBorders = true; // TODO: when layer selected in editor
|
||||
|
||||
for(size_t i = 0; i < storage.tiles.size(); ++i)
|
||||
{
|
||||
const TileData& tile = storage.tiles[i];
|
||||
const Vector tilepos(tile.x, tile.y);
|
||||
const Vector tmp = T + (F * tilepos);
|
||||
const Vector pos = tilepos * M1 + (tmp * M); // lerp, used to select whether to use original v or parallax-corrected v
|
||||
|
||||
rs.gpu.setBlend(blend);
|
||||
|
||||
ElementTemplate * const et = tile.et;
|
||||
if(Texture * const tex = et->tex.content())
|
||||
{
|
||||
unsigned texid = tex->gltexid;
|
||||
unsigned rep = tile.flags & TILEFLAG_REPEAT;
|
||||
if(texid != lastTexId || rep != lastTexRepeat)
|
||||
{
|
||||
lastTexId = texid;
|
||||
lastTexRepeat = rep;
|
||||
tex->apply(!!rep);
|
||||
}
|
||||
}
|
||||
else
|
||||
glBindTexture(GL_TEXTURE_2D, 0); // unlikely
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(pos.x, pos.y, pos.z);
|
||||
|
||||
glRotatef(tile.rotation, 0, 0, 1);
|
||||
if(tile.flags & TILEFLAG_FH)
|
||||
glRotatef(180, 0, 1, 0);
|
||||
|
||||
// this is only relevant in editor mode and is always 0 otherwise
|
||||
glTranslatef(tile.beforeScaleOffset.x, tile.beforeScaleOffset.y, tile.beforeScaleOffset.z);
|
||||
|
||||
glScalef(tile.scale.x, tile.scale.y, 1);
|
||||
|
||||
// TODO: only need to do this when prev. tile had different alpha
|
||||
{
|
||||
const float alpha = 1; // TODO: via efx
|
||||
Vector col = rs.color;
|
||||
glColor4f(col.x, col.y, col.z, rs.alpha*alpha);
|
||||
}
|
||||
|
||||
const float _w2 = float(int(et->w)) * 0.5f;
|
||||
const float _h2 = float(int(et->h)) * 0.5f;
|
||||
|
||||
// render texture
|
||||
{
|
||||
const Vector upperLeftTextureCoordinates(et->tu1, et->tv1);
|
||||
const Vector lowerRightTextureCoordinates(et->tu2, et->tv2);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
{
|
||||
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);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
if(renderBorders)
|
||||
{
|
||||
lastTexId = 0;
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
Vector color(0.5f,0.5f,0.5f); // TODO: (1,1,1) when selected
|
||||
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
RenderObject::lastTextureApplied = lastTexId;
|
||||
RenderObject::lastTextureRepeat = !!lastTexRepeat;
|
||||
}
|
||||
|
||||
void TileRender::onUpdate(float dt)
|
||||
{
|
||||
}
|
24
BBGE/TileRender.h
Normal file
24
BBGE/TileRender.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
#ifndef BBGE_TILERENDER_H
|
||||
#define BBGE_TILERENDER_H
|
||||
|
||||
#include "RenderObject.h"
|
||||
#include "Tile.h"
|
||||
|
||||
class Tileset;
|
||||
|
||||
class TileRender : public RenderObject
|
||||
{
|
||||
private:
|
||||
const TileStorage& storage;
|
||||
public:
|
||||
|
||||
TileRender(const TileStorage& tiles);
|
||||
virtual ~TileRender();
|
||||
virtual void onRender(const RenderState& rs) const;
|
||||
virtual void onUpdate(float dt);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
#endif // BBGE_TILERENDER_H
|
94
BBGE/Tileset.cpp
Normal file
94
BBGE/Tileset.cpp
Normal file
|
@ -0,0 +1,94 @@
|
|||
#include "Tileset.h"
|
||||
#include "SimpleIStringStream.h"
|
||||
#include "Base.h"
|
||||
#include "ttvfs_stdio.h"
|
||||
#include "TextureMgr.h"
|
||||
#include "Core.h"
|
||||
|
||||
bool Tileset::loadFile(const char *fn, const unsigned char *usedIdx, size_t usedIdxLen)
|
||||
{
|
||||
elementTemplates.clear();
|
||||
|
||||
InStream in(fn);
|
||||
if(!in)
|
||||
return false;
|
||||
|
||||
std::string line, gfx;
|
||||
while (std::getline(in, line))
|
||||
{
|
||||
int idx=-1, w=0, h=0;
|
||||
SimpleIStringStream is(line.c_str(), SimpleIStringStream::REUSE);
|
||||
is >> idx >> gfx >> w >> h;
|
||||
if(idx > 0)
|
||||
{
|
||||
ElementTemplate t;
|
||||
t.idx = idx;
|
||||
t.gfx = gfx;
|
||||
t.w = w;
|
||||
t.h = h;
|
||||
elementTemplates.push_back(t);
|
||||
}
|
||||
}
|
||||
in.close();
|
||||
|
||||
std::sort(elementTemplates.begin(), elementTemplates.end());
|
||||
|
||||
// begin preloading textures
|
||||
|
||||
std::vector<std::string> usedTex;
|
||||
usedTex.reserve(elementTemplates.size()); // optimistically assume all textures in the tileset are used
|
||||
|
||||
for (size_t i = 0; i < elementTemplates.size(); i++)
|
||||
{
|
||||
size_t idx = elementTemplates[i].idx;
|
||||
if (!usedIdx || (idx < usedIdxLen && usedIdx[idx]))
|
||||
usedTex.push_back(elementTemplates[i].gfx);
|
||||
}
|
||||
std::sort(usedTex.begin(), usedTex.end());
|
||||
// drop duplicates
|
||||
usedTex.resize(std::distance(usedTex.begin(), std::unique(usedTex.begin(), usedTex.end())));
|
||||
|
||||
std::ostringstream os;
|
||||
os << "Loading " << usedTex.size()
|
||||
<< " used textures out of the " << elementTemplates.size() << " tileset entries";
|
||||
debugLog(os.str());
|
||||
|
||||
// preload all used textures
|
||||
if(usedTex.size())
|
||||
core->texmgr.loadBatch(NULL, &usedTex[0], usedTex.size());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Tileset::clear()
|
||||
{
|
||||
elementTemplates.clear();
|
||||
}
|
||||
|
||||
ElementTemplate *Tileset::getByIdx(size_t idx)
|
||||
{
|
||||
for (size_t i = 0; i < elementTemplates.size(); i++)
|
||||
{
|
||||
if (elementTemplates[i].idx == idx)
|
||||
{
|
||||
return &elementTemplates[i];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Texture* ElementTemplate::getTexture()
|
||||
{
|
||||
if(tex)
|
||||
return tex.content();
|
||||
|
||||
tex = core->getTexture(gfx);
|
||||
if(!w)
|
||||
w = tex->width;
|
||||
if(!h)
|
||||
h = tex->height;
|
||||
|
||||
return tex.content();
|
||||
|
||||
}
|
||||
|
40
BBGE/Tileset.h
Normal file
40
BBGE/Tileset.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
#ifndef BBGE_TILESET_H
|
||||
#define BBGE_TILESET_H
|
||||
|
||||
#include "Vector.h"
|
||||
#include <vector>
|
||||
#include "Texture.h"
|
||||
|
||||
class ElementTemplate
|
||||
{
|
||||
public:
|
||||
ElementTemplate() { w=0; h=0; idx=-1; tu1=tv1=0; tu2=tv2=1; }
|
||||
inline bool operator<(const ElementTemplate& o) const { return idx < o.idx; }
|
||||
|
||||
Texture *getTexture(); // loads if not already loaded
|
||||
|
||||
// lazily assigned when tex is loaded
|
||||
CountedPtr<Texture> tex;
|
||||
unsigned w,h; // custom size if used, otherwise texture size
|
||||
|
||||
// fixed
|
||||
float tu1, tu2, tv1, tv2; // texcoords
|
||||
size_t idx;
|
||||
std::string gfx;
|
||||
};
|
||||
|
||||
class Tileset
|
||||
{
|
||||
public:
|
||||
// pass usedIdx == NULL to preload all textures from tileset
|
||||
// pass usedIdx != NULL to preload only textures where usedIdx[i] != 0
|
||||
bool loadFile(const char *fn, const unsigned char *usedIdx, size_t usedIdxLen);
|
||||
void clear();
|
||||
|
||||
ElementTemplate *getByIdx(size_t idx);
|
||||
|
||||
std::vector<ElementTemplate> elementTemplates;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue