More servicesWindows Live
HomeHotmailSpacesOneCare
 
MSN
Sign in
 
 
Spaces home  Bryan's spaceProfileFriendsBlogMore Tools Explore the Spaces community

Bryan's space

Game development/Graphics/DirectX/XNA
Games I've made using XNA

Bryan

View spaceSend a message
Occupation:
Age:
Location:
Interests:
I"m going to be working at Microsoft as an SDET on the Project team soon!
View space
DodongoXP

No list items have been added yet.
July 23

Megatexturing and new UI stuff..

I've waylaid megatexturing for now. The work to payoff is not very high. The reason is that, although a very cool feature; for indie games it is not so practical. Especially XNA games which have to be less than < 150 MB. Therefore, i'll be focusing more on other projects.
 
My current project is creating a windows designer for my UI system. Its very promising, Stephen Styrchak's blog has some great info about getting started.
 
Before I knew it was even possibel to create a windows designer, I built an editor into my engine, which could be accessed during run time by pressing a key combo (like ctrl-E or something). It let you do some stuff like move and resize elements, and save and load panels from XML.
 
However, this windows designer stuff is way cooler. You get to leverage things like the Property Editor, toolbox, etc - basically for free. And it serializes your components into code, which is awesome. There is no "magic" happening - whenever you make a change to the UI you can see the corresponding code. In addition, code serializaiton is way faster at run time - the Xbox XML deserialization is very slow, and writing content writers for XML gets tedious. You can't get much faster than code serialization because there is nothing to be loaded (besides the assembly of course) at run time.
 
So I'm really excited about this. There has been all this talk about .NET enabling "Rapid Application Development" - I'm hoping things like this could bring  "Rapid Game Development" to the masses.
 
i'll have a video soon =)

Alternatives to GetData

As promised (although I don't get many blog hits, haha, so not sure anyone cares =) i'm proposing an alternative to using GetData in certain circumstances.
 
The problem with GetData is that it is a pipeline stalling function, so it can take more than just a few milliseconds for it to complete. In a fast render loop, this is unacceptable! In general, as with SetData, the advice is to not use GetData in high frequency or critical sections of code. However, what if you really really need to know what the pixel values are?
 
First, lets establish some motivation. Why would you what to know or care about what pixels are being rendered? You might be thinkning, hey, as long as DX is rendering my scene, thats cool, I don't need any info back. However, when you get into more advanced features, like HDR, you'll need to know some info about the colors your scene is producing.
 
HDR stands for High Dynamic Range  Rendering - and basically it allows you to overcome the limitation of 256 values for each color channel. 256 values for each color is not a very high range. I believe the human eye can perceive a contrast ratio of 10,000 : 1 - which is far greater than a computer monitor can display. I'm not going to go into the nitty gritty details of HDR rendering - just enough to whet your appetite and see why you might need to read data. Basically, the idea with HDR is to take a higher range of values, and then tonemap it to fit the 256 values presented on the monitor. So basically we take a high range of color values - apply a tone map operator - and the result is a range of values we can display on the screen. This is great because we still get detail in light and dark areas but light areas appear really light and dark areas appear really dark.
 
Now, most tonemapping implementations need to know the average luminance of what you are looking at. Luminance simply means the brightness of a pixel, with no regard for color. To calculate the average luminance for a scene, one way would be to use a floating point render target (to give us more range), draw to that, and then use GetData(). We could then loop through the values for the pixels we get, sum and divide to get an average.
However, as mentioned above, this is SLOW!
 
The solution presented in the DX SDK for this is to render to multiple floating point rendertargets - first, render to a smaller target, ie one that is 256x256. Then, render that render target to one that is 128x128, etc until you get a render target that is 1x1. You can these use this render target as an input to your HDR tonemapping shader to get the average luminance.
 
Another, really cool alternative (and this is where the alternative to GetData comes in), is to use Occlusion Queries to check if pixels match a certain criteria. You could use an occlusion query to test how many pixels fall within a certain luminance range, for example, or see which pixels match a color. Obviously, this is not a perfect replacement for GetData, because you need to know exactly what you want - either an exact color or range of colors. But the advantage is that you are working with the GPU instead of against it - the occlusion queries can be run asynchronously. The Source engine uses this technique (where i found out about it, lol) - they keep a runniing histogram of luminance values (they keep track of 16 ranges of luminances), and each frame they update this histogram by updating one bin per frame. For example, at frame 1 they might use an occlusion query to see which pixels have luminance < 0.2, and then frame 2, they might use an occlusion query to see which pixels have luminance between 0.2 and 0.4 and update the histogram. The nice thing about this is you get more data than just taking the average of the scene.
 
So, if you are thinking GetData(), think about maybe using an occlusion query if possible - if you know exactly the colors or information you need.
 
Best of luck-
Bryan
July 07

Alternatives to SetData

While working on the mega texturing, I've had quite a few areas that bottlenecked my approach. At first, it seemed impossible to get things to a real time speed, but I think i'm almost there. I had made assumptions that GetData and SetData were my bottlenecks -and initially this wasn't even true! It wasn't until I started doing some profiling that I realized code inefficiences in the texture fetching and atlasing algorithms were causing severe bottlenecks.
 
However, once I improved this, it turned out that SetData calls were definitely a bottleneck. Ideally you don't want to use SetData in any sort of real time sense. You should be able to hopefully offload most work to the GPU in places where you would wish to use SetData. However, in the mega texturing, I am streaming texture data from a binary file on disk to a texture - so it seems like there is really no alternative to SetData. I actually used it in two places - one for an index texture, which tells the GPU where to look in a larger Lookup Texture for the actually texture data. If there is no valid lookup texture data, then the index texture has the average color of the lookup data.
 
So, it appears that you need at least two SetData calls - one to set information in the index texture about where to look in the lookup texture (offsets, sizes, etc), and a second SetData call to send data to the lookup texture. However, this turned out to be exceptionally slow. I tried many schemes, all running from a seperate execution thread:
 
1) Call SetData only on the affected regions
2) Make many small textures, call SetData on these, and then use a SpriteBatch to draw these over to a lookup texture rendertarget
 
None of these proved acceptable - SetData just was tooo slow.
 
An alternative that helped out tremendously was to do the following in place of SetData:
Use a render target, and render a white 1x1 pixel for each pixel in the texture. I could draw only the portions of the lookup texture that had changed this way, and it was MUCH faster than calling SetData. So basically instead of using SetData, I use a SpriteBatch to draw each pixel individually. This works well because not every pixel changes every frame, so in the general case it is a very reasonable amount of spritebath.Draw() calls, and they are all using the same texture, so ideally it should only be 1 extra actual Draw() call. If you need to use SetData in your application, and find it to be a bottleneck, I would suggest trying this approach.
 
The downfall is that my index texture is actually a HalfVector4 texture instead of a Color texture. The added precision is needed for the offsets and sizes into the lookup texture - 1B isn't enough precision for my current system. So I still need to use a SetData<> call on the HalfVector4 texture as there isn't a good way that I know of to draw to anything but a Color surface using a spriteBatch. Maybe I could do something clever and use a few different pre-set HalfVector4 textures to get all the ranges I need, or maybe with some fine tuning I could get away with 1B of precision. So we'll see!
 
This isn't a groundbreaking idea or anything but just in case someone is stuck with SetData<> its cool to have some other options to try and see if they help.
 
Next post: An alternative to GetData<> for certain scenarios!
June 21

Working on new game : Quarx

My brother and I have been working on a new XNA game - Quarx. It's basically a Dr. Mario clone. I was a big fan of Dr Mario back in the day, especially the 2-player mode, so i thought it'd be fun to bring it to the 360. My brother has been helping out a ton with the graphics and game screens and everything, so its shaping up to look very nice. We have some details to add & polish, and hopefully you'll see it on the community games pretty soon!
 
quarx1quarx2quarx4quarx3
View more entries