Sign in to follow this  

Creating a "hole" sprite that sees another layer

This topic is 3589 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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!

Share this post


Link to post
Share on other sites
Using the stencil buffer isn't going to be a good approach. You'll add extra fillrate and memory overhead for the stencil buffer, the code will be more complicated since it'll be a two pass process, and (IMHO most importantly) since the stencil buffer is only a pass/fail choice you'll end up with nasty hard sprite edges rather than nicely anti-aliased sprites.

A pixel shader would be the easiest approach (the shader itself would be an easy 3 or 4 lines), and you're going to have to learn them eventually. Try this.

Share this post


Link to post
Share on other sites

This topic is 3589 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this