diff options
Diffstat (limited to 'mwe/resource-manager/map_layer.cpp')
| -rw-r--r-- | mwe/resource-manager/map_layer.cpp | 110 | 
1 files changed, 110 insertions, 0 deletions
diff --git a/mwe/resource-manager/map_layer.cpp b/mwe/resource-manager/map_layer.cpp new file mode 100644 index 0000000..6339707 --- /dev/null +++ b/mwe/resource-manager/map_layer.cpp @@ -0,0 +1,110 @@ + + +#include "map_layer.h" +#include "TextureMap.h" +#include <tmxlite/Layer.hpp> +#include <tmxlite/TileLayer.hpp> + +MapLayer::MapLayer() {} + +MapLayer::~MapLayer() { m_subsets.clear(); } + +bool MapLayer::create(const tmx::Map & map, std::uint32_t layerIndex, +					  const std::vector<TextureMap *> & textures) { +	const auto & layers = map.getLayers(); +	assert(layers[layerIndex]->getType() == tmx::Layer::Type::Tile); + +	const auto & layer = layers[layerIndex]->getLayerAs<tmx::TileLayer>(); +	const auto mapSize = map.getTileCount(); +	const auto mapTileSize = map.getTileSize(); +	const auto & tileSets = map.getTilesets(); + +	const auto tintColour = layer.getTintColour(); +	const SDL_Colour vertColour +		= {tintColour.r, tintColour.g, tintColour.b, tintColour.a}; + +	for (auto i = 0u; i < tileSets.size(); ++i) { +		//check tile ID to see if it falls within the current tile set +		const auto & ts = tileSets[i]; +		const auto & tileIDs = layer.getTiles(); + +		const auto texSize = textures[i]->getSize(); +		const auto tileCountX = texSize.x / mapTileSize.x; +		const auto tileCountY = texSize.y / mapTileSize.y; + +		const float uNorm = static_cast<float>(mapTileSize.x) / texSize.x; +		const float vNorm = static_cast<float>(mapTileSize.y) / texSize.y; + +		std::vector<SDL_Vertex> verts; +		for (auto y = 0u; y < mapSize.y; ++y) { +			for (auto x = 0u; x < mapSize.x; ++x) { +				const auto idx = y * mapSize.x + x; +				if (idx < tileIDs.size() && tileIDs[idx].ID >= ts.getFirstGID() +					&& tileIDs[idx].ID +						   < (ts.getFirstGID() + ts.getTileCount())) { +					//tex coords +					auto idIndex = (tileIDs[idx].ID - ts.getFirstGID()); +					float u = static_cast<float>(idIndex % tileCountX); +					float v = static_cast<float>(idIndex / tileCountY); +					u *= mapTileSize +							 .x; //TODO we should be using the tile set size, as this may be different from the map's grid size +					v *= mapTileSize.y; + +					//normalise the UV +					u /= textures[i]->getSize().x; +					v /= textures[i]->getSize().y; + +					//vert pos +					const float tilePosX +						= static_cast<float>(x) * mapTileSize.x; +					const float tilePosY +						= (static_cast<float>(y) * mapTileSize.y); + +					//push back to vert array +					SDL_Vertex vert +						= {{tilePosX, tilePosY}, vertColour, {u, v}}; +					verts.emplace_back(vert); +					vert = {{tilePosX + mapTileSize.x, tilePosY}, +							vertColour, +							{u + uNorm, v}}; +					verts.emplace_back(vert); +					vert = {{tilePosX, tilePosY + mapTileSize.y}, +							vertColour, +							{u, v + vNorm}}; +					verts.emplace_back(vert); + +					vert = {{tilePosX, tilePosY + mapTileSize.y}, +							vertColour, +							{u, v + vNorm}}; +					verts.emplace_back(vert); +					vert = {{tilePosX + mapTileSize.x, tilePosY}, +							vertColour, +							{u + uNorm, v}}; +					verts.emplace_back(vert); +					vert +						= {{tilePosX + mapTileSize.x, tilePosY + mapTileSize.y}, +						   vertColour, +						   {u + uNorm, v + vNorm}}; +					verts.emplace_back(vert); +				} +			} +		} + +		if (!verts.empty()) { +			m_subsets.emplace_back(); +			m_subsets.back().texture = *textures[i]; +			m_subsets.back().vertexData.swap(verts); +		} +	} + +	return true; +} + +void MapLayer::draw(SDL_Renderer * renderer) const { +	assert(renderer); +	for (const auto & s : m_subsets) { +		SDL_RenderGeometry(renderer, s.texture, s.vertexData.data(), +						   static_cast<std::int32_t>(s.vertexData.size()), +						   nullptr, 0); +	} +}  |