[.net] Picking a 2D texture in DirectX

Started by
2 comments, last by Hyper Sonic 17 years, 8 months ago
Hi everyone. I have been looking around for information about clicking a texture in DirectX. I have read a lot about doing this with mehses in a 3D scene by using a ray to find the closest triangle, but i think that doesn't work for my textures because they are rendered with 2 triangles and i need to click an image only on it's visible area (i'm using a color key as the transparent area of my texture). Right now i'm using a bounding box to detect if an image is being clicked on, but now i need a more sophisticated implementation by clicking only on the visible area of the image. I was thinking about checking the mouse coordinates against my texture and check if the pixel was transparent so i could determine if the texture is being clicked, but i still don't know how to do it and i'm also scaling my texture, so i'm not sure this process is a good solution when comparing a mouse coordinate against a scaled texture. I'm using a Direct3D.Sprite class to render my texture. The following is my current rendering method.

public override void Render(Device dispositivo) {
	//Rotation
	Quaternion rotation=new Quaternion();
	rotation.RotateAxis(this.Rotation,this.Angle);
			
	Vector3 traslation=new Vector3();

	mySprite.Transform = Matrix.Transformation(this.ScaleCenter, new Quaternion(), this.Scale,this.RotationCenter, rotation, traslation);

	mySprite.Begin(SpriteFlags.AlphaBlend);
	mySprite.Draw(myTexture, ObjetCenter, Position,ColorFilter.ToArgb());
	mySprite.End();
}

I'm not sure if my rendering method may become a problem to implement a solution, so i'm posting it in case there is somthing to do with it. Any suggestions will be greatly appreciated. Best regards.
Advertisement
It may be overkill, or a bit complicated programming-wise, if you have fewer than 224 objects (I sure hope so!), you could do the following: Create a secondary render-target the same size as your back buffer. Whenever you need to check a mouse click, set this render target as the active render target. Set the texture stage states so that the alpha component comes from the sprite's texture with alpha testing operating normally (alpha blending needs to be disabled), but with the color component coming from a constant value that you specify. For each sprite that you render, use a different color (if they're all in a single array, for example, just use the array index and split the value up into 3 8-bit segments for red, green, and blue). Then render all your sprites exactly as you would normally, aside from the changes above. Once done, lock the back buffer, and check the color of the pixel where the mouse clicked. Use the color to figure out which sprite is visible at that pixel. (The render target needs to be cleared first, to a color that won't be used by any of your sprites. That way you can also tell if you didn't click on any object.)

After this process (and without calling present; you don't want this render target to get displayed), you can just set the render target back to what it was previously, and continue rendering like normal.
"We should have a great fewer disputes in the world if words were taken for what they are, the signs of our ideas only, and not for things themselves." - John Locke
Using a ray should work. If the location you hit is transparent, cast the ray again from that location instead of the camera. Repeat until you find a non-transparent result. If the performance of such a solution is unacceptable, you might need a custom solution which would depend on (and perhaps impact) your choice of data structures and such.
Hi everybody, thanks for your suggestions.

Agony:
The secondary target is an interesting idea, do you know if texture stage states works when using 3D objects? I mean, if i can render my sprites and other objects with this technique (i don't want to pick a 3D object with this, but i don't want a cube rendered with a color 255,0,0 to be confused with a texture just because that texture had the same key color to test picking). Do you have any references to learn about changing the render-target and the texture stage states?


richardurich:
Do you mean it's possible to test a pixel in a 3D space? I knew that using a ray i could test if a triangle is being clicked on, but i didn't know that it was possible to test a pixel with a ray. If it's possible, i think that should be a good solution. Do you know how to test a pixel in a 3D space or any resources to learn this?




thanks in advance.

This topic is closed to new replies.

Advertisement