Preserve 16:9 tile aspect on resize
This commit is contained in:
+101
-22
@@ -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(),
|
||||
|
||||
Reference in New Issue
Block a user