This may be a precursor to something bigger…
I’m working on what I think will be a pretty cool game for the marketplace, and I’ll share the source code here eventually. Right now I had to conceptually understand something: how to draw a cube using only vertices.
You see, in my XNA experience I’ve never dealt directly with vertices; I’ve always just drawn models or sprites on the screen. In this case, now, I need to be able to generate a cube and later have the option to change just once face at a time. That will come later!
Right now I’ve got some working code which constructs and textures a cube and then draws it. This is in XNA 4.0 for Windows Phone 7. The starting point I used was this excellent XNA 3.1 article. The code I use to set up the vertices in ManualCube.cs is more or less a direct ripoff; there wasn’t much to change. Where I made changes was in the rendering, and also one area that was causing a memory leak.
Download my solution here:
So, let’s be honest. It’s not like this is the most amazing thing in the gaming world. The point is, the method I’m using adds a lot more control over what you can do with the resulting object.
In what way is this better than making a cube in Blender/Mod Tool/whatever, skinning it, exporting it to FBX and going on with your life?
Well, in theory, you can change the appearance of the cube’s faces individually, or even animate them. You have total control over the appearance of your shape, the effects you choose to use, and more. When you have a lot of dynamic-ness especially related to the textures or colors on the shape, this is a good way to go.
The ManualCube Class
This is kinda the meat and potatoes of this method. Basically in this class we are manually setting up a ton of values that compute vertex locations (with normals and UV texture coordinates) for a cube. A cube has six faces, which is made of two triangles, each of which have 3 vertices. So we have 6 vertices per face and 6 faces = 36 total vertices to enter data for.
The texture coordinates are important because they indicate how the texture will be displayed on the face: rotated, scaled, translated, etc.
This class is different from Cube.cs in the original article in that the _shapeBuffer variable is no longer used. In the Render method, I stuck it in a using statement (see line 8 below) so that it is properly disposed of. I ran out of memory pretty quickly with the original code.
RenderToDevice fills a vertex buffer and makes the graphics device use it for what it will draw next. RenderToDevice needs to be called from the main game’s draw method in order for anything to happen, and of course, you need to properly set up the effect that will be used to draw it.
Also, in the code that sets up the vertices in ConstructCube, at the end, I set a local boolean called _isConstructed to true. That way, we are not constructing the cube from scratch every single frame.
Drawing the Cube
I have set up a new effect in this class: a BasicEffect called cubeEffect, which we’ll use to set our world, view and projection matrices, as well as the texture to apply.
In XNA 4.0 you don’t have to call Begin and End on an effect, or on effect passes. The new way of drawing with an effect is actually very simple and streamlined as you’ll see in my Draw method below:
protected override void Draw(GameTime gameTime)
// Set the World matrix which defines the position of the cube
cubeEffect.World = Matrix.CreateRotationY(MathHelper.ToRadians(rotation)) *
Matrix.CreateRotationX(MathHelper.ToRadians(rotation)) * Matrix.CreateTranslation(modelPosition);
// Set the View matrix which defines the camera and what it's looking at
cubeEffect.View = Matrix.CreateLookAt(cameraPosition, modelPosition, Vector3.Up);
// Set the Projection matrix which defines how we see the scene (Field of view)
cubeEffect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, aspectRatio, 1.0f, 1000.0f);
// Enable textures on the Cube Effect. this is necessary to texture the model
cubeEffect.TextureEnabled = true;
cubeEffect.Texture = cubeTexture;
// Enable some pretty lights
// apply the effect and render the cube
foreach (EffectPass pass in cubeEffect.CurrentTechnique.Passes)
This is a great start to what I think is a cool game. Thanks also to Shawn Hargreaves for answering some of my silly questions.