9526
Graphics / Re: Fading without artifacts
« on: October 01, 2012, 11:38:48 am »
IIRC it's not very good to not clear the RenderTexture every frame iteration, so you might want to keep track of all the objects you have and fade one after the other slowly.
For example like this:
Keep in mind that calling erase on a std::vector isn't very performant and could be avoided with a better structure. With another structure you could also make use of that the fading process is linear and thus the oldest element can get removed first. Also to minimize the memory usage/object creation you could also just store the positions and draw a single shape/sprite/etc. while changing it's position and it's transparency.
I guess there could be other ways but that was just the most straight forward one that popped into my head.
For example like this:
#include <SFML/Graphics.hpp>
#include <vector>
#include <iostream>
int main()
{
sf::RenderWindow window(sf::VideoMode(300, 300), "Test");
window.setFramerateLimit(60);
sf::Vector2f old_pos(0, 0);
static const int STEP = 5;
std::vector<sf::CircleShape> points;
while(window.isOpen())
{
sf::Event event;
while(window.pollEvent(event))
{
if(event.type == sf::Event::Closed)
window.close();
}
sf::Vector2f pos = static_cast<sf::Vector2f>(sf::Mouse::getPosition(window));
if(pos != old_pos)
{
sf::CircleShape cs;
cs.setRadius(10);
cs.setPosition(pos);
cs.setFillColor(sf::Color::Red);
points.push_back(cs);
old_pos = pos;
}
window.clear();
for(auto it = points.begin(); it != points.end(); ++it)
{
window.draw(*it);
if(it->getFillColor().a-STEP < 0)
it = points.erase(it);
else
it->setFillColor(sf::Color(255, 0, 0, it->getFillColor().a-STEP));
}
window.display();
}
}
#include <vector>
#include <iostream>
int main()
{
sf::RenderWindow window(sf::VideoMode(300, 300), "Test");
window.setFramerateLimit(60);
sf::Vector2f old_pos(0, 0);
static const int STEP = 5;
std::vector<sf::CircleShape> points;
while(window.isOpen())
{
sf::Event event;
while(window.pollEvent(event))
{
if(event.type == sf::Event::Closed)
window.close();
}
sf::Vector2f pos = static_cast<sf::Vector2f>(sf::Mouse::getPosition(window));
if(pos != old_pos)
{
sf::CircleShape cs;
cs.setRadius(10);
cs.setPosition(pos);
cs.setFillColor(sf::Color::Red);
points.push_back(cs);
old_pos = pos;
}
window.clear();
for(auto it = points.begin(); it != points.end(); ++it)
{
window.draw(*it);
if(it->getFillColor().a-STEP < 0)
it = points.erase(it);
else
it->setFillColor(sf::Color(255, 0, 0, it->getFillColor().a-STEP));
}
window.display();
}
}
Keep in mind that calling erase on a std::vector isn't very performant and could be avoided with a better structure. With another structure you could also make use of that the fading process is linear and thus the oldest element can get removed first. Also to minimize the memory usage/object creation you could also just store the positions and draw a single shape/sprite/etc. while changing it's position and it's transparency.
I guess there could be other ways but that was just the most straight forward one that popped into my head.