The more astute of you may notice a *minor* change in the site. We are moving to blogengine.net (rather than WordPress) since its .net and not mySQL. There almost certainly will be teething issues so please bare with us.
As you can probably tell, madgamedev.com is no more. As part of the change of hands, the DNS tripped us up - and since we wanted to change the focus of the site a little (XNA isn't really the juggernaut it once was) we decided that a new name was needed. So, since I am 'mad ninja skillz', mad game dev was born - focusing on C# game dev, with a heavy dose of XNA, we also want to cover MonoGame, SlimDX/SharpDX and even native code on Win8/WP8.
We hope the change isn't too jarring, and if you have any feedback, please feel free to comment.
As almost everyone in the world I took a quick look at Diablo 3 earlier this week, while I was a bit disappointed I noticed a fun small feat (which has been in games for ages): if you stand under a roof or archway it disappears or, at least, becomes semi transparent so that you can see your player character. I was quite curious how they did this. So I tried to recreate this effect as I’ll show you in this small tutorial.

We’ll demonstrate this technique by creating a simple archway in Blender, after which we’ll set up a small scene, finally we will render the scene in parts, using a shader to determine what parts to draw fully opaque and what parts to make transparent.
So let’s fire up trusty old blender! Now mind you I’m not a modeler so I’m going to create the simplest archway that there was ever built:

Yes, that’s it, just two cubes stretched and skewed a bit. The lower cube is going to be always visible while the upper cube (aka archway) is going to be made partially transparent when it’s in front of our player. You’ll have to export and store them separately. I’ve exported my lower part as pilar.fbx and the upper part as arc.fbx.
Also create a simple sphere and export it as cut.fbx, we’ll use the sphere to cut away parts that obstruct our view of the player
Now let’s write some code, create a new XNA 4.0 PC project. Add the arc.fbx, pilar.fbx and cut.fbx to the content project. Then create some members and load them:
private Model arc;
private Model pillar;
private Model cut;
private Model player; // just a cube as well
protected override void LoadContent()
{
// ... //
arc = Content.Load("arc");
pillar = Content.Load("pillar");
cut = Content.Load("cut");
player = Content.Load("pillar");
}
Now we’re going to set up our scene, we’ll divide it in a low part, which will include the floor, the pillar and the player. We’ll also make a high part where the tall part of walls, archways and roofs will be drawn. We’ll draw the low part and the high part to different render targets. Create a member RenderTarget2D[] rts; in Game1.cs and add the following code in LoadContent()
rts = new RenderTarget2D[]
{
new RenderTarget2D(GraphicsDevice, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height, false, SurfaceFormat.Color, DepthFormat.Depth16),
new RenderTarget2D(GraphicsDevice, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height, false, SurfaceFormat.Color, DepthFormat.Depth16)
};
We now have two render targets, let’s make two methods and a little helper method in Game1.cs to draw the pillar, ground and player to rt[0] and the arc to rt[1]:
private void RenderHighObjectsAndRoofs()
{
GraphicsDevice.SetRenderTarget(rts[1]);
GraphicsDevice.Clear(Color.Transparent);
DrawColoredModel(arc, Matrix.Identity, Color.Red);
}
private void RenderLowObjectsAndPlayer(GameTime gameTime)
{
GraphicsDevice.SetRenderTarget(rts[0]);
GraphicsDevice.Clear(Color.Transparent);
Matrix groundMatrix = Matrix.CreateTranslation(new Vector3(0, -40f, 0)) *
Matrix.CreateScale(new Vector3(10, 0.1f, 10));
Matrix playerMatrix = Matrix.CreateScale(new Vector3(0.5f, 0.25f, 0.5f)) *
Matrix.CreateTranslation(new Vector3(5, 0, 0)) *
Matrix.CreateRotationY((float)gameTime.TotalGameTime.TotalSeconds);
DrawColoredModel(pillar, groundMatrix, Color.Gray);
DrawColoredModel(pillar, Matrix.Identity, Color.Green);
DrawColoredModel(player, playerMatrix, Color.Yellow);
}
private void DrawColoredModel(Model model, Matrix worldMatrix, Color color)
{
foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.World = model.Bones[mesh.ParentBone.Index].Transform * worldMatrix;
effect.View = camera.ViewMatrix;
effect.Projection = camera.ProjectionMatrix;
effect.LightingEnabled = false;
effect.DiffuseColor = color.ToVector3();
}
mesh.Draw();
}
}
Let’s see if everything went well so far, set up a camera (for a sample camera and set up of that camera see the attached source code) and add the following code to the Draw method in Game1.cs
RenderLowObjectsAndPlayer(gameTime);
RenderHighObjectsAndRoofs();
GraphicsDevice.SetRenderTarget(null);
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend,
SamplerState.LinearClamp, DepthStencilState.Default, RasterizerState.CullNone);
spriteBatch.Draw(rts[0], new Rectangle(0, 0, GraphicsDevice.Viewport.Width / 2,
GraphicsDevice.Viewport.Height / 2), Color.White);
spriteBatch.Draw(rts[1], new Rectangle(GraphicsDevice.Viewport.Width / 2, 0,
GraphicsDevice.Viewport.Width / 2, GraphicsDevice.Viewport.Height / 2),
Color.White);
spriteBatch.End();
//snip
Run the game, you should now see something like this:

As you can see the scene is nicely rendered in two parts, left the parts that are low and on the right the parts that are high. Great! We’ll now add a 3rd render target. In this render target we’re going to decide what part of the right screen to cut away and what part to keep.
cut = Content.Load("cut");
Change the construction of rts in LoadContent() to this:
rts = new RenderTarget2D[]
{
new RenderTarget2D(GraphicsDevice, GraphicsDevice.Viewport.Width,
GraphicsDevice.Viewport.Height, false, SurfaceFormat.Color, DepthFormat.Depth16),
new RenderTarget2D(GraphicsDevice, GraphicsDevice.Viewport.Width,
GraphicsDevice.Viewport.Height, false, SurfaceFormat.Color, DepthFormat.Depth16),
new RenderTarget2D(GraphicsDevice, GraphicsDevice.Viewport.Width,
GraphicsDevice.Viewport.Height, false, SurfaceFormat.Color, DepthFormat.Depth16)
};
Now let’s create another helper method, this time to draw to rt[2] exactly what part of the screen should never be obstructed by what’s in rt[1]:
private void RenderCutOutShape(GameTime gameTime)
{
GraphicsDevice.SetRenderTarget(rts[2]);
GraphicsDevice.Clear(Color.White);
Matrix cutMatrix = Matrix.CreateScale(2.0f) *
Matrix.CreateTranslation(new Vector3(5, 0, 0)) *
Matrix.CreateRotationY((float)gameTime.TotalGameTime.TotalSeconds);
DrawColoredModel(cut, cutMatrix, Color.Black);
}
Notice that we scale up the sphere a little bit so that it’s bigger than the player, it also moves along the same path as the player, the scale of the cut is something that you’ll probably want to tweak later to give the best result. Make it larger to give the player a better view of the player character and the enemies around him, make it smaller for an extra claustrophobic effect.
Anyway let’s draw this render target to the 3rd quadrant of our screen. Change the code in your draw method to this:
RenderLowObjectsAndPlayer(gameTime);
RenderHighObjectsAndRoofs();
GraphicsDevice.SetRenderTarget(null);
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend,
SamplerState.LinearClamp, DepthStencilState.Default, RasterizerState.CullNone);
spriteBatch.Draw(rts[0], new Rectangle(0, 0, GraphicsDevice.Viewport.Width / 2,
GraphicsDevice.Viewport.Height / 2), Color.White);
spriteBatch.Draw(rts[1], new Rectangle(GraphicsDevice.Viewport.Width / 2, 0,
GraphicsDevice.Viewport.Width / 2, GraphicsDevice.Viewport.Height / 2),
Color.White);
spriteBatch.Draw(rts[2], new Rectangle(0, GraphicsDevice.Viewport.Height / 2,
GraphicsDevice.Viewport.Width / 2, GraphicsDevice.Viewport.Height / 2),
Color.White);
spriteBatch.End();
//snip
In the bottom left part of the screen you should see a white square with a black sphere moving exactly like the yellow cube that represents our player in the top left part of the screen.
Great! Now all we need to do is combine these 3 pictures. Let’s write a simple shader. This shader picks for each position a pixel from either rt[0] or rt[1] based on the alpha value of the pixel in rt[1] and whether rt[2] is black or white.
Create a new effect file in your content project, clear all autogenerate text and then write the following shader:
sampler lowSampler : register(s0);
texture highTexture;
sampler highSampler = sampler_state
{
Texture = (highTexture);
};
texture cutTexture;
sampler cutSampler = sampler_state
{
Texture = (cutTexture);
};
float4 PixelShaderFunction(float2 texCoord: TEXCOORD0) : COLOR0
{
float4 baseColor = tex2D(lowSampler, texCoord).rgba;
float4 highColor = tex2D(highSampler, texCoord).rgba;
float cutColor = tex2D(cutSampler, texCoord).r;
if(cutColor < 1) { return baseColor + highColor * cutColor; } else { if(highColor.a > 0)
{
return highColor;
}
else
{
return baseColor;
}
}
}
technique CutAway
{
pass Pass1
{
PixelShader = compile ps_2_0 PixelShaderFunction();
}
}
Now to display some results, add a new member “Effect cutAwayEffect” to Game1.cs and initialize it in the LoadContent() method by adding the following line to it:
cutAwayEffect = Content.Load("CutAwayEffect");
Then add the following code to the end of the Draw method, right before base.Draw()
cutAwayEffect.Parameters["highTexture"].SetValue(rts[1]);
cutAwayEffect.Parameters["cutTexture"].SetValue(rts[2]);
cutAwayEffect.Parameters["blurWidth"].SetValue(0.07f);
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, null, null, null,
cutAwayEffect);
spriteBatch.Draw(rts[0], new Rectangle(GraphicsDevice.Viewport.Width / 2,
GraphicsDevice.Viewport.Height / 2, GraphicsDevice.Viewport.Width / 2,
GraphicsDevice.Viewport.Height / 2), Color.White);
spriteBatch.End();
You should now see that a spherical part of the archway becomes transparent every time the player passes under it:

Now this effect is quite harsh, not like the smooth effect of Diablo 3 at all. So let’s soften it a bit. In the shader add a nice radial blur function (adapted from the nVidia shader library) above the pixel shader function.
float4 RadialBlur(float2 texCoord, sampler2D tex)
{
float4 c = 0;
float modifier = 0.08;
// this loop will be unrolled by compiler and the constants precalculated:
for(int i= -NSAMPLES / 2.0; i < NSAMPLES / 2.0; i++) {
float scale = modifier * (i / (float)(NSAMPLES - 1.0));
c += tex2D(tex, texCoord.xy*scale + texCoord);
}
c /= NSAMPLES;
return c;
}
And change the PixelShaderFunction to this:
float4 PixelShaderFunction(float2 texCoord: TEXCOORD0) : COLOR0
{
float4 baseColor = tex2D(lowSampler, texCoord).rgba;
float4 highColor = tex2D(highSampler, texCoord).rgba;
float cutColor = tex2D(cutSampler, texCoord).r;
if(cutColor < 1 && highColor.a > 0)
{
float3 blend = RadialBlur(texCoord, cutSampler).rgb;
float3 mix = lerp(baseColor.rgb, highColor.rgb, blend);
return float4(mix, 1);
}
else
{
if(highColor.a > 0)
{
return highColor;
}
else
{
return baseColor;
}
}
}
This should give us a lot smoother effect:

You can tweak the smoothness of this effect by modifying the ‘modified’ variable in the RadialBlur function, try some higher values for modifier together with a bigger cut object and your result will get smoother, but there will be more cut away from the scene.
Now that we've got the basics covered you can try to:
- Use weird objects as cut out
- Smooth in the blur effect over time
- Cut away entire parts in full instead of cutting a circle out of them
Anyway that concludes this tutorial. I’m very interested how you will extend it so leave a couple of screenshots at the bottom of the page!
Source Code
Article Submitted by Roy Triesscheijn
In the efnet #xna channel theres is a subject that keeps rearing its ugly head: spriteFonts took a quality dive in XNA4.0. This post is the SIMPLEST methods to resolve this. They are NOT the BEST solution.
First key is to understand the problem. Its related to some new defaults - preumultiplied alpha - and how DXT compression can suffer in this scenario. When XNA builds your spritefont, the quality will be lower than if it was created in XNA3.1. Easy fix? Don't let XNA build it - use an external tool. XNA supports textures as spritefonts. my personal fave is Sprite font 2. This alone will resolve most of the issues.
Another solution is to mitigate the poor antialiasing by using a larger font than you intend to use and scaling it down. This means the antialiasing is performed by the GPU at runtime rather than being stored in the font. This also has the benefit of letting you use one font file for multiple font sizes.
I have also attached an example project that uses both of these tricks (and a simple helper function) to show what's possible without huge amounts of effort.

Example Project
The helper function in its entirety:
private void DrawString(string text,Vector2 position,Color colr,float scale,Color? border,int BorderSize)
{
if (border != null)
{
spriteBatch.DrawString(font, text, position - new Vector2(BorderSize, 0), (Color)border, 0, Vector2.Zero, scale, SpriteEffects.None, 1f);
spriteBatch.DrawString(font, text, position - new Vector2(0, BorderSize), (Color)border, 0, Vector2.Zero, scale, SpriteEffects.None, 1f);
spriteBatch.DrawString(font, text, position + new Vector2(BorderSize, 0), (Color)border, 0, Vector2.Zero, scale, SpriteEffects.None, 1f);
spriteBatch.DrawString(font, text, position + new Vector2(0, BorderSize), (Color)border, 0, Vector2.Zero, scale, SpriteEffects.None, 1f);
}
spriteBatch.DrawString(font, text, position, colr, 0, Vector2.Zero, scale, SpriteEffects.None, 1f);
}
Obviously its possible to come up with more elegant solutions, but when you need an easy life, fixes like this are always welcome.
The death bells have been wrung many times for XNA by the community but as they've been ringing for several years and XNA is still here what is happening? Is XNA a dead platform? And does it have any benefits - should you still be using it - or even learning it?
Firstly - we have to consider the platforms:
XBOX:
With the 360, the ONLY option for indie games is XNA. While support from Microsoft has been spotty at best, a few people - myself included - make a decent living from this platform alone. Even just as a platform to toy with to show your friends code running on consumer hardware, XNA on Xbox is valuable. Is it dying? Well, we are likely to see the NEW Xbox (720, loop, whatever) Holiday 2013. That's nearly 2 years away. And the 360 wont die instantly - in fact, its likely for people who cant afford to upgrade - indie games may be the only outlet of new games after a while.
Its possible the new Xbox will run XBLIG games - and possible that you'll be able to publish new XBLIG games but in all likelihood it'll be a new SDK.
WindowsPhone:
Microsoft has already announced the death of Silverlight pretty much - and in the same announcement has either said WP8 will support new XNA apps - or wont. It's hard to truly read between the lines. What we DO know is that everything in the store right now will run on WP8. There is also a good chance that WP8 will not be rolled out to the old devices, meaning you've got a captive market.
Windows:
This platform is the home of most of the paranoia - yet its the easiest to answer. Windows 8 will not support XNA within the metro environment. Does this mean XNA is dead? Anything but. Firstly, XNA on PC can only be compiled for x86 (not ARM) meaning all machines capable of running it will have desktop mode. Desktop mode will always support XNA - for the same reasons it will always support VB6 and so on. The PC is an open platform and thus you cant place limits on what it can run.
The concern is more that, as its not supported under Metro, it cannot be sold under the new Win8 store. This doesn't mean XNA is more dead - it just means its not more alive. However, just because Microsoft hasn't given us the tools to make XNA run in metro doesn't mean they wont exist. Because native development is possible - and how open windows is - there is no limit to what you can do - and there are several teams working to bring XNA to metro. The earliest we are aware of is the ANX Framework which is a port of XNA to DirectX11 - and openGL for Linux. Also announced recently is that MonoGame will be working towards a metro version.
If this new store is of no concern to you, such as you wish to release for free, or on another marketplace such as Steam or IndieCity then the changes (or lack there of) in Windows8 are of no concern at all - XNA is as valid a platform as it was with Windows 7, Vista and XP.
There is also Shawn H's new toy - DirectXTK - created with Chuck Walbourn - a few little toys for c++ that are based on XNA ideals - so you can make the move to Metro smoother for yourself while learning a new language.
iPhone:
Iphone? Yes, thanks to MonoTouch, c# apps can be run on ios, and thanks to the open sourcproject MonoGame , porting XNA apps is a lot less work than you imagine. The MonoGame port gets stronger and stronger every day, with 3D support being added recently - and new platforms being added frequently. iPhone seems to be the primary platform for the MonoGame and probably the healthiest platform if you intend to at least cover costs. the iPhone is actually a platform where XNA support is getting STRONGER rather than weaker and there are some rather interesting facts. Due to the apple app store rules, c# cannot be JIT on the iPhone - it has to be compiled. This means XNA code on the iPhone runs fast. REALLY fast. Much faster than the same code on WP7 for instance. There were some early concerns about some small print in the developer T&C's but apple has reverted these meaning using c# for iOS development is fully legit.
Android:
As above, MonoGame is allowing XNA dev on android. While not as mature, progress is being made fast and is worth consideration.
MacOS/Linux:
Both MonoGame and ANX are targeting these platforms. ANX seems to be more solid graphically, MonoGame more solid in the nitty-gritty stuff.
Playstation Vita:
Sony's Playstation Suite is a c# (mono based) platform for indies to create games on the PSV and 'Plasystation' android devices. While nothing concrete yet, since it supports c# already, using MonoGame or something similar wouldn't be a huge stretch. Its early days yet, but its certainly on the radar.
So what does it all mean?
If you a WP7 developer, your future is unknown. If you develop for XBOX, the future is uncertain but you've got at least 2 years of marketplace left. However, XNA is far from dead - in fact, if you're willing to stray from MS platforms - or at least non MS versions of XNA at least - its more alive than its ever been. Us developers - especially in the XNA community do like a bit of doom and gloom but its just not warranted. MS may not be supporting XNA directly for a while, but its got a lot of legs left in it.
Not only that, if you are starting out, XNA is an amazing platform to cut your teeth on - and what you learn is applicable on pretty much every other platform out there.
madgamedev.com will be covering all of the above tech and will cover issues of porting, multiplatform development and the like. XNA isn't at the end of its life, its just growing up and leaving home.
The illustrious leader has stepped aside for the time being and I, madninjaskillz, have taken command until he returns from his globe trotting/domination.
Some of you may know me already, many will not. I cut my teeth in XNA programming with an XBLIG app called 'ezmuze', which I followed up with the super successful 'ezmuze+'. In that time I went from decent zero to hero somewhat, so I think I'm rather well positioned to know what articles the noobs need and also, what the pros need too.
I hope under my command, the site will shake its reputation for not so many updates. I hope to expand the scope slightly, with tutorials and news on alternative XNA platforms such as monoGame, technologies such as DirectXTK (the spritebatch like c++ libs from Shawn H) and maybe even a little bit of WinRT/Metro.
My expertise are most certainly in the audio realm so I will be looking to others for other articles as you can only discuss iPad ports and DSP so much. If you want to contribute, please contact me with an article.
Hopefully we can restore Sgt.Conker to its former glory and help and inform a few people along the way.
Looks like there were a new addition to the league of XNA/DirectX (didn’t that read DirectX/XNA once?) MVPs: the German Roland “Glatzemann” Rosenkranz, who is running amokcausing havockeeping posting on the XNA.mag and our beloved AppBuh forums. Congratulations, chap!
Meanwhile, in Jim “So Evil That Even George Ducks and Covers” Perry-land the Overlocker himself continues to spam his blog. This time, he covers Spy Game Design – Multiplatform Issues/Capability and Spy Game Design – Character Training. Lets see if he can keep up the pace while The Hidden One continues to, well, hide.
As George W. “Father of an Army” Clingerman went quite quiet recently (conspiracy theorists claim he’s the XNA/XBLIG community manager now and hence is as quiet as the void that wasn’t a community manager…) we have to turn our head to the Evil MVP Jim “The Replacement Clingerman” Perry, who replaced locking with blogging what seems to be some sort of The Spy Game Design Series:
And, compared to the AppBuh Forums mess his forums are alive and kicking.
Catalin “Too Proud To Self-promote” Zima (you might know him as our local XNA MVP Captain ZSquare) has a nice write-up of 2D Skeletal Animations over at his blog. So, if you ever wondered what the benefits of skeletal animations in the 2D world as compared to our beloved sprite sheets are, his post would be your starting point to explore this very topic.
Via The Dead Pixel Society comes the word about the impact of the Joplin Tornado on the XNA community:
As you may or may not know (until now) a fellow XNA developer @DeathmatchGames and his family were victims of the May 22nd tornado that ravaged Joplin, MO. You can find extensive coverage of the tornado and the devestation [sic] it's caused at CNN.com, Google, and everywhere else.
Head over to the DeathmatchGames - Joplin Tornado Fund to read more and to learn about the ways to help.