SFML community forums
Help => Graphics => Topic started by: sadin97 on September 23, 2017, 10:25:46 pm
-
If this is a sprite:
(https://image.ibb.co/bRAtOk/Untitled_12.png)
Blue color is transparent (I just marked it as color to help me explain question).
How can I than make only selectable this tree. Is it possible?
Is it possible to just select everything within red border of the sprite?
Because, I have some sprites that I'm drawing behind and in front of and I can only detect the whole rectangle of sprite. Is there any solution for this?
-
One possibility is keeping the image and finding out which pixel was clicked and checking if it's transparent or not.
-
(FRex his solution is a lot simpler ;D)
This can be done by using the GPU (little hack) or with some polygon point checking algorithm.
1) On the GPU, this is called "picking". You simply draw the tree onto another rendertarget (e.g. renderTexture). When you click you check the color of this position, if it is transparent you missed, if it is a non transparent color you hit the tree. This is easy if you have one element you want to check.
If you have multiple object this is a bit tricky, because you cannot create a renderTexture for every object, you would run out of GPU VRAM, or the multiple getPixelColor will slow down your game (Transfer from GPU to CPU bottleneck). Howerver there is a trick, you can draw with a custom shader where you set a unique color for all your objects. So if the alpha of the sprite/texture fragment is > 0 draw this color otherwise dont fill the pixel. Then you can draw every object with a different color onto one renderTexture get the color and match it to one(clicked) object.
2) On the CPU, for this you have to model the non transparent parts of the image as a polygon. There is also the option to create it automatically (google it, but it may be compilcated). If you have the polygon you have to check if your point is inside this polygon, for an example for such an algorithm look here (https://stackoverflow.com/questions/217578/how-can-i-determine-whether-a-2d-point-is-within-a-polygon).
-
Jesus, AlexAUT, these ideas... ;D ;D
The first is too complex and too much work and will be slower and the second one is too complex to do for such a simple task and would require that 'modeling' work or creating some auto modeller (that'd actually be super fun and simple with right lib or two.. but still!).
-
@Frex: The first idea can be quite fast for 2D, by using the depth buffer and depth test settings to your advantage, so you wont have an extra draw call ;).
AlexAUT
-
FRex solution is indeed simpler. In that case how could I check which pixel is clicked and more important is that pixel transparent or not? ::)
Thank you both for replying!
-
AlexAUT, it's still too complex and definitely slower than just a transform and pixel picking.
sadin97, here is the example: https://gist.github.com/FRex/31971e02a9e6d342a575d7ee128d74bf
We use an inverse transform because that's what we need, mapping from world coords to sprite rect, the sprite's transform maps its int rect into world coords, so we take inverse of that. The mapping from int pixel in window to float coords is also done with linear algebra and transforms (aka matrices).
This also doesn't handle texture rects and texture repeating/stretching but that'd just be a few extra ops before texture lookup. Doing that might be a good exercise for the reader. ;)