122 lines
2.7 KiB
C++
122 lines
2.7 KiB
C++
#include "TileLayout.hpp"
|
|
|
|
#include <algorithm>
|
|
#include <cmath>
|
|
|
|
namespace
|
|
{
|
|
std::vector<Vertex> makeQuad(
|
|
float x0,
|
|
float y0,
|
|
float x1,
|
|
float y1)
|
|
{
|
|
return {
|
|
{{x0, y0}, {0.0f, 0.0f}},
|
|
{{x1, y0}, {1.0f, 0.0f}},
|
|
{{x1, y1}, {1.0f, 1.0f}},
|
|
|
|
{{x0, y0}, {0.0f, 0.0f}},
|
|
{{x1, y1}, {1.0f, 1.0f}},
|
|
{{x0, y1}, {0.0f, 1.0f}},
|
|
};
|
|
}
|
|
}
|
|
|
|
std::vector<Vertex> makeGridLayout(
|
|
uint32_t cols,
|
|
uint32_t rows,
|
|
float gapX,
|
|
float gapY)
|
|
{
|
|
std::vector<Vertex> vertices;
|
|
vertices.reserve(
|
|
static_cast<size_t>(cols) * rows * 6);
|
|
|
|
const float tileW =
|
|
(2.0f - gapX * static_cast<float>(cols - 1)) /
|
|
static_cast<float>(cols);
|
|
const float tileH =
|
|
(2.0f - gapY * static_cast<float>(rows - 1)) /
|
|
static_cast<float>(rows);
|
|
|
|
for (uint32_t row = 0; row < rows; ++row)
|
|
{
|
|
for (uint32_t col = 0; col < cols; ++col)
|
|
{
|
|
const float x0 =
|
|
-1.0f +
|
|
static_cast<float>(col) * (tileW + gapX);
|
|
const float y0 =
|
|
-1.0f +
|
|
static_cast<float>(row) * (tileH + gapY);
|
|
const float x1 = x0 + tileW;
|
|
const float y1 = y0 + tileH;
|
|
|
|
auto quad = makeQuad(x0, y0, x1, y1);
|
|
vertices.insert(
|
|
vertices.end(),
|
|
quad.begin(),
|
|
quad.end());
|
|
}
|
|
}
|
|
|
|
return vertices;
|
|
}
|
|
|
|
void updateGridLayout(
|
|
Vertex* vertices,
|
|
uint32_t cols,
|
|
uint32_t rows,
|
|
float gapX,
|
|
float gapY)
|
|
{
|
|
std::vector<Vertex> updated =
|
|
makeGridLayout(cols, rows, gapX, gapY);
|
|
|
|
std::copy(
|
|
updated.begin(),
|
|
updated.end(),
|
|
vertices
|
|
);
|
|
}
|
|
|
|
void updateUvForAspectRatio(
|
|
Vertex* vertices,
|
|
uint32_t quadIndex,
|
|
float srcAspect,
|
|
float tileAspect)
|
|
{
|
|
Vertex* quad = vertices + quadIndex * 6;
|
|
|
|
float uMin = 0.0f;
|
|
float uMax = 1.0f;
|
|
float vMin = 0.0f;
|
|
float vMax = 1.0f;
|
|
|
|
if (srcAspect > tileAspect)
|
|
{
|
|
float scale = tileAspect / srcAspect;
|
|
float bar = (1.0f - scale) * 0.5f;
|
|
vMin = bar;
|
|
vMax = 1.0f - bar;
|
|
}
|
|
else if (srcAspect < tileAspect)
|
|
{
|
|
float scale = srcAspect / tileAspect;
|
|
float bar = (1.0f - scale) * 0.5f;
|
|
uMin = bar;
|
|
uMax = 1.0f - bar;
|
|
}
|
|
|
|
// Triangle 1: vertices 0-2
|
|
quad[0].uv[0] = uMin; quad[0].uv[1] = vMin;
|
|
quad[1].uv[0] = uMax; quad[1].uv[1] = vMin;
|
|
quad[2].uv[0] = uMax; quad[2].uv[1] = vMax;
|
|
|
|
// Triangle 2: vertices 3-5
|
|
quad[3].uv[0] = uMin; quad[3].uv[1] = vMin;
|
|
quad[4].uv[0] = uMax; quad[4].uv[1] = vMax;
|
|
quad[5].uv[0] = uMin; quad[5].uv[1] = vMax;
|
|
}
|