1
\$\begingroup\$

I need to remove a section of an image using a 2D mesh. Since the image is destructible (artillery game style), it would be helpful to shrink the image in memory afterward. The portion in the blue section should be kept, the portion in red is within the mesh and should be removed. Note that the image is rotated as well.

\$\endgroup\$
  • \$\begingroup\$ Possible duplicate: Best way to mask 2D sprites in XNA? \$\endgroup\$ – MichaelHouse Dec 13 '13 at 4:56
  • 1
    \$\begingroup\$ This would be the inverse of that - I don't want the intersecting area, I want to eliminate it and resize the image. But, if I can use the information in that answer to come up with something I'll post it. \$\endgroup\$ – jzx Dec 13 '13 at 5:04
  • \$\begingroup\$ I would be surprised if shrinking the image in memory - reallocating it smaller - would be a good tradeoff. If at the start of the game you have all the memory needed to load all the images (and you do; memory is big enough to hold many many screenfuls of images!) then what purpose does reallocating images to make them smaller do? \$\endgroup\$ – Will Dec 13 '13 at 7:05
  • \$\begingroup\$ I'm not (too) worried about the memory size (yet), but I'll need to do pixel accurate collision tests and erase parts using another sprite (ala Worms or Scorched Earth) later on, and that might require some scanning that could be expensive if the image remains very large (greater than 256x256 for some instances). \$\endgroup\$ – jzx Dec 13 '13 at 17:25
1
\$\begingroup\$

Here's my possibly naive way of doing it:

I. Create a render target the same size as the image that will be partially erased (should be transparent). I'll call this render target brush.

II. Render the polygon, offset relative to the image's origin and size, in white to brush, here shown with checkers and border to indicate transparent section.

III. Either set the render target to the image to be erased or create a render target that is a copy of the original. I'll call this target canvas.

IV. Draw the image to canvas using non-premultiplied alpha blending.

V. I came up with the following blend state in XNA to use for the next step

_blendErase = new BlendState
{
    ColorBlendFunction = BlendFunction.Add,
    AlphaBlendFunction = BlendFunction.ReverseSubtract,

    ColorSourceBlend = Blend.One,
    AlphaSourceBlend = Blend.One,

    ColorDestinationBlend = Blend.InverseSourceAlpha,
    AlphaDestinationBlend = Blend.InverseSourceAlpha,
};

VI. Use that blend mode to draw brush to canvas, again shown with checkers to indicate the transparent area.

Optional: Scan from the polygon's center toward the far edge of the image to find the new edge of the pixels, then trace the edge (eg using marching squares) to adjust its bounding box.

Note: This doesn't seem work with pre-multiplied alpha images, although I'm probably doing that wrong.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.