cesium-native/CesiumVectorData/test/TestVectorRasterizer.cpp

527 lines
18 KiB
C++
Raw Permalink Normal View History

2025-04-18 23:14:25 +08:00
#include <CesiumGeospatial/CartographicPolygon.h>
#include <CesiumGeospatial/GlobeRectangle.h>
2025-04-22 06:11:23 +08:00
#include <CesiumGltf/ImageAsset.h>
2025-06-21 05:13:53 +08:00
#include <CesiumNativeTests/readFile.h>
2025-06-14 02:49:31 +08:00
#include <CesiumNativeTests/writeTga.h>
2025-06-03 23:00:18 +08:00
#include <CesiumUtility/Color.h>
2025-04-22 06:11:23 +08:00
#include <CesiumUtility/IntrusivePointer.h>
2025-04-18 23:14:25 +08:00
#include <CesiumVectorData/VectorRasterizer.h>
#include <doctest/doctest.h>
2025-04-25 05:29:01 +08:00
#include <fmt/format.h>
2025-04-18 23:14:25 +08:00
#include <glm/fwd.hpp>
2025-04-22 22:58:29 +08:00
#include <chrono>
2025-04-18 23:14:25 +08:00
#include <cstddef>
2025-06-04 01:09:04 +08:00
#include <filesystem>
2025-04-22 22:58:29 +08:00
#include <iostream>
#include <random>
2025-04-18 23:14:25 +08:00
using namespace CesiumGeospatial;
using namespace CesiumVectorData;
using namespace CesiumUtility;
2025-06-14 02:49:31 +08:00
using namespace CesiumNativeTests;
2025-04-18 23:14:25 +08:00
2025-06-04 01:09:04 +08:00
namespace {
void checkFilesEqual(
const std::filesystem::path& fileA,
const std::filesystem::path& fileB) {
const std::vector<std::byte>& bytes = readFile(fileA);
const std::vector<std::byte>& bytes2 = readFile(fileB);
REQUIRE(bytes.size() == bytes2.size());
for (size_t i = 0; i < bytes.size(); i++) {
CHECK(bytes[i] == bytes2[i]);
}
}
} // namespace
2025-04-18 23:14:25 +08:00
TEST_CASE("VectorRasterizer::rasterize") {
2025-06-04 01:09:04 +08:00
const std::filesystem::path dir(
std::filesystem::path(CesiumVectorData_TEST_DATA_DIR) / "rasterized");
const std::filesystem::path thisDir = std::filesystem::current_path();
GlobeRectangle rect{
0.0,
0.0,
Math::degreesToRadians(1.0),
Math::degreesToRadians(1.0)};
2025-04-18 23:14:25 +08:00
2025-04-22 22:58:29 +08:00
SUBCASE("Renders a single triangle") {
2025-04-22 06:11:23 +08:00
CesiumUtility::IntrusivePointer<CesiumGltf::ImageAsset> asset;
asset.emplace();
asset->width = 256;
asset->height = 256;
asset->channels = 4;
asset->bytesPerChannel = 1;
asset->pixelData.resize(
2025-06-14 04:05:40 +08:00
(size_t)(asset->width * asset->height * asset->channels * asset->bytesPerChannel),
2025-04-18 23:14:25 +08:00
std::byte{255});
2025-04-22 06:11:23 +08:00
VectorRasterizer rasterizer(rect, asset);
CartographicPolygon triangle(std::vector<glm::dvec2>{
glm::dvec2(Math::degreesToRadians(0.25), Math::degreesToRadians(0.25)),
glm::dvec2(Math::degreesToRadians(0.5), Math::degreesToRadians(0.75)),
glm::dvec2(
Math::degreesToRadians(0.75),
Math::degreesToRadians(0.25))});
2025-04-22 06:11:23 +08:00
2025-06-14 03:35:52 +08:00
rasterizer.drawPolygon(
triangle,
VectorStyle{Color{0, 255, 255, 255}}.polygon);
2025-04-22 06:11:23 +08:00
rasterizer.finalize();
2025-06-14 02:49:31 +08:00
writeImageToTgaFile(*asset, "triangle.tga");
2025-06-04 01:09:04 +08:00
checkFilesEqual(dir / "triangle.tga", thisDir / "triangle.tga");
2025-04-18 23:14:25 +08:00
}
2025-04-19 05:01:08 +08:00
2025-04-25 05:29:01 +08:00
SUBCASE("Triangle as tiles lines up") {
CesiumUtility::IntrusivePointer<CesiumGltf::ImageAsset> asset;
asset.emplace();
asset->width = 256;
asset->height = 256;
asset->channels = 4;
asset->bytesPerChannel = 1;
asset->pixelData.resize(
2025-06-14 04:05:40 +08:00
(size_t)(asset->width * asset->height * asset->channels * asset->bytesPerChannel),
2025-04-25 05:29:01 +08:00
std::byte{255});
CartographicPolygon triangle(std::vector<glm::dvec2>{
glm::dvec2(Math::degreesToRadians(0.25), Math::degreesToRadians(0.25)),
glm::dvec2(Math::degreesToRadians(0.5), Math::degreesToRadians(0.75)),
glm::dvec2(
Math::degreesToRadians(0.75),
Math::degreesToRadians(0.25))});
2025-06-03 23:00:18 +08:00
VectorStyle style{Color{0, 255, 255, 255}};
2025-04-25 05:29:01 +08:00
{
VectorRasterizer rasterizer(rect, asset);
2025-06-14 03:35:52 +08:00
rasterizer.drawPolygon(triangle, style.polygon);
2025-04-25 05:29:01 +08:00
rasterizer.finalize();
}
for (size_t i = 0; i < 2; i++) {
for (size_t j = 0; j < 2; j++) {
CesiumUtility::IntrusivePointer<CesiumGltf::ImageAsset> tile;
tile.emplace();
tile->width = 128;
tile->height = 128;
tile->channels = 4;
tile->bytesPerChannel = 1;
tile->pixelData.resize(
2025-06-14 04:05:40 +08:00
(size_t)(tile->width * tile->height * tile->channels * tile->bytesPerChannel),
2025-04-25 05:29:01 +08:00
std::byte{255});
VectorRasterizer rasterizer(
GlobeRectangle(
Math::degreesToRadians((double)i * 0.5),
Math::degreesToRadians((double)j * 0.5),
Math::degreesToRadians(0.5 + (double)i * 0.5),
Math::degreesToRadians(0.5 + (double)j * 0.5)),
2025-04-25 05:29:01 +08:00
tile);
2025-06-14 03:35:52 +08:00
rasterizer.drawPolygon(triangle, style.polygon);
2025-04-25 05:29:01 +08:00
rasterizer.finalize();
2025-06-04 01:09:04 +08:00
const std::string fileName = fmt::format("tile-{}-{}.tga", i, j);
2025-06-14 02:49:31 +08:00
writeImageToTgaFile(*tile, fileName);
2025-06-04 01:09:04 +08:00
checkFilesEqual(dir / fileName, thisDir / fileName);
2025-04-25 05:29:01 +08:00
for (size_t x = 0; x < (size_t)128; x++) {
for (size_t y = 0; y < (size_t)128; y++) {
CHECK(
tile->pixelData[(x * 128 + y) * 4] ==
asset->pixelData[((x + i * 128) * 256 + (y + j * 128)) * 4]);
}
}
}
}
}
2025-04-22 22:58:29 +08:00
SUBCASE("Renders a polyline") {
CesiumUtility::IntrusivePointer<CesiumGltf::ImageAsset> asset;
asset.emplace();
asset->width = 256;
asset->height = 256;
asset->channels = 4;
asset->bytesPerChannel = 1;
asset->pixelData.resize(
2025-06-14 04:05:40 +08:00
(size_t)(asset->width * asset->height * asset->channels * asset->bytesPerChannel),
2025-04-19 05:01:08 +08:00
std::byte{255});
2025-04-22 22:58:29 +08:00
VectorRasterizer rasterizer(rect, asset);
std::vector<glm::dvec3> polyline{
glm::dvec3(0.25, 0.25, 0.0),
glm::dvec3(0.25, 0.5, 0.0),
glm::dvec3(0.3, 0.7, 0.0),
glm::dvec3(0.25, 0.8, 0.0),
glm::dvec3(0.8, 1.0, 0.0),
glm::dvec3(0.8, 0.9, 0.0),
glm::dvec3(0.9, 0.9, 0.0)};
2025-04-22 22:58:29 +08:00
2025-06-14 03:35:52 +08:00
rasterizer.drawPolyline(
polyline,
VectorStyle{Color{81, 33, 255, 255}}.line);
2025-04-22 22:58:29 +08:00
rasterizer.finalize();
2025-06-14 02:49:31 +08:00
writeImageToTgaFile(*asset, "polyline.tga");
2025-06-04 01:09:04 +08:00
checkFilesEqual(dir / "polyline.tga", thisDir / "polyline.tga");
2025-04-22 22:58:29 +08:00
}
2025-04-25 05:29:01 +08:00
SUBCASE("Transforms bounds properly") {
GlobeRectangle rect2(
Math::degreesToRadians(0.25),
Math::degreesToRadians(0.25),
Math::degreesToRadians(0.75),
Math::degreesToRadians(0.5));
2025-04-25 05:29:01 +08:00
CesiumUtility::IntrusivePointer<CesiumGltf::ImageAsset> asset;
asset.emplace();
asset->width = 256;
asset->height = 256;
asset->channels = 4;
asset->bytesPerChannel = 1;
asset->pixelData.resize(
2025-06-14 04:05:40 +08:00
(size_t)(asset->width * asset->height * asset->channels * asset->bytesPerChannel),
2025-04-25 05:29:01 +08:00
std::byte{255});
VectorRasterizer rasterizer(rect2, asset);
CartographicPolygon triangle(std::vector<glm::dvec2>{
glm::dvec2(
Math::degreesToRadians(0.375),
Math::degreesToRadians(0.3125)),
glm::dvec2(Math::degreesToRadians(0.5), Math::degreesToRadians(0.4375)),
glm::dvec2(
Math::degreesToRadians(0.625),
Math::degreesToRadians(0.3125))});
2025-04-25 05:29:01 +08:00
2025-06-14 03:35:52 +08:00
rasterizer.drawPolygon(
triangle,
VectorStyle{Color{255, 127, 100, 255}}.polygon);
2025-04-25 05:29:01 +08:00
rasterizer.finalize();
2025-06-14 02:49:31 +08:00
writeImageToTgaFile(*asset, "triangle-scaled.tga");
2025-06-04 01:09:04 +08:00
checkFilesEqual(
dir / "triangle-scaled.tga",
thisDir / "triangle-scaled.tga");
2025-04-25 05:29:01 +08:00
}
SUBCASE("Polygon with holes") {
CesiumUtility::IntrusivePointer<CesiumGltf::ImageAsset> asset;
asset.emplace();
asset->width = 256;
asset->height = 256;
asset->channels = 4;
asset->bytesPerChannel = 1;
asset->pixelData.resize(
2025-06-14 04:05:40 +08:00
(size_t)(asset->width * asset->height * asset->channels * asset->bytesPerChannel),
std::byte{255});
VectorRasterizer rasterizer(rect, asset);
std::vector<std::vector<glm::dvec3>> composite{
std::vector<glm::dvec3>{
glm::dvec3(0.25, 0.25, 0.0),
glm::dvec3(0.75, 0.25, 0.0),
glm::dvec3(0.75, 0.75, 0.0),
glm::dvec3(0.25, 0.75, 0.0),
glm::dvec3(0.25, 0.25, 0.0)},
std::vector<glm::dvec3>{
glm::dvec3(0.4, 0.4, 0.0),
glm::dvec3(0.4, 0.6, 0.0),
glm::dvec3(0.6, 0.6, 0.0),
glm::dvec3(0.6, 0.4, 0.0),
glm::dvec3(0.4, 0.4, 0.0)}};
2025-06-14 03:35:52 +08:00
rasterizer.drawPolygon(
composite,
VectorStyle{Color{255, 50, 12, 255}}.polygon);
rasterizer.finalize();
2025-06-14 02:49:31 +08:00
writeImageToTgaFile(*asset, "polygon-holes.tga");
2025-06-04 01:09:04 +08:00
checkFilesEqual(dir / "polygon-holes.tga", thisDir / "polygon-holes.tga");
}
2025-04-29 05:24:43 +08:00
SUBCASE("Polygon with holes and outline") {
CesiumUtility::IntrusivePointer<CesiumGltf::ImageAsset> asset;
asset.emplace();
asset->width = 256;
asset->height = 256;
asset->channels = 4;
asset->bytesPerChannel = 1;
asset->pixelData.resize(
(size_t)(asset->width * asset->height * asset->channels * asset->bytesPerChannel),
std::byte{255});
VectorRasterizer rasterizer(rect, asset);
std::vector<std::vector<glm::dvec3>> composite{
std::vector<glm::dvec3>{
glm::dvec3(0.25, 0.25, 0.0),
glm::dvec3(0.25, 0.75, 0.0),
glm::dvec3(0.75, 0.75, 0.0),
glm::dvec3(0.75, 0.25, 0.0),
glm::dvec3(0.25, 0.25, 0.0)},
std::vector<glm::dvec3>{
glm::dvec3(0.4, 0.4, 0.0),
glm::dvec3(0.6, 0.4, 0.0),
glm::dvec3(0.6, 0.6, 0.0),
glm::dvec3(0.4, 0.6, 0.0),
glm::dvec3(0.4, 0.4, 0.0)}};
VectorStyle style{Color{255, 50, 12, 255}};
style.polygon.outline = LineStyle{
ColorStyle{Color{0, 0, 0, 255}, ColorMode::Normal},
5.0,
LineWidthMode::Pixels};
rasterizer.drawPolygon(composite, style.polygon);
rasterizer.finalize();
writeImageToTgaFile(*asset, "polygon-holes-outline.tga");
checkFilesEqual(
dir / "polygon-holes-outline.tga",
thisDir / "polygon-holes-outline.tga");
}
SUBCASE("Proper antimeridian handling") {
CesiumUtility::IntrusivePointer<CesiumGltf::ImageAsset> asset;
asset.emplace();
asset->width = 256;
asset->height = 256;
asset->channels = 4;
asset->bytesPerChannel = 1;
asset->pixelData.resize(
(size_t)(asset->width * asset->height * asset->channels * asset->bytesPerChannel),
std::byte{255});
GlobeRectangle antiRect{
Math::degreesToRadians(175.0),
0,
Math::degreesToRadians(-175.0),
Math::degreesToRadians(10.0)};
CartographicPolygon square(std::vector<glm::dvec2>{
glm::dvec2{Math::degreesToRadians(175.0), Math::degreesToRadians(0.0)},
glm::dvec2{Math::degreesToRadians(175.0), Math::degreesToRadians(10.0)},
glm::dvec2{Math::degreesToRadians(180.0), Math::degreesToRadians(10.0)},
glm::dvec2{Math::degreesToRadians(180.0), Math::degreesToRadians(0.0)},
glm::dvec2{
Math::degreesToRadians(175.0),
Math::degreesToRadians(0.0)}});
CartographicPolygon square2(std::vector<glm::dvec2>{
glm::dvec2{Math::degreesToRadians(-180.0), Math::degreesToRadians(0.0)},
glm::dvec2{
Math::degreesToRadians(-180.0),
Math::degreesToRadians(10.0)},
glm::dvec2{
Math::degreesToRadians(-175.0),
Math::degreesToRadians(10.0)},
glm::dvec2{Math::degreesToRadians(-175.0), Math::degreesToRadians(0.0)},
glm::dvec2{
Math::degreesToRadians(-180.0),
Math::degreesToRadians(0.0)}});
VectorStyle style{Color{0xff, 0x9e, 0x33, 0xff}};
VectorRasterizer rasterizer(antiRect, asset);
rasterizer.drawPolygon(
square,
VectorStyle{Color{0xff, 0xbb, 0x55, 0xff}}.polygon);
rasterizer.drawPolygon(
square2,
VectorStyle{Color{0x55, 0xbb, 0xff, 0xff}}.polygon);
rasterizer.finalize();
writeImageToTgaFile(*asset, "antimeridian.tga");
checkFilesEqual(dir / "antimeridian.tga", thisDir / "antimeridian.tga");
}
2025-04-29 05:24:43 +08:00
SUBCASE("Mip levels") {
CesiumUtility::IntrusivePointer<CesiumGltf::ImageAsset> asset;
asset.emplace();
asset->width = 256;
asset->height = 256;
asset->channels = 4;
asset->bytesPerChannel = 1;
asset->mipPositions.resize(4);
size_t totalSize = 0;
for (size_t i = 0; i < 4; i++) {
int32_t width = 256 >> i;
int32_t height = 256 >> i;
asset->mipPositions[i] = {totalSize, (size_t)(width * height * 4)};
totalSize += asset->mipPositions[i].byteSize;
}
asset->pixelData.resize(totalSize, std::byte{255});
std::vector<glm::dvec3> polyline{
glm::dvec3(0.25, 0.25, 0.0),
glm::dvec3(0.25, 0.5, 0.0),
glm::dvec3(0.3, 0.7, 0.0),
glm::dvec3(0.25, 0.8, 0.0),
glm::dvec3(0.8, 1.0, 0.0),
glm::dvec3(0.8, 0.9, 0.0),
glm::dvec3(0.9, 0.9, 0.0)};
2025-06-03 23:00:18 +08:00
VectorStyle style{Color{255, 50, 12, 255}};
2025-04-29 05:24:43 +08:00
for (uint32_t i = 0; i < 4; i++) {
VectorRasterizer rasterizer(rect, asset, i);
2025-06-14 03:35:52 +08:00
rasterizer.drawPolyline(polyline, style.line);
2025-04-29 05:24:43 +08:00
rasterizer.finalize();
}
2025-06-14 02:49:31 +08:00
writeImageToTgaFile(*asset, "mipmap.tga");
2025-06-04 01:09:04 +08:00
checkFilesEqual(dir / "mipmap-mip0.tga", thisDir / "mipmap-mip0.tga");
checkFilesEqual(dir / "mipmap-mip1.tga", thisDir / "mipmap-mip1.tga");
checkFilesEqual(dir / "mipmap-mip2.tga", thisDir / "mipmap-mip2.tga");
checkFilesEqual(dir / "mipmap-mip3.tga", thisDir / "mipmap-mip3.tga");
2025-04-29 05:24:43 +08:00
}
2025-04-29 23:42:36 +08:00
SUBCASE("Styling") {
CesiumUtility::IntrusivePointer<CesiumGltf::ImageAsset> asset;
asset.emplace();
asset->width = 256;
asset->height = 256;
asset->channels = 4;
asset->bytesPerChannel = 1;
asset->pixelData.resize(
2025-06-14 04:05:40 +08:00
(size_t)(asset->width * asset->height * asset->channels * asset->bytesPerChannel),
2025-04-29 23:42:36 +08:00
std::byte{255});
CartographicPolygon square(std::vector<glm::dvec2>{
glm::dvec2(Math::degreesToRadians(0.25), Math::degreesToRadians(0.25)),
glm::dvec2(Math::degreesToRadians(0.25), Math::degreesToRadians(0.75)),
glm::dvec2(Math::degreesToRadians(0.75), Math::degreesToRadians(0.75)),
glm::dvec2(
Math::degreesToRadians(0.75),
Math::degreesToRadians(0.25))});
2025-04-29 23:42:36 +08:00
CartographicPolygon triangle(std::vector<glm::dvec2>{
glm::dvec2(Math::degreesToRadians(0.25), Math::degreesToRadians(0.25)),
glm::dvec2(Math::degreesToRadians(0.5), Math::degreesToRadians(0.75)),
glm::dvec2(
Math::degreesToRadians(0.75),
Math::degreesToRadians(0.25))});
2025-04-29 23:42:36 +08:00
std::vector<glm::dvec3> polyline{
glm::dvec3(0.1, 0.1, 0.0),
glm::dvec3(0.9, 0.1, 0.0),
glm::dvec3(0.9, 0.9, 0.0)};
2025-04-29 23:42:36 +08:00
VectorStyle style{
LineStyle{ColorStyle{Color{0xff, 0xaa, 0x33}, ColorMode::Normal}, 2.0},
PolygonStyle{
2025-06-04 01:09:04 +08:00
ColorStyle{Color{0x33, 0xaa, 0xff}, ColorMode::Normal},
2025-06-14 03:35:52 +08:00
LineStyle{
ColorStyle{Color{0xff, 0xaa, 0x33}, ColorMode::Normal},
2.0}}};
2025-04-29 23:42:36 +08:00
VectorRasterizer rasterizer(rect, asset);
2025-06-14 03:35:52 +08:00
rasterizer.drawPolygon(square, style.polygon);
rasterizer.drawPolygon(triangle, style.polygon);
rasterizer.drawPolyline(polyline, style.line);
2025-04-29 23:42:36 +08:00
rasterizer.finalize();
2025-06-14 02:49:31 +08:00
writeImageToTgaFile(*asset, "styling.tga");
2025-06-04 01:09:04 +08:00
checkFilesEqual(dir / "styling.tga", thisDir / "styling.tga");
2025-04-29 23:42:36 +08:00
}
2025-08-22 23:17:19 +08:00
SUBCASE("Random color uses the same color across calls") {
CesiumUtility::IntrusivePointer<CesiumGltf::ImageAsset> asset;
asset.emplace();
asset->width = 1;
asset->height = 1;
asset->channels = 4;
asset->bytesPerChannel = 1;
asset->pixelData.resize(4, std::byte{255});
CartographicPolygon square(std::vector<glm::dvec2>{
2025-08-22 23:17:19 +08:00
glm::dvec2{Math::degreesToRadians(0.0), Math::degreesToRadians(0.0)},
glm::dvec2{Math::degreesToRadians(0.0), Math::degreesToRadians(1.0)},
glm::dvec2{Math::degreesToRadians(1.0), Math::degreesToRadians(1.0)},
glm::dvec2{Math::degreesToRadians(1.0), Math::degreesToRadians(0.0)},
glm::dvec2{Math::degreesToRadians(0.0), Math::degreesToRadians(0.0)}});
VectorStyle style;
2025-08-22 23:17:19 +08:00
style.polygon.fill =
ColorStyle{Color{0xff, 0x00, 0xaa, 0xff}, ColorMode::Random};
VectorRasterizer rasterizer(rect, asset);
rasterizer.drawPolygon(square, style.polygon);
rasterizer.finalize();
const uint32_t writtenColor =
2025-08-22 23:17:19 +08:00
*reinterpret_cast<uint32_t*>(asset->pixelData.data());
VectorRasterizer rasterizer2(rect, asset);
rasterizer2.drawPolygon(square, style.polygon);
rasterizer2.finalize();
2025-08-22 23:17:19 +08:00
CHECK(
*reinterpret_cast<uint32_t*>(asset->pixelData.data()) == writtenColor);
}
2025-04-18 23:14:25 +08:00
}
2025-06-21 05:13:53 +08:00
TEST_CASE("VectorRasterizer::rasterize benchmark" * doctest::skip(true)) {
2025-06-04 01:09:04 +08:00
GlobeRectangle rect{
0.0,
0.0,
Math::degreesToRadians(1.0),
Math::degreesToRadians(1.0)};
2025-04-19 05:01:08 +08:00
std::chrono::steady_clock clock;
2025-04-18 23:14:25 +08:00
std::random_device r;
std::default_random_engine rand(r());
std::chrono::microseconds total(0);
2025-04-22 22:58:29 +08:00
CesiumUtility::IntrusivePointer<CesiumGltf::ImageAsset> asset;
asset.emplace();
asset->width = 256;
asset->height = 256;
asset->channels = 4;
asset->bytesPerChannel = 1;
asset->pixelData.resize(
2025-06-14 04:05:40 +08:00
(size_t)(asset->width * asset->height * asset->channels * asset->bytesPerChannel),
2025-04-22 22:58:29 +08:00
std::byte{255});
2025-04-18 23:14:25 +08:00
for (int i = 0; i < 100; i++) {
std::vector<CartographicPolygon> polygons;
2025-04-29 23:42:36 +08:00
std::vector<VectorStyle> styles;
2025-04-18 23:14:25 +08:00
std::uniform_real_distribution<double> uniformDist;
for (int j = 0; j < 1000; j++) {
polygons.emplace_back(std::vector<glm::dvec2>{
glm::dvec2(
Math::degreesToRadians(uniformDist(rand)),
Math::degreesToRadians(uniformDist(rand))),
glm::dvec2(
Math::degreesToRadians(uniformDist(rand)),
Math::degreesToRadians(uniformDist(rand))),
glm::dvec2(
Math::degreesToRadians(uniformDist(rand)),
Math::degreesToRadians(uniformDist(rand))),
2025-04-18 23:14:25 +08:00
});
2025-04-29 23:42:36 +08:00
styles.emplace_back(Color{
2025-06-03 23:00:18 +08:00
(uint8_t)(uniformDist(rand) * 255.0),
(uint8_t)(uniformDist(rand) * 255.0),
(uint8_t)(uniformDist(rand) * 255.0),
(uint8_t)(uniformDist(rand) * 255.0)});
2025-04-18 23:14:25 +08:00
}
2025-04-19 05:01:08 +08:00
std::chrono::steady_clock::time_point start = clock.now();
2025-04-22 22:58:29 +08:00
VectorRasterizer rasterizer(rect, asset);
for (size_t j = 0; j < polygons.size(); j++) {
2025-06-14 03:35:52 +08:00
rasterizer.drawPolygon(polygons[j], styles[j].polygon);
2025-04-22 22:58:29 +08:00
}
rasterizer.finalize();
2025-04-18 23:14:25 +08:00
std::chrono::microseconds time =
std::chrono::duration_cast<std::chrono::microseconds>(
clock.now() - start);
total += time;
std::cout << "rasterized 1000 triangles in " << time.count()
<< " microseconds\n";
2025-06-14 02:49:31 +08:00
writeImageToTgaFile(*asset, "rand.tga");
2025-04-18 23:14:25 +08:00
}
double seconds =
std::chrono::duration_cast<std::chrono::duration<double>>(total).count();
std::cout << "100 runs in " << seconds << " seconds, avg per run "
<< (seconds / 100.0) << " seconds\n";
2025-04-22 22:58:29 +08:00
}