#include // Other 1st party headers #include #include #include #include #include #include TEST_CASE("[Graphics] sf::Texture", runDisplayTests()) { SECTION("Type traits") { STATIC_CHECK(std::is_copy_constructible_v); STATIC_CHECK(std::is_copy_assignable_v); STATIC_CHECK(std::is_nothrow_move_constructible_v); STATIC_CHECK(std::is_nothrow_move_assignable_v); STATIC_CHECK(std::is_nothrow_swappable_v); } SECTION("Construction") { SECTION("Default constructor") { const sf::Texture texture; CHECK(texture.getSize() == sf::Vector2u()); CHECK(!texture.isSmooth()); CHECK(!texture.isSrgb()); CHECK(!texture.isRepeated()); CHECK(texture.getNativeHandle() == 0); } SECTION("Vector") { SECTION("At least one zero dimension") { CHECK_THROWS_AS(sf::Texture(sf::Vector2u()), std::runtime_error); CHECK_THROWS_AS(sf::Texture(sf::Vector2u(0, 1)), std::runtime_error); CHECK_THROWS_AS(sf::Texture(sf::Vector2u(1, 0)), std::runtime_error); } SECTION("Valid size") { const sf::Texture texture(sf::Vector2u(100, 100)); CHECK(texture.getSize() == sf::Vector2u(100, 100)); CHECK(texture.getNativeHandle() != 0); } SECTION("Too large") { CHECK_THROWS_AS(sf::Texture(sf::Vector2u(100'000, 100'000)), std::runtime_error); CHECK_THROWS_AS(sf::Texture(sf::Vector2u(1'000'000, 1'000'000)), std::runtime_error); } } SECTION("File") { const sf::Texture texture("Graphics/sfml-logo-big.png"); CHECK(texture.getSize() == sf::Vector2u(1001, 304)); CHECK(!texture.isSmooth()); CHECK(!texture.isSrgb()); CHECK(!texture.isRepeated()); CHECK(texture.getNativeHandle() != 0); } SECTION("Memory") { const auto memory = loadIntoMemory("Graphics/sfml-logo-big.png"); const sf::Texture texture(memory.data(), memory.size()); CHECK(texture.getSize() == sf::Vector2u(1001, 304)); CHECK(!texture.isSmooth()); CHECK(!texture.isSrgb()); CHECK(!texture.isRepeated()); CHECK(texture.getNativeHandle() != 0); } SECTION("Stream") { sf::FileInputStream stream("Graphics/sfml-logo-big.png"); const sf::Texture texture(stream); CHECK(texture.getSize() == sf::Vector2u(1001, 304)); CHECK(!texture.isSmooth()); CHECK(!texture.isSrgb()); CHECK(!texture.isRepeated()); CHECK(texture.getNativeHandle() != 0); } SECTION("Image") { SECTION("Subarea of image") { const sf::Image image(sf::Vector2u(10, 15)); SECTION("Non-truncated area") { const sf::Texture texture(image, false, {{0, 0}, {5, 10}}); CHECK(texture.getSize() == sf::Vector2u(5, 10)); CHECK(texture.getNativeHandle() != 0); } SECTION("Truncated area (negative position)") { const sf::Texture texture(image, false, {{-5, -5}, {4, 8}}); CHECK(texture.getSize() == sf::Vector2u(4, 8)); CHECK(texture.getNativeHandle() != 0); } SECTION("Truncated area (width/height too big)") { const sf::Texture texture(image, false, {{5, 5}, {12, 18}}); CHECK(texture.getSize() == sf::Vector2u(5, 10)); CHECK(texture.getNativeHandle() != 0); } } } } SECTION("Move semantics") { SECTION("Construction") { sf::Texture movedTexture; const sf::Texture texture = std::move(movedTexture); CHECK(texture.getSize() == sf::Vector2u()); CHECK(!texture.isSmooth()); CHECK(!texture.isSrgb()); CHECK(!texture.isRepeated()); CHECK(texture.getNativeHandle() == 0); } SECTION("Assignment") { sf::Texture movedTexture; sf::Texture texture; texture = std::move(movedTexture); CHECK(texture.getSize() == sf::Vector2u()); CHECK(!texture.isSmooth()); CHECK(!texture.isSrgb()); CHECK(!texture.isRepeated()); CHECK(texture.getNativeHandle() == 0); } } SECTION("Move semantics") { SECTION("Construction") { sf::Texture movedTexture(sf::Vector2u(64, 64)); const sf::Texture texture = std::move(movedTexture); CHECK(texture.getSize() == sf::Vector2u(64, 64)); CHECK(!texture.isSmooth()); CHECK(!texture.isSrgb()); CHECK(!texture.isRepeated()); CHECK(texture.getNativeHandle() != 0); } SECTION("Assignment") { sf::Texture movedTexture(sf::Vector2u(64, 64)); sf::Texture texture(sf::Vector2u(128, 128)); texture = std::move(movedTexture); CHECK(texture.getSize() == sf::Vector2u(64, 64)); CHECK(!texture.isSmooth()); CHECK(!texture.isSrgb()); CHECK(!texture.isRepeated()); CHECK(texture.getNativeHandle() != 0); } } SECTION("resize()") { sf::Texture texture; SECTION("At least one zero dimension") { CHECK(!texture.resize({})); CHECK(!texture.resize({0, 1})); CHECK(!texture.resize({1, 0})); } SECTION("Valid size") { CHECK(texture.resize({100, 100})); CHECK(texture.getSize() == sf::Vector2u(100, 100)); CHECK(texture.getNativeHandle() != 0); } SECTION("Too large") { CHECK(!texture.resize({100'000, 100'000})); CHECK(!texture.resize({1'000'000, 1'000'000})); } } SECTION("loadFromFile()") { sf::Texture texture; REQUIRE(texture.loadFromFile("Graphics/sfml-logo-big.png")); CHECK(texture.getSize() == sf::Vector2u(1001, 304)); CHECK(!texture.isSmooth()); CHECK(!texture.isSrgb()); CHECK(!texture.isRepeated()); CHECK(texture.getNativeHandle() != 0); } SECTION("loadFromMemory()") { const auto memory = loadIntoMemory("Graphics/sfml-logo-big.png"); sf::Texture texture; REQUIRE(texture.loadFromMemory(memory.data(), memory.size())); CHECK(texture.getSize() == sf::Vector2u(1001, 304)); CHECK(!texture.isSmooth()); CHECK(!texture.isSrgb()); CHECK(!texture.isRepeated()); CHECK(texture.getNativeHandle() != 0); } SECTION("loadFromStream()") { sf::Texture texture; sf::FileInputStream stream; REQUIRE(stream.open("Graphics/sfml-logo-big.png")); REQUIRE(texture.loadFromStream(stream)); CHECK(texture.getSize() == sf::Vector2u(1001, 304)); CHECK(!texture.isSmooth()); CHECK(!texture.isSrgb()); CHECK(!texture.isRepeated()); CHECK(texture.getNativeHandle() != 0); } SECTION("loadFromImage()") { SECTION("Empty image") { const sf::Image image; sf::Texture texture; REQUIRE(!texture.loadFromImage(image)); REQUIRE(!texture.loadFromImage(image, false, {{0, 0}, {1, 1}})); } SECTION("Subarea of image") { sf::Image image; image.resize(sf::Vector2u(10, 15)); sf::Texture texture; SECTION("Non-truncated area") { REQUIRE(texture.loadFromImage(image, false, {{0, 0}, {5, 10}})); CHECK(texture.getSize() == sf::Vector2u(5, 10)); } SECTION("Truncated area (negative position)") { REQUIRE(texture.loadFromImage(image, false, {{-5, -5}, {4, 8}})); CHECK(texture.getSize() == sf::Vector2u(4, 8)); } SECTION("Truncated area (width/height too big)") { REQUIRE(texture.loadFromImage(image, false, {{5, 5}, {12, 18}})); CHECK(texture.getSize() == sf::Vector2u(5, 10)); } CHECK(texture.getNativeHandle() != 0); } } SECTION("Copy semantics") { constexpr std::uint8_t red[] = {0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF}; sf::Texture texture(sf::Vector2u(1, 2)); texture.update(red); SECTION("Construction") { const sf::Texture textureCopy(texture); // NOLINT(performance-unnecessary-copy-initialization) REQUIRE(textureCopy.getSize() == sf::Vector2u(1, 2)); CHECK(textureCopy.copyToImage().getPixel(sf::Vector2u(0, 1)) == sf::Color::Red); } SECTION("Assignment") { sf::Texture textureCopy(sf::Vector2u(64, 64)); textureCopy = texture; REQUIRE(textureCopy.getSize() == sf::Vector2u(1, 2)); CHECK(textureCopy.copyToImage().getPixel(sf::Vector2u(0, 1)) == sf::Color::Red); } } SECTION("update()") { constexpr std::uint8_t yellow[] = {0xFF, 0xFF, 0x00, 0xFF}; constexpr std::uint8_t cyan[] = {0x00, 0xFF, 0xFF, 0xFF}; SECTION("Pixels") { sf::Texture texture(sf::Vector2u(1, 1)); texture.update(yellow); CHECK(texture.copyToImage().getPixel(sf::Vector2u(0, 0)) == sf::Color::Yellow); } SECTION("Pixels, size and destination") { sf::Texture texture(sf::Vector2u(2, 1)); 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); } SECTION("Another texture") { sf::Texture otherTexture(sf::Vector2u(1, 1)); otherTexture.update(cyan); sf::Texture texture(sf::Vector2u(1, 1)); texture.update(otherTexture); CHECK(texture.copyToImage().getPixel(sf::Vector2u(0, 0)) == sf::Color::Cyan); } SECTION("Another texture and destination") { sf::Texture texture(sf::Vector2u(2, 1)); sf::Texture otherTexture1(sf::Vector2u(1, 1)); otherTexture1.update(cyan); sf::Texture otherTexture2(sf::Vector2u(1, 1)); 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); } SECTION("Image") { sf::Texture texture(sf::Vector2u(16, 32)); const sf::Image image(sf::Vector2u(16, 32), sf::Color::Red); texture.update(image); CHECK(texture.copyToImage().getPixel(sf::Vector2u(7, 15)) == sf::Color::Red); } SECTION("Image and destination") { sf::Texture texture(sf::Vector2u(16, 32)); const sf::Image image1(sf::Vector2u(16, 16), sf::Color::Red); texture.update(image1); const sf::Image image2(sf::Vector2u(16, 16), sf::Color::Green); 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); } } SECTION("Set/get smooth") { sf::Texture texture(sf::Vector2u(64, 64)); CHECK(!texture.isSmooth()); texture.setSmooth(true); CHECK(texture.isSmooth()); texture.setSmooth(false); CHECK(!texture.isSmooth()); } SECTION("Set/get repeated") { sf::Texture texture(sf::Vector2u(64, 64)); CHECK(!texture.isRepeated()); texture.setRepeated(true); CHECK(texture.isRepeated()); texture.setRepeated(false); CHECK(!texture.isRepeated()); } SECTION("generateMipmap()") { sf::Texture texture(sf::Vector2u(100, 100)); CHECK(texture.generateMipmap()); } SECTION("swap()") { constexpr std::uint8_t blue[] = {0x00, 0x00, 0xFF, 0xFF}; constexpr std::uint8_t green[] = {0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF}; sf::Texture texture1(sf::Vector2u(1, 1), true); texture1.update(blue); texture1.setSmooth(false); texture1.setRepeated(true); sf::Texture texture2(sf::Vector2u(2, 1), false); texture2.update(green); texture2.setSmooth(true); texture2.setRepeated(false); sf::swap(texture1, texture2); CHECK_FALSE(texture1.isSrgb()); CHECK(texture1.isSmooth()); CHECK_FALSE(texture1.isRepeated()); // Cannot check texture2.isSrgb() because Srgb is sometimes disabled when using OpenGL ES CHECK_FALSE(texture2.isSmooth()); CHECK(texture2.isRepeated()); const sf::Image image1 = texture1.copyToImage(); const sf::Image image2 = texture2.copyToImage(); 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); } SECTION("Get Maximum Size") { CHECK(sf::Texture::getMaximumSize() > 0); } }