If you've seen any of the write-ups in the press about XNA, you'll notice that none of them get any further than a spinning cube.
DB Pro
MAKE OBJECT CUBE 1, 1
DO
TURN OBJECT RIGHT 1, 0.1
LOOP
XNA
<Canvas x:Name="spinningCubeCanvas">
<Canvas.Resources>
<Storyboard x:Name="spinningCubeStorybard" Completed="spinningCubeCanvas_Render"/>
</Canvas.Resources>
</Canvas>
public void spinningCubeCanvas_Render(object sender, EventArgs e)
{ this.spinningCubeStorybard.Begin();}
private class Vertex
{
public double X, Y, Z;
public double RotatedX, RotatedY, RotatedZ;
public int TranslatedX, TranslatedY;
}
private class Face
{
public int VertexA, VertexB, VertexC;
}
private Vertex[] _vertices = new Vertex[]
{
new Vertex() { X=-150, Y=-150, Z=-150},
new Vertex() { X=150, Y=-150, Z=-150},
new Vertex() { X=-150, Y=150, Z=-150},
new Vertex() { X=150, Y=150, Z=-150},
new Vertex() { X=-150, Y=-150, Z=150},
new Vertex() { X=150, Y=-150, Z=150},
new Vertex() { X=-150, Y=150, Z=150},
new Vertex() { X=150, Y=150, Z=150},
};
private Face[] _faces = new Face[] {
new Face() { VertexA=2, VertexB=1, VertexC=0},
new Face() { VertexA=1, VertexB=2, VertexC=3},
new Face() { VertexA=4, VertexB=5, VertexC=6},
new Face() { VertexA=7, VertexB=6, VertexC=5},
new Face() { VertexA=0, VertexB=4, VertexC=6},
new Face() { VertexA=0, VertexB=6, VertexC=2},
new Face() { VertexA=7, VertexB=5, VertexC=1},
new Face() { VertexA=3, VertexB=7, VertexC=1},
new Face() { VertexA=5, VertexB=4, VertexC=0},
new Face() { VertexA=1, VertexB=5, VertexC=0},
new Face() { VertexA=2, VertexB=6, VertexC=7},
new Face() { VertexA=2, VertexB=7, VertexC=3},
};
// Calculate all the vertices
foreach (Vertex vertex in this._vertices)
{
// Rotate the vertex around the Z axis
tempY1 = (vertex.X * Math.Sin(this._zRotation)) +
(vertex.Y * Math.Cos(this._zRotation));
tempX1 = (vertex.X * Math.Cos(this._zRotation)) -
(vertex.Y * Math.Sin(this._zRotation));
// Rotate the vertex around the Y axis
vertex.RotatedX = (vertex.Z * Math.Sin(this._yRotation)) +
(tempX1 * Math.Cos(this._yRotation));
tempZ1 = (vertex.Z * Math.Cos(this._yRotation)) - (tempX1 * Math.Sin(this._yRotation));
// Rotate the vertex around the X axis vertex.RotatedZ = (tempY1 * Math.Sin(this._xRotation)) +
(tempZ1 * Math.Cos(this._xRotation));
vertex.RotatedY = (tempY1 * Math.Cos(this._xRotation)) -
(tempZ1 * Math.Sin(this._xRotation));
// Translate the vertex into a 2D coordinate
vertex.TranslatedX = ((int) ((vertex.RotatedX * focalLength) /
(vertex.RotatedZ + zoom)))+xoffset;
vertex.TranslatedY = ((int) ((vertex.RotatedY * focalLength) /
(vertex.RotatedZ + zoom)))+yoffset;
}
// Create polygons for Silverlight to work with from the newly
// calculated vertices
this.spinningCubeCanvas.Children.Clear();
foreach (Face face in this._faces){
Vertex vertexA = this._vertices[face.VertexA];
Vertex vertexB = this._vertices[face.VertexB];
Vertex vertexC = this._vertices[face.VertexC];
// Do a mixedproduct of all vertices for hidden surface removal
double mixedProduct = (vertexB.TranslatedX - vertexA.TranslatedX) *
(vertexC.TranslatedY - vertexA.TranslatedY) -
(vertexC.TranslatedX - vertexA.TranslatedX) *
(vertexB.TranslatedY - vertexA.TranslatedY);
bool visible = mixedProduct < 0;
if (!visible)
{
continue;
}
// Use the mixed product for "shading".
// The larger the face, the brighter it is.
double shade = -mixedProduct;
// *512; shade /= 1024;
int color = (int)shade;
color += 128;
if (color >= 250) { color = 250;
} if (color < 30) { color = 30;
} byte red = (byte)(color >> 3);
byte green = (byte)(color >> 1);
byte blue = (byte)(color);
// Create the polygon and initialize the point and the color
Polygon polygon = new Polygon();
polygon.Points = new Point[]
{
new Point(vertexA.TranslatedX,vertexA.TranslatedY), new Point(vertexB.TranslatedX,vertexB.TranslatedY),
new Point(vertexC.TranslatedX,vertexC.TranslatedY)
};
polygon.Fill = new SolidColorBrush(Color.FromRgb(red, green, blue));
this.spinningCubeCanvas.Children.Add(polygon);
}