This article is an example of 3D rendering and content processing with XNA, and a good start for those of you who want to start learning XNA. Although it's not a full working Billiards game (that will be another article), it can be a good starting point for one too.
It's not intended to show the best way of doing anything, it's just a quick example I've made in four or five hours. Any improvement is really welcome!
It covers the following topics:
- Content processor development
- Content exporting from 3DSMax, including Max Shaders, ready to use with XNA
- Content loading
- 3D rendering, with and without Max Shaders
- Basic camera development
- Basic Sprite management
- Basic custom user interface development
- Mouse reading
- Scene and 3D models management
- Settings serialization with XML
- Additional model properties implementation
The zips are divided into two groups:
- Article_demo_XXX: for the binaries only. (Every demo_XXX Zip file should be uncompressed to the same folder.)
- Article_src_XXX: for the full Visual Studio project (every src_XXX Zip file should be uncompressed to the same folder)
The project you will find in Article_src is a Visual C# Express project. So, you'll need Visual C# Express (with Service Pack 1) and the XNA Game Studio (version 1.0 Refresh) to compile and run it.
This project may be used as a starting point to learn some intermediate 3D rendering and scene management concepts, and their implementation in XNA.
If you don't know what a Camera is, how a 3D object (made up of polygons) is rendered, or don't have some basic algebraic knowledge, I'd suggest you to first read some introductory tutorial. Until The Code Project has more articles on game development, a good place to start looking is GameDev.
If you already have all this basic knowledge, keep reading:
Where possible, everything has been implemented in a component oriented way. XNA has a
GameComponent class you can inherit from, which guides you in this way of working. Basically, all the functionality can be expressed in three stages or steps:
- Initialization: Called once for the object's boot up, mem reserving, whatever
- Update: Called once per frame, to do any update of states necessary
- Draw: Called once per frame, to paint visible objects, UI, and stuff like that.
3D scene preliminary
Any 3D application needs some data to compose the scenes, typically:
- 3D or 2D geometry
- Materials and shaders
- Any additional information, like physics, game-specific properties, ...
Textures are usually created in a design suite like Photoshop, Gimp, or any other. Materials and 3D geometry are usually created in a 3D modeling package like 3DSMax, Maya, or others. Textures are incorporated to 3D scenes here as well. For shaders creation, there are many options:
- Use specific software, like ATI RenderMonkey or nVidia Shader FX
- Use the 3D modeling package itself
- Write them "by hand" (with the most powerful tool ever created: the Notepad, as this guy always says - Hi Chema!-;)
Additional object properties can be included in the scene through the modeling package (with custom attributes), or can be specified by hand in separate files (I prefer this way, using XML files, for example).
What is not so clear is how to export all this bunch of information: Can it all be included in a single file? In many cases, no.
So, how did I do it?
- 3D scenes composed by free-downloaded models
- Some basic geometry modeled in 3DSMax (walls, etc.)
- Basic textures done with Gimp
- Advanced lighting textures done with our own software
- Materials composed in 3DSMax
- Shaders composed in 3DSMax (with DirectX Shader materials)
- Everything exported to an X-File with KW X Export plug-in for Max9
Using the code
The project you will find in the Zip file is a full working XNA Windows Game project.
I'll talk a little bit about the classes it includes. For space reasons, I cannot extend this section too much, but feel free to ask for any additional information you may need:
PositionNormalTexture: this is a XNA Content Processor. It is used to transform the X Files used for 3D geometry into the .xnb format. It basically writes all the geometry in a specific format, so every model is expressed in the same way.
TargetedCamera: a camera class ready to work as an orbit-targeted camera. You just have to tell it an initial target and eyepoint, and call the Orbit methods.
CMouseInput: Includes all the mouse reading functionality, and exposes two useful events:
OnMouseMove. Both work in a very similar way to Windows Forms events.
Model3D: Designed as a
GameComponent that encapsulates a 3D model. This class is ready to read X Files exported from 3DS Max. It supports default materials (treated through the
BasicEffect shader, a default in XNA), and DirectX Shader Materials (shaders designed in 3DSMax).
Scene: This class is just an example of scene management. In this case, the room and the pool table are different models. They are both together in the
Scene class, as they are part of the scene. If you'd want to extend this example to a full Billiards game, this class would be the perfect place to put a collection of balls, for example.
Settings: I included this class in the project to explain how application settings can be handled to be compatible both with Windows projects and XBox projects, because the normal .NET classes for such issues (
System.Configuration) are not available on the Compact Framework (and therefore 360).
MySprite: This class is a helper for drawing Sprites, holding in a single class a
SpriteBatch, a Texture2D, a position to render the sprite in, and other features, like a tint color for the sprite. Please note that using
MySprite to render lots of sprites is not efficient, as it will require one
SpriteBatch for each sprite. You should use a single
SpriteBatch to render lots of sprites instead, but for this example, this suffices (and is really simple). It is used to render a "sniper" sprite at cursor position.
MySpriteButton: Inherits from
MySprite but adds a button-like functionality. It includes a
Click event, very much like the one in Windows Forms, and a mouse hover effect changing the sprite tint color when the mouse is over it. It's used for the UI buttons that allow the user to select different targets for the camera.
BilliardsGame: This is the XNA game itself. It inherits
Microsoft.Xna.Framework.Game and basically holds and uses all the others:
Settings class' instance,
MySpritesButtons for the User Interface, ...
Hope you find it useful
Points of interest
Make sure to take a look at the XNA Home Page for updates of the framework, tutorials, starter kits, and always look at the forums when you have a problem. Maybe someone already had it and someone else already found a solution.
There are a lot of good people there! ;)
- Initial version: November 19, 2007.
Inaki Ayucar is a Microsoft MVP in DirectX/XNA, and a software engineer involved in development since his first Spectrum 48k, in the year 1987. He is the founder and chief developer of The Simax Project (www.simaxvirt.com) and is very interested in DirectX/XNA, physics, game development, simulation, C++ and C#.
His blog is: http://graphicdna.blogspot.com
To contact Inaki: firstname.lastname@example.org