diff --git a/src/scene.cpp b/src/scene.cpp index 24b07547..f1a24313 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -41,12 +41,9 @@ array Scene::g_scenes; struct Tile { - TileSet *tileset; - uint32_t prio; - vec3 pos; - vec2 scale; - float angle; - int id, o; + mat4 m_model; + TileSet *m_tileset; + int m_id; }; //----------------------------------------------------------------------------- @@ -455,15 +452,25 @@ void Scene::AddTile(TileSet *tileset, int id, vec3 pos, int o, vec2 scale, float { ASSERT(id < tileset->GetTileCount()); + ivec2 size = tileset->GetTileSize(id); + vec2 flip(scale.x > 0.f ? 1.f : -1.f, + scale.y > 0.f ? 1.f : -1.f); + mat4 model = mat4::translate(pos) + * mat4::scale(scale.x, scale.y, 1.f) + * mat4::translate(size.x * 0.5f, size.y * 0.5f, 0.f) + * mat4::rotate(angle * flip.x * flip.y, vec3::axis_z); + + AddTile(tileset, id, model); +} + +void Scene::AddTile(TileSet *tileset, int id, mat4 model) +{ + ASSERT(id < tileset->GetTileCount()); + Tile t; - /* FIXME: this sorting only works for a 45-degree camera */ - t.prio = (uint32_t)(-pos.y - (int)(2 * 32 * pos.z) + ((float)o ? 0 : 32)); - t.tileset = tileset; - t.id = id; - t.pos = pos; - t.o = o; - t.scale = scale; - t.angle = angle; + t.m_model = model; + t.m_tileset = tileset; + t.m_id = id; if (tileset->GetPalette()) data->m_palettes.push(t); @@ -594,6 +601,10 @@ void Scene::RenderTiles() // XXX: rename to Blit() if (!data->m_tiles.count() && !data->m_palettes.count()) return; + /* FIXME: we disable culling for now because we don’t have a reliable + * way to know which side is facing the camera. */ + rc.SetCullMode(CullMode::Disabled); + rc.SetDepthFunc(DepthFunc::LessOrEqual); rc.SetBlendFunc(BlendFunc::SrcAlpha, BlendFunc::OneMinusSrcAlpha); rc.SetBlendEquation(BlendEquation::Add, BlendEquation::Max); @@ -640,7 +651,7 @@ void Scene::RenderTiles() // XXX: rename to Blit() { /* Count how many quads will be needed */ for (n = i + 1; n < tiles.count(); n++) - if (tiles[i].tileset != tiles[n].tileset) + if (tiles[i].m_tileset != tiles[n].m_tileset) break; /* Create a vertex array object */ @@ -654,9 +665,7 @@ void Scene::RenderTiles() // XXX: rename to Blit() for (int j = i; j < n; j++) { - tiles[i].tileset->BlitTile(tiles[j].id, - tiles[j].pos, tiles[j].o, - tiles[j].scale, tiles[j].angle, + tiles[i].m_tileset->BlitTile(tiles[j].m_id, tiles[j].m_model, vertex + 6 * (j - i), texture + 6 * (j - i)); } @@ -664,22 +673,22 @@ void Scene::RenderTiles() // XXX: rename to Blit() vb2->Unlock(); /* Bind texture */ - if (tiles[i].tileset->GetPalette()) + if (tiles[i].m_tileset->GetPalette()) { - if (tiles[i].tileset->GetTexture()) - shader->SetUniform(uni_tex, tiles[i].tileset->GetTexture()->GetTextureUniform(), 0); - if (tiles[i].tileset->GetPalette()->GetTexture()) - shader->SetUniform(uni_pal, tiles[i].tileset->GetPalette()->GetTexture()->GetTextureUniform(), 1); + if (tiles[i].m_tileset->GetTexture()) + shader->SetUniform(uni_tex, tiles[i].m_tileset->GetTexture()->GetTextureUniform(), 0); + if (tiles[i].m_tileset->GetPalette()->GetTexture()) + shader->SetUniform(uni_pal, tiles[i].m_tileset->GetPalette()->GetTexture()->GetTextureUniform(), 1); } else { shader->SetUniform(uni_tex, 0); - if (tiles[i].tileset->GetTexture()) - shader->SetUniform(uni_tex, tiles[i].tileset->GetTexture()->GetTextureUniform(), 0); - tiles[i].tileset->Bind(); + if (tiles[i].m_tileset->GetTexture()) + shader->SetUniform(uni_tex, tiles[i].m_tileset->GetTexture()->GetTextureUniform(), 0); + tiles[i].m_tileset->Bind(); } shader->SetUniform(uni_texsize, - (vec2)tiles[i].tileset->GetTextureSize()); + (vec2)tiles[i].m_tileset->GetTextureSize()); /* Bind vertex and texture coordinate buffers */ data->m_tile_vdecl->Bind(); @@ -689,7 +698,7 @@ void Scene::RenderTiles() // XXX: rename to Blit() /* Draw arrays */ data->m_tile_vdecl->DrawElements(MeshPrimitive::Triangles, 0, (n - i) * 6); data->m_tile_vdecl->Unbind(); - tiles[i].tileset->Unbind(); + tiles[i].m_tileset->Unbind(); } tiles.empty(); diff --git a/src/scene.h b/src/scene.h index 943967bc..5c24af8c 100644 --- a/src/scene.h +++ b/src/scene.h @@ -227,6 +227,7 @@ public: /* FIXME: this should be deprecated -- it doesn't really match * the architecture we want to build */ void AddTile(TileSet *tileset, int id, vec3 pos, int o, vec2 scale, float angle); + void AddTile(TileSet *tileset, int id, mat4 model); public: void SetLineTime(float new_time = -1.f); diff --git a/src/tileset.cpp b/src/tileset.cpp index a066e16c..1e872571 100644 --- a/src/tileset.cpp +++ b/src/tileset.cpp @@ -180,8 +180,7 @@ TileSet const* TileSet::GetPalette() const return m_palette; } -void TileSet::BlitTile(uint32_t id, vec3 pos, int o, vec2 scale, float angle, - vec3 *vertex, vec2 *texture) +void TileSet::BlitTile(uint32_t id, mat4 model, vec3 *vertex, vec2 *texture) { ibox2 pixels = m_tileset_data->m_tiles[id].m1; box2 texels = m_tileset_data->m_tiles[id].m2; @@ -190,20 +189,6 @@ void TileSet::BlitTile(uint32_t id, vec3 pos, int o, vec2 scale, float angle, float tx = texels.aa.x; float ty = texels.aa.y; - int dx = (int)(pixels.extent().x * scale.x); - int dy = o ? 0 : (int)(pixels.extent().y * scale.y); - int dz = o ? (int)(pixels.extent().y * scale.y) : 0; - - /* If scaling is negative, switch triangle winding */ - if (scale.x * scale.y < 0.0f) - { - pos.x += dx; - dx = -dx; - - tx += dtx; - dtx = -dtx; - } - #if 1 /* HACK: tweak UV values */ tx += (1.f / 128.f) * dtx; @@ -212,20 +197,18 @@ void TileSet::BlitTile(uint32_t id, vec3 pos, int o, vec2 scale, float angle, dty *= 126.f / 128.f; #endif - vec3 extent_x = 0.5f * vec3((float)dx, 0.f, 0.f); - vec3 extent_y = 0.5f * vec3(0.f, (float)dy, (float)dz); - vec3 center = pos + extent_x + extent_y; - extent_x = mat3::rotate(angle, vec3::axis_z) * extent_x; - extent_y = mat3::rotate(angle, vec3::axis_z) * extent_y; + vec3 pos = (model * vec4(0.f, 0.f, 0.f, 1.f)).xyz; + vec3 extent_x = 0.5f * pixels.extent().x * (model * vec4::axis_x).xyz; + vec3 extent_y = 0.5f * pixels.extent().y * (model * vec4::axis_y).xyz; if (!m_data->m_image && m_data->m_texture) { - *vertex++ = center + extent_x + extent_y; - *vertex++ = center - extent_x + extent_y; - *vertex++ = center + extent_x - extent_y; - *vertex++ = center + extent_x - extent_y; - *vertex++ = center - extent_x + extent_y; - *vertex++ = center - extent_x - extent_y; + *vertex++ = pos + extent_x + extent_y; + *vertex++ = pos - extent_x + extent_y; + *vertex++ = pos + extent_x - extent_y; + *vertex++ = pos + extent_x - extent_y; + *vertex++ = pos - extent_x + extent_y; + *vertex++ = pos - extent_x - extent_y; *texture++ = vec2(tx + dtx, ty); *texture++ = vec2(tx, ty); diff --git a/src/tileset.h b/src/tileset.h index 2907878e..227c7945 100644 --- a/src/tileset.h +++ b/src/tileset.h @@ -64,8 +64,7 @@ public: void SetPalette(TileSet* palette); TileSet* GetPalette(); TileSet const * GetPalette() const; - void BlitTile(uint32_t id, vec3 pos, int o, vec2 scale, float angle, - vec3 *vertex, vec2 *texture); + void BlitTile(uint32_t id, mat4 model, vec3 *vertex, vec2 *texture); protected: TileSetData *m_tileset_data;