- Website design & DirectX code : Riemer Grootjans -
- Rotations and translations
This chapter will
cover the basics of drawing. First a few things you should
know.
This chapter will
make your triangle spin around. Since we are using world space
coordinates, this is very easy. Let's first add a variable
'angle' to our class to store the current rotation angle. Just
add it to your variables.
private float angle = 0f;
Now, increase this
variable with 0.05f every time OnPaint is called. Add this to
the end of the OnPaint class:
angle +=
0.05f;
With our angle
increasing automaticly, all we have to do is to rotate the
world coordinates. I hope you remember from you maths class
this is done using transformation matrices. Luckily, all you
have to do is specify the rotation axis and the rotation
angle. All the rest is done by Direct3D!
You should add the
following line right before you actually draw the triangle,
this is before the call to device.DrawUserPrimitives
:
device.Transform.World =
Matrix.RotationZ(angle);
When you run the
application, you will see that your triangle is spinning
around its (0,0,0) point as expected! But imagine we would
like to spin it through the center. One possibility is to
redefine the point so the (0,0,0) would be in the center of
our triangle. The better solution would be to first move
(=translate) the triangle a bit to the left and down, and then
rotate it. To do this, simply first multiply your World matrix
with a translation matrix :
device.Transform.World =
Matrix.Translation(-5,-10*1/3,0)*Matrix.RotationZ(angle);
This will move the
triangle so the (0,0,0) point is positioned in the gravity
point of the triangle. Then our triangle is rotated
around this point, giving us the wanted result. Please note
the order of transformations. Go ahead and place the
translation AFTER the rotation. You will see a triangle
rotation around one point, moved to the left and below. You
can easily change the code to make the triangle rotate around
the Y or Z axis. Make sure to try one of them, to get the
first feel of 3D. I bit more complex is the Matrix.RotateAxis,
where you first have to specify your own custom
rotation axis :
device.Transform.World =
Matrix.Translation(-5,-10*1/3,0)*Matrix.RotationAxis(new
Vector3(angle*4,angle*2,angle*3),
angle);
This will make our triangle spin around an
every changing axe. To start next chaptern let's clear things
up a bit. put the camera positioning in a new method CameraPositioning() and the vertex
declaration in VertexDeclaration(). Since both of them need to be
declared only once, we'll only call them in our Main method,
so the OnPaint method will go
faster. Don't forget to make vertices a variable
in your class by adjusting its definition and
placing this line in the top of your class
:
private
CustomVertex.PositionColored[]
vertices;
Here's the
code:
using
System;
using
System.Drawing;
using
System.Collections;
using
System.ComponentModel;
using
System.Windows.Forms;
using
System.Data;
using
Microsoft.DirectX;
using
Microsoft.DirectX.Direct3D;
namespace
DirectX_Tutorial
{
public class WinForm :
System.Windows.Forms.Form
{
private Device device;
private System.ComponentModel.Container components =
null;
private float angle = 0f;
private
CustomVertex.PositionColored[]
vertices;
public WinForm()
{
InitializeComponent();
this.SetStyle(ControlStyles.AllPaintingInWmPaint |
ControlStyles.Opaque, true);
}
public void InitializeDevice()
{
PresentParameters presentParams = new
PresentParameters();
presentParams.Windowed = true;
presentParams.SwapEffect =
SwapEffect.Discard;
device = new Device(0, DeviceType.Hardware, this,
CreateFlags.SoftwareVertexProcessing,
presentParams);
}
private void
CameraPositioning()
{
device.Transform.Projection =
Matrix.PerspectiveFovLH((float)Math.PI/4,
this.Width/this.Height, 1f, 50f);
device.Transform.View = Matrix.LookAtLH(new
Vector3(0,0,-30), new Vector3(0,0,0), new
Vector3(0,1,0));
device.RenderState.Lighting =
false;
device.RenderState.CullMode =
Cull.None;
}
private void
VertexDeclaration()
{
vertices = new
CustomVertex.PositionColored[3];
vertices[0].SetPosition(new Vector3(0f, 0f,
0f));
vertices[0].Color =
Color.Red.ToArgb();
vertices[1].SetPosition(new Vector3(10f, 0f,
0f));
vertices[1].Color =
Color.Green.ToArgb();
vertices[2].SetPosition(new Vector3(5f, 10f,
0f));
vertices[2].Color =
Color.Yellow.ToArgb();
}
protected override void
OnPaint(System.Windows.Forms.PaintEventArgs
e)
{
device.Clear(ClearFlags.Target, Color.DarkSlateBlue ,
1.0f, 0);
device.BeginScene();
device.VertexFormat =
CustomVertex.PositionColored.Format;
device.Transform.World =
Matrix.Translation(-5,-10*1/3,0)*Matrix.RotationAxis(new
Vector3(angle*4,angle*2,angle*3),
angle);
device.DrawUserPrimitives(PrimitiveType.TriangleList,
1, vertices);
device.EndScene();
device.Present();
this.Invalidate();
angle +=
0.05f;
}
protected override void Dispose (bool
disposing)
{
if (disposing)
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose(disposing);
}
private void
InitializeComponent()
{
this.components = new
System.ComponentModel.Container();
this.Size = new
System.Drawing.Size(500,500);
this.Text = "DirectX Tutorial";
}
static void Main()
{
using (WinForm our_directx_form = new
WinForm())
{
our_directx_form.InitializeDevice();
our_directx_form.CameraPositioning();
our_directx_form.VertexDeclaration();
Application.Run(our_directx_form);
}
}
}
}
|