Remove default empty state of sf::RenderTexture

This commit is contained in:
Chris Thrasher 2024-05-21 15:12:13 -06:00
parent 6f459bb14c
commit fdcd899d2b
6 changed files with 75 additions and 95 deletions

View File

@ -182,9 +182,6 @@ public:
bool onLoad() override bool onLoad() override
{ {
// Create the off-screen surface
if (!m_surface.create({800, 600}))
return false;
m_surface.setSmooth(true); m_surface.setSmooth(true);
// Load the textures // Load the textures
@ -242,7 +239,7 @@ public:
} }
private: private:
sf::RenderTexture m_surface; sf::RenderTexture m_surface{sf::RenderTexture::create({800, 600}).value()};
sf::Texture m_backgroundTexture; sf::Texture m_backgroundTexture;
sf::Texture m_entityTexture; sf::Texture m_entityTexture;
std::optional<sf::Sprite> m_backgroundSprite; std::optional<sf::Sprite> m_backgroundSprite;

View File

@ -37,6 +37,7 @@
#include <SFML/System/Vector2.hpp> #include <SFML/System/Vector2.hpp>
#include <memory> #include <memory>
#include <optional>
namespace sf namespace sf
@ -53,17 +54,6 @@ class RenderTextureImpl;
class SFML_GRAPHICS_API RenderTexture : public RenderTarget class SFML_GRAPHICS_API RenderTexture : public RenderTarget
{ {
public: public:
////////////////////////////////////////////////////////////
/// \brief Default constructor
///
/// Constructs an empty, invalid render-texture. You must
/// call create to have a valid render-texture.
///
/// \see create
///
////////////////////////////////////////////////////////////
RenderTexture();
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Destructor /// \brief Destructor
/// ///
@ -97,10 +87,6 @@ public:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Create the render-texture /// \brief Create the render-texture
/// ///
/// Before calling this function, the render-texture is in
/// an invalid state, thus it is mandatory to call it before
/// doing anything with the render-texture.
///
/// The last parameter, \a settings, is useful if you want to enable /// The last parameter, \a settings, is useful if you want to enable
/// multi-sampling or use the render-texture for OpenGL rendering that /// multi-sampling or use the render-texture for OpenGL rendering that
/// requires a depth or stencil buffer. Otherwise it is unnecessary, and /// requires a depth or stencil buffer. Otherwise it is unnecessary, and
@ -112,10 +98,11 @@ public:
/// \param size Width and height of the render-texture /// \param size Width and height of the render-texture
/// \param settings Additional settings for the underlying OpenGL texture and context /// \param settings Additional settings for the underlying OpenGL texture and context
/// ///
/// \return True if creation has been successful /// \return Render texture if creation has been successful, otherwise `std::nullopt`
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
[[nodiscard]] bool create(const Vector2u& size, const ContextSettings& settings = ContextSettings()); [[nodiscard]] static std::optional<RenderTexture> create(const Vector2u& size,
const ContextSettings& settings = ContextSettings());
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Get the maximum anti-aliasing level supported by the system /// \brief Get the maximum anti-aliasing level supported by the system
@ -226,7 +213,6 @@ public:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Vector2u getSize() const override; Vector2u getSize() const override;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Tell if the render-texture will use sRGB encoding when drawing on it /// \brief Tell if the render-texture will use sRGB encoding when drawing on it
/// ///
@ -255,6 +241,12 @@ public:
const Texture& getTexture() const; const Texture& getTexture() const;
private: private:
////////////////////////////////////////////////////////////
/// \brief Construct from texture
///
////////////////////////////////////////////////////////////
explicit RenderTexture(Texture&& texture);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Member data // Member data
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -288,9 +280,7 @@ private:
/// sf::RenderWindow window(sf::VideoMode({800, 600}), "SFML window"); /// sf::RenderWindow window(sf::VideoMode({800, 600}), "SFML window");
/// ///
/// // Create a new render-texture /// // Create a new render-texture
/// sf::RenderTexture texture; /// auto texture = sf::RenderTexture::create({500, 500}).value();
/// if (!texture.create({500, 500}))
/// return -1;
/// ///
/// // The main loop /// // The main loop
/// while (window.isOpen()) /// while (window.isOpen())

View File

@ -34,15 +34,9 @@
#include <memory> #include <memory>
#include <ostream> #include <ostream>
#include <cassert>
namespace sf namespace sf
{ {
////////////////////////////////////////////////////////////
RenderTexture::RenderTexture() = default;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
RenderTexture::~RenderTexture() = default; RenderTexture::~RenderTexture() = default;
@ -56,45 +50,49 @@ RenderTexture& RenderTexture::operator=(RenderTexture&&) noexcept = default;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
bool RenderTexture::create(const Vector2u& size, const ContextSettings& settings) std::optional<RenderTexture> RenderTexture::create(const Vector2u& size, const ContextSettings& settings)
{ {
sf::Texture texture;
// Set texture to be in sRGB scale if requested // Set texture to be in sRGB scale if requested
m_texture.setSrgb(settings.sRgbCapable); texture.setSrgb(settings.sRgbCapable);
// Create the texture // Create the texture
if (!m_texture.create(size)) if (!texture.create(size))
{ {
err() << "Impossible to create render texture (failed to create the target texture)" << std::endl; err() << "Impossible to create render texture (failed to create the target texture)" << std::endl;
return false; return std::nullopt;
} }
RenderTexture renderTexture(std::move(texture));
// We disable smoothing by default for render textures // We disable smoothing by default for render textures
setSmooth(false); renderTexture.setSmooth(false);
// Create the implementation // Create the implementation
if (priv::RenderTextureImplFBO::isAvailable()) if (priv::RenderTextureImplFBO::isAvailable())
{ {
// Use frame-buffer object (FBO) // Use frame-buffer object (FBO)
m_impl = std::make_unique<priv::RenderTextureImplFBO>(); renderTexture.m_impl = std::make_unique<priv::RenderTextureImplFBO>();
// Mark the texture as being a framebuffer object attachment // Mark the texture as being a framebuffer object attachment
m_texture.m_fboAttachment = true; renderTexture.m_texture.m_fboAttachment = true;
} }
else else
{ {
// Use default implementation // Use default implementation
m_impl = std::make_unique<priv::RenderTextureImplDefault>(); renderTexture.m_impl = std::make_unique<priv::RenderTextureImplDefault>();
} }
// Initialize the render texture // Initialize the render texture
// We pass the actual size of our texture since OpenGL ES requires that all attachments have identical sizes // We pass the actual size of our texture since OpenGL ES requires that all attachments have identical sizes
if (!m_impl->create(m_texture.m_actualSize, m_texture.m_texture, settings)) if (!renderTexture.m_impl->create(renderTexture.m_texture.m_actualSize, renderTexture.m_texture.m_texture, settings))
return false; return std::nullopt;
// We can now initialize the render target part // We can now initialize the render target part
RenderTarget::initialize(); renderTexture.initialize();
return true; return renderTexture;
} }
@ -151,7 +149,7 @@ bool RenderTexture::generateMipmap()
bool RenderTexture::setActive(bool active) bool RenderTexture::setActive(bool active)
{ {
// Update RenderTarget tracking // Update RenderTarget tracking
if (m_impl && m_impl->activate(active)) if (m_impl->activate(active))
return RenderTarget::setActive(active); return RenderTarget::setActive(active);
return false; return false;
@ -160,8 +158,6 @@ bool RenderTexture::setActive(bool active)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void RenderTexture::display() void RenderTexture::display()
{
if (m_impl)
{ {
if (priv::RenderTextureImplFBO::isAvailable()) if (priv::RenderTextureImplFBO::isAvailable())
{ {
@ -181,7 +177,6 @@ void RenderTexture::display()
m_texture.m_pixelsFlipped = true; m_texture.m_pixelsFlipped = true;
m_texture.invalidateMipmap(); m_texture.invalidateMipmap();
} }
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -194,7 +189,6 @@ Vector2u RenderTexture::getSize() const
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
bool RenderTexture::isSrgb() const bool RenderTexture::isSrgb() const
{ {
assert(m_impl && "Must call RenderTexture::create first");
return m_impl->isSrgb(); return m_impl->isSrgb();
} }
@ -205,4 +199,11 @@ const Texture& RenderTexture::getTexture() const
return m_texture; return m_texture;
} }
////////////////////////////////////////////////////////////
RenderTexture::RenderTexture(Texture&& texture) : m_texture(std::move(texture))
{
}
} // namespace sf } // namespace sf

View File

@ -46,8 +46,7 @@ TEST_CASE("[Graphics] sf::Drawable", runDisplayTests())
SECTION("draw()") SECTION("draw()")
{ {
const DrawableTest drawableTest; const DrawableTest drawableTest;
sf::RenderTexture renderTexture; auto renderTexture = sf::RenderTexture::create({32, 32}).value();
CHECK(renderTexture.create({32, 32}));
CHECK(drawableTest.callCount() == 0); CHECK(drawableTest.callCount() == 0);
renderTexture.draw(drawableTest); renderTexture.draw(drawableTest);
CHECK(drawableTest.callCount() == 1); CHECK(drawableTest.callCount() == 1);

View File

@ -12,8 +12,7 @@ TEST_CASE("[Graphics] Render Tests", runDisplayTests())
{ {
SECTION("Stencil Tests") SECTION("Stencil Tests")
{ {
sf::RenderTexture renderTexture; auto renderTexture = sf::RenderTexture::create({100, 100}, sf::ContextSettings(0, 8)).value();
REQUIRE(renderTexture.create({100, 100}, sf::ContextSettings(0, 8)) == true);
renderTexture.clear(sf::Color::Red, 127); renderTexture.clear(sf::Color::Red, 127);
sf::RectangleShape shape1({100, 100}); sf::RectangleShape shape1({100, 100});

View File

@ -9,33 +9,31 @@ TEST_CASE("[Graphics] sf::RenderTexture", runDisplayTests())
{ {
SECTION("Type traits") SECTION("Type traits")
{ {
STATIC_CHECK(!std::is_default_constructible_v<sf::RenderTexture>);
STATIC_CHECK(!std::is_copy_constructible_v<sf::RenderTexture>); STATIC_CHECK(!std::is_copy_constructible_v<sf::RenderTexture>);
STATIC_CHECK(!std::is_copy_assignable_v<sf::RenderTexture>); STATIC_CHECK(!std::is_copy_assignable_v<sf::RenderTexture>);
STATIC_CHECK(std::is_nothrow_move_constructible_v<sf::RenderTexture>); STATIC_CHECK(std::is_nothrow_move_constructible_v<sf::RenderTexture>);
STATIC_CHECK(std::is_nothrow_move_assignable_v<sf::RenderTexture>); STATIC_CHECK(std::is_nothrow_move_assignable_v<sf::RenderTexture>);
} }
SECTION("Construction")
{
const sf::RenderTexture renderTexture;
CHECK(!renderTexture.isSmooth());
CHECK(!renderTexture.isRepeated());
CHECK(renderTexture.getSize() == sf::Vector2u(0, 0));
}
SECTION("create()") SECTION("create()")
{ {
sf::RenderTexture renderTexture; CHECK(!sf::RenderTexture::create({1'000'000, 1'000'000}));
CHECK(!renderTexture.create({1'000'000, 1'000'000}));
CHECK(renderTexture.create({480, 360})); CHECK(sf::RenderTexture::create({100, 100}, sf::ContextSettings(8, 0)));
CHECK(sf::RenderTexture::create({100, 100}, sf::ContextSettings(0, 8)));
const auto renderTexture = sf::RenderTexture::create({360, 480}).value();
CHECK(renderTexture.getSize() == sf::Vector2u(360, 480));
CHECK(!renderTexture.isSmooth()); CHECK(!renderTexture.isSmooth());
CHECK(!renderTexture.isRepeated()); CHECK(!renderTexture.isRepeated());
CHECK(renderTexture.getSize() == sf::Vector2u(480, 360));
CHECK(!renderTexture.isSrgb()); CHECK(!renderTexture.isSrgb());
CHECK(renderTexture.create({360, 480})); const auto& texture = renderTexture.getTexture();
CHECK(renderTexture.getSize() == sf::Vector2u(360, 480)); CHECK(texture.getSize() == sf::Vector2u(360, 480));
CHECK(renderTexture.create({100, 100}, sf::ContextSettings(8, 0))); CHECK(!texture.isSmooth());
CHECK(renderTexture.create({100, 100}, sf::ContextSettings(0, 8))); CHECK(!texture.isSrgb());
CHECK(!texture.isRepeated());
CHECK(texture.getNativeHandle() != 0);
} }
SECTION("getMaximumAntialiasingLevel()") SECTION("getMaximumAntialiasingLevel()")
@ -45,39 +43,35 @@ TEST_CASE("[Graphics] sf::RenderTexture", runDisplayTests())
SECTION("Set/get smooth") SECTION("Set/get smooth")
{ {
sf::RenderTexture renderTexture; auto renderTexture = sf::RenderTexture::create({64, 64}).value();
renderTexture.setSmooth(true); renderTexture.setSmooth(true);
CHECK(renderTexture.isSmooth()); CHECK(renderTexture.isSmooth());
} }
SECTION("Set/get repeated") SECTION("Set/get repeated")
{ {
sf::RenderTexture renderTexture; auto renderTexture = sf::RenderTexture::create({64, 64}).value();
renderTexture.setRepeated(true); renderTexture.setRepeated(true);
CHECK(renderTexture.isRepeated()); CHECK(renderTexture.isRepeated());
} }
SECTION("generateMipmap()") SECTION("generateMipmap()")
{ {
sf::RenderTexture renderTexture; auto renderTexture = sf::RenderTexture::create({64, 64}).value();
CHECK(!renderTexture.generateMipmap());
CHECK(renderTexture.create({480, 360}));
CHECK(renderTexture.generateMipmap()); CHECK(renderTexture.generateMipmap());
} }
SECTION("setActive()") SECTION("setActive()")
{ {
sf::RenderTexture renderTexture; auto renderTexture = sf::RenderTexture::create({64, 64}).value();
CHECK(!renderTexture.setActive());
CHECK(renderTexture.create({480, 360}));
CHECK(renderTexture.setActive()); CHECK(renderTexture.setActive());
CHECK(renderTexture.setActive(false));
CHECK(renderTexture.setActive(true));
} }
SECTION("getTexture()") SECTION("getTexture()")
{ {
sf::RenderTexture renderTexture; const auto renderTexture = sf::RenderTexture::create({64, 64}).value();
CHECK(renderTexture.getTexture().getSize() == sf::Vector2u(0, 0)); CHECK(renderTexture.getTexture().getSize() == sf::Vector2u(64, 64));
CHECK(renderTexture.create({480, 360}));
CHECK(renderTexture.getTexture().getSize() == sf::Vector2u(480, 360));
} }
} }