SFML community forums
Help => Graphics => Topic started by: zackh on August 18, 2010, 01:31:35 pm
-
In the game I'm writing I need the ability to change parts of a sf::Sprite as if I were using a flood/seed fill algorithm. Before I go on to write that up, is there a way to 'mask' parts of a sf::Sprite with a color based on the sf::Image color?
For example, if I had a map of countries with different greyscale values for each country, does a method exist where I could change the color of a country by picking the greyscale value and masking red (for example) over all pixels of that value.
If not, I suppose it's on to writing a flood/seed fill algorithm or splitting the map into several PNGs with an alpha layer (not excited about the latter idea).
-
For anyone interested:
#include <vector>
struct Point
{
Point(int x, int y) : X(x), Y(y) { }
int X, Y;
};
void fill(int x, int y, sf::Color fill, sf::Image* img)
{
int w = img->GetWidth(), h = img->GetHeight();
if (x < 0 || x > w-1 || y < 0 || y > h-1)
return;
sf::Color seedColor = img->GetPixel(x, y);
std::vector<Point> points;
points.push_back(Point(x, y));
while (points.size() > 0)
{
Point p = points.back();
int tx = p.X, ty = p.Y;
points.pop_back();
if (ty < 0 || ty > h-1 || tx < 0 || tx > w-1)
continue;
sf::Color col = img->GetPixel(tx, ty);
if (col == seedColor)
{
img->SetPixel(tx, ty, fill);
points.push_back(Point(tx+1, ty));
points.push_back(Point(tx-1, ty));
points.push_back(Point(tx, ty+1));
points.push_back(Point(tx, ty-1));
}
}
}
fill(75, 75, sf::Color(255, 0, 0), ImgManager::Instance()->getResource("test.bmp"));
The question still stands though. I'm not sure that it's quite fast enough to be used in the middle of a game (No other PCs to test it on atm).
-
I'm also interested in this function. I'll list below things that may help speed up the process (or not):
- OpenGL
- Masking
- Binary Search
- Spiral (box) search
- Scan line search
- Edge detection then polygon fill algorithm
- Memcpy()