From 3be45d0558f2d1a67ab3b85b7ecdb32642986fa0 Mon Sep 17 00:00:00 2001 From: Chris Thrasher Date: Thu, 23 May 2024 23:05:13 -0600 Subject: [PATCH] Remove default empty state of `sf::Texture` --- doc/mainpage.hpp | 4 +- examples/android/app/src/main/jni/main.cpp | 4 +- examples/cocoa/CocoaAppDelegate.mm | 5 +- examples/opengl/OpenGL.cpp | 12 +- examples/shader/Shader.cpp | 25 +--- examples/sound_effects/SoundEffects.cpp | 4 +- examples/tennis/Tennis.cpp | 4 +- examples/win32/Win32.cpp | 6 +- include/SFML/Graphics/RenderWindow.hpp | 6 +- include/SFML/Graphics/Sprite.hpp | 8 +- include/SFML/Graphics/Texture.hpp | 93 +++++++------ include/SFML/System/InputStream.hpp | 6 +- src/SFML/Graphics/Font.cpp | 47 ++++--- src/SFML/Graphics/RenderTexture.cpp | 10 +- src/SFML/Graphics/Texture.cpp | 120 ++++++++--------- test/Graphics/RenderWindow.test.cpp | 3 +- test/Graphics/Shape.test.cpp | 4 +- test/Graphics/Sprite.test.cpp | 10 +- test/Graphics/Texture.test.cpp | 122 ++++++------------ .../SFML/SFML App.xctemplate/main.cpp | 6 +- .../SFML/SFML CLT.xctemplate/main.cpp | 6 +- 21 files changed, 201 insertions(+), 304 deletions(-) diff --git a/doc/mainpage.hpp b/doc/mainpage.hpp index 0c34174e5f..140c0de5d0 100644 --- a/doc/mainpage.hpp +++ b/doc/mainpage.hpp @@ -21,9 +21,7 @@ /// sf::RenderWindow window(sf::VideoMode({800, 600}), "SFML window"); /// /// // Load a sprite to display -/// sf::Texture texture; -/// if (!texture.loadFromFile("cute_image.jpg")) -/// return EXIT_FAILURE; +/// const auto texture = sf::Texture::loadFromFile("cute_image.jpg").value(); /// sf::Sprite sprite(texture); /// /// // Create a graphical text to display diff --git a/examples/android/app/src/main/jni/main.cpp b/examples/android/app/src/main/jni/main.cpp index 31805652ca..18da48f893 100644 --- a/examples/android/app/src/main/jni/main.cpp +++ b/examples/android/app/src/main/jni/main.cpp @@ -86,9 +86,7 @@ int main(int argc, char* argv[]) sf::RenderWindow window(screen, ""); window.setFramerateLimit(30); - sf::Texture texture; - if (!texture.loadFromFile("image.png")) - return EXIT_FAILURE; + const auto texture = sf::Texture::loadFromFile("image.png").value(); sf::Sprite image(texture); image.setPosition(sf::Vector2f(screen.size) / 2.f); diff --git a/examples/cocoa/CocoaAppDelegate.mm b/examples/cocoa/CocoaAppDelegate.mm index 269cfad2bf..cc56d55fe3 100644 --- a/examples/cocoa/CocoaAppDelegate.mm +++ b/examples/cocoa/CocoaAppDelegate.mm @@ -41,9 +41,6 @@ { SFMLmainWindow(sf::WindowHandle win) : renderWindow(win) { - if (!logo.loadFromFile(resPath / "logo.png")) - NSLog(@"Couldn't load the logo image"); - logo.setSmooth(true); sprite.setOrigin(sprite.getLocalBounds().getCenter()); @@ -57,7 +54,7 @@ sf::RenderWindow renderWindow; sf::Font font{sf::Font::loadFromFile(resPath / "tuffy.ttf").value()}; sf::Text text{font}; - sf::Texture logo; + sf::Texture logo{sf::Texture::loadFromFile(resPath / "logo.png").value()}; sf::Sprite sprite{logo}; sf::Color background{sf::Color::Blue}; }; diff --git a/examples/opengl/OpenGL.cpp b/examples/opengl/OpenGL.cpp index 9730132742..cd093409f6 100644 --- a/examples/opengl/OpenGL.cpp +++ b/examples/opengl/OpenGL.cpp @@ -58,10 +58,7 @@ int main() window.setMaximumSize(sf::Vector2u(1200, 900)); // Create a sprite for the background - sf::Texture backgroundTexture; - backgroundTexture.setSrgb(sRgb); - if (!backgroundTexture.loadFromFile(resourcesDir() / "background.jpg")) - return EXIT_FAILURE; + const auto backgroundTexture = sf::Texture::loadFromFile(resourcesDir() / "background.jpg", sRgb).value(); const sf::Sprite background(backgroundTexture); // Create some text to draw on top of our OpenGL object @@ -78,9 +75,7 @@ int main() mipmapInstructions.setPosition({200.f, 550.f}); // Load a texture to apply to our 3D cube - sf::Texture texture; - if (!texture.loadFromFile(resourcesDir() / "logo.png")) - return EXIT_FAILURE; + auto texture = sf::Texture::loadFromFile(resourcesDir() / "logo.png").value(); // Attempt to generate a mipmap for our cube texture // We don't check the return value here since @@ -230,8 +225,7 @@ int main() if (mipmapEnabled) { // We simply reload the texture to disable mipmapping - if (!texture.loadFromFile(resourcesDir() / "logo.png")) - return EXIT_FAILURE; + texture = sf::Texture::loadFromFile(resourcesDir() / "logo.png").value(); mipmapEnabled = false; } diff --git a/examples/shader/Shader.cpp b/examples/shader/Shader.cpp index ad33ee984e..df2aca8f31 100644 --- a/examples/shader/Shader.cpp +++ b/examples/shader/Shader.cpp @@ -33,9 +33,7 @@ class Pixelate : public Effect bool onLoad() override { - // Load the texture and initialize the sprite - if (!m_texture.loadFromFile("resources/background.jpg")) - return false; + // Initialize the sprite m_sprite.emplace(m_texture); m_shader.setUniform("texture", sf::Shader::CurrentTexture); @@ -55,7 +53,7 @@ class Pixelate : public Effect } private: - sf::Texture m_texture; + sf::Texture m_texture{sf::Texture::loadFromFile("resources/background.jpg").value()}; std::optional m_sprite; sf::Shader m_shader{sf::Shader::loadFromFile("resources/pixelate.frag", sf::Shader::Type::Fragment).value()}; }; @@ -184,12 +182,7 @@ class Edge : public Effect { m_surface.setSmooth(true); - // Load the textures - if (!m_backgroundTexture.loadFromFile("resources/sfml.png")) - return false; m_backgroundTexture.setSmooth(true); - if (!m_entityTexture.loadFromFile("resources/devices.png")) - return false; m_entityTexture.setSmooth(true); // Initialize the background sprite @@ -240,8 +233,8 @@ class Edge : public Effect private: sf::RenderTexture m_surface{sf::RenderTexture::create({800, 600}).value()}; - sf::Texture m_backgroundTexture; - sf::Texture m_entityTexture; + sf::Texture m_backgroundTexture{sf::Texture::loadFromFile("resources/sfml.png").value()}; + sf::Texture m_entityTexture{sf::Texture::loadFromFile("resources/devices.png").value()}; std::optional m_backgroundSprite; std::vector m_entities; sf::Shader m_shader{sf::Shader::loadFromFile("resources/edge.frag", sf::Shader::Type::Fragment).value()}; @@ -273,10 +266,6 @@ class Geometry : public Effect m_pointCloud[i].position = {positionDistribution(rng), positionDistribution(rng)}; } - // Load the texture - if (!m_logoTexture.loadFromFile("resources/logo.png")) - return false; - // Load the shader m_shader = sf::Shader::loadFromFile("resources/billboard.vert", "resources/billboard.geom", @@ -319,7 +308,7 @@ class Geometry : public Effect } private: - sf::Texture m_logoTexture; + sf::Texture m_logoTexture{sf::Texture::loadFromFile("resources/logo.png").value()}; sf::Transform m_transform; std::optional m_shader; sf::VertexArray m_pointCloud; @@ -358,9 +347,7 @@ int main() effect->load(); // Create the messages background - sf::Texture textBackgroundTexture; - if (!textBackgroundTexture.loadFromFile("resources/text-background.png")) - return EXIT_FAILURE; + const auto textBackgroundTexture = sf::Texture::loadFromFile("resources/text-background.png").value(); sf::Sprite textBackground(textBackgroundTexture); textBackground.setPosition({0.f, 520.f}); textBackground.setColor(sf::Color(255, 255, 255, 200)); diff --git a/examples/sound_effects/SoundEffects.cpp b/examples/sound_effects/SoundEffects.cpp index f0429f5fe4..b7bed8c90f 100644 --- a/examples/sound_effects/SoundEffects.cpp +++ b/examples/sound_effects/SoundEffects.cpp @@ -1080,9 +1080,7 @@ int main() effects[current]->start(); // Create the messages background - sf::Texture textBackgroundTexture; - if (!textBackgroundTexture.loadFromFile(resourcesDir() / "text-background.png")) - return EXIT_FAILURE; + const auto textBackgroundTexture = sf::Texture::loadFromFile(resourcesDir() / "text-background.png").value(); sf::Sprite textBackground(textBackgroundTexture); textBackground.setPosition({0.f, 520.f}); textBackground.setColor(sf::Color(255, 255, 255, 200)); diff --git a/examples/tennis/Tennis.cpp b/examples/tennis/Tennis.cpp index 83a60fc38f..6e7af5268a 100644 --- a/examples/tennis/Tennis.cpp +++ b/examples/tennis/Tennis.cpp @@ -53,9 +53,7 @@ int main() sf::Sound ballSound(ballSoundBuffer); // Create the SFML logo texture: - sf::Texture sfmlLogoTexture; - if (!sfmlLogoTexture.loadFromFile(resourcesDir() / "sfml_logo.png")) - return EXIT_FAILURE; + const auto sfmlLogoTexture = sf::Texture::loadFromFile(resourcesDir() / "sfml_logo.png").value(); sf::Sprite sfmlLogo(sfmlLogoTexture); sfmlLogo.setPosition({170.f, 50.f}); diff --git a/examples/win32/Win32.cpp b/examples/win32/Win32.cpp index ff9010c5e3..79922d0e7e 100644 --- a/examples/win32/Win32.cpp +++ b/examples/win32/Win32.cpp @@ -111,10 +111,8 @@ int main() sf::RenderWindow sfmlView2(view2); // Load some textures to display - sf::Texture texture1; - sf::Texture texture2; - if (!texture1.loadFromFile("resources/image1.jpg") || !texture2.loadFromFile("resources/image2.jpg")) - return EXIT_FAILURE; + const auto texture1 = sf::Texture::loadFromFile("resources/image1.jpg").value(); + const auto texture2 = sf::Texture::loadFromFile("resources/image2.jpg").value(); sf::Sprite sprite1(texture1); sf::Sprite sprite2(texture2); sprite1.setOrigin(sf::Vector2f(texture1.getSize()) / 2.f); diff --git a/include/SFML/Graphics/RenderWindow.hpp b/include/SFML/Graphics/RenderWindow.hpp index d6b2bef3b7..a19481e140 100644 --- a/include/SFML/Graphics/RenderWindow.hpp +++ b/include/SFML/Graphics/RenderWindow.hpp @@ -266,11 +266,7 @@ class SFML_GRAPHICS_API RenderWindow : public Window, public RenderTarget /// sf::RenderWindow window(sf::VideoMode({800, 600}), "SFML OpenGL"); /// /// // Create a sprite and a text to display -/// sf::Texture texture; -/// if (!texture.loadFromFile("circle.png")) -/// { -/// // error... -/// } +/// const auto texture = sf::Texture::loadFromFile("circle.png").value(); /// sf::Sprite sprite(texture); /// const auto font = sf::Font::loadFromFile("arial.ttf").value(); /// sf::Text text(font); diff --git a/include/SFML/Graphics/Sprite.hpp b/include/SFML/Graphics/Sprite.hpp index c2b000a716..67cfdace76 100644 --- a/include/SFML/Graphics/Sprite.hpp +++ b/include/SFML/Graphics/Sprite.hpp @@ -266,12 +266,8 @@ class SFML_GRAPHICS_API Sprite : public Drawable, public Transformable /// /// Usage example: /// \code -/// // Declare and load a texture -/// sf::Texture texture; -/// if (!texture.loadFromFile("texture.png")) -/// { -/// // Handle error... -/// } +/// // Load a texture +/// const auto texture = sf::Texture::loadFromFile("texture.png").value(); /// /// // Create a sprite /// sf::Sprite sprite(texture); diff --git a/include/SFML/Graphics/Texture.hpp b/include/SFML/Graphics/Texture.hpp index 8e75dc4b06..a01df976dc 100644 --- a/include/SFML/Graphics/Texture.hpp +++ b/include/SFML/Graphics/Texture.hpp @@ -37,6 +37,7 @@ #include #include +#include #include #include @@ -55,14 +56,6 @@ class Image; class SFML_GRAPHICS_API Texture : GlResource { public: - //////////////////////////////////////////////////////////// - /// \brief Default constructor - /// - /// Creates an empty texture. - /// - //////////////////////////////////////////////////////////// - Texture(); - //////////////////////////////////////////////////////////// /// \brief Destructor /// @@ -101,11 +94,12 @@ class SFML_GRAPHICS_API Texture : GlResource /// If this function fails, the texture is left unchanged. /// /// \param size Width and height of the texture + /// \param sRgb True to enable sRGB conversion, false to disable it /// - /// \return True if creation was successful + /// \return Texture if creation was successful, otherwise `std::nullopt` /// //////////////////////////////////////////////////////////// - [[nodiscard]] bool create(const Vector2u& size); + [[nodiscard]] static std::optional create(const Vector2u& size, bool sRgb = false); //////////////////////////////////////////////////////////// /// \brief Load the texture from a file on disk @@ -122,14 +116,17 @@ class SFML_GRAPHICS_API Texture : GlResource /// If this function fails, the texture is left unchanged. /// /// \param filename Path of the image file to load + /// \param sRgb True to enable sRGB conversion, false to disable it /// \param area Area of the image to load /// - /// \return True if loading was successful + /// \return Texture if loading was successful, otherwise `std::nullopt` /// /// \see loadFromMemory, loadFromStream, loadFromImage /// //////////////////////////////////////////////////////////// - [[nodiscard]] bool loadFromFile(const std::filesystem::path& filename, const IntRect& area = {}); + [[nodiscard]] static std::optional loadFromFile(const std::filesystem::path& filename, + bool sRgb = false, + const IntRect& area = {}); //////////////////////////////////////////////////////////// /// \brief Load the texture from a file in memory @@ -147,14 +144,19 @@ class SFML_GRAPHICS_API Texture : GlResource /// /// \param data Pointer to the file data in memory /// \param size Size of the data to load, in bytes + /// \param sRgb True to enable sRGB conversion, false to disable it /// \param area Area of the image to load /// - /// \return True if loading was successful + /// \return Texture if loading was successful, otherwise `std::nullopt` /// /// \see loadFromFile, loadFromStream, loadFromImage /// //////////////////////////////////////////////////////////// - [[nodiscard]] bool loadFromMemory(const void* data, std::size_t size, const IntRect& area = {}); + [[nodiscard]] static std::optional loadFromMemory( + const void* data, + std::size_t size, + bool sRgb = false, + const IntRect& area = {}); //////////////////////////////////////////////////////////// /// \brief Load the texture from a custom stream @@ -171,14 +173,15 @@ class SFML_GRAPHICS_API Texture : GlResource /// If this function fails, the texture is left unchanged. /// /// \param stream Source stream to read from + /// \param sRgb True to enable sRGB conversion, false to disable it /// \param area Area of the image to load /// - /// \return True if loading was successful + /// \return Texture if loading was successful, otherwise `std::nullopt` /// /// \see loadFromFile, loadFromMemory, loadFromImage /// //////////////////////////////////////////////////////////// - [[nodiscard]] bool loadFromStream(InputStream& stream, const IntRect& area = {}); + [[nodiscard]] static std::optional loadFromStream(InputStream& stream, bool sRgb = false, const IntRect& area = {}); //////////////////////////////////////////////////////////// /// \brief Load the texture from an image @@ -195,14 +198,15 @@ class SFML_GRAPHICS_API Texture : GlResource /// If this function fails, the texture is left unchanged. /// /// \param image Image to load into the texture + /// \param sRgb True to enable sRGB conversion, false to disable it /// \param area Area of the image to load /// - /// \return True if loading was successful + /// \return Texture if loading was successful, otherwise `std::nullopt` /// /// \see loadFromFile, loadFromMemory /// //////////////////////////////////////////////////////////// - [[nodiscard]] bool loadFromImage(const Image& image, const IntRect& area = {}); + [[nodiscard]] static std::optional loadFromImage(const Image& image, bool sRgb = false, const IntRect& area = {}); //////////////////////////////////////////////////////////// /// \brief Return the size of the texture @@ -402,31 +406,6 @@ class SFML_GRAPHICS_API Texture : GlResource //////////////////////////////////////////////////////////// bool isSmooth() const; - //////////////////////////////////////////////////////////// - /// \brief Enable or disable conversion from sRGB - /// - /// When providing texture data from an image file or memory, it can - /// either be stored in a linear color space or an sRGB color space. - /// Most digital images account for gamma correction already, so they - /// would need to be "uncorrected" back to linear color space before - /// being processed by the hardware. The hardware can automatically - /// convert it from the sRGB color space to a linear color space when - /// it gets sampled. When the rendered image gets output to the final - /// framebuffer, it gets converted back to sRGB. - /// - /// After enabling or disabling sRGB conversion, make sure to reload - /// the texture data in order for the setting to take effect. - /// - /// This option is only useful in conjunction with an sRGB capable - /// framebuffer. This can be requested during window creation. - /// - /// \param sRgb True to enable sRGB conversion, false to disable it - /// - /// \see isSrgb - /// - //////////////////////////////////////////////////////////// - void setSrgb(bool sRgb); - //////////////////////////////////////////////////////////// /// \brief Tell whether the texture source is converted from sRGB or not /// @@ -566,6 +545,14 @@ class SFML_GRAPHICS_API Texture : GlResource friend class RenderTexture; friend class RenderTarget; + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + /// Creates an empty texture. + /// + //////////////////////////////////////////////////////////// + Texture(); + //////////////////////////////////////////////////////////// /// \brief Get a valid image size according to hardware support /// @@ -657,15 +644,25 @@ SFML_GRAPHICS_API void swap(Texture& left, Texture& right) noexcept; /// that a pixel must be composed of 8 bits red, green, blue and /// alpha channels -- just like a sf::Color. /// +/// When providing texture data from an image file or memory, it can +/// either be stored in a linear color space or an sRGB color space. +/// Most digital images account for gamma correction already, so they +/// would need to be "uncorrected" back to linear color space before +/// being processed by the hardware. The hardware can automatically +/// convert it from the sRGB color space to a linear color space when +/// it gets sampled. When the rendered image gets output to the final +/// framebuffer, it gets converted back to sRGB. +/// +/// This option is only useful in conjunction with an sRGB capable +/// framebuffer. This can be requested during window creation. +/// /// Usage example: /// \code /// // This example shows the most common use of sf::Texture: /// // drawing a sprite /// /// // Load a texture from a file -/// sf::Texture texture; -/// if (!texture.loadFromFile("texture.png")) -/// return -1; +/// const auto texture = sf::Texture::loadFromFile("texture.png").value(); /// /// // Assign it to a sprite /// sf::Sprite sprite(texture); @@ -679,9 +676,7 @@ SFML_GRAPHICS_API void swap(Texture& left, Texture& right) noexcept; /// // streaming real-time data, like video frames /// /// // Create an empty texture -/// sf::Texture texture; -/// if (!texture.create({640, 480})) -/// return -1; +/// auto texture = sf::Texture::create({640, 480}).value(); /// /// // Create a sprite that will display the texture /// sf::Sprite sprite(texture); diff --git a/include/SFML/System/InputStream.hpp b/include/SFML/System/InputStream.hpp index c62610bda1..d910cb2226 100644 --- a/include/SFML/System/InputStream.hpp +++ b/include/SFML/System/InputStream.hpp @@ -133,7 +133,6 @@ class SFML_SYSTEM_API InputStream /// }; /// /// // now you can load textures... -/// sf::Texture texture; /// ZipStream stream("resources.zip"); /// /// if (!stream.open("images/img.png")) @@ -141,10 +140,7 @@ class SFML_SYSTEM_API InputStream /// // Handle error... /// } /// -/// if (!texture.loadFromStream(stream)) -/// { -/// // Handle error... -/// } +/// const auto texture = sf::Texture::loadFromStream(stream).value(); /// /// // musics... /// sf::Music music; diff --git a/src/SFML/Graphics/Font.cpp b/src/SFML/Graphics/Font.cpp index c052dc1e9d..03b5abbd26 100644 --- a/src/SFML/Graphics/Font.cpp +++ b/src/SFML/Graphics/Font.cpp @@ -679,16 +679,16 @@ IntRect Font::findGlyphRect(Page& page, const Vector2u& size) const if ((textureSize.x * 2 <= Texture::getMaximumSize()) && (textureSize.y * 2 <= Texture::getMaximumSize())) { // Make the texture 2 times bigger - Texture newTexture; - if (!newTexture.create(textureSize * 2u)) + auto newTexture = sf::Texture::create(textureSize * 2u); + if (!newTexture) { err() << "Failed to create new page texture" << std::endl; return {{0, 0}, {2, 2}}; } - newTexture.setSmooth(m_isSmooth); - newTexture.update(page.texture); - page.texture.swap(newTexture); + newTexture->setSmooth(m_isSmooth); + newTexture->update(page.texture); + page.texture.swap(*newTexture); } else { @@ -757,23 +757,28 @@ bool Font::setCurrentSize(unsigned int characterSize) const //////////////////////////////////////////////////////////// -Font::Page::Page(bool smooth) +Font::Page::Page(bool smooth) : +texture( + [smooth] + { + // Make sure that the texture is initialized by default + Image image({128, 128}, Color::Transparent); + + // Reserve a 2x2 white square for texturing underlines + for (unsigned int x = 0; x < 2; ++x) + for (unsigned int y = 0; y < 2; ++y) + image.setPixel({x, y}, Color::White); + + // Create the texture + auto maybeTexture = sf::Texture::loadFromImage(image); + if (!maybeTexture) + err() << "Failed to load font page texture" << std::endl; + + auto newTexture = maybeTexture.value(); + newTexture.setSmooth(smooth); + return newTexture; + }()) { - // Make sure that the texture is initialized by default - Image image({128, 128}, Color::Transparent); - - // Reserve a 2x2 white square for texturing underlines - for (unsigned int x = 0; x < 2; ++x) - for (unsigned int y = 0; y < 2; ++y) - image.setPixel({x, y}, Color::White); - - // Create the texture - if (!texture.loadFromImage(image)) - { - err() << "Failed to load font page texture" << std::endl; - } - - texture.setSmooth(smooth); } } // namespace sf diff --git a/src/SFML/Graphics/RenderTexture.cpp b/src/SFML/Graphics/RenderTexture.cpp index 7bb47fe268..c149b7bb12 100644 --- a/src/SFML/Graphics/RenderTexture.cpp +++ b/src/SFML/Graphics/RenderTexture.cpp @@ -52,19 +52,15 @@ RenderTexture& RenderTexture::operator=(RenderTexture&&) noexcept = default; //////////////////////////////////////////////////////////// std::optional RenderTexture::create(const Vector2u& size, const ContextSettings& settings) { - sf::Texture texture; - - // Set texture to be in sRGB scale if requested - texture.setSrgb(settings.sRgbCapable); - // Create the texture - if (!texture.create(size)) + auto texture = sf::Texture::create(size, settings.sRgbCapable); + if (!texture) { err() << "Impossible to create render texture (failed to create the target texture)" << std::endl; return std::nullopt; } - RenderTexture renderTexture(std::move(texture)); + RenderTexture renderTexture(std::move(*texture)); // We disable smoothing by default for render textures renderTexture.setSmooth(false); diff --git a/src/SFML/Graphics/Texture.cpp b/src/SFML/Graphics/Texture.cpp index 4221979087..96448d5a17 100644 --- a/src/SFML/Graphics/Texture.cpp +++ b/src/SFML/Graphics/Texture.cpp @@ -79,16 +79,14 @@ m_sRgb(copy.m_sRgb), m_isRepeated(copy.m_isRepeated), m_cacheId(TextureImpl::getUniqueId()) { - if (copy.m_texture) + if (auto texture = create(copy.getSize(), copy.isSrgb())) { - if (create(copy.getSize())) - { - update(copy); - } - else - { - err() << "Failed to copy texture, failed to create new texture" << std::endl; - } + *this = std::move(*texture); + update(copy); + } + else + { + err() << "Failed to copy texture, failed to create new texture" << std::endl; } } @@ -151,13 +149,13 @@ Texture& Texture::operator=(Texture&& right) noexcept //////////////////////////////////////////////////////////// -bool Texture::create(const Vector2u& size) +std::optional Texture::create(const Vector2u& size, bool sRgb) { // Check if texture parameters are valid before creating it if ((size.x == 0) || (size.y == 0)) { err() << "Failed to create texture, invalid size (" << size.x << "x" << size.y << ")" << std::endl; - return false; + return std::nullopt; } const TransientContextLock lock; @@ -175,22 +173,21 @@ bool Texture::create(const Vector2u& size) err() << "Failed to create texture, its internal size is too high " << "(" << actualSize.x << "x" << actualSize.y << ", " << "maximum is " << maxSize << "x" << maxSize << ")" << std::endl; - return false; + return std::nullopt; } // All the validity checks passed, we can store the new texture settings - m_size = size; - m_actualSize = actualSize; - m_pixelsFlipped = false; - m_fboAttachment = false; - - // Create the OpenGL texture if it doesn't exist yet - if (!m_texture) - { - GLuint texture = 0; - glCheck(glGenTextures(1, &texture)); - m_texture = texture; - } + Texture texture; + texture.m_size = size; + texture.m_actualSize = actualSize; + texture.m_pixelsFlipped = false; + texture.m_fboAttachment = false; + texture.m_sRgb = sRgb; + + // Create the OpenGL texture + GLuint glTexture = 0; + glCheck(glGenTextures(1, &glTexture)); + texture.m_texture = glTexture; // Make sure that the current texture binding will be preserved const priv::TextureSaver save; @@ -198,7 +195,7 @@ bool Texture::create(const Vector2u& size) static const bool textureEdgeClamp = GLEXT_texture_edge_clamp || GLEXT_GL_VERSION_1_2 || Context::isExtensionAvailable("GL_EXT_texture_edge_clamp"); - if (!m_isRepeated && !textureEdgeClamp) + if (!textureEdgeClamp) { static bool warned = false; @@ -214,7 +211,7 @@ bool Texture::create(const Vector2u& size) static const bool textureSrgb = GLEXT_texture_sRGB; - if (m_sRgb && !textureSrgb) + if (texture.m_sRgb && !textureSrgb) { static bool warned = false; @@ -230,70 +227,70 @@ bool Texture::create(const Vector2u& size) warned = true; } - m_sRgb = false; + texture.m_sRgb = false; } #ifndef SFML_OPENGL_ES - const GLint textureWrapParam = m_isRepeated ? GL_REPEAT : (textureEdgeClamp ? GLEXT_GL_CLAMP_TO_EDGE : GLEXT_GL_CLAMP); + const GLint textureWrapParam = textureEdgeClamp ? GLEXT_GL_CLAMP_TO_EDGE : GLEXT_GL_CLAMP; #else - const GLint textureWrapParam = m_isRepeated ? GL_REPEAT : GLEXT_GL_CLAMP_TO_EDGE; + const GLint textureWrapParam = GLEXT_GL_CLAMP_TO_EDGE; #endif // Initialize the texture - glCheck(glBindTexture(GL_TEXTURE_2D, m_texture)); + glCheck(glBindTexture(GL_TEXTURE_2D, texture.m_texture)); glCheck(glTexImage2D(GL_TEXTURE_2D, 0, - (m_sRgb ? GLEXT_GL_SRGB8_ALPHA8 : GL_RGBA), - static_cast(m_actualSize.x), - static_cast(m_actualSize.y), + (texture.m_sRgb ? GLEXT_GL_SRGB8_ALPHA8 : GL_RGBA), + static_cast(texture.m_actualSize.x), + static_cast(texture.m_actualSize.y), 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr)); glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, textureWrapParam)); glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, textureWrapParam)); - glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, m_isSmooth ? GL_LINEAR : GL_NEAREST)); - glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_isSmooth ? GL_LINEAR : GL_NEAREST)); - m_cacheId = TextureImpl::getUniqueId(); + glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); + glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); + texture.m_cacheId = TextureImpl::getUniqueId(); - m_hasMipmap = false; + texture.m_hasMipmap = false; - return true; + return texture; } //////////////////////////////////////////////////////////// -bool Texture::loadFromFile(const std::filesystem::path& filename, const IntRect& area) +std::optional Texture::loadFromFile(const std::filesystem::path& filename, bool sRgb, const IntRect& area) { const auto image = sf::Image::loadFromFile(filename); if (!image) - return false; - return loadFromImage(*image, area); + return std::nullopt; + return loadFromImage(*image, sRgb, area); } //////////////////////////////////////////////////////////// -bool Texture::loadFromMemory(const void* data, std::size_t size, const IntRect& area) +std::optional Texture::loadFromMemory(const void* data, std::size_t size, bool sRgb, const IntRect& area) { const auto image = sf::Image::loadFromMemory(data, size); if (!image) - return false; - return loadFromImage(*image, area); + return std::nullopt; + return loadFromImage(*image, sRgb, area); } //////////////////////////////////////////////////////////// -bool Texture::loadFromStream(InputStream& stream, const IntRect& area) +std::optional Texture::loadFromStream(InputStream& stream, bool sRgb, const IntRect& area) { const auto image = sf::Image::loadFromStream(stream); if (!image) - return false; - return loadFromImage(*image, area); + return std::nullopt; + return loadFromImage(*image, sRgb, area); } //////////////////////////////////////////////////////////// -bool Texture::loadFromImage(const Image& image, const IntRect& area) +std::optional Texture::loadFromImage(const Image& image, bool sRgb, const IntRect& area) { // Retrieve the image size const auto [width, height] = Vector2i(image.getSize()); @@ -303,15 +300,15 @@ bool Texture::loadFromImage(const Image& image, const IntRect& area) ((area.left <= 0) && (area.top <= 0) && (area.width >= width) && (area.height >= height))) { // Load the entire image - if (create(image.getSize())) + if (auto texture = sf::Texture::create(image.getSize(), sRgb)) { - update(image); + texture->update(image); - return true; + return texture; } else { - return false; + return std::nullopt; } } else @@ -326,7 +323,7 @@ bool Texture::loadFromImage(const Image& image, const IntRect& area) rectangle.height = std::min(rectangle.height, height - rectangle.top); // Create the texture and upload the pixels - if (create(Vector2u(rectangle.getSize()))) + if (auto texture = sf::Texture::create(Vector2u(rectangle.getSize()), sRgb)) { const TransientContextLock lock; @@ -335,25 +332,25 @@ bool Texture::loadFromImage(const Image& image, const IntRect& area) // Copy the pixels to the texture, row by row const std::uint8_t* pixels = image.getPixelsPtr() + 4 * (rectangle.left + (width * rectangle.top)); - glCheck(glBindTexture(GL_TEXTURE_2D, m_texture)); + glCheck(glBindTexture(GL_TEXTURE_2D, texture->m_texture)); for (int i = 0; i < rectangle.height; ++i) { glCheck(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, i, rectangle.width, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels)); pixels += 4 * width; } - glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_isSmooth ? GL_LINEAR : GL_NEAREST)); - m_hasMipmap = false; + glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); + texture->m_hasMipmap = false; // Force an OpenGL flush, so that the texture will appear updated // in all contexts immediately (solves problems in multi-threaded apps) glCheck(glFlush()); - return true; + return texture; } else { - return false; + return std::nullopt; } } } @@ -736,13 +733,6 @@ bool Texture::isSmooth() const } -//////////////////////////////////////////////////////////// -void Texture::setSrgb(bool sRgb) -{ - m_sRgb = sRgb; -} - - //////////////////////////////////////////////////////////// bool Texture::isSrgb() const { diff --git a/test/Graphics/RenderWindow.test.cpp b/test/Graphics/RenderWindow.test.cpp index f0c8d68613..e10db5ebfc 100644 --- a/test/Graphics/RenderWindow.test.cpp +++ b/test/Graphics/RenderWindow.test.cpp @@ -75,8 +75,7 @@ TEST_CASE("[Graphics] sf::RenderWindow", runDisplayTests()) sf::ContextSettings()); REQUIRE(window.getSize() == sf::Vector2u(256, 256)); - sf::Texture texture; - REQUIRE(texture.create(window.getSize())); + auto texture = sf::Texture::create(window.getSize()).value(); window.clear(sf::Color::Red); texture.update(window); diff --git a/test/Graphics/Shape.test.cpp b/test/Graphics/Shape.test.cpp index bd0abfde35..f8110e6e15 100644 --- a/test/Graphics/Shape.test.cpp +++ b/test/Graphics/Shape.test.cpp @@ -66,8 +66,8 @@ TEST_CASE("[Graphics] sf::Shape", runDisplayTests()) SECTION("Set/get texture") { - const sf::Texture texture; - TriangleShape triangleShape({}); + const auto texture = sf::Texture::create({64, 64}).value(); + TriangleShape triangleShape({}); triangleShape.setTexture(&texture, true); CHECK(triangleShape.getTexture() == &texture); } diff --git a/test/Graphics/Sprite.test.cpp b/test/Graphics/Sprite.test.cpp index 73afc41142..d6726c70f7 100644 --- a/test/Graphics/Sprite.test.cpp +++ b/test/Graphics/Sprite.test.cpp @@ -19,7 +19,7 @@ TEST_CASE("[Graphics] sf::Sprite", runDisplayTests()) STATIC_CHECK(std::is_nothrow_move_assignable_v); } - const sf::Texture texture; + const auto texture = sf::Texture::create({64, 64}).value(); SECTION("Construction") { @@ -27,10 +27,10 @@ TEST_CASE("[Graphics] sf::Sprite", runDisplayTests()) { const sf::Sprite sprite(texture); CHECK(&sprite.getTexture() == &texture); - CHECK(sprite.getTextureRect() == sf::IntRect()); + CHECK(sprite.getTextureRect() == sf::IntRect({}, {64, 64})); CHECK(sprite.getColor() == sf::Color::White); - CHECK(sprite.getLocalBounds() == sf::FloatRect()); - CHECK(sprite.getGlobalBounds() == sf::FloatRect()); + CHECK(sprite.getLocalBounds() == sf::FloatRect({}, {64, 64})); + CHECK(sprite.getGlobalBounds() == sf::FloatRect({}, {64, 64})); } SECTION("Texture and rectangle constructor") @@ -47,7 +47,7 @@ TEST_CASE("[Graphics] sf::Sprite", runDisplayTests()) SECTION("Set/get texture") { sf::Sprite sprite(texture); - const sf::Texture otherTexture; + const sf::Texture otherTexture = sf::Texture::create({64, 64}).value(); sprite.setTexture(otherTexture); CHECK(&sprite.getTexture() == &otherTexture); } diff --git a/test/Graphics/Texture.test.cpp b/test/Graphics/Texture.test.cpp index 99b4e6cf62..b5a6678b7f 100644 --- a/test/Graphics/Texture.test.cpp +++ b/test/Graphics/Texture.test.cpp @@ -15,6 +15,7 @@ TEST_CASE("[Graphics] sf::Texture", runDisplayTests()) { SECTION("Type traits") { + STATIC_CHECK(!std::is_default_constructible_v); STATIC_CHECK(std::is_copy_constructible_v); STATIC_CHECK(std::is_copy_assignable_v); STATIC_CHECK(std::is_nothrow_move_constructible_v); @@ -22,71 +23,58 @@ TEST_CASE("[Graphics] sf::Texture", runDisplayTests()) STATIC_CHECK(std::is_nothrow_swappable_v); } - SECTION("Construction") - { - const sf::Texture texture; - 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; - const sf::Texture texture = std::move(movedTexture); - CHECK(texture.getSize() == sf::Vector2u()); + sf::Texture movedTexture = sf::Texture::create({64, 64}).value(); + 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); + CHECK(texture.getNativeHandle() != 0); } SECTION("Assignment") { - sf::Texture movedTexture; - sf::Texture texture; - texture = std::move(movedTexture); - CHECK(texture.getSize() == sf::Vector2u()); + 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)); CHECK(!texture.isSmooth()); CHECK(!texture.isSrgb()); CHECK(!texture.isRepeated()); - CHECK(texture.getNativeHandle() == 0); + CHECK(texture.getNativeHandle() != 0); } } SECTION("create()") { - sf::Texture texture; - SECTION("At least one zero dimension") { - CHECK(!texture.create({})); - CHECK(!texture.create({0, 1})); - CHECK(!texture.create({1, 0})); + CHECK(!sf::Texture::create({})); + CHECK(!sf::Texture::create({0, 1})); + CHECK(!sf::Texture::create({1, 0})); } SECTION("Valid size") { - CHECK(texture.create({100, 100})); + const auto texture = sf::Texture::create({100, 100}).value(); CHECK(texture.getSize() == sf::Vector2u(100, 100)); CHECK(texture.getNativeHandle() != 0); } SECTION("Too large") { - CHECK(!texture.create({100'000, 100'000})); - CHECK(!texture.create({1'000'000, 1'000'000})); + CHECK(!sf::Texture::create({100'000, 100'000})); + CHECK(!sf::Texture::create({1'000'000, 1'000'000})); } } SECTION("loadFromFile()") { - sf::Texture texture; - REQUIRE(texture.loadFromFile("Graphics/sfml-logo-big.png")); + const auto texture = sf::Texture::loadFromFile("Graphics/sfml-logo-big.png").value(); CHECK(texture.getSize() == sf::Vector2u(1001, 304)); CHECK(!texture.isSmooth()); CHECK(!texture.isSrgb()); @@ -96,9 +84,8 @@ TEST_CASE("[Graphics] sf::Texture", runDisplayTests()) SECTION("loadFromMemory()") { - const auto memory = loadIntoMemory("Graphics/sfml-logo-big.png"); - sf::Texture texture; - REQUIRE(texture.loadFromMemory(memory.data(), memory.size())); + const auto memory = loadIntoMemory("Graphics/sfml-logo-big.png"); + const auto texture = sf::Texture::loadFromMemory(memory.data(), memory.size()).value(); CHECK(texture.getSize() == sf::Vector2u(1001, 304)); CHECK(!texture.isSmooth()); CHECK(!texture.isSrgb()); @@ -108,10 +95,9 @@ TEST_CASE("[Graphics] sf::Texture", runDisplayTests()) SECTION("loadFromStream()") { - sf::Texture texture; sf::FileInputStream stream; REQUIRE(stream.open("Graphics/sfml-logo-big.png")); - REQUIRE(texture.loadFromStream(stream)); + const auto texture = sf::Texture::loadFromStream(stream).value(); CHECK(texture.getSize() == sf::Vector2u(1001, 304)); CHECK(!texture.isSmooth()); CHECK(!texture.isSrgb()); @@ -124,27 +110,27 @@ TEST_CASE("[Graphics] sf::Texture", runDisplayTests()) SECTION("Subarea of image") { const sf::Image image(sf::Vector2u(10, 15)); - sf::Texture texture; SECTION("Non-truncated area") { - REQUIRE(texture.loadFromImage(image, {{0, 0}, {5, 10}})); + const auto texture = sf::Texture::loadFromImage(image, false, {{0, 0}, {5, 10}}).value(); CHECK(texture.getSize() == sf::Vector2u(5, 10)); + CHECK(texture.getNativeHandle() != 0); } SECTION("Truncated area (negative position)") { - REQUIRE(texture.loadFromImage(image, {{-5, -5}, {4, 8}})); + const auto texture = sf::Texture::loadFromImage(image, false, {{-5, -5}, {4, 8}}).value(); CHECK(texture.getSize() == sf::Vector2u(4, 8)); + CHECK(texture.getNativeHandle() != 0); } SECTION("Truncated area (width/height too big)") { - REQUIRE(texture.loadFromImage(image, {{5, 5}, {12, 18}})); + const auto texture = sf::Texture::loadFromImage(image, false, {{5, 5}, {12, 18}}).value(); CHECK(texture.getSize() == sf::Vector2u(5, 10)); + CHECK(texture.getNativeHandle() != 0); } - - CHECK(texture.getNativeHandle() != 0); } } @@ -152,8 +138,7 @@ TEST_CASE("[Graphics] sf::Texture", runDisplayTests()) { constexpr std::uint8_t red[] = {0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF}; - sf::Texture texture; - REQUIRE(texture.create(sf::Vector2u(1, 2))); + auto texture = sf::Texture::create({1, 2}).value(); texture.update(red); SECTION("Construction") @@ -165,8 +150,8 @@ TEST_CASE("[Graphics] sf::Texture", runDisplayTests()) SECTION("Assignment") { - sf::Texture textureCopy; - textureCopy = texture; + sf::Texture textureCopy = sf::Texture::create({64, 64}).value(); + textureCopy = texture; REQUIRE(textureCopy.getSize() == sf::Vector2u(1, 2)); CHECK(textureCopy.copyToImage().getPixel(sf::Vector2u(0, 1)) == sf::Color::Red); } @@ -177,18 +162,16 @@ TEST_CASE("[Graphics] sf::Texture", runDisplayTests()) constexpr std::uint8_t yellow[] = {0xFF, 0xFF, 0x00, 0xFF}; constexpr std::uint8_t cyan[] = {0x00, 0xFF, 0xFF, 0xFF}; - sf::Texture texture; - SECTION("Pixels") { - REQUIRE(texture.create(sf::Vector2u(1, 1))); + auto texture = sf::Texture::create(sf::Vector2u(1, 1)).value(); texture.update(yellow); CHECK(texture.copyToImage().getPixel(sf::Vector2u(0, 0)) == sf::Color::Yellow); } SECTION("Pixels, size and destination") { - REQUIRE(texture.create(sf::Vector2u(2, 1))); + auto texture = sf::Texture::create(sf::Vector2u(2, 1)).value(); 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); @@ -197,22 +180,19 @@ TEST_CASE("[Graphics] sf::Texture", runDisplayTests()) SECTION("Another texture") { - sf::Texture otherTexture; - REQUIRE(otherTexture.create(sf::Vector2u(1, 1))); + auto otherTexture = sf::Texture::create(sf::Vector2u(1, 1)).value(); otherTexture.update(cyan); - REQUIRE(texture.create(sf::Vector2u(1, 1))); + auto texture = sf::Texture::create(sf::Vector2u(1, 1)).value(); texture.update(otherTexture); CHECK(texture.copyToImage().getPixel(sf::Vector2u(0, 0)) == sf::Color::Cyan); } SECTION("Another texture and destination") { - REQUIRE(texture.create(sf::Vector2u(2, 1))); - sf::Texture otherTexture1; - REQUIRE(otherTexture1.create(sf::Vector2u(1, 1))); + auto texture = sf::Texture::create(sf::Vector2u(2, 1)).value(); + auto otherTexture1 = sf::Texture::create(sf::Vector2u(1, 1)).value(); otherTexture1.update(cyan); - sf::Texture otherTexture2; - REQUIRE(otherTexture2.create(sf::Vector2u(1, 1))); + auto otherTexture2 = sf::Texture::create(sf::Vector2u(1, 1)).value(); otherTexture2.update(yellow); texture.update(otherTexture1, sf::Vector2u(0, 0)); texture.update(otherTexture2, sf::Vector2u(1, 0)); @@ -222,7 +202,7 @@ TEST_CASE("[Graphics] sf::Texture", runDisplayTests()) SECTION("Image") { - REQUIRE(texture.create(sf::Vector2u(16, 32))); + auto texture = sf::Texture::create(sf::Vector2u(16, 32)).value(); 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); @@ -230,7 +210,7 @@ TEST_CASE("[Graphics] sf::Texture", runDisplayTests()) SECTION("Image and destination") { - REQUIRE(texture.create(sf::Vector2u(16, 32))); + auto texture = sf::Texture::create(sf::Vector2u(16, 32)).value(); 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); @@ -243,7 +223,7 @@ TEST_CASE("[Graphics] sf::Texture", runDisplayTests()) SECTION("Set/get smooth") { - sf::Texture texture; + sf::Texture texture = sf::Texture::create({64, 64}).value(); CHECK(!texture.isSmooth()); texture.setSmooth(true); CHECK(texture.isSmooth()); @@ -251,19 +231,9 @@ TEST_CASE("[Graphics] sf::Texture", runDisplayTests()) CHECK(!texture.isSmooth()); } - SECTION("Set/get srgb") - { - sf::Texture texture; - CHECK(!texture.isSrgb()); - texture.setSrgb(true); - CHECK(texture.isSrgb()); - texture.setSrgb(false); - CHECK(!texture.isSrgb()); - } - SECTION("Set/get repeated") { - sf::Texture texture; + sf::Texture texture = sf::Texture::create({64, 64}).value(); CHECK(!texture.isRepeated()); texture.setRepeated(true); CHECK(texture.isRepeated()); @@ -273,9 +243,7 @@ TEST_CASE("[Graphics] sf::Texture", runDisplayTests()) SECTION("generateMipmap()") { - sf::Texture texture; - CHECK(!texture.generateMipmap()); - CHECK(texture.create({100, 100})); + sf::Texture texture = sf::Texture::create({100, 100}).value(); CHECK(texture.generateMipmap()); } @@ -284,17 +252,13 @@ TEST_CASE("[Graphics] sf::Texture", runDisplayTests()) 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; - REQUIRE(texture1.create(sf::Vector2u(1, 1))); + auto texture1 = sf::Texture::create(sf::Vector2u(1, 1), true).value(); texture1.update(blue); - texture1.setSrgb(true); texture1.setSmooth(false); texture1.setRepeated(true); - sf::Texture texture2; - REQUIRE(texture2.create(sf::Vector2u(2, 1))); + auto texture2 = sf::Texture::create(sf::Vector2u(2, 1), false).value(); texture2.update(green); - texture2.setSrgb(false); texture2.setSmooth(true); texture2.setRepeated(false); diff --git a/tools/xcode/templates/SFML/SFML App.xctemplate/main.cpp b/tools/xcode/templates/SFML/SFML App.xctemplate/main.cpp index 0b6b4ec897..96802448ea 100644 --- a/tools/xcode/templates/SFML/SFML App.xctemplate/main.cpp +++ b/tools/xcode/templates/SFML/SFML App.xctemplate/main.cpp @@ -34,11 +34,7 @@ int main() window.setIcon(icon); // Load a sprite to display - sf::Texture texture; - if (!texture.loadFromFile(resourcePath() / "background.jpg")) - { - return EXIT_FAILURE; - } + const auto texture = sf::Texture::loadFromFile(resourcePath() / "background.jpg").value(); sf::Sprite sprite(texture); // Create a graphical text to display diff --git a/tools/xcode/templates/SFML/SFML CLT.xctemplate/main.cpp b/tools/xcode/templates/SFML/SFML CLT.xctemplate/main.cpp index e13e6c9c7b..1a9841068a 100644 --- a/tools/xcode/templates/SFML/SFML CLT.xctemplate/main.cpp +++ b/tools/xcode/templates/SFML/SFML CLT.xctemplate/main.cpp @@ -32,11 +32,7 @@ int main() window.setIcon(icon); // Load a sprite to display - sf::Texture texture; - if (!texture.loadFromFile("background.jpg")) - { - return EXIT_FAILURE; - } + const auto texture = sf::Texture::loadFromFile("background.jpg").value(); sf::Sprite sprite(texture); // Create a graphical text to display