My name is Crappy Coding Guy, and I use Texture2D.GetData

October 16, 2010 by Dave · 2 Comments
Filed under: Game Programming, WP7DEV, XNA 

In a previous post about texture modification, I mentioned the evils of transferring data from the GPU to the CPU, and then presented an example showing one way to avoid doing it.  The post wasn’t really about deformable 2D terrain or collision detection, but was intended to help newer game programmers open up a new way of thinking when it comes to using the GPU to accomplish tasks.

Since that post, and the one showing a video of my WP7 game, I’ve received a couple of questions about how I do the collision detection in Guardian, which would seem to require the use of Texture2D.GetData.

As it turns out, I am evil, and I do use GetData.  But, my evilness is optimized based on information from here, here, and here.

  • Crater drawing is batched, meaning that rather than draw each one as it’s created, I add them to a list and draw all of them every few frames. This reduces the number of GetData calls – one per batch of craters rather than one per crater.
  • After drawing craters to the render target, I wait a few frames before calling GetData to make sure the GPU has processed all of the drawing commands. This minimizes pipeline stalls.
  • If I have a pending GetData call to make and more craters come in, the craters will stay batched until the GetData call is complete.  In other words, the drawing and getting are synchronized so that a GetData call always happens several frames after drawing a batch of craters, and any new crater draw requests wait until after a pending GetData.

If there are a lot of craters being created the built-in delays can cause some slightly innacurate collision detection since we may be looking at collision data that’s outdated by several frames. At least in this particular game there are never huge numbers of crater adds going on so this isn’t a problem.  If there are more than several crater adds they tend to be bunched close together, so the explosion animation hides any visual oddities.

There is one other optimization that I have available but haven’t needed to use.  The collision data doesn’t need to be at the same resolution as the drawing data.  Basically have two sets of render targets – one for the visual texture, and a lower resolution set for the collision data.  Do the GetData on the collision texture and scale everything appropriately when doing the collision check. You have to draw twice – once for the visual data and once for the collision data – but you’re pulling much less data from the GPU which would possibly offset the extra drawing time (this isn’t something I’ve tested yet). You won’t be pixel perfect, but for this type of game that isn’t necessary.  As I write this it seems using multiple render targets would eliminate the “draw twice” issue here, but I’ve never done that so some research would be required.

So there you have it. Is this the best or most efficient way?  I don’t know – I’m far from an expert on any of this. To be honest, I never actually tested doing this just on the CPU, so it’s entirely possible that that approach is better if there are collision detection requirements. There are also other considerations, such as whether your game is CPU or GPU bound, which would go into determining which method is better suited to your needs. Ultimately, whatever works in your situation is the right method.

Guardian WP7 Bosses

October 4, 2010 by Dave · 3 Comments
Filed under: Game Programming, Movies, WP7DEV, XNA, XNA 4.0 

Added some tough “boss” asteroids. This one just has a single kill point so it’s relatively simple. Later waves will require destroying multiple targets for the kill. Still need to add a destruction sequence when it’s destroyed, rather than just fading away like it currently does.

WP7 Planet Defender Progress Video

September 23, 2010 by Dave · Leave a Comment
Filed under: C#, Game Programming, WP7DEV, XNA, XNA 4.0 

I’ve been working on a Windows Phone 7 port of Guardian and finally have something to show for it. All of the systems are in place now, just need to do a lot of tuning and game play tweaking. Of course, at this point I have no idea how it’s going to perform on an actual phone, but it should do fairly well. Hopefully there won’t be too much optimization required after I get my hands on some hardware.

I recorded the video using Fraps while running the version compiled for Windows. Keeping a version working in Windows has made testing and debugging work much more smoothly than having to deploy to the simulator each time I make a change. It’s also a fairly simple matter to simulate the touch functionality using the mouse.

Using CLR Profiler 2.0 with XNA 4.0

September 6, 2010 by Dave · 9 Comments
Filed under: C#, XNA 4.0 

By default (at least on my computer, running Windows 7), CLR Profiler 2 won’t work with new XNA apps since they utilize the new .NET framework.  It looks like it’s working when you try it, but when it shows the final statistics window it’s empty.  Fortunately, it’s possible to enable support using the new profiler compatibility settings functionality, which for this case involves simply setting the COMPLUS_ProfAPI_ProfilerCompatibilitySetting environment variable before running CLR Profiler.

Here’s what I did:

Create a batch file called start_clr_profiler.bat with this content, save it in Documents or wherever:


c:
cd "\program files (x86)\clrprofiler\binaries\x86
set COMPLUS_ProfAPI_ProfilerCompatibilitySetting=EnableV2Profiler
clrprofiler

It goes without saying that you’ll need to change the drive and path to where you have CLR Profiler installed.

Once you have this file, create a shortcut  to it on your desktop.  Right click on the shortcut, select Properties, click the Advanced button and check “Run as Administrator”.  Click OK a couple of times, and you’re good to go. Just start the profiler with the batch file and the environment variable will be set, and the profiling magic will happen.

You could also set that environment variable at the user or machine level so it’s set all the time, but I don’t know what ramifications that has so prefer setting it just when needed. Happy garbage collecting!

Texture Modification in XNA 3.1

September 5, 2010 by Dave · Leave a Comment
Filed under: C#, Game Programming, WP7DEV, XNA, XNA 3.1 

I’ve had a couple of questions about what changes are needed to get the texture modification tutorial to work in XNA 3.1.

So, here’s a 3.1 version of the project, and a quick overview of the major things that need to change.

  • You need to create the depth/stencil buffer yourself, set it on the GraphicsDevice when setting the render target, and restore the previous buffer when you’re done.
  • RenderTarget2D can’t be used directly as a texture, you must call RenderTarget2D.GetTexture instead and use that when drawing.
  • Render states are all set in GraphicsDevice.RenderState instead of the various classes used in 4.0.
  • Various minor syntax changes.

Some Sugar with your Syntax?

August 11, 2010 by Dave · 2 Comments
Filed under: C#, Crappy Code 

In my recently posted tutorial, I created the render state objects using some old-school syntax.

StencilAlways = new DepthStencilState();
StencilAlways.StencilEnable = true;
StencilAlways.StencilFunction = CompareFunction.Always;
StencilAlways.StencilPass = StencilOperation.Replace;
StencilAlways.ReferenceStencil = 1;
StencilAlways.DepthBufferEnable = false;

You can do this in a much prettier way nowadays.

StencilAlways = new DepthStencilState()
{
  StencilEnable = true,
  StencilFunction = CompareFunction.Always,
  StencilPass = StencilOperation.Replace,
  ReferenceStencil = 1,
  DepthBufferEnable = false
};

That is so much nicer to read. I’ve seen this syntax before, but 20 years of habits die hard and I rarely remember to use it. Hopefully it will stick now, and make my crappy code that much less crappy.

« Previous PageNext Page »