1

I want to know how to remove part of a Texture from a Texture2D. I have a simple game in which I want to blow up a planet piece by piece, when a bullet hits it "digs" into the planet.

The physics are already working but I am stuck on how to cut the texture properly.

I need to create a function that takes a Texture2D a position and a radius as input and returns the new Texture2D.

Here is an example of the Texture2D before and after what I want to accomplish. http://img513.imageshack.us/img513/6749/redplanet512examplesmal.png

Also note that i drew a thin brown border around the crater hole. If this is possible it would be a great bonus.

JensB
  • 6,663
  • 2
  • 55
  • 94

3 Answers3

4

After doing alot of googling on the subject it seems the best and fastest way to achieve the effect i want is to use pixel shaders.

More specifically a shader method called 'Alpha mapping'. Alpha mapping is done by using the original texture and another greyscale texture that defines what parts are visible or not.

The idea of the shader is to go through each pixel in the original texture and check how black each pixel in the greyscale image is at the same coordinate. The blacker the pixel in the greyscale picture is the higher the alpha value (more visible) the pixel in the original texture becomes. Since all this is done on the GPU it is lightning fast and leaves the CPU ready to do the actual logic for the game.

For my example I will create a black image to use as my greyscale image and then draw white circles on this corresponding to the parts i want to remove.

I've found a MSDN examples with working source code for XNA 4 that does this (the cat example):

http://create.msdn.com/en-US/education/catalog/sample/sprite_effects

EDIT: I got this to work quite nicely. Created a small tutorial with source code here: http://syntaxwarriors.com/2012/xna-alpha-mapping-with-pixel-shaders/

JensB
  • 6,663
  • 2
  • 55
  • 94
0

A good way of doing this is to render a "hole texture" using alphablend on top of your planet texture. Think of it like drawing an invisibility circle over your original texture. Take a look at this thread for a few nice links worms-style-destructible-terrain.

To achieve your brown edges I'd guess you'd need to take a similar approach. First render the hole to your terrain with say radius 10px. Then you render another circle from the same origin point but with a slightly larger radius, say 12px. You'd then need to set this circle to a blendmode that results in a brown color.

Community
  • 1
  • 1
Henrik Sonesson
  • 79
  • 1
  • 11
  • I might be missing something really simple here but.. I set up my RenderTarget2D, draw my original texture too it, and then want to render my hole.. How would I actually render the hole? Textures are square.. So I cant have a transparent circle in the center of my transparent square texture, or can I? – JensB Feb 13 '12 at 12:10
  • On one of the subthreads (http://web.archive.org/web/20090101215451/http://blog.xna3.com/2007/12/2d-deformable-level.html). They use SetData and GetData to achieve the result I'm after but this is lifting the problem to the CPU instead of doing it on the GPU and as such should be much slower, and in practice not be a good solution, right? – JensB Feb 13 '12 at 12:14
  • @wokawka I guess I should add that I haven't implemented this in C# (only action script), so I don't have any code to show you that I know works. But you can take a look at this post that holds some code for it: [link](http://stackoverflow.com/questions/2656835/xna-alpha-blending-to-make-part-of-a-texture-transparent) What it boils down to is that you draw an image on top of your image, but with the option to alphablend it set to true. That basically means that when rendering this image to your terrain texture, any overlapping areas will have its alpha channel set to transparent. – Henrik Sonesson Feb 13 '12 at 15:37
  • Thanks, trying to see if i can figure it out from that link. It seems the code in that link is written in XNA 3 (4 being the current version). So about half of the commands used arent available anymore. When I just converted it straight over using http://nelxon.com/resources/xna-3-1-to-xna-4-0-cheatsheet/ it did not work at all. – JensB Feb 13 '12 at 16:45
0

look at my class here: http://www.codeproject.com/Articles/328894/XNA-Sprite-Class-with-useful-methods

1.Simply create an object of Sprite class for your planet
Sprite PlanetSprite = new Sprite(PlanetTexture2D , new Vector2(//yourPlanet.X, //yourPlanet.Y));

2.when the bullet hits the planet, make a circle texure2d by the center of collision point using "GetCollisionPoint(Sprite b)" method

-you can have a Circle.png with transparent corners
-or you can create a Circle using math(which is better if you want to have bullet power)

3.then create an Sprite object of your circle

4.now use the "GetCollisionArea(Sprite b)" to get the overlapped area

5.now use the "ChangeBatchPixelColor(List pixels, Color color)" where pixels is the overlapped area and color is Color.FromNonPremultiplied(0, 0, 0, 0)

-note you don't need to draw your circle at all, after using it you can destroy it, or leave it for further use

Ashkan Ghodrat
  • 3,162
  • 2
  • 32
  • 36
  • "This article is still being written and is not currently available for general viewing." – JensB Feb 14 '12 at 08:05
  • oh, sry about that, please give you email, i ll send the class to you, my email is ashkanpower@gamil.com if you don't want to publish yours. – Ashkan Ghodrat Feb 14 '12 at 09:52