2022-07-25 14:36:05 +08:00
|
|
|
#include <SFML/Graphics/Texture.hpp>
|
|
|
|
|
2023-03-10 09:05:53 +08:00
|
|
|
// Other 1st party headers
|
|
|
|
#include <SFML/Graphics/Image.hpp>
|
|
|
|
|
2023-11-17 01:03:29 +08:00
|
|
|
#include <SFML/System/FileInputStream.hpp>
|
|
|
|
|
2023-01-18 12:51:08 +08:00
|
|
|
#include <catch2/catch_test_macros.hpp>
|
2022-12-16 16:14:47 +08:00
|
|
|
|
|
|
|
#include <GraphicsUtil.hpp>
|
2024-02-08 21:28:57 +08:00
|
|
|
#include <WindowUtil.hpp>
|
2022-07-25 14:36:05 +08:00
|
|
|
#include <type_traits>
|
|
|
|
|
2023-01-18 12:51:08 +08:00
|
|
|
TEST_CASE("[Graphics] sf::Texture", runDisplayTests())
|
2022-12-16 16:14:47 +08:00
|
|
|
{
|
2023-01-18 12:51:08 +08:00
|
|
|
SECTION("Type traits")
|
|
|
|
{
|
2024-05-24 13:05:13 +08:00
|
|
|
STATIC_CHECK(!std::is_default_constructible_v<sf::Texture>);
|
2023-01-18 12:51:08 +08:00
|
|
|
STATIC_CHECK(std::is_copy_constructible_v<sf::Texture>);
|
|
|
|
STATIC_CHECK(std::is_copy_assignable_v<sf::Texture>);
|
|
|
|
STATIC_CHECK(std::is_nothrow_move_constructible_v<sf::Texture>);
|
|
|
|
STATIC_CHECK(std::is_nothrow_move_assignable_v<sf::Texture>);
|
|
|
|
STATIC_CHECK(std::is_nothrow_swappable_v<sf::Texture>);
|
|
|
|
}
|
|
|
|
|
2024-04-12 00:29:03 +08:00
|
|
|
SECTION("Move semantics")
|
|
|
|
{
|
|
|
|
SECTION("Construction")
|
|
|
|
{
|
2024-05-24 13:05:13 +08:00
|
|
|
sf::Texture movedTexture = sf::Texture::create({64, 64}).value();
|
|
|
|
const sf::Texture texture = std::move(movedTexture);
|
|
|
|
CHECK(texture.getSize() == sf::Vector2u(64, 64));
|
2024-04-12 00:29:03 +08:00
|
|
|
CHECK(!texture.isSmooth());
|
|
|
|
CHECK(!texture.isSrgb());
|
|
|
|
CHECK(!texture.isRepeated());
|
2024-05-24 13:05:13 +08:00
|
|
|
CHECK(texture.getNativeHandle() != 0);
|
2024-04-12 00:29:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
SECTION("Assignment")
|
|
|
|
{
|
2024-05-24 13:05:13 +08:00
|
|
|
sf::Texture movedTexture = sf::Texture::create({64, 64}).value();
|
|
|
|
sf::Texture texture = sf::Texture::create({128, 128}).value();
|
|
|
|
texture = std::move(movedTexture);
|
|
|
|
CHECK(texture.getSize() == sf::Vector2u(64, 64));
|
2024-04-12 00:29:03 +08:00
|
|
|
CHECK(!texture.isSmooth());
|
|
|
|
CHECK(!texture.isSrgb());
|
|
|
|
CHECK(!texture.isRepeated());
|
2024-05-24 13:05:13 +08:00
|
|
|
CHECK(texture.getNativeHandle() != 0);
|
2024-04-12 00:29:03 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-18 12:51:08 +08:00
|
|
|
SECTION("create()")
|
2023-03-10 09:05:53 +08:00
|
|
|
{
|
2023-01-18 12:51:08 +08:00
|
|
|
SECTION("At least one zero dimension")
|
2023-03-10 09:05:53 +08:00
|
|
|
{
|
2024-05-24 13:05:13 +08:00
|
|
|
CHECK(!sf::Texture::create({}));
|
|
|
|
CHECK(!sf::Texture::create({0, 1}));
|
|
|
|
CHECK(!sf::Texture::create({1, 0}));
|
2023-03-10 09:05:53 +08:00
|
|
|
}
|
|
|
|
|
2023-01-18 12:51:08 +08:00
|
|
|
SECTION("Valid size")
|
2023-03-10 09:05:53 +08:00
|
|
|
{
|
2024-05-24 13:05:13 +08:00
|
|
|
const auto texture = sf::Texture::create({100, 100}).value();
|
2023-03-10 09:05:53 +08:00
|
|
|
CHECK(texture.getSize() == sf::Vector2u(100, 100));
|
|
|
|
CHECK(texture.getNativeHandle() != 0);
|
|
|
|
}
|
|
|
|
|
2023-01-18 12:51:08 +08:00
|
|
|
SECTION("Too large")
|
2023-03-10 09:05:53 +08:00
|
|
|
{
|
2024-05-24 13:05:13 +08:00
|
|
|
CHECK(!sf::Texture::create({100'000, 100'000}));
|
|
|
|
CHECK(!sf::Texture::create({1'000'000, 1'000'000}));
|
2023-03-10 09:05:53 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-05 09:32:33 +08:00
|
|
|
SECTION("loadFromFile()")
|
|
|
|
{
|
2024-05-24 13:05:13 +08:00
|
|
|
const auto texture = sf::Texture::loadFromFile("Graphics/sfml-logo-big.png").value();
|
2023-08-05 09:32:33 +08:00
|
|
|
CHECK(texture.getSize() == sf::Vector2u(1001, 304));
|
|
|
|
CHECK(!texture.isSmooth());
|
|
|
|
CHECK(!texture.isSrgb());
|
|
|
|
CHECK(!texture.isRepeated());
|
|
|
|
CHECK(texture.getNativeHandle() != 0);
|
2023-11-17 01:03:29 +08:00
|
|
|
}
|
|
|
|
|
2024-04-12 00:29:03 +08:00
|
|
|
SECTION("loadFromMemory()")
|
|
|
|
{
|
2024-05-24 13:05:13 +08:00
|
|
|
const auto memory = loadIntoMemory("Graphics/sfml-logo-big.png");
|
|
|
|
const auto texture = sf::Texture::loadFromMemory(memory.data(), memory.size()).value();
|
2024-04-12 00:29:03 +08:00
|
|
|
CHECK(texture.getSize() == sf::Vector2u(1001, 304));
|
|
|
|
CHECK(!texture.isSmooth());
|
|
|
|
CHECK(!texture.isSrgb());
|
|
|
|
CHECK(!texture.isRepeated());
|
|
|
|
CHECK(texture.getNativeHandle() != 0);
|
|
|
|
}
|
|
|
|
|
2023-11-17 01:03:29 +08:00
|
|
|
SECTION("loadFromStream()")
|
|
|
|
{
|
2024-06-10 11:02:54 +08:00
|
|
|
auto stream = sf::FileInputStream::open("Graphics/sfml-logo-big.png").value();
|
2024-05-24 13:05:13 +08:00
|
|
|
const auto texture = sf::Texture::loadFromStream(stream).value();
|
2023-11-17 01:03:29 +08:00
|
|
|
CHECK(texture.getSize() == sf::Vector2u(1001, 304));
|
|
|
|
CHECK(!texture.isSmooth());
|
|
|
|
CHECK(!texture.isSrgb());
|
|
|
|
CHECK(!texture.isRepeated());
|
|
|
|
CHECK(texture.getNativeHandle() != 0);
|
2023-08-05 09:32:33 +08:00
|
|
|
}
|
|
|
|
|
2024-02-27 05:51:25 +08:00
|
|
|
SECTION("loadFromImage()")
|
|
|
|
{
|
|
|
|
SECTION("Subarea of image")
|
|
|
|
{
|
2024-05-19 03:07:26 +08:00
|
|
|
const sf::Image image(sf::Vector2u(10, 15));
|
2024-02-27 05:51:25 +08:00
|
|
|
|
|
|
|
SECTION("Non-truncated area")
|
|
|
|
{
|
2024-05-24 13:05:13 +08:00
|
|
|
const auto texture = sf::Texture::loadFromImage(image, false, {{0, 0}, {5, 10}}).value();
|
2024-02-27 05:51:25 +08:00
|
|
|
CHECK(texture.getSize() == sf::Vector2u(5, 10));
|
2024-05-24 13:05:13 +08:00
|
|
|
CHECK(texture.getNativeHandle() != 0);
|
2024-02-27 05:51:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
SECTION("Truncated area (negative position)")
|
|
|
|
{
|
2024-05-24 13:05:13 +08:00
|
|
|
const auto texture = sf::Texture::loadFromImage(image, false, {{-5, -5}, {4, 8}}).value();
|
2024-02-27 05:51:25 +08:00
|
|
|
CHECK(texture.getSize() == sf::Vector2u(4, 8));
|
2024-05-24 13:05:13 +08:00
|
|
|
CHECK(texture.getNativeHandle() != 0);
|
2024-02-27 05:51:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
SECTION("Truncated area (width/height too big)")
|
|
|
|
{
|
2024-05-24 13:05:13 +08:00
|
|
|
const auto texture = sf::Texture::loadFromImage(image, false, {{5, 5}, {12, 18}}).value();
|
2024-02-27 05:51:25 +08:00
|
|
|
CHECK(texture.getSize() == sf::Vector2u(5, 10));
|
2024-05-24 13:05:13 +08:00
|
|
|
CHECK(texture.getNativeHandle() != 0);
|
2024-02-27 05:51:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-18 12:51:08 +08:00
|
|
|
SECTION("Copy semantics")
|
2023-03-10 09:05:53 +08:00
|
|
|
{
|
|
|
|
constexpr std::uint8_t red[] = {0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF};
|
|
|
|
|
2024-05-24 13:05:13 +08:00
|
|
|
auto texture = sf::Texture::create({1, 2}).value();
|
2023-03-10 09:05:53 +08:00
|
|
|
texture.update(red);
|
|
|
|
|
2023-01-18 12:51:08 +08:00
|
|
|
SECTION("Construction")
|
2023-03-10 09:05:53 +08:00
|
|
|
{
|
2023-04-09 02:51:35 +08:00
|
|
|
const sf::Texture textureCopy(texture); // NOLINT(performance-unnecessary-copy-initialization)
|
2023-03-10 09:05:53 +08:00
|
|
|
REQUIRE(textureCopy.getSize() == sf::Vector2u(1, 2));
|
|
|
|
CHECK(textureCopy.copyToImage().getPixel(sf::Vector2u(0, 1)) == sf::Color::Red);
|
|
|
|
}
|
|
|
|
|
2023-01-18 12:51:08 +08:00
|
|
|
SECTION("Assignment")
|
2023-03-10 09:05:53 +08:00
|
|
|
{
|
2024-05-24 13:05:13 +08:00
|
|
|
sf::Texture textureCopy = sf::Texture::create({64, 64}).value();
|
|
|
|
textureCopy = texture;
|
2023-03-10 09:05:53 +08:00
|
|
|
REQUIRE(textureCopy.getSize() == sf::Vector2u(1, 2));
|
|
|
|
CHECK(textureCopy.copyToImage().getPixel(sf::Vector2u(0, 1)) == sf::Color::Red);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-18 12:51:08 +08:00
|
|
|
SECTION("update()")
|
2023-03-10 09:05:53 +08:00
|
|
|
{
|
|
|
|
constexpr std::uint8_t yellow[] = {0xFF, 0xFF, 0x00, 0xFF};
|
|
|
|
constexpr std::uint8_t cyan[] = {0x00, 0xFF, 0xFF, 0xFF};
|
|
|
|
|
2023-01-18 12:51:08 +08:00
|
|
|
SECTION("Pixels")
|
2023-03-10 09:05:53 +08:00
|
|
|
{
|
2024-05-24 13:05:13 +08:00
|
|
|
auto texture = sf::Texture::create(sf::Vector2u(1, 1)).value();
|
2023-03-10 09:05:53 +08:00
|
|
|
texture.update(yellow);
|
|
|
|
CHECK(texture.copyToImage().getPixel(sf::Vector2u(0, 0)) == sf::Color::Yellow);
|
|
|
|
}
|
|
|
|
|
2023-01-18 12:51:08 +08:00
|
|
|
SECTION("Pixels, size and destination")
|
2023-03-10 09:05:53 +08:00
|
|
|
{
|
2024-05-24 13:05:13 +08:00
|
|
|
auto texture = sf::Texture::create(sf::Vector2u(2, 1)).value();
|
2023-03-10 09:05:53 +08:00
|
|
|
texture.update(yellow, sf::Vector2u(1, 1), sf::Vector2u(0, 0));
|
|
|
|
texture.update(cyan, sf::Vector2u(1, 1), sf::Vector2u(1, 0));
|
|
|
|
CHECK(texture.copyToImage().getPixel(sf::Vector2u(0, 0)) == sf::Color::Yellow);
|
|
|
|
CHECK(texture.copyToImage().getPixel(sf::Vector2u(1, 0)) == sf::Color::Cyan);
|
|
|
|
}
|
|
|
|
|
2023-01-18 12:51:08 +08:00
|
|
|
SECTION("Another texture")
|
2023-03-10 09:05:53 +08:00
|
|
|
{
|
2024-05-24 13:05:13 +08:00
|
|
|
auto otherTexture = sf::Texture::create(sf::Vector2u(1, 1)).value();
|
2023-03-10 09:05:53 +08:00
|
|
|
otherTexture.update(cyan);
|
2024-05-24 13:05:13 +08:00
|
|
|
auto texture = sf::Texture::create(sf::Vector2u(1, 1)).value();
|
2023-03-10 09:05:53 +08:00
|
|
|
texture.update(otherTexture);
|
|
|
|
CHECK(texture.copyToImage().getPixel(sf::Vector2u(0, 0)) == sf::Color::Cyan);
|
|
|
|
}
|
|
|
|
|
2023-01-18 12:51:08 +08:00
|
|
|
SECTION("Another texture and destination")
|
2023-03-10 09:05:53 +08:00
|
|
|
{
|
2024-05-24 13:05:13 +08:00
|
|
|
auto texture = sf::Texture::create(sf::Vector2u(2, 1)).value();
|
|
|
|
auto otherTexture1 = sf::Texture::create(sf::Vector2u(1, 1)).value();
|
2023-03-10 09:05:53 +08:00
|
|
|
otherTexture1.update(cyan);
|
2024-05-24 13:05:13 +08:00
|
|
|
auto otherTexture2 = sf::Texture::create(sf::Vector2u(1, 1)).value();
|
2023-03-10 09:05:53 +08:00
|
|
|
otherTexture2.update(yellow);
|
|
|
|
texture.update(otherTexture1, sf::Vector2u(0, 0));
|
|
|
|
texture.update(otherTexture2, sf::Vector2u(1, 0));
|
|
|
|
CHECK(texture.copyToImage().getPixel(sf::Vector2u(0, 0)) == sf::Color::Cyan);
|
|
|
|
CHECK(texture.copyToImage().getPixel(sf::Vector2u(1, 0)) == sf::Color::Yellow);
|
|
|
|
}
|
|
|
|
|
2023-01-18 12:51:08 +08:00
|
|
|
SECTION("Image")
|
2023-03-10 09:05:53 +08:00
|
|
|
{
|
2024-05-24 13:05:13 +08:00
|
|
|
auto texture = sf::Texture::create(sf::Vector2u(16, 32)).value();
|
2024-05-19 03:07:26 +08:00
|
|
|
const sf::Image image(sf::Vector2u(16, 32), sf::Color::Red);
|
2023-03-10 09:05:53 +08:00
|
|
|
texture.update(image);
|
|
|
|
CHECK(texture.copyToImage().getPixel(sf::Vector2u(7, 15)) == sf::Color::Red);
|
|
|
|
}
|
|
|
|
|
2023-01-18 12:51:08 +08:00
|
|
|
SECTION("Image and destination")
|
2023-03-10 09:05:53 +08:00
|
|
|
{
|
2024-05-24 13:05:13 +08:00
|
|
|
auto texture = sf::Texture::create(sf::Vector2u(16, 32)).value();
|
2024-05-19 03:07:26 +08:00
|
|
|
const sf::Image image1(sf::Vector2u(16, 16), sf::Color::Red);
|
2023-03-10 09:05:53 +08:00
|
|
|
texture.update(image1);
|
2024-05-19 03:07:26 +08:00
|
|
|
const sf::Image image2(sf::Vector2u(16, 16), sf::Color::Green);
|
2023-03-10 09:05:53 +08:00
|
|
|
texture.update(image1, sf::Vector2u(0, 0));
|
|
|
|
texture.update(image2, sf::Vector2u(0, 16));
|
|
|
|
CHECK(texture.copyToImage().getPixel(sf::Vector2u(7, 7)) == sf::Color::Red);
|
|
|
|
CHECK(texture.copyToImage().getPixel(sf::Vector2u(7, 22)) == sf::Color::Green);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-18 12:51:08 +08:00
|
|
|
SECTION("Set/get smooth")
|
2023-03-10 09:05:53 +08:00
|
|
|
{
|
2024-05-24 13:05:13 +08:00
|
|
|
sf::Texture texture = sf::Texture::create({64, 64}).value();
|
2023-03-10 09:05:53 +08:00
|
|
|
CHECK(!texture.isSmooth());
|
|
|
|
texture.setSmooth(true);
|
|
|
|
CHECK(texture.isSmooth());
|
|
|
|
texture.setSmooth(false);
|
|
|
|
CHECK(!texture.isSmooth());
|
|
|
|
}
|
|
|
|
|
2023-01-18 12:51:08 +08:00
|
|
|
SECTION("Set/get repeated")
|
2023-03-10 09:05:53 +08:00
|
|
|
{
|
2024-05-24 13:05:13 +08:00
|
|
|
sf::Texture texture = sf::Texture::create({64, 64}).value();
|
2023-03-10 09:05:53 +08:00
|
|
|
CHECK(!texture.isRepeated());
|
|
|
|
texture.setRepeated(true);
|
|
|
|
CHECK(texture.isRepeated());
|
|
|
|
texture.setRepeated(false);
|
|
|
|
CHECK(!texture.isRepeated());
|
|
|
|
}
|
|
|
|
|
2023-09-05 23:15:16 +08:00
|
|
|
SECTION("generateMipmap()")
|
|
|
|
{
|
2024-05-24 13:05:13 +08:00
|
|
|
sf::Texture texture = sf::Texture::create({100, 100}).value();
|
2023-09-05 23:15:16 +08:00
|
|
|
CHECK(texture.generateMipmap());
|
|
|
|
}
|
|
|
|
|
2023-01-18 12:51:08 +08:00
|
|
|
SECTION("swap()")
|
2023-03-10 09:05:53 +08:00
|
|
|
{
|
|
|
|
constexpr std::uint8_t blue[] = {0x00, 0x00, 0xFF, 0xFF};
|
|
|
|
constexpr std::uint8_t green[] = {0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF};
|
|
|
|
|
2024-05-24 13:05:13 +08:00
|
|
|
auto texture1 = sf::Texture::create(sf::Vector2u(1, 1), true).value();
|
2023-03-10 09:05:53 +08:00
|
|
|
texture1.update(blue);
|
|
|
|
texture1.setSmooth(false);
|
|
|
|
texture1.setRepeated(true);
|
|
|
|
|
2024-05-24 13:05:13 +08:00
|
|
|
auto texture2 = sf::Texture::create(sf::Vector2u(2, 1), false).value();
|
2023-03-10 09:05:53 +08:00
|
|
|
texture2.update(green);
|
|
|
|
texture2.setSmooth(true);
|
|
|
|
texture2.setRepeated(false);
|
|
|
|
|
2023-05-13 12:25:06 +08:00
|
|
|
sf::swap(texture1, texture2);
|
2023-03-10 09:05:53 +08:00
|
|
|
CHECK_FALSE(texture1.isSrgb());
|
|
|
|
CHECK(texture1.isSmooth());
|
|
|
|
CHECK_FALSE(texture1.isRepeated());
|
2024-05-24 13:05:13 +08:00
|
|
|
// Cannot check texture2.isSrgb() because Srgb is sometimes disabled when using OpenGL ES
|
2023-03-10 09:05:53 +08:00
|
|
|
CHECK_FALSE(texture2.isSmooth());
|
|
|
|
CHECK(texture2.isRepeated());
|
|
|
|
|
2023-02-15 11:42:12 +08:00
|
|
|
const sf::Image image1 = texture1.copyToImage();
|
|
|
|
const sf::Image image2 = texture2.copyToImage();
|
2023-03-10 09:05:53 +08:00
|
|
|
REQUIRE(image1.getSize() == sf::Vector2u(2, 1));
|
|
|
|
REQUIRE(image2.getSize() == sf::Vector2u(1, 1));
|
|
|
|
CHECK(image1.getPixel(sf::Vector2u(1, 0)) == sf::Color::Green);
|
|
|
|
CHECK(image2.getPixel(sf::Vector2u(0, 0)) == sf::Color::Blue);
|
|
|
|
}
|
|
|
|
|
2023-01-18 12:51:08 +08:00
|
|
|
SECTION("Get Maximum Size")
|
2023-03-10 09:05:53 +08:00
|
|
|
{
|
|
|
|
CHECK(sf::Texture::getMaximumSize() > 0);
|
|
|
|
}
|
2022-12-16 16:14:47 +08:00
|
|
|
}
|