Files
Faset_Engine/tests/render_sprite_tests.cpp
T

77 lines
3.4 KiB
C++

#include <cmath>
#include <faset/render/renderer.hpp>
#include <iostream>
#include <stdexcept>
#include <utility>
using namespace faset::render;
namespace {
void require(bool condition, const char* message) {
if (!condition)
throw std::runtime_error(message);
}
} // namespace
int main() {
try {
Renderer renderer({64, 64, "Faset sprite alpha validation", true, true});
Snapshot scene;
scene.clear_color = {0, 0, 0, 1};
Sprite front{{0, 0, .2f}, {2, 2}, {0, 1, 0, 0}};
Sprite back{{0, 0, .8f}, {2, 2}, {1, 0, 0, 1}};
auto color = [&](int red, int green, const char* message) {
renderer.render(scene);
const auto pixels = renderer.pixels();
const auto index = (32 * 64 + 32) * 4;
require(std::abs(int(pixels[index]) - red) <= 2 &&
std::abs(int(pixels[index + 1]) - green) <= 2 && pixels[index + 2] <= 2,
message);
require(renderer.stats().validation_errors == 0, "Sprite Vulkan validation error");
};
scene.sprites = {front, back};
color(255, 0, "Fully transparent front sprite must not occlude a later opaque sprite");
front.color[3] = .5f;
scene.sprites = {front, back};
color(128, 128, "Partial alpha must composite over the farther sprite");
scene.sprites = {back, front};
color(128, 128, "Unequal-depth compositing must be independent of submission order");
front.position[2] = .9f;
front.layer = 5;
scene.sprites = {front, back};
color(128, 128, "Explicit higher layer must take priority over sprite depth");
front.position[2] = back.position[2];
front.layer = back.layer;
scene.sprites = {front, back};
color(255, 0, "Equal-layer/equal-depth sprites must preserve submission order");
scene.sprites = {back, front};
color(128, 128, "Later equal-depth sprite must composite on top");
auto texture = std::make_shared<Texture>();
texture->width = texture->height = 1;
texture->rgba = {0, 255, 0, 0};
front.color = {1, 1, 1, 1};
front.texture = texture;
front.position[2] = .2f;
scene.sprites = {front, back};
color(255, 0, "Transparent texture pixels must preserve underlying sprites");
texture->rgba[3] = 128;
++texture->revision;
color(127, 128, "Texture alpha must blend with the already rendered background");
auto opaque = std::make_shared<Mesh>();
for (const auto point : {Vec3{-1, -1, .4f}, Vec3{1, -1, .4f}, Vec3{1, 1, .4f},
Vec3{-1, -1, .4f}, Vec3{1, 1, .4f}, Vec3{-1, 1, .4f}})
opaque->vertices.push_back({point, {0, 0, 0}, {1, 0, 0, 1}});
scene.draws.push_back({opaque, identity, {1, 1, 1, 1}, .5f, 0, false});
front.position[2] = .8f;
scene.sprites = {front};
color(255, 0, "Sprites behind opaque mesh depth must remain occluded");
front.position[2] = .2f;
scene.sprites = {front};
color(127, 128, "Sprites in front of opaque mesh depth must composite normally");
std::cout << "Sprite depth/layer ordering, stable ties, color/texture alpha and opaque "
"mesh occlusion passed\n";
return 0;
} catch (const std::exception& error) {
std::cerr << error.what() << '\n';
return 1;
}
}