Creating a "hole" sprite that sees another layer

Started by
9 comments, last by OrangyTang 16 years, 2 months ago
Basically, I'm trying to make it so that there's a collage effect in a little game I'm writing. Normally, when sprites move in games, the image moves with them. Duh. What I want to do is make a sort of background texture that stays still while the object moves around. That's the best I can describe it. If you've ever seen the old show "The Offbeats" on Nickelodeon you might know what I'm talking about. EDIT:
">Found a video of it. Keep an eye on the kid in the plaid shirt, and August's 'cool' shirt. I made a little demo for myself in C# where I got the effect working like this:

// There are actually three bitmaps I work with here
// The mask is a black and white image representing which 
// areas can be drawn. In this case, the mask is a simple
// black circle on a white background
// The background is the background of the sprite. It's the
// texture that's staying still while the ball moves. 
// The buffer is what I draw everything to, before I draw the
// finished product.
public void draw(Graphics g)
{
    // Decide where to draw the background
    int xOffset = x % background.Width;  
    int yOffset = y % background.Height;

    // Place the background in it's location, and place the mask over it
    Graphics gBuffer = Graphics.FromImage(buffer);
    gBuffer.DrawImage(background, -xOffset, -yOffset);
    gBuffer.DrawImage(mask, 0, 0);
    buffer.MakeTransparent(Color.White);

    // draw the finished product, and give it a border for a more cartoony effect
    g.DrawImage(buffer, x, y);
    g.DrawEllipse(new Pen(Color.Black, 2), x, y, buffer.Width, buffer.Height);
}
This works just fine. I don't know if there's a better way to do it. This is just the most obvious method to me (this is not perfect code btw, I need to fix it for cases where the background of the sprite is very small). Anyway, I'm doing a game in XNA right now and I want to use the same effect, but I can't find any kind of drawing functions outside of the methods used for drawing Texture2D's. I can't find a way to edit Texture2D's either. There's no Graphics.FromImage() or anything that I can see. I don't think importing the System.Drawing namespace would work. Anyone know how to do this sort of thing in XNA?
Advertisement
Couldn't you simply make your images PNG's and let the image loader take care of drawing, or in you case not drawing, the transparent background of the sprite? That's what I have always done - it works with GIF's that contain transparency also.
Maybe I'm not understanding you correctly, but I don't see how that would help. That would let me use a sprite with transparency, but that's not what I'm looking for.
Write a pixel shader. When you're rendering the "see through" piece of clothing, generate texture coordinates based on the pixel's position, and use the appropriate texture.

For example, for the plaid clothing: you'd have a plaid texture the size of the screen. When rendering the pixel, determine what color to use, by looking up the color at the equivalent position in the texture.

edit - or better yet, for a repeating pattern like plaid, just use a small texture and tile it.

[Edited by - gharen2 on February 12, 2008 1:28:17 PM]
I've never made a Pixel Shader before, I'm not sure where to start. I've looked up some tutorials on google, but after looking through them and downloading some simple example solutions I still don't really know what I'm doing.

Can you give me a primer or show me a site with something that'll get me started?
All you have to do (not talking about pixel shaders) is create a "mask" sprite that has full opacity white where the texture should "bleed through" and transparency where the normal background in the game should show through.

Then you render this mask using dynamic texture coordinates based on the pixel coordinates of the sprite on screen.
Can you explain that in a little more detail. It sounds almost like what I'm doing in my original code, but I don't know how to accomplish that in XNA
You could create the exact same effect using stenciling. It'd basically be the exact same thing that Boder was talking about, but you could just render the texture across the entire screen using fairly simple coordinates to map the repeating pattern, and it'd only show up where you tell it to (like on a shirt). You could even have the same thing show up on numerous things without having to re-calculate the coordinates for them.
I'm sorry if I sound like a newbie for keep asking these questions, but could you guys explain a little better? I'm still new to XNA, and I've only got a semester of graphics programming and all that was in OpenGL.

For Boder's solution to my problem, I made a simple png file that has a white circle in the middle and everything else is completely transparent. I'm not sure what to do now. I can get the white circle itself to display just fine, but I don't know what you mean in your last sentence, "Then you render this mask using dynamic texture coordinates based on the pixel coordinates of the sprite on screen."

The only way I know to draw a sprite to the screen is by calling spriteBatch.Draw(...), and I'm not sure how I'm supposed to get the texture I want to only draw on that circle.

---

Also, Gorax, could you explain what stenciling is? I tried wikipedia and google, but it's hard to find what you're looking for when you don't know what you're looking for =P
Unfortunately, I don't know much about XNA.

I don't think these can be done with the sprite methods in XNA.

My method uses multitexturing to use the mask as the alpha component.

The other method uses the stencil buffer, which can block out specific regions on the screen to render only to those places. So imagine the screen is black and you render the guy's shirt, and it's white on the stencil buffer, so now when you draw the texture across the screen, it only shows up in the white area.

I'm sure there are shader ways to do it, but I know not of those things!

This topic is closed to new replies.

Advertisement