Graphics: Add origin to all sprite-based renderables (and made it a factor)

This commit is contained in:
SirLynix 2022-12-17 14:48:50 +01:00
parent 0537be3201
commit d4422c4102
12 changed files with 98 additions and 38 deletions

View File

@ -38,8 +38,10 @@ namespace Nz
const std::shared_ptr<MaterialInstance>& GetMaterial(std::size_t i = 0) const override; const std::shared_ptr<MaterialInstance>& GetMaterial(std::size_t i = 0) const override;
std::size_t GetMaterialCount() const override; std::size_t GetMaterialCount() const override;
inline Orientation GetOrientation() const; inline Orientation GetOrientation() const;
inline const Vector2f& GetOrigin() const;
inline const Section& GetSection(std::size_t sectionIndex) const; inline const Section& GetSection(std::size_t sectionIndex) const;
std::size_t GetSectionCount() const; std::size_t GetSectionCount() const;
inline float GetSize() const;
inline const Rectf& GetTextureCoords() const; inline const Rectf& GetTextureCoords() const;
Vector3ui GetTextureSize() const; Vector3ui GetTextureSize() const;
@ -47,10 +49,11 @@ namespace Nz
inline void SetColor(const Color& color); inline void SetColor(const Color& color);
inline void SetMaterial(std::shared_ptr<MaterialInstance> material); inline void SetMaterial(std::shared_ptr<MaterialInstance> material);
inline void SetOrigin(const Vector2f& origin);
inline void SetSection(std::size_t sectionIndex, float size, float textureCoord); inline void SetSection(std::size_t sectionIndex, float size, float textureCoord);
inline void SetSectionSize(std::size_t sectionIndex, float size); inline void SetSectionSize(std::size_t sectionIndex, float size);
inline void SetSectionTextureCoord(std::size_t sectionIndex, float textureCoord); inline void SetSectionTextureCoord(std::size_t sectionIndex, float textureCoord);
inline void SetSize(const Vector2f& size); inline void SetSize(float size);
inline void SetTextureCoords(const Rectf& textureCoords); inline void SetTextureCoords(const Rectf& textureCoords);
inline void SetTextureRect(const Rectf& textureRect); inline void SetTextureRect(const Rectf& textureRect);
@ -82,7 +85,8 @@ namespace Nz
Color m_color; Color m_color;
Orientation m_orientation; Orientation m_orientation;
Rectf m_textureCoords; Rectf m_textureCoords;
Vector2f m_size; Vector2f m_origin;
float m_size;
}; };
} }

View File

@ -37,6 +37,11 @@ namespace Nz
return m_orientation; return m_orientation;
} }
inline const Vector2f& LinearSlicedSprite::GetOrigin() const
{
return m_origin;
}
inline auto LinearSlicedSprite::GetSection(std::size_t sectionIndex) const -> const Section& inline auto LinearSlicedSprite::GetSection(std::size_t sectionIndex) const -> const Section&
{ {
NazaraAssert(sectionIndex < m_sectionCount, "out of range section"); NazaraAssert(sectionIndex < m_sectionCount, "out of range section");
@ -48,6 +53,11 @@ namespace Nz
return m_sectionCount; return m_sectionCount;
} }
inline float LinearSlicedSprite::GetSize() const
{
return m_size;
}
inline const Rectf& LinearSlicedSprite::GetTextureCoords() const inline const Rectf& LinearSlicedSprite::GetTextureCoords() const
{ {
return m_textureCoords; return m_textureCoords;
@ -84,6 +94,13 @@ namespace Nz
} }
} }
inline void LinearSlicedSprite::SetOrigin(const Vector2f& origin)
{
m_origin = origin;
UpdateVertices();
}
inline void LinearSlicedSprite::SetSection(std::size_t sectionIndex, float size, float textureCoord) inline void LinearSlicedSprite::SetSection(std::size_t sectionIndex, float size, float textureCoord)
{ {
NazaraAssert(sectionIndex < m_sectionCount, "out of range section"); NazaraAssert(sectionIndex < m_sectionCount, "out of range section");
@ -115,10 +132,9 @@ namespace Nz
UpdateVertices(); UpdateVertices();
} }
inline void LinearSlicedSprite::SetSize(const Vector2f& size) inline void LinearSlicedSprite::SetSize(float size)
{ {
NazaraAssert(size.x >= 0.f, "width must be positive"); NazaraAssert(size >= 0.f, "size must be positive");
NazaraAssert(size.y >= 0.f, "height must be positive");
m_size = size; m_size = size;

View File

@ -33,6 +33,8 @@ namespace Nz
inline const Corner& GetBottomRightCorner() const; inline const Corner& GetBottomRightCorner() const;
const std::shared_ptr<MaterialInstance>& GetMaterial(std::size_t i = 0) const override; const std::shared_ptr<MaterialInstance>& GetMaterial(std::size_t i = 0) const override;
std::size_t GetMaterialCount() const override; std::size_t GetMaterialCount() const override;
inline const Vector2f& GetOrigin() const;
inline const Vector2f& GetSize() const;
inline const Corner& GetTopLeftCorner() const; inline const Corner& GetTopLeftCorner() const;
inline const Rectf& GetTextureCoords() const; inline const Rectf& GetTextureCoords() const;
Vector3ui GetTextureSize() const; Vector3ui GetTextureSize() const;
@ -42,6 +44,7 @@ namespace Nz
inline void SetCornersSize(const Vector2f& topLeftSize, const Vector2f& bottomRightSize); inline void SetCornersSize(const Vector2f& topLeftSize, const Vector2f& bottomRightSize);
inline void SetCornersTextureCoords(const Vector2f& topLeftTextureCoords, const Vector2f& bottomRightTextureCoords); inline void SetCornersTextureCoords(const Vector2f& topLeftTextureCoords, const Vector2f& bottomRightTextureCoords);
inline void SetMaterial(std::shared_ptr<MaterialInstance> material); inline void SetMaterial(std::shared_ptr<MaterialInstance> material);
inline void SetOrigin(const Vector2f& origin);
inline void SetSize(const Vector2f& size); inline void SetSize(const Vector2f& size);
inline void SetTextureCoords(const Rectf& textureCoords); inline void SetTextureCoords(const Rectf& textureCoords);
inline void SetTextureRect(const Rectf& textureRect); inline void SetTextureRect(const Rectf& textureRect);
@ -65,6 +68,7 @@ namespace Nz
Corner m_topLeftCorner; Corner m_topLeftCorner;
Corner m_bottomRightCorner; Corner m_bottomRightCorner;
Rectf m_textureCoords; Rectf m_textureCoords;
Vector2f m_origin;
Vector2f m_size; Vector2f m_size;
}; };
} }

View File

@ -23,6 +23,16 @@ namespace Nz
return m_textureCoords; return m_textureCoords;
} }
inline const Vector2f& SlicedSprite::GetOrigin() const
{
return m_origin;
}
inline const Vector2f& SlicedSprite::GetSize() const
{
return m_size;
}
inline auto SlicedSprite::GetTopLeftCorner() const -> const Corner& inline auto SlicedSprite::GetTopLeftCorner() const -> const Corner&
{ {
return m_topLeftCorner; return m_topLeftCorner;
@ -72,6 +82,13 @@ namespace Nz
} }
} }
inline void SlicedSprite::SetOrigin(const Vector2f& origin)
{
m_origin = origin;
UpdateVertices();
}
inline void SlicedSprite::SetSize(const Vector2f& size) inline void SlicedSprite::SetSize(const Vector2f& size)
{ {
m_size = size; m_size = size;

View File

@ -31,7 +31,7 @@ namespace Nz
inline const Color& GetCornerColor(RectCorner corner) const; inline const Color& GetCornerColor(RectCorner corner) const;
const std::shared_ptr<MaterialInstance>& GetMaterial(std::size_t i = 0) const override; const std::shared_ptr<MaterialInstance>& GetMaterial(std::size_t i = 0) const override;
std::size_t GetMaterialCount() const override; std::size_t GetMaterialCount() const override;
inline const Vector3f& GetOrigin() const; inline const Vector2f& GetOrigin() const;
inline const Vector2f& GetSize() const; inline const Vector2f& GetSize() const;
inline const Rectf& GetTextureCoords() const; inline const Rectf& GetTextureCoords() const;
Vector3ui GetTextureSize() const; Vector3ui GetTextureSize() const;
@ -39,7 +39,7 @@ namespace Nz
inline void SetColor(const Color& color); inline void SetColor(const Color& color);
inline void SetCornerColor(RectCorner corner, const Color& color); inline void SetCornerColor(RectCorner corner, const Color& color);
inline void SetMaterial(std::shared_ptr<MaterialInstance> material); inline void SetMaterial(std::shared_ptr<MaterialInstance> material);
inline void SetOrigin(const Vector3f& origin); inline void SetOrigin(const Vector2f& origin);
inline void SetSize(const Vector2f& size); inline void SetSize(const Vector2f& size);
inline void SetTextureCoords(const Rectf& textureCoords); inline void SetTextureCoords(const Rectf& textureCoords);
inline void SetTextureRect(const Rectf& textureRect); inline void SetTextureRect(const Rectf& textureRect);
@ -55,8 +55,8 @@ namespace Nz
std::shared_ptr<MaterialInstance> m_material; std::shared_ptr<MaterialInstance> m_material;
Color m_color; Color m_color;
Rectf m_textureCoords; Rectf m_textureCoords;
Vector2f m_origin;
Vector2f m_size; Vector2f m_size;
Vector3f m_origin;
}; };
} }

View File

@ -18,7 +18,7 @@ namespace Nz
return m_cornerColor[UnderlyingCast(corner)]; return m_cornerColor[UnderlyingCast(corner)];
} }
inline const Vector3f& Sprite::GetOrigin() const inline const Vector2f& Sprite::GetOrigin() const
{ {
return m_origin; return m_origin;
} }
@ -60,7 +60,7 @@ namespace Nz
} }
} }
inline void Sprite::SetOrigin(const Vector3f& origin) inline void Sprite::SetOrigin(const Vector2f& origin)
{ {
m_origin = origin; m_origin = origin;
@ -99,10 +99,12 @@ namespace Nz
cornerExtent[UnderlyingCast(RectCorner::LeftTop)] = Vector2f(0.f, 1.f); cornerExtent[UnderlyingCast(RectCorner::LeftTop)] = Vector2f(0.f, 1.f);
cornerExtent[UnderlyingCast(RectCorner::RightTop)] = Vector2f(1.f, 1.f); cornerExtent[UnderlyingCast(RectCorner::RightTop)] = Vector2f(1.f, 1.f);
Vector3f originShift = m_origin * m_size;
for (RectCorner corner : { RectCorner::LeftBottom, RectCorner::RightBottom, RectCorner::LeftTop, RectCorner::RightTop }) for (RectCorner corner : { RectCorner::LeftBottom, RectCorner::RightBottom, RectCorner::LeftTop, RectCorner::RightTop })
{ {
vertices->color = m_color * m_cornerColor[UnderlyingCast(corner)]; vertices->color = m_color * m_cornerColor[UnderlyingCast(corner)];
vertices->position = Vector3f(m_size * cornerExtent[UnderlyingCast(corner)], 0.f) - m_origin; vertices->position = Vector3f(m_size * cornerExtent[UnderlyingCast(corner)], 0.f) - originShift;
vertices->uv = m_textureCoords.GetCorner(corner); vertices->uv = m_textureCoords.GetCorner(corner);
if (aabb.IsValid()) if (aabb.IsValid())

View File

@ -47,6 +47,7 @@ namespace Nz
inline const Vector2ui& GetMapSize() const; inline const Vector2ui& GetMapSize() const;
const std::shared_ptr<MaterialInstance>& GetMaterial(std::size_t i) const override; const std::shared_ptr<MaterialInstance>& GetMaterial(std::size_t i) const override;
std::size_t GetMaterialCount() const override; std::size_t GetMaterialCount() const override;
inline const Vector2f& GetOrigin() const;
inline Vector2f GetSize() const; inline Vector2f GetSize() const;
inline const Tile& GetTile(const Vector2ui& tilePos) const; inline const Tile& GetTile(const Vector2ui& tilePos) const;
inline const Vector2f& GetTileSize() const; inline const Vector2f& GetTileSize() const;
@ -54,7 +55,7 @@ namespace Nz
inline bool IsIsometricModeEnabled() const; inline bool IsIsometricModeEnabled() const;
void SetMaterial(std::size_t matIndex, std::shared_ptr<MaterialInstance> material); void SetMaterial(std::size_t matIndex, std::shared_ptr<MaterialInstance> material);
inline void SetOrigin(const Vector3f& origin); inline void SetOrigin(const Vector2f& origin);
struct Tile struct Tile
{ {
@ -82,8 +83,8 @@ namespace Nz
std::vector<Tile> m_tiles; std::vector<Tile> m_tiles;
std::vector<Layer> m_layers; std::vector<Layer> m_layers;
Vector2ui m_mapSize; Vector2ui m_mapSize;
Vector2f m_origin;
Vector2f m_tileSize; Vector2f m_tileSize;
Vector3f m_origin;
bool m_isometricModeEnabled; bool m_isometricModeEnabled;
mutable bool m_shouldRebuildVertices; mutable bool m_shouldRebuildVertices;
}; };

View File

@ -310,6 +310,15 @@ namespace Nz
return m_mapSize; return m_mapSize;
} }
/*!
* \brief Gets the tilemap origin
* \return Tilemap origin
*/
inline const Vector2f& Tilemap::GetOrigin() const
{
return m_origin;
}
/*! /*!
* \brief Returns the size of the tilemap in units (which is equivalent to GetMapSize() * GetTileSize()) * \brief Returns the size of the tilemap in units (which is equivalent to GetMapSize() * GetTileSize())
* \return Maximum size in units occupied by this tilemap * \return Maximum size in units occupied by this tilemap
@ -359,7 +368,7 @@ namespace Nz
return m_isometricModeEnabled; return m_isometricModeEnabled;
} }
inline void Tilemap::SetOrigin(const Vector3f& origin) inline void Tilemap::SetOrigin(const Vector2f& origin)
{ {
m_origin = origin; m_origin = origin;

View File

@ -18,7 +18,8 @@ namespace Nz
m_color(Color::White), m_color(Color::White),
m_orientation(orientation), m_orientation(orientation),
m_textureCoords(0.f, 0.f, 1.f, 1.f), m_textureCoords(0.f, 0.f, 1.f, 1.f),
m_size(64.f, 64.f) m_origin(0.f, 0.f),
m_size(64.f)
{ {
UpdateVertices(); UpdateVertices();
} }
@ -74,16 +75,20 @@ namespace Nz
void LinearSlicedSprite::UpdateVertices() void LinearSlicedSprite::UpdateVertices()
{ {
VertexStruct_XYZ_Color_UV* vertices = m_vertices.data(); float totalSectionSize = 0.f;
for (const Section& section : m_sections)
totalSectionSize += std::max(section.size, 0.f);
Vector3f origin = Vector3f::Zero(); Vector2f originShift = m_origin * ((m_orientation == Orientation::Horizontal) ? Vector2f(totalSectionSize, m_size) : Vector2f(m_size, totalSectionSize));
Vector3f topLeftCorner = -originShift;
Vector2f topLeftUV = m_textureCoords.GetCorner(RectCorner::LeftTop); Vector2f topLeftUV = m_textureCoords.GetCorner(RectCorner::LeftTop);
m_spriteCount = 0; m_spriteCount = 0;
for (std::size_t i = 0; i < m_sectionCount; ++i) VertexStruct_XYZ_Color_UV* vertices = m_vertices.data();
for (const Section& section : m_sections)
{ {
const auto& section = m_sections[i];
if (section.size <= 0.f) if (section.size <= 0.f)
continue; continue;
@ -93,37 +98,37 @@ namespace Nz
if (m_orientation == Orientation::Horizontal) if (m_orientation == Orientation::Horizontal)
{ {
dir = Vector2(1.f, 0.f); dir = Vector2(1.f, 0.f);
size = Vector2f(section.size, m_size.y); size = Vector2f(section.size, m_size);
texCoords = Vector2f(section.textureCoord, m_textureCoords.height); texCoords = Vector2f(section.textureCoord, m_textureCoords.height);
} }
else else
{ {
dir = Vector2(0.f, 1.f); dir = Vector2(0.f, 1.f);
size = Vector2f(m_size.x, section.size); size = Vector2f(m_size, section.size);
texCoords = Vector2f(m_textureCoords.width, section.textureCoord); texCoords = Vector2f(m_textureCoords.width, section.textureCoord);
} }
vertices->color = m_color; vertices->color = m_color;
vertices->position = origin; vertices->position = topLeftCorner;
vertices->uv = topLeftUV; vertices->uv = topLeftUV;
vertices++; vertices++;
vertices->color = m_color; vertices->color = m_color;
vertices->position = origin + size.x * Vector3f::Right(); vertices->position = topLeftCorner + size.x * Vector3f::Right();
vertices->uv = topLeftUV + Vector2f(texCoords.x, 0.f); vertices->uv = topLeftUV + Vector2f(texCoords.x, 0.f);
vertices++; vertices++;
vertices->color = m_color; vertices->color = m_color;
vertices->position = origin + size.y * Vector3f::Up(); vertices->position = topLeftCorner + size.y * Vector3f::Up();
vertices->uv = topLeftUV + Vector2f(0.f, texCoords.y); vertices->uv = topLeftUV + Vector2f(0.f, texCoords.y);
vertices++; vertices++;
vertices->color = m_color; vertices->color = m_color;
vertices->position = origin + size.x * Vector3f::Right() + size.y * Vector3f::Up(); vertices->position = topLeftCorner + size.x * Vector3f::Right() + size.y * Vector3f::Up();
vertices->uv = topLeftUV + Vector2f(texCoords.x, texCoords.y); vertices->uv = topLeftUV + Vector2f(texCoords.x, texCoords.y);
vertices++; vertices++;
origin += dir * section.size; topLeftCorner += dir * section.size;
topLeftUV += dir * section.textureCoord; topLeftUV += dir * section.textureCoord;
m_spriteCount++; m_spriteCount++;
} }

View File

@ -15,6 +15,7 @@ namespace Nz
m_material(std::move(material)), m_material(std::move(material)),
m_color(Color::White), m_color(Color::White),
m_textureCoords(0.f, 0.f, 1.f, 1.f), m_textureCoords(0.f, 0.f, 1.f, 1.f),
m_origin(0.f, 0.f),
m_size(64.f, 64.f) m_size(64.f, 64.f)
{ {
UpdateVertices(); UpdateVertices();
@ -98,7 +99,8 @@ namespace Nz
m_bottomRightCorner.textureCoords.y * m_textureCoords.height m_bottomRightCorner.textureCoords.y * m_textureCoords.height
}; };
Vector3f origin = Vector3f::Zero(); Vector3f originShift = m_origin * m_size;
Vector3f topLeftCorner = -originShift;
Vector2f topLeftUV = m_textureCoords.GetCorner(RectCorner::LeftTop); Vector2f topLeftUV = m_textureCoords.GetCorner(RectCorner::LeftTop);
m_spriteCount = 0; m_spriteCount = 0;
@ -113,36 +115,36 @@ namespace Nz
if (width > 0.f) if (width > 0.f)
{ {
vertices->color = m_color; vertices->color = m_color;
vertices->position = origin; vertices->position = topLeftCorner;
vertices->uv = topLeftUV; vertices->uv = topLeftUV;
vertices++; vertices++;
vertices->color = m_color; vertices->color = m_color;
vertices->position = origin + width * Vector3f::Right(); vertices->position = topLeftCorner + width * Vector3f::Right();
vertices->uv = topLeftUV + Vector2f(texCoordsX[x], 0.f); vertices->uv = topLeftUV + Vector2f(texCoordsX[x], 0.f);
vertices++; vertices++;
vertices->color = m_color; vertices->color = m_color;
vertices->position = origin + height * Vector3f::Up(); vertices->position = topLeftCorner + height * Vector3f::Up();
vertices->uv = topLeftUV + Vector2f(0.f, texCoordsY[y]); vertices->uv = topLeftUV + Vector2f(0.f, texCoordsY[y]);
vertices++; vertices++;
vertices->color = m_color; vertices->color = m_color;
vertices->position = origin + width * Vector3f::Right() + height * Vector3f::Up(); vertices->position = topLeftCorner + width * Vector3f::Right() + height * Vector3f::Up();
vertices->uv = topLeftUV + Vector2f(texCoordsX[x], texCoordsY[y]); vertices->uv = topLeftUV + Vector2f(texCoordsX[x], texCoordsY[y]);
vertices++; vertices++;
origin.x += width; topLeftCorner.x += width;
m_spriteCount++; m_spriteCount++;
} }
topLeftUV.x += texCoordsX[x]; topLeftUV.x += texCoordsX[x];
} }
origin.y += height; topLeftCorner.y += height;
} }
origin.x = 0; topLeftCorner.x = -originShift.x;
topLeftUV.x = m_textureCoords.x; topLeftUV.x = m_textureCoords.x;
topLeftUV.y += texCoordsY[y]; topLeftUV.y += texCoordsY[y];

View File

@ -16,8 +16,8 @@ namespace Nz
m_material(std::move(material)), m_material(std::move(material)),
m_color(Color::White), m_color(Color::White),
m_textureCoords(0.f, 0.f, 1.f, 1.f), m_textureCoords(0.f, 0.f, 1.f, 1.f),
m_size(64.f, 64.f), m_origin(0.f, 0.f),
m_origin(0.f, 0.f, 0.f) m_size(64.f, 64.f)
{ {
m_cornerColor.fill(Color::White); m_cornerColor.fill(Color::White);

View File

@ -27,6 +27,7 @@ namespace Nz
m_layers(materialCount), m_layers(materialCount),
m_mapSize(mapSize), m_mapSize(mapSize),
m_tileSize(tileSize), m_tileSize(tileSize),
m_origin(0.f, 0.f),
m_isometricModeEnabled(false), m_isometricModeEnabled(false),
m_shouldRebuildVertices(false) m_shouldRebuildVertices(false)
{ {
@ -120,9 +121,8 @@ namespace Nz
m_vertices.resize(spriteCount * 4); m_vertices.resize(spriteCount * 4);
VertexStruct_XYZ_Color_UV* vertexPtr = reinterpret_cast<VertexStruct_XYZ_Color_UV*>(m_vertices.data()); VertexStruct_XYZ_Color_UV* vertexPtr = reinterpret_cast<VertexStruct_XYZ_Color_UV*>(m_vertices.data());
Vector3f originShift = m_origin * GetSize();
float topCorner = m_tileSize.y * (m_mapSize.y - 1); float topCorner = m_tileSize.y * (m_mapSize.y - 1);
Vector3f originShift = m_origin * GetSize();
for (const Layer& layer : m_layers) for (const Layer& layer : m_layers)
{ {