I have a simple tilemap game engine that shows vertical and horizontal line artifacts, but only when sf::Texture::setSmooth() is set to true. Attached is a simplified version of the game engine that demonstrates the problem, along with screenshots for when smoothing is turned on and off.
Simply turning off texture smoothing completely eliminates the artifacts, so either there is a bug here or I'm going about this wrong.
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <string>
#include <vector>
const sf::IntRect mapCharToTileRect(const char ch)
{
if (ch == 'R') return { 0, 0, 32, 32 };
else if (ch == 'G') return { 32, 0, 32, 32 };
else if (ch == 'Y') return { 32, 32, 32, 32 };
else return { 0, 32, 32, 32 };
}
void fit(sf::Sprite & sprite, const sf::Vector2f & size)
{
const float scaleHoriz{ size.x / sprite.getLocalBounds().width };
sprite.setScale(scaleHoriz, scaleHoriz);
if (sprite.getGlobalBounds().height > size.y)
{
const float scaleVert{ size.y / sprite.getLocalBounds().height };
sprite.setScale(scaleVert, scaleVert);
}
}
int main(void)
{
sf::RenderWindow window({ 640, 480, 32 }, "test");
sf::RenderTexture renderTexture;
renderTexture.create(64, 64);
renderTexture.setSmooth(true); // *** artifacts disapear if false ***
renderTexture.clear();
sf::RectangleShape rectangleShape;
rectangleShape.setSize({ 32.0f, 32.0f });
rectangleShape.setPosition(0.0f, 0.0f);
rectangleShape.setFillColor(sf::Color::Red);
renderTexture.draw(rectangleShape);
rectangleShape.setPosition(32.0f, 0.0f);
rectangleShape.setFillColor(sf::Color::Green);
renderTexture.draw(rectangleShape);
rectangleShape.setPosition(0.0f, 32.0f);
rectangleShape.setFillColor(sf::Color::Blue);
renderTexture.draw(rectangleShape);
rectangleShape.setPosition(32.0f, 32.0f);
rectangleShape.setFillColor(sf::Color::Yellow);
renderTexture.draw(rectangleShape);
renderTexture.display();
const std::vector<std::string> map = {
" ",
" R ",
" G R ",
" G G ",
" GGGGGGG G ",
" GGYGYGGGGGGG ",
" GGGGGGG ",
" GGGYGGGGGG ",
" GGGGGGG G ",
" G ",
" RGGGGG ",
" "
};
const sf::Vector2f tileSize(40.0f, 40.0f);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (sf::Event::Closed == event.type)
{
window.close();
}
}
window.clear();
const sf::Vector2i mapSize(map.front().size(), map.size());
for (int y(0); y < mapSize.y; ++y)
{
for (int x(0); x < mapSize.x; ++x)
{
const char mapChar = map[y][x];
sf::Sprite sprite(renderTexture.getTexture(), mapCharToTileRect(mapChar));
fit(sprite, tileSize);
sprite.setPosition((x * tileSize.x), (y * tileSize.y));
window.draw(sprite);
}
}
window.display();
}
return 0;
}