- Website design & DirectX code : Riemer Grootjans -
- Drawing your first Triangle
This chapter will
cover the basics of drawing. First a few things you should
know.
Every object drawn by
Direct3D is drawn using triangles. Surprisingly enough, a
triangle is defined bij 3 points. Every point is defined by a
vector, giving the X, Y and Z coordinates of the point.
However, just knowing the coordinates of a point might
not be enough. For example, you might want to define a color
for the given point as well. This is where a vertex (pl.
vertices) comes in: it is the list of properties of a given
point, including the position, color and so on.
DirectX has a
construct that fits perfectly to hold our vertex information
the CustomVertex class. Just add the following code to the
beginning of the OnPaint method :
CustomVertex.TransformedColored[]
vertices = new CustomVertex.TransformedColored[3];
vertices[0].Position = new
Vector4(150f, 100f, 0f, 1f);
vertices[0].Color =
Color.Red.ToArgb();
vertices[1].Position = new Vector4(this.Width/2+100f, 100f,
0f, 1f);
vertices[1].Color =
Color.Green.ToArgb();
vertices[2].Position =
new Vector4(250f, 300f, 0f, 1f);
vertices[2].Color =
Color.Yellow.ToArgb();
The first line creates an
array to hold the information for 3 vertices.
TransformedColored means the coordinates of the points will be
screen coordinates and each of the points can have its own
color. Next we fill in the position and information for 3
points. The'f' behind the numbers simply convert the integers
to floats, the expected format. Don't pay attention to the 4th
coordinate for now.
All we have to do now is tell the device to paint the
triangle! Right after the Clear call, add these lines:
device.BeginScene();
device.EndScene();
The first line tells the device the 'scene' will be built
next. The scene is the whole world of objects the device has
to display. The last line indicates the end of the scene
definition. The following lines will define our scene (that
currently only consists of 1 simple triangle), so add them
between the BeginScene and EndScene calls:
device.VertexFormat =
CustomVertex.TransformedColored.Format;
device.DrawUserPrimitives(PrimitiveType.TriangleList,
1, vertices);
First we tell the device what kind of vertex information to
expect. The last line actually draws the triangle. The
first argument indicates that a list of separate triangles is
coming. If you would draw 4 triangles, you would need a vertex
array of 12 vertices. Another possibility is
a TriangleStrip. This is useful to draw triangles that
are connected to each other. The first 3 vertices of the array
define the first triangle. The second triangle is defined by
the second, third en fourth vertex of the array. The third
triangle by the third, fourth and fifth vertex and so on.
So for drawing 4 triangles, you will only need 6
vertices.
That's all there is to it! Running this code will already
give you a colorfull triangle on a blue background. Feel free
to experiment with the colors and the coordinates.
There still is a problem you might encounter while resizing
the window. Try adjusting the width of the window. Sometimes,
Windows doesn't consider resizing a window important enough to
repaint the whole window. To solve the problem, simply add the
following line to the bottom of your OnPaint method:
this.Invalidate();
You should also add the following line to the constructor
of your form:
this.SetStyle(ControlStyles.AllPaintingInWmPaint |
ControlStyles.Opaque, true);
Much better. I've listed the total code below :
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;
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);
}
protected override void
OnPaint(System.Windows.Forms.PaintEventArgs
e)
{
CustomVertex.TransformedColored[] vertices
= new CustomVertex.TransformedColored[3];
vertices[0].Position
= new Vector4(150f, 100f, 0f, 1f);
vertices[0].Color =
Color.Red.ToArgb();
vertices[1].Position = new Vector4(this.Width/2+100f,
100f, 0f, 1f);
vertices[1].Color =
Color.Green.ToArgb();
vertices[2].Position = new Vector4(250f, 300f, 0f,
1f);
vertices[2].Color =
Color.Yellow.ToArgb();
device.Clear(ClearFlags.Target, Color.DarkSlateBlue ,
1.0f, 0);
device.BeginScene();
device.VertexFormat =
CustomVertex.TransformedColored.Format;
device.DrawUserPrimitives(PrimitiveType.TriangleList,
1, vertices);
device.EndScene();
device.Present();
this.Invalidate();
}
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();
Application.Run(our_directx_form);
}
}
}
}
|