SFML community forums

Help => Graphics => Topic started by: GarrickW on July 19, 2013, 04:32:34 am

Title: Figuring out which pixel of Sprite's Texture a given point is over
Post by: GarrickW on July 19, 2013, 04:32:34 am
So I have a Sprite, which itself has a Texture, and which may be scaled/rotated/translated.  I should probably also note that it is centered, i.e.

Sprite.setOrigin(Sprite.getLocalBounds().width / 2, Sprite.getLocalBounds().height / 2);

I also have a given Point (sf::Vector2f) in global space.

If the point is within the Sprite's local bounds, I want to figure out the color of the exact pixel of the source Texture the point corresponds to.

Obviously I somehow need to convert from global to local space, but I'm not sure how to do this.  My previous attempt was:

//I also tried without subtracting the position,
//since I assume that the sprite's translation is also included in its transform
Point.x -= Sprite.getPosition().x;
Point.y -= Sprite.getPosition().y;

//I also tried getTransform(), which unsurprisingly didn't work either
Point = Sprite.getInverseTransform().transformPoint(Point);

sf::Color PointColor = Sprite.getTexture()->copyToImage().getPixel(Point.x, Point.y);

What is the correct way of doing this?
Title: Re: Figuring out which pixel of Sprite's Texture a given point is over
Post by: eXpl0it3r on July 19, 2013, 10:12:57 am
Since you already got the code, why don't you simply run it and check if it does what you want? If it does, yes that's the correct way, if it doesn't, there might be a problem. From what I see, this could work, but to be sure, I'd have to run it. :D

Keep in mind though that through the transformation with OpenGL regarding the coloring, I'd say there's no 100% guarantee that you'll actually get the color of that pixel at position x,y. What you could do however to be sure, is render the transformed sprite to a render texture and extract the pixel 1:1.
Title: Re: Figuring out which pixel of Sprite's Texture a given point is over
Post by: Laurent on July 19, 2013, 10:32:22 am
Your code is almost ok: you must offset the point by the (left, top) coordinates of the sprite's texture rect. Because the local point (0, 0) of the sprite maps to the top-left corner of the texture rect in the texture, not to point (0, 0).

Point = Sprite.getInverseTransform().transformPoint(Point);
Point.x += Sprite.getTextureRect().left;
Point.y += Sprite.getTextureRect().top;

sf::Color PointColor = Sprite.getTexture()->copyToImage().getPixel(Point.x, Point.y);

Note that the copyToImage() function will be damn slow, you should consider doing it once and storing the resulting image if you have to run this code often.