Selaa lähdekoodia

tileset: refactor the tile generation code.

legacy
Sam Hocevar sam 11 vuotta sitten
vanhempi
commit
9a752c84d8
3 muutettua tiedostoa jossa 77 lisäystä ja 47 poistoa
  1. +1
    -1
      src/scene.cpp
  2. +71
    -44
      src/tileset.cpp
  3. +5
    -2
      src/tileset.h

+ 1
- 1
src/scene.cpp Näytä tiedosto

@@ -272,7 +272,7 @@ void Scene::Render() // XXX: rename to Blit()
/* Bind texture */ /* Bind texture */
data->m_tiles[i].tileset->Bind(); data->m_tiles[i].tileset->Bind();
data->m_tile_shader->SetUniform(uni_texsize, data->m_tile_shader->SetUniform(uni_texsize,
data->m_tiles[i].tileset->GetImageSize());
(vec2)data->m_tiles[i].tileset->GetTextureSize());


/* Bind vertex and texture coordinate buffers */ /* Bind vertex and texture coordinate buffers */
data->m_tile_vdecl->Bind(); data->m_tile_vdecl->Bind();


+ 71
- 44
src/tileset.cpp Näytä tiedosto

@@ -50,11 +50,12 @@ class TileSetData


private: private:
String m_name; String m_name;
int ntiles;
ivec2 m_tile_size, m_image_size, count;
vec2 m_texcoord;


Image *m_img;
/* Pixels, then texture coordinates */
Array<ibox2, box2> m_tiles;
ivec2 m_tile_size, m_image_size, m_texture_size;

Image *m_image;
Texture *m_texture; Texture *m_texture;
}; };


@@ -62,37 +63,61 @@ private:
* Public TileSet class * Public TileSet class
*/ */


TileSet::TileSet(char const *path, ivec2 size, ivec2 count)
TileSet::TileSet(char const *path)
: m_data(new TileSetData()) : m_data(new TileSetData())
{ {
m_data->m_name = String("<tileset> ") + path;
Init(path);


m_data->m_texture = 0;
m_data->m_img = Image::Create(path);
m_data->m_image_size = m_data->m_img->GetSize();
m_drawgroup = DRAWGROUP_BEFORE;
}


TileSet::TileSet(char const *path, ivec2 size, ivec2 count)
: m_data(new TileSetData())
{
Init(path);

/* If count is valid, fix size; otherwise, fix count. */
if (count.x > 0 && count.y > 0) if (count.x > 0 && count.y > 0)
{ {
m_data->count = count;
m_data->m_tile_size = m_data->m_image_size / count;
size = m_data->m_image_size / count;
} }
else else
{ {
if (size.x <= 0 || size.y <= 0) if (size.x <= 0 || size.y <= 0)
size = ivec2(32, 32); size = ivec2(32, 32);
m_data->count.x = m_data->m_image_size.x / min(size.x, m_data->m_image_size.x);
m_data->count.y = m_data->m_image_size.y / min(size.y, m_data->m_image_size.y);
m_data->m_tile_size = size;
count = ivec2(max(1, m_data->m_image_size.x / size.x),
max(1, m_data->m_image_size.y / size.y));
} }


m_data->m_texcoord.x = (float)m_data->m_tile_size.x / PotUp(m_data->m_image_size.x);
m_data->m_texcoord.y = (float)m_data->m_tile_size.y / PotUp(m_data->m_image_size.y);

m_data->ntiles = m_data->count.x * m_data->count.y;
for (int j = 0; j < count.y; ++j)
for (int i = 0; i < count.x; ++i)
{
AddTile(ibox2(size * ivec2(i, j),
size * ivec2(i + 1, j + 1)));
}


m_drawgroup = DRAWGROUP_BEFORE; m_drawgroup = DRAWGROUP_BEFORE;
} }


void TileSet::Init(char const *path)
{
m_data->m_name = String("<tileset> ") + path;

m_data->m_texture = 0;
m_data->m_image = Image::Create(path);
m_data->m_image_size = m_data->m_image->GetSize();
m_data->m_texture_size = ivec2(PotUp(m_data->m_image_size.x),
PotUp(m_data->m_image_size.y));
}

int TileSet::AddTile(ibox2 rect)
{
m_data->m_tiles.Push(rect,
box2((vec2)rect.A / (vec2)m_data->m_texture_size,
(vec2)rect.B / (vec2)m_data->m_texture_size));
return m_data->m_tiles.Count() - 1;
}

TileSet::~TileSet() TileSet::~TileSet()
{ {
delete m_data; delete m_data;
@@ -104,10 +129,10 @@ void TileSet::TickDraw(float seconds)


if (IsDestroying()) if (IsDestroying())
{ {
if (m_data->m_img)
if (m_data->m_image)
{ {
Image::Destroy(m_data->m_img);
m_data->m_img = nullptr;
Image::Destroy(m_data->m_image);
m_data->m_image = nullptr;
} }
else else
{ {
@@ -115,10 +140,10 @@ void TileSet::TickDraw(float seconds)
m_data->m_texture = nullptr; m_data->m_texture = nullptr;
} }
} }
else if (m_data->m_img)
else if (m_data->m_image)
{ {
int planes; int planes;
PixelFormat format = m_data->m_img->GetFormat();
PixelFormat format = m_data->m_image->GetFormat();


switch (format) switch (format)
{ {
@@ -133,10 +158,10 @@ void TileSet::TickDraw(float seconds)
break; break;
} }


int w = PotUp(m_data->m_image_size.x);
int h = PotUp(m_data->m_image_size.y);
int w = m_data->m_texture_size.x;
int h = m_data->m_texture_size.y;


uint8_t *pixels = m_data->m_img->GetData();
uint8_t *pixels = m_data->m_image->GetData();
if (w != m_data->m_image_size.x || h != m_data->m_image_size.y) if (w != m_data->m_image_size.x || h != m_data->m_image_size.y)
{ {
uint8_t *tmp = new uint8_t[planes * w * h]; uint8_t *tmp = new uint8_t[planes * w * h];
@@ -150,10 +175,10 @@ void TileSet::TickDraw(float seconds)
m_data->m_texture = new Texture(ivec2(w, h), format); m_data->m_texture = new Texture(ivec2(w, h), format);
m_data->m_texture->SetData(pixels); m_data->m_texture->SetData(pixels);


if (pixels != m_data->m_img->GetData())
if (pixels != m_data->m_image->GetData())
delete[] pixels; delete[] pixels;
Image::Destroy(m_data->m_img);
m_data->m_img = nullptr;
Image::Destroy(m_data->m_image);
m_data->m_image = nullptr;
} }
} }


@@ -162,22 +187,22 @@ char const *TileSet::GetName()
return m_data->m_name.C(); return m_data->m_name.C();
} }


ivec2 TileSet::GetTileCount() const
int TileSet::GetTileCount() const
{ {
return m_data->count;
return m_data->m_tiles.Count();
} }


ivec2 TileSet::GetTileSize(int tileid) const ivec2 TileSet::GetTileSize(int tileid) const
{ {
(void)tileid; (void)tileid;


return m_data->m_tile_size;
ibox2 const &box = m_data->m_tiles[tileid].m1;
return box.B - box.A;
} }


vec2 TileSet::GetImageSize() const
ivec2 TileSet::GetTextureSize() const
{ {
return vec2(PotUp(m_data->m_image_size.x),
PotUp(m_data->m_image_size.y));
return m_data->m_texture_size;
} }


ShaderTexture TileSet::GetTexture() const ShaderTexture TileSet::GetTexture() const
@@ -187,7 +212,7 @@ ShaderTexture TileSet::GetTexture() const


void TileSet::Bind() void TileSet::Bind()
{ {
if (!m_data->m_img && m_data->m_texture)
if (!m_data->m_image && m_data->m_texture)
m_data->m_texture->Bind(); m_data->m_texture->Bind();
} }


@@ -199,14 +224,16 @@ void TileSet::Unbind()
void TileSet::BlitTile(uint32_t id, vec3 pos, int o, vec2 scale, void TileSet::BlitTile(uint32_t id, vec3 pos, int o, vec2 scale,
float *vertex, float *texture) float *vertex, float *texture)
{ {
float dtx = m_data->m_texcoord.x;
float dty = m_data->m_texcoord.y;
float tx = dtx * ((id & 0xffff) % m_data->count.x);
float ty = dty * ((id & 0xffff) / m_data->count.x);
ibox2 pixels = m_data->m_tiles[id].m1;
box2 texels = m_data->m_tiles[id].m2;
float dtx = texels.B.x - texels.A.x;
float dty = texels.B.y - texels.A.y;
float tx = texels.A.x;
float ty = texels.A.y;


int dx = m_data->m_tile_size.x * scale.x;
int dy = o ? 0 : m_data->m_tile_size.y * scale.y;
int dz = o ? m_data->m_tile_size.y * scale.y : 0;
int dx = (pixels.B.x - pixels.A.x) * scale.x;
int dy = o ? 0 : (pixels.B.y - pixels.A.y) * scale.y;
int dz = o ? (pixels.B.y - pixels.A.y) * scale.y : 0;


/* If scaling is negative, switch triangle winding */ /* If scaling is negative, switch triangle winding */
if (scale.x * scale.y < 0.0f) if (scale.x * scale.y < 0.0f)
@@ -226,7 +253,7 @@ void TileSet::BlitTile(uint32_t id, vec3 pos, int o, vec2 scale,
dty *= 126.f / 128.f; dty *= 126.f / 128.f;
#endif #endif


if (!m_data->m_img && m_data->m_texture)
if (!m_data->m_image && m_data->m_texture)
{ {
float tmp[10]; float tmp[10];




+ 5
- 2
src/tileset.h Näytä tiedosto

@@ -44,9 +44,9 @@ protected:


public: public:
/* New methods */ /* New methods */
ivec2 GetTileCount() const;
int GetTileCount() const;
ivec2 GetTileSize(int tileid) const; ivec2 GetTileSize(int tileid) const;
vec2 GetImageSize() const;
ivec2 GetTextureSize() const;
ShaderTexture GetTexture() const; ShaderTexture GetTexture() const;
void Bind(); void Bind();
void Unbind(); void Unbind();
@@ -54,6 +54,9 @@ public:
float *vertex, float *texture); float *vertex, float *texture);


private: private:
void Init(char const *path);
int AddTile(ibox2 rect);

TileSetData *m_data; TileSetData *m_data;
}; };




Ladataan…
Peruuta
Tallenna