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

View File

@ -37,6 +37,7 @@
#include <SFML/System/Vector2.hpp>
#include <memory>
#include <optional>
namespace sf
@ -53,17 +54,6 @@ class RenderTextureImpl;
class SFML_GRAPHICS_API RenderTexture : public RenderTarget
{
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
///
@ -97,10 +87,6 @@ public:
////////////////////////////////////////////////////////////
/// \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
/// multi-sampling or use the render-texture for OpenGL rendering that
/// 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 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
@ -226,7 +213,6 @@ public:
////////////////////////////////////////////////////////////
Vector2u getSize() const override;
////////////////////////////////////////////////////////////
/// \brief Tell if the render-texture will use sRGB encoding when drawing on it
///
@ -255,6 +241,12 @@ public:
const Texture& getTexture() const;
private:
////////////////////////////////////////////////////////////
/// \brief Construct from texture
///
////////////////////////////////////////////////////////////
explicit RenderTexture(Texture&& texture);
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
@ -288,9 +280,7 @@ private:
/// sf::RenderWindow window(sf::VideoMode({800, 600}), "SFML window");
///
/// // Create a new render-texture
/// sf::RenderTexture texture;
/// if (!texture.create({500, 500}))
/// return -1;
/// auto texture = sf::RenderTexture::create({500, 500}).value();
///
/// // The main loop
/// while (window.isOpen())

View File

@ -34,15 +34,9 @@
#include <memory>
#include <ostream>
#include <cassert>
namespace sf
{
////////////////////////////////////////////////////////////
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
m_texture.setSrgb(settings.sRgbCapable);
texture.setSrgb(settings.sRgbCapable);
// 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;
return false;
return std::nullopt;
}
RenderTexture renderTexture(std::move(texture));
// We disable smoothing by default for render textures
setSmooth(false);
renderTexture.setSmooth(false);
// Create the implementation
if (priv::RenderTextureImplFBO::isAvailable())
{
// 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
m_texture.m_fboAttachment = true;
renderTexture.m_texture.m_fboAttachment = true;
}
else
{
// Use default implementation
m_impl = std::make_unique<priv::RenderTextureImplDefault>();
renderTexture.m_impl = std::make_unique<priv::RenderTextureImplDefault>();
}
// Initialize the render texture
// 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))
return false;
if (!renderTexture.m_impl->create(renderTexture.m_texture.m_actualSize, renderTexture.m_texture.m_texture, settings))
return std::nullopt;
// 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)
{
// Update RenderTarget tracking
if (m_impl && m_impl->activate(active))
if (m_impl->activate(active))
return RenderTarget::setActive(active);
return false;
@ -161,26 +159,23 @@ bool RenderTexture::setActive(bool active)
////////////////////////////////////////////////////////////
void RenderTexture::display()
{
if (m_impl)
if (priv::RenderTextureImplFBO::isAvailable())
{
if (priv::RenderTextureImplFBO::isAvailable())
{
// Perform a RenderTarget-only activation if we are using FBOs
if (!RenderTarget::setActive())
return;
}
else
{
// Perform a full activation if we are not using FBOs
if (!setActive())
return;
}
// Update the target texture
m_impl->updateTexture(m_texture.m_texture);
m_texture.m_pixelsFlipped = true;
m_texture.invalidateMipmap();
// Perform a RenderTarget-only activation if we are using FBOs
if (!RenderTarget::setActive())
return;
}
else
{
// Perform a full activation if we are not using FBOs
if (!setActive())
return;
}
// Update the target texture
m_impl->updateTexture(m_texture.m_texture);
m_texture.m_pixelsFlipped = true;
m_texture.invalidateMipmap();
}
@ -194,7 +189,6 @@ Vector2u RenderTexture::getSize() const
////////////////////////////////////////////////////////////
bool RenderTexture::isSrgb() const
{
assert(m_impl && "Must call RenderTexture::create first");
return m_impl->isSrgb();
}
@ -205,4 +199,11 @@ const Texture& RenderTexture::getTexture() const
return m_texture;
}
////////////////////////////////////////////////////////////
RenderTexture::RenderTexture(Texture&& texture) : m_texture(std::move(texture))
{
}
} // namespace sf

View File

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

View File

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

View File

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