Graphics: Add TileMap class
Former-commit-id: 0a45b956501998a40a6406f7fff6e6cc85b4b4db [formerly ab84ea10c52b128b17241844e6a4b3887c6618ab] Former-commit-id: d62bbb11f5205daa6af3f7b9152be3fb213ca564
This commit is contained in:
parent
56443c91e4
commit
25d7112054
|
|
@ -0,0 +1,97 @@
|
|||
// Copyright (C) 2016 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_TILEMAP_HPP
|
||||
#define NAZARA_TILEMAP_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Graphics/InstancedRenderable.hpp>
|
||||
#include <Nazara/Graphics/Material.hpp>
|
||||
#include <Nazara/Utility/VertexStruct.hpp>
|
||||
#include <array>
|
||||
#include <set>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class TileMap;
|
||||
|
||||
using TileMapConstRef = ObjectRef<const TileMap>;
|
||||
using TileMapLibrary = ObjectLibrary<TileMap>;
|
||||
using TileMapRef = ObjectRef<TileMap>;
|
||||
|
||||
class NAZARA_GRAPHICS_API TileMap : public InstancedRenderable
|
||||
{
|
||||
friend TileMapLibrary;
|
||||
friend class Graphics;
|
||||
|
||||
public:
|
||||
struct Tile;
|
||||
|
||||
inline TileMap(const Nz::Vector2ui& mapSize, const Nz::Vector2f& tileSize, std::size_t materialCount = 1);
|
||||
TileMap(const TileMap& TileMap) = default;
|
||||
TileMap(TileMap&&) = delete;
|
||||
~TileMap() = default;
|
||||
|
||||
void AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const override;
|
||||
|
||||
inline void DisableTile(const Vector2ui& tilePos);
|
||||
inline void DisableTiles();
|
||||
inline void DisableTiles(const Vector2ui* tilesPos, std::size_t tileCount);
|
||||
|
||||
inline void EnableTile(const Vector2ui& tilePos, const Rectf& coords, const Color& color = Color::White, std::size_t materialIndex = 0U);
|
||||
inline void EnableTile(const Vector2ui& tilePos, const Rectui& rect, const Color& color = Color::White, std::size_t materialIndex = 0U);
|
||||
inline void EnableTiles(const Rectf& coords, const Color& color = Color::White, std::size_t materialIndex = 0U);
|
||||
inline void EnableTiles(const Rectui& rect, const Color& color = Color::White, std::size_t materialIndex = 0U);
|
||||
inline void EnableTiles(const Vector2ui* tilesPos, std::size_t tileCount, const Rectf& coords, const Color& color = Color::White, std::size_t materialIndex = 0U);
|
||||
inline void EnableTiles(const Vector2ui* tilesPos, std::size_t tileCount, const Rectui& rect, const Color& color = Color::White, std::size_t materialIndex = 0U);
|
||||
|
||||
inline const MaterialRef& GetMaterial(std::size_t index) const;
|
||||
inline std::size_t GetMaterialCount() const;
|
||||
inline const Vector2ui& GetMapSize() const;
|
||||
inline Vector2f GetSize() const;
|
||||
inline const Tile& GetTile(const Vector2ui& tilePos) const;
|
||||
inline const Vector2f& GetTileSize() const;
|
||||
|
||||
inline void SetMaterial(std::size_t index, MaterialRef material);
|
||||
|
||||
inline TileMap& operator=(const TileMap& TileMap);
|
||||
TileMap& operator=(TileMap&& TileMap) = delete;
|
||||
|
||||
template<typename... Args> static TileMapRef New(Args&&... args);
|
||||
|
||||
struct Tile
|
||||
{
|
||||
std::size_t layerIndex = 0U;
|
||||
Color color = Color::White;
|
||||
Rectf textureCoords = Rectf::Zero();
|
||||
bool enabled = false;
|
||||
};
|
||||
|
||||
private:
|
||||
void MakeBoundingVolume() const override;
|
||||
void UpdateData(InstanceData* instanceData) const override;
|
||||
|
||||
static bool Initialize();
|
||||
static void Uninitialize();
|
||||
|
||||
struct Layer
|
||||
{
|
||||
MaterialRef material;
|
||||
std::set<std::size_t> tiles;
|
||||
};
|
||||
|
||||
std::vector<Tile> m_tiles;
|
||||
std::vector<Layer> m_layers;
|
||||
Vector2ui m_mapSize;
|
||||
Vector2f m_tileSize;
|
||||
|
||||
static TileMapLibrary::LibraryMap s_library;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/TileMap.inl>
|
||||
|
||||
#endif // NAZARA_TILEMAP_HPP
|
||||
|
|
@ -0,0 +1,441 @@
|
|||
// Copyright (C) 2015 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Graphics/TileMap.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <memory>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
/*!
|
||||
* \brief Constructs a TileMap object, containing mapSize tileSize-sized tiles
|
||||
*
|
||||
* \param mapSize Number of tiles in each dimension, must be
|
||||
* \param tileSize Size of each tile of the TileMap
|
||||
* \param materialCount The maximum number of differents Material this TileMap will use
|
||||
*
|
||||
* \remark When constructed, a TileMap has no tile active and will not be rendered
|
||||
* To use it, you have to enable some tiles.
|
||||
*
|
||||
* \remark The default material is used for every material requested
|
||||
*/
|
||||
inline TileMap::TileMap(const Nz::Vector2ui& mapSize, const Nz::Vector2f& tileSize, std::size_t materialCount) :
|
||||
m_tiles(mapSize.x * mapSize.y),
|
||||
m_layers(materialCount),
|
||||
m_mapSize(mapSize),
|
||||
m_tileSize(tileSize)
|
||||
{
|
||||
NazaraAssert(m_tiles.size() != 0U, "Invalid map size");
|
||||
NazaraAssert(m_tileSize.x != 0U && m_tileSize.y != 0U, "Invalid tile size");
|
||||
NazaraAssert(m_layers.size() != 0U, "Invalid material count");
|
||||
|
||||
for (Layer& layer : m_layers)
|
||||
layer.material = Material::GetDefault();
|
||||
|
||||
InvalidateBoundingVolume();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Disable the tile at position tilePos, disabling rendering at this location
|
||||
*
|
||||
* \param tilePos Position of the tile to disable
|
||||
*
|
||||
* \seealso DisableTiles
|
||||
*/
|
||||
inline void TileMap::DisableTile(const Vector2ui& tilePos)
|
||||
{
|
||||
NazaraAssert(tilePos.x < m_mapSize.x && tilePos.y < m_mapSize.y, "Tile position is out of bounds");
|
||||
|
||||
std::size_t tileIndex = tilePos.y * m_mapSize.x + tilePos.x;
|
||||
Tile& tile = m_tiles[tileIndex];
|
||||
tile.enabled = false;
|
||||
|
||||
m_layers[tile.layerIndex].tiles.erase(tileIndex);
|
||||
|
||||
InvalidateInstanceData(1U << tile.layerIndex);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Disable all tiles
|
||||
*/
|
||||
inline void TileMap::DisableTiles()
|
||||
{
|
||||
for (Tile& tile : m_tiles)
|
||||
tile.enabled = false;
|
||||
|
||||
for (Layer& layer : m_layers)
|
||||
layer.tiles.clear();
|
||||
|
||||
InvalidateInstanceData(0xFFFFFFFF);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Disable tileCount tiles at positions contained at tilesPos location, disabling rendering at those locations
|
||||
*
|
||||
* This is equivalent to calling tileCount times DisableTile with the positions contained at tilesPos
|
||||
*
|
||||
* \param tilesPos Pointer to a valid array of at least tileCount positions
|
||||
* \param tileCount Number of tiles to disable
|
||||
*
|
||||
* \remark if tileCount is zero, this is a no-op and the value of tilesPos is not used
|
||||
*
|
||||
* \seealso DisableTile
|
||||
*/
|
||||
inline void TileMap::DisableTiles(const Vector2ui* tilesPos, std::size_t tileCount)
|
||||
{
|
||||
NazaraAssert(tilesPos || tileCount == 0, "Invalid tile position array with a non-zero tileCount");
|
||||
|
||||
UInt32 invalidatedLayers = 0;
|
||||
|
||||
for (std::size_t i = 0; i < tileCount; ++i)
|
||||
{
|
||||
NazaraAssert(tilesPos->x < m_mapSize.x && tilesPos->y < m_mapSize.y, "Tile position is out of bounds");
|
||||
|
||||
std::size_t tileIndex = tilesPos->y * m_mapSize.x + tilesPos->x;
|
||||
Tile& tile = m_tiles[tileIndex];
|
||||
tile.enabled = false;
|
||||
|
||||
m_layers[tile.layerIndex].tiles.erase(tileIndex);
|
||||
|
||||
invalidatedLayers |= 1U << tile.layerIndex;
|
||||
|
||||
tilesPos++;
|
||||
}
|
||||
|
||||
if (tileCount > 0)
|
||||
InvalidateInstanceData(invalidatedLayers);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Enable and sets the tile at position tilePos
|
||||
*
|
||||
* Setup the tile at position tilePos using color, normalized coordinates coords and materialIndex
|
||||
*
|
||||
* \param tilePos Position of the tile to enable
|
||||
* \param coords Normalized coordinates ([0..1]) used to specify which region of the material textures will be used
|
||||
* \param color The multiplicative color applied to the tile
|
||||
* \param materialIndex The material which will be used for rendering this tile
|
||||
*
|
||||
* \seealso EnableTiles
|
||||
*/
|
||||
inline void TileMap::EnableTile(const Vector2ui& tilePos, const Rectf& coords, const Color& color, std::size_t materialIndex)
|
||||
{
|
||||
NazaraAssert(tilePos.x < m_mapSize.x && tilePos.y < m_mapSize.y, "Tile position is out of bounds");
|
||||
NazaraAssert(materialIndex < m_layers.size(), "Material out of bounds");
|
||||
|
||||
UInt32 invalidatedLayers = 1U << materialIndex;
|
||||
|
||||
std::size_t tileIndex = tilePos.y * m_mapSize.x + tilePos.x;
|
||||
Tile& tile = m_tiles[tilePos.y * m_mapSize.x + tilePos.x];
|
||||
|
||||
if (!tile.enabled)
|
||||
m_layers[materialIndex].tiles.insert(tileIndex);
|
||||
else if (materialIndex != tile.layerIndex)
|
||||
{
|
||||
m_layers[materialIndex].tiles.erase(tileIndex);
|
||||
m_layers[tile.layerIndex].tiles.insert(tileIndex);
|
||||
|
||||
invalidatedLayers |= 1U << tile.layerIndex;
|
||||
}
|
||||
|
||||
tile.enabled = true;
|
||||
tile.color = color;
|
||||
tile.textureCoords = coords;
|
||||
tile.layerIndex = materialIndex;
|
||||
|
||||
InvalidateInstanceData(invalidatedLayers);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Enable and sets the tile at position tilePos
|
||||
*
|
||||
* Setup the tile at position tilePos using color, unnormalized coordinates rect and materialIndex
|
||||
*
|
||||
* \param tilePos Position of the tile to enable
|
||||
* \param coords Unnormalized coordinates ([0..size]) used to specify which region of the material textures will be used
|
||||
* \param color The multiplicative color applied to the tile
|
||||
* \param materialIndex The material which will be used for rendering this tile
|
||||
*
|
||||
* \remark The material at [materialIndex] must have a valid diffuse map before using this function,
|
||||
* as the size of the material diffuse map is used to compute normalized texture coordinates before returning.
|
||||
*
|
||||
* \seealso EnableTiles
|
||||
*/
|
||||
inline void TileMap::EnableTile(const Vector2ui& tilePos, const Rectui& rect, const Color& color, std::size_t materialIndex)
|
||||
{
|
||||
NazaraAssert(materialIndex < m_layers.size(), "Material out of bounds");
|
||||
NazaraAssert(m_layers[materialIndex].material->HasDiffuseMap(), "Material has no diffuse map");
|
||||
|
||||
Texture* diffuseMap = m_layers[materialIndex].material->GetDiffuseMap();
|
||||
float invWidth = 1.f / diffuseMap->GetWidth();
|
||||
float invHeight = 1.f / diffuseMap->GetHeight();
|
||||
|
||||
Rectf unnormalizedCoords(invWidth * rect.x, invHeight * rect.y, invWidth * rect.width, invHeight * rect.height);
|
||||
EnableTile(tilePos, unnormalizedCoords, color, materialIndex);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Enable and sets all the tiles
|
||||
*
|
||||
* Setup all tiles using color, normalized coordinates coords and materialIndex
|
||||
*
|
||||
* \param coords Normalized coordinates ([0..1]) used to specify which region of the material textures will be used
|
||||
* \param color The multiplicative color applied to the tile
|
||||
* \param materialIndex The material which will be used for rendering this tile
|
||||
*
|
||||
* \remark The material at [materialIndex] must have a valid diffuse map before using this function,
|
||||
* as the size of the material diffuse map is used to compute normalized texture coordinates before returning.
|
||||
*
|
||||
* \seealso EnableTile
|
||||
*/
|
||||
inline void TileMap::EnableTiles(const Rectf& coords, const Color& color, std::size_t materialIndex)
|
||||
{
|
||||
NazaraAssert(materialIndex < m_layers.size(), "Material out of bounds");
|
||||
|
||||
for (Layer& layer : m_layers)
|
||||
layer.tiles.clear();
|
||||
|
||||
std::size_t tileIndex = 0;
|
||||
for (Tile& tile : m_tiles)
|
||||
{
|
||||
tile.enabled = true;
|
||||
tile.color = color;
|
||||
tile.textureCoords = coords;
|
||||
tile.layerIndex = materialIndex;
|
||||
|
||||
m_layers[materialIndex].tiles.insert(tileIndex++);
|
||||
}
|
||||
|
||||
InvalidateInstanceData(0xFFFFFFFF);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Enable and sets all the tiles
|
||||
*
|
||||
* Setup all tiles using color, unnormalized coordinates coords and materialIndex
|
||||
*
|
||||
* \param coords Unnormalized coordinates ([0..size]) used to specify which region of the material textures will be used
|
||||
* \param color The multiplicative color applied to the tile
|
||||
* \param materialIndex The material which will be used for rendering this tile
|
||||
*
|
||||
* \remark The material at [materialIndex] must have a valid diffuse map before using this function,
|
||||
* as the size of the material diffuse map is used to compute normalized texture coordinates before returning.
|
||||
*
|
||||
* \seealso EnableTile
|
||||
*/
|
||||
inline void TileMap::EnableTiles(const Rectui& rect, const Color& color, std::size_t materialIndex)
|
||||
{
|
||||
NazaraAssert(materialIndex < m_layers.size(), "Material out of bounds");
|
||||
|
||||
Texture* diffuseMap = m_layers[materialIndex].material->GetDiffuseMap();
|
||||
float invWidth = 1.f / diffuseMap->GetWidth();
|
||||
float invHeight = 1.f / diffuseMap->GetHeight();
|
||||
|
||||
Rectf unnormalizedCoords(invWidth * rect.x, invHeight * rect.y, invWidth * rect.width, invHeight * rect.height);
|
||||
EnableTiles(unnormalizedCoords, color, materialIndex);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Enable and sets tileCount tiles at positions contained at tilesPos location, enabling rendering at those locations
|
||||
*
|
||||
* Setup all tiles using color, normalized coordinates coords and materialIndex
|
||||
*
|
||||
* \param tilesPos Pointer to a valid array of at least tileCount positions
|
||||
* \param tileCount Number of tiles to enable
|
||||
* \param coords Normalized coordinates ([0..1]) used to specify which region of the material textures will be used
|
||||
* \param color The multiplicative color applied to the tile
|
||||
* \param materialIndex The material which will be used for rendering this tile
|
||||
*
|
||||
* \seealso EnableTile
|
||||
*/
|
||||
inline void TileMap::EnableTiles(const Vector2ui* tilesPos, std::size_t tileCount, const Rectf& coords, const Color& color, std::size_t materialIndex)
|
||||
{
|
||||
NazaraAssert(tilesPos || tileCount == 0, "Invalid tile position array with a non-zero tileCount");
|
||||
NazaraAssert(materialIndex < m_layers.size(), "Material out of bounds");
|
||||
|
||||
UInt32 invalidatedLayers = 1U << materialIndex;
|
||||
|
||||
for (std::size_t i = 0; i < tileCount; ++i)
|
||||
{
|
||||
NazaraAssert(tilesPos->x < m_mapSize.x && tilesPos->y < m_mapSize.y, "Tile position is out of bounds");
|
||||
|
||||
std::size_t tileIndex = tilesPos->y * m_mapSize.x + tilesPos->x;
|
||||
Tile& tile = m_tiles[tileIndex];
|
||||
|
||||
if (!tile.enabled)
|
||||
m_layers[materialIndex].tiles.insert(tileIndex);
|
||||
else if (materialIndex != tile.layerIndex)
|
||||
{
|
||||
m_layers[materialIndex].tiles.erase(tileIndex);
|
||||
m_layers[tile.layerIndex].tiles.insert(tileIndex);
|
||||
|
||||
invalidatedLayers |= 1U << tile.layerIndex;
|
||||
}
|
||||
|
||||
tile.enabled = true;
|
||||
tile.color = color;
|
||||
tile.textureCoords = coords;
|
||||
tile.layerIndex = materialIndex;
|
||||
tilesPos++;
|
||||
}
|
||||
|
||||
if (tileCount > 0)
|
||||
InvalidateInstanceData(invalidatedLayers);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Enable and sets tileCount tiles at positions contained at tilesPos location, enabling rendering at those locations
|
||||
*
|
||||
* Setup all tiles using color, unnormalized coordinates coords and materialIndex
|
||||
*
|
||||
* \param tilesPos Pointer to a valid array of at least tileCount positions
|
||||
* \param tileCount Number of tiles to enable
|
||||
* \param coords Unnormalized coordinates ([0..size]) used to specify which region of the material textures will be used
|
||||
* \param color The multiplicative color applied to the tile
|
||||
* \param materialIndex The material which will be used for rendering this tile
|
||||
*
|
||||
* \remark The material at [materialIndex] must have a valid diffuse map before using this function,
|
||||
* as the size of the material diffuse map is used to compute normalized texture coordinates before returning.
|
||||
*
|
||||
* \seealso EnableTile
|
||||
*/
|
||||
inline void TileMap::EnableTiles(const Vector2ui* tilesPos, std::size_t tileCount, const Rectui& rect, const Color& color, std::size_t materialIndex)
|
||||
{
|
||||
NazaraAssert(materialIndex < m_layers.size(), "Material out of bounds");
|
||||
NazaraAssert(m_layers[materialIndex].material->HasDiffuseMap(), "Material has no diffuse map");
|
||||
|
||||
Texture* diffuseMap = m_layers[materialIndex].material->GetDiffuseMap();
|
||||
float invWidth = 1.f / diffuseMap->GetWidth();
|
||||
float invHeight = 1.f / diffuseMap->GetHeight();
|
||||
|
||||
Rectf unnormalizedCoords(invWidth * rect.x, invHeight * rect.y, invWidth * rect.width, invHeight * rect.height);
|
||||
EnableTiles(tilesPos, tileCount, unnormalizedCoords, color, materialIndex);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the material at position index used by the TileMap
|
||||
*
|
||||
* \param index Index of the material to query
|
||||
*
|
||||
* \return Material at index
|
||||
*/
|
||||
inline const MaterialRef& TileMap::GetMaterial(std::size_t index) const
|
||||
{
|
||||
NazaraAssert(index < m_layers.size(), "Material out of bounds");
|
||||
|
||||
return m_layers[index].material;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the maximum material count this TileMap can use
|
||||
* \return Material count
|
||||
*/
|
||||
inline std::size_t TileMap::GetMaterialCount() const
|
||||
{
|
||||
return m_layers.size();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the tilemap size (i.e. number of tiles in each dimension)
|
||||
* \return Number of tiles in each dimension
|
||||
*
|
||||
* \seealso GetSize
|
||||
* \seealso GetTileSize
|
||||
*/
|
||||
inline const Vector2ui& TileMap::GetMapSize() const
|
||||
{
|
||||
return m_mapSize;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the size of the tilemap in units (which is equivalent to GetMapSize() * GetTileSize())
|
||||
* \return Maximum size in units occupied by this tilemap
|
||||
*
|
||||
* \seealso GetMapSize
|
||||
* \seealso GetTileSize
|
||||
*/
|
||||
inline Vector2f TileMap::GetSize() const
|
||||
{
|
||||
return Vector2f(m_mapSize) * m_tileSize;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns informations about a particular tile
|
||||
*
|
||||
* \param tilePos Position of the tile to get (enabled or not)
|
||||
*
|
||||
* \return Maximum size in units occupied by this tilemap
|
||||
*/
|
||||
inline const TileMap::Tile& TileMap::GetTile(const Vector2ui& tilePos) const
|
||||
{
|
||||
NazaraAssert(tilePos.x < m_mapSize.x && tilePos.y < m_mapSize.y, "Tile position is out of bounds");
|
||||
|
||||
return m_tiles[tilePos.y * m_mapSize.x + tilePos.x];
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the tile size (i.e. number of units occupied by a tile in each dimension)
|
||||
* \return Tile size in each dimension
|
||||
*
|
||||
* \seealso GetMapSize
|
||||
* \seealso GetSize
|
||||
*/
|
||||
inline const Vector2f& TileMap::GetTileSize() const
|
||||
{
|
||||
return m_tileSize;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets a material of the TileMap
|
||||
*
|
||||
* \param index Index of the material to change
|
||||
* \param material Material for the TileMap
|
||||
*/
|
||||
inline void TileMap::SetMaterial(std::size_t index, MaterialRef material)
|
||||
{
|
||||
NazaraAssert(index < m_layers.size(), "Material out of bounds");
|
||||
|
||||
m_layers[index].material = std::move(material);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the current TileMap with the content of the other one
|
||||
* \return A reference to this
|
||||
*
|
||||
* \param TileMap The other TileMap
|
||||
*/
|
||||
inline TileMap& TileMap::operator=(const TileMap& TileMap)
|
||||
{
|
||||
InstancedRenderable::operator=(TileMap);
|
||||
|
||||
m_layers = TileMap.m_layers;
|
||||
m_mapSize = TileMap.m_mapSize;
|
||||
m_tiles = TileMap.m_tiles;
|
||||
m_tileSize = TileMap.m_tileSize;
|
||||
|
||||
// We do not copy final vertices because it's highly probable that our parameters are modified and they must be regenerated
|
||||
InvalidateBoundingVolume();
|
||||
InvalidateInstanceData(0xFFFFFFFF);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Creates a new TileMap from the arguments
|
||||
* \return A reference to the newly created TileMap
|
||||
*
|
||||
* \param args Arguments for the TileMap
|
||||
*/
|
||||
template<typename... Args>
|
||||
TileMapRef TileMap::New(Args&&... args)
|
||||
{
|
||||
std::unique_ptr<TileMap> object(new TileMap(std::forward<Args>(args)...));
|
||||
object->SetPersistent(false);
|
||||
|
||||
return object.release();
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
|
|
@ -20,6 +20,7 @@
|
|||
#include <Nazara/Graphics/SkinningManager.hpp>
|
||||
#include <Nazara/Graphics/SkyboxBackground.hpp>
|
||||
#include <Nazara/Graphics/Sprite.hpp>
|
||||
#include <Nazara/Graphics/TileMap.hpp>
|
||||
#include <Nazara/Graphics/Formats/MeshLoader.hpp>
|
||||
#include <Nazara/Graphics/Formats/TextureLoader.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
|
|
@ -110,6 +111,12 @@ namespace Nz
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!TileMap::Initialize())
|
||||
{
|
||||
NazaraError("Failed to initialize tilemaps");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Generic loaders
|
||||
Loaders::RegisterMesh();
|
||||
Loaders::RegisterTexture();
|
||||
|
|
@ -217,6 +224,7 @@ namespace Nz
|
|||
Material::Uninitialize();
|
||||
SkyboxBackground::Uninitialize();
|
||||
Sprite::Uninitialize();
|
||||
TileMap::Uninitialize();
|
||||
|
||||
NazaraNotice("Uninitialized: Graphics module");
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,110 @@
|
|||
// Copyright (C) 2015 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Graphics/TileMap.hpp>
|
||||
#include <Nazara/Graphics/AbstractRenderQueue.hpp>
|
||||
#include <Nazara/Graphics/AbstractViewer.hpp>
|
||||
#include <Nazara/Math/Rect.hpp>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
/*!
|
||||
* \ingroup graphics
|
||||
* \class Nz::TileMap
|
||||
* \brief Graphics class that represent several tiles of the same size assembled into a grid
|
||||
* This class is far more efficient than using a sprite for every tile
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Adds the TileMap to the rendering queue
|
||||
*
|
||||
* \param renderQueue Queue to be added
|
||||
* \param instanceData Data for the instance
|
||||
*/
|
||||
void TileMap::AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const
|
||||
{
|
||||
const VertexStruct_XYZ_Color_UV* vertices = reinterpret_cast<const VertexStruct_XYZ_Color_UV*>(instanceData.data.data());
|
||||
|
||||
std::size_t spriteCount = 0;
|
||||
for (const Layer& layer : m_layers)
|
||||
{
|
||||
if (layer.material)
|
||||
renderQueue->AddSprites(instanceData.renderOrder, layer.material, &vertices[spriteCount], layer.tiles.size());
|
||||
|
||||
spriteCount += layer.tiles.size();
|
||||
}
|
||||
}
|
||||
|
||||
void TileMap::MakeBoundingVolume() const
|
||||
{
|
||||
Nz::Vector2f size = GetSize();
|
||||
m_boundingVolume.Set(Vector3f(0.f), size.x*Vector3f::Right() + size.y*Vector3f::Down());
|
||||
}
|
||||
|
||||
void TileMap::UpdateData(InstanceData* instanceData) const
|
||||
{
|
||||
std::size_t spriteCount = 0;
|
||||
for (const Layer& layer : m_layers)
|
||||
spriteCount += layer.tiles.size();
|
||||
|
||||
instanceData->data.resize(4 * spriteCount * sizeof(VertexStruct_XYZ_Color_UV));
|
||||
VertexStruct_XYZ_Color_UV* vertices = reinterpret_cast<VertexStruct_XYZ_Color_UV*>(instanceData->data.data());
|
||||
|
||||
spriteCount = 0;
|
||||
for (const Layer& layer : m_layers)
|
||||
{
|
||||
SparsePtr<Color> colorPtr(&vertices[spriteCount].color, sizeof(VertexStruct_XYZ_Color_UV));
|
||||
SparsePtr<Vector3f> posPtr(&vertices[spriteCount].position, sizeof(VertexStruct_XYZ_Color_UV));
|
||||
SparsePtr<Vector2f> texCoordPtr(&vertices[spriteCount].uv, sizeof(VertexStruct_XYZ_Color_UV));
|
||||
|
||||
for (std::size_t tileIndex : layer.tiles)
|
||||
{
|
||||
const Tile& tile = m_tiles[tileIndex];
|
||||
NazaraAssert(tile.enabled, "Tile specified for rendering is not enabled");
|
||||
|
||||
std::size_t x = tileIndex % m_mapSize.x;
|
||||
std::size_t y = tileIndex / m_mapSize.x;
|
||||
Vector3f tileLeftCorner(x * m_tileSize.x, y * -m_tileSize.y, 0.f);
|
||||
|
||||
*colorPtr++ = tile.color;
|
||||
*posPtr++ = instanceData->transformMatrix->Transform(tileLeftCorner);
|
||||
*texCoordPtr++ = tile.textureCoords.GetCorner(RectCorner_LeftTop);
|
||||
|
||||
*colorPtr++ = tile.color;
|
||||
*posPtr++ = instanceData->transformMatrix->Transform(tileLeftCorner + m_tileSize.x * Vector3f::Right());
|
||||
*texCoordPtr++ = tile.textureCoords.GetCorner(RectCorner_RightTop);
|
||||
|
||||
*colorPtr++ = tile.color;
|
||||
*posPtr++ = instanceData->transformMatrix->Transform(tileLeftCorner + m_tileSize.y * Vector3f::Down());
|
||||
*texCoordPtr++ = tile.textureCoords.GetCorner(RectCorner_LeftBottom);
|
||||
|
||||
*colorPtr++ = tile.color;
|
||||
*posPtr++ = instanceData->transformMatrix->Transform(tileLeftCorner + m_tileSize.x * Vector3f::Right() + m_tileSize.y * Vector3f::Down());
|
||||
*texCoordPtr++ = tile.textureCoords.GetCorner(RectCorner_RightBottom);
|
||||
}
|
||||
spriteCount += layer.tiles.size();
|
||||
}
|
||||
}
|
||||
|
||||
bool TileMap::Initialize()
|
||||
{
|
||||
if (!TileMapLibrary::Initialize())
|
||||
{
|
||||
NazaraError("Failed to initialise library");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TileMap::Uninitialize()
|
||||
{
|
||||
TileMapLibrary::Uninitialize();
|
||||
}
|
||||
|
||||
TileMapLibrary::LibraryMap TileMap::s_library;
|
||||
}
|
||||
Loading…
Reference in New Issue