Preserve 16:9 tile aspect on resize

This commit is contained in:
Johanness
2026-05-19 00:37:12 +03:00
parent 52e9898701
commit 3df545e95c
3 changed files with 157 additions and 83 deletions
+101 -22
View File
@@ -21,46 +21,116 @@ std::vector<Vertex> makeQuad(
{{x0, y1}, {0.0f, 1.0f}},
};
}
float toNdcX(float x, float viewportWidth)
{
return x * 2.0f / viewportWidth - 1.0f;
}
std::vector<Vertex> makeGridLayout(
float toNdcY(float y, float viewportHeight)
{
return y * 2.0f / viewportHeight - 1.0f;
}
}
std::vector<TileRect> makeGridTileRects(
uint32_t cols,
uint32_t rows,
float gapX,
float gapY)
float viewportWidth,
float viewportHeight,
float gapPixels,
float targetAspect)
{
std::vector<Vertex> vertices;
vertices.reserve(
static_cast<size_t>(cols) * rows * 6);
std::vector<TileRect> rects;
rects.reserve(static_cast<size_t>(cols) * rows);
const float tileW =
(2.0f - gapX * static_cast<float>(cols - 1)) /
if (cols == 0 || rows == 0 ||
viewportWidth <= 0.0f || viewportHeight <= 0.0f ||
targetAspect <= 0.0f)
{
return rects;
}
const float gapX =
std::min(gapPixels, viewportWidth * 0.1f);
const float gapY =
std::min(gapPixels, viewportHeight * 0.1f);
const float cellW =
(viewportWidth - gapX * static_cast<float>(cols - 1)) /
static_cast<float>(cols);
const float tileH =
(2.0f - gapY * static_cast<float>(rows - 1)) /
const float cellH =
(viewportHeight - gapY * static_cast<float>(rows - 1)) /
static_cast<float>(rows);
float tileW = cellW;
float tileH = tileW / targetAspect;
if (tileH > cellH)
{
tileH = cellH;
tileW = tileH * targetAspect;
}
const float insetX = (cellW - tileW) * 0.5f;
const float insetY = (cellH - tileH) * 0.5f;
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);
static_cast<float>(col) * (cellW + gapX) +
insetX;
const float y0 =
-1.0f +
static_cast<float>(row) * (tileH + gapY);
static_cast<float>(row) * (cellH + gapY) +
insetY;
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());
rects.push_back({x0, y0, x1, y1});
}
}
return rects;
}
std::vector<Vertex> makeGridLayout(
uint32_t cols,
uint32_t rows,
float viewportWidth,
float viewportHeight,
float gapPixels,
float targetAspect)
{
std::vector<Vertex> vertices;
vertices.reserve(
static_cast<size_t>(cols) * rows * 6);
std::vector<TileRect> rects =
makeGridTileRects(
cols,
rows,
viewportWidth,
viewportHeight,
gapPixels,
targetAspect
);
for (const TileRect& rect : rects)
{
auto quad = makeQuad(
toNdcX(rect.x0, viewportWidth),
toNdcY(rect.y0, viewportHeight),
toNdcX(rect.x1, viewportWidth),
toNdcY(rect.y1, viewportHeight)
);
vertices.insert(
vertices.end(),
quad.begin(),
quad.end());
}
return vertices;
}
@@ -68,11 +138,20 @@ void updateGridLayout(
Vertex* vertices,
uint32_t cols,
uint32_t rows,
float gapX,
float gapY)
float viewportWidth,
float viewportHeight,
float gapPixels,
float targetAspect)
{
std::vector<Vertex> updated =
makeGridLayout(cols, rows, gapX, gapY);
makeGridLayout(
cols,
rows,
viewportWidth,
viewportHeight,
gapPixels,
targetAspect
);
std::copy(
updated.begin(),