DirectX9 3D quick start 2
By SSSA2000
4/13/2005
According to the general tutorial, it will finish the establishment of the equipment, it should be said to the Vertices, of course, this is also very important concept, have to learn.
Look at the Tutorial2 of the SDK, this example is also very simple to draw a triangle on the basis of the example 1, and fill it with the gradual color. As shown below:
First look at how Vertices are built.
CustomvertEx.TransformedColored [] VERTS = New CustomvertEx.transformedColored [3];
VERTS [0] .x = 150; VERTS [0] .y = 50; VERTS [0] .z =
0.5f; VERTS [0] .RHW = 1; VERTS [0] .COLOR = system.drawing.color.aqua.toargb ();
VERTS [1] .x = 250; VERTS [1] .y = 250; VERTS [1] .z =
0.5F; VERTS [1] .RHW = 1; VERTS [1] .COLOR = system.drawing.color.brown.toargb ();
VERTS [2] .x = 50; VERTS [2] .y = 250; VERTS [2] .z =
0.5F; VERTS [2] .RHW = 1; VERTS [2] .color = system.drawing.color.lightpink.toargb ();
CustomvertEx.transformedColored contains data that transforms vertices and color values, why do you want to transform? The coordinate system used by DX is related. To say, one or two do two sentences are also difficult, here is used to change the vertices, the specified coordinates are the coordinates of the screen, it is very intuitive, and then feel the benefits of RAD. Of course, CustomvertEx also includes a lot of other structures, suitable for other needs, interested in see.
The RHW represents the countdown of homogenic W coordinates, and is only suitable for transforming vertices.
Note that different versions of DirectX9, syntax will be somewhat different, pay attention to the documentation, my DirectX
9.0c (October 2004).
In fact, it can now be rendered, but this time is less efficient. Every time you render the scene, you must allocate a list of new vertices and all things are stored in system memory. The modern graphics card integrates sufficient memory, putting the vertex data in memory to get a large new energy increase: stored in system memory, copy to graphics cards when each frame is rendered, which will bring great losses. This allocation is removed only to help us improve performance.
So we need to buffer, so there is Vertex buffers. The following is a commonly used 2 constructor:
Public VertexBuffer (Device Device, Int SizeofbufferinBytes, Usage Usage, VertexFormats VertexFormat, Pool Pool)
Public VertexBuffer (Type TypevertEXTYPE, INT Numverts, Device Device, Usage Usage, VertexFormats VertexFormat, Pool Pool);
The following is the meaning of each parameter:
Device - Used to create a vertex buffered Device, the vertex buffer created can only be used by this device; SizeOfbufferinBytes - the vertex buffer size created, in bytes. The vertex buffer created with this parameter can be stored any type of vertex; typeVertextype - If you want to create the vertex buffer that only stores a type of vertex, use this parameter. Its value can be the vertex structure type in the CustomvertEX class, or it can be a custom vertex type. And this value cannot be null; Numvert - specifies the number of cushioned vertices maximum of the buffer storage after the storage type of the vertex buffer is specified. This value must be greater than 0; USAGE - defines how to use vertex buffers. Not all USAGE types of members can be used, only a few are the correct parameters: DonotClip, Dynamic, Npatches, Points, Ptpatches, SoftwareProcessing, Writeonly; VertexFormat - defines the vertex format stored in the vertex buffer. If you created a universal buffer, use VertexFormat.none; pool - to locate the memory pool position used by the vertex, you can specify a few memory pool position: Default, Managed, SystemMemory, Scratch. Let's take a look at how it is doing it in this example of SDK:
Public Void OncreateDevice (Object Sender, Eventargs E)
{
Device dev = (device) sender;
VertexBuffer = New VertexBuffer (TypeOf (CustomvertEx.TransformedColored), 3, DEV, 0, CustomvertEx.transformedColored.Format, pool.default;
VertexBuffer.created = New System.EventHandler (this.oncreatevertexbuffer);
This.oncreateVertexBuffer (VertexBuffer, NULL);
}
As expected, and, there is also an event: VertexBuffer.created, in this event we can write each vertex value, just like we write in front. If you are not too embarrassed, let's take a look at:
Public void oncreatevertexbuffer (Object Sender, Eventargs E)
{
VertexBuffer VB = (VertexBuffer) Sender;
GraphicsStream STM = VB.LOCK (0, 0, 0);
CustomvertEx.TransformedColored [] VERTS = New CustomvertEx.transformedColored [3];
VERTS [0] .x = 150; VERTS [0] .y = 50; VERTS [0] .z =
0.5f; VERTS [0] .RHW = 1; VERTS [0] .COLOR = system.drawing.color.aqua.toargb ();
VERTS [1] .x = 250; VERTS [1] .y = 250; VERTS [1] .z =
0.5F; VERTS [1] .RHW = 1; VERTS [1] .COLOR = system.drawing.color.brown.toargb ();
VERTS [2] .x = 50; VERTS [2] .y = 250; VERTS [2] .z = 0.5f; VERTS [2] .RHW = 1; VERTS [2] .color = system.drawing.color. Lightpink.toargb ();
Stm.write (VERTS);
vb.unlock ();
}
In order to understand simple, we can understand that if you need to use VertexBuffer, you must use GraphicsTream. Of course, you need to use it with indexbuffer, which will naturally speak later.
Here, in order to avoid multiple places to read and write, use the Lock () method, in fact, in many places in the future, you have to come into contact with this method. Take a look at the original shape of the Lock method:
Public GraphicsStream Lock (int offsettolock, // offset, set to 0) INT SIZETOLOCK, // Set to 0 means all data LockFlags flags // is typically set to 0, of course, you can also be selected, see SDK documentation);
Now we are ready, now we can draw DrawPrimitives will draw geometry from the data stream source. DrawPrimities has three parameters
Public Void DrawPrimities (PrimitiType PrimitiveType, // Geometry INT StartVertex, // Indicates the number of geometric numbers to draw in the starting top point int primitivecount //);
Let's take a look at the render () function
Private void render ()
{
IF (device == null)
Return;
// Clear the Backbuffer to a blue color (argb = 000000FF)
Device.clear (Clearflags.target, System.drawing.color.blue,
1.0F, 0);
// Begin the Scene
DEVICE.BEGINSCENE ();
Device.setStreamSource (0, VertexBuffer, 0);
Device.vertexFormat = CustomvertEx.TransformedColored.Format; // Specify format
Device.drawPrimitives (PrimitiveType.trianglelist, 0, 1); // Draw a 3 angle
// end the scene
Device.endscene ();
Device.Present ();
}
The role of SetStreamSource is to read the vertex buffer when Direct3D drawing. Using this method is of course to cooperate with the previous DrawPrimitives (). This method has the following two overloads:
Public Void SetStreamSource (int StreamNumber, VertexBuffer StreamData, int offsetinBytes, int Stride);
Public Void SetStreamSource (int StreamNumber, VertexBuffer StreamData, int offsetinbytes);
The difference between the two functions is that one of the two parameters indicating (data) flow rate size (Stride size of the stream).
The first parameter is the number of streams used in this data. Now set it to 0;
The second parameter is a vertex buffer as a data source.
The third is the offset (byte) of the data that requires DirectX to be drawn in the vertex buffer. Stride is the size of each vertex in the buffer. This parameter is not required if the vertex buffer created with a particular type. Ok, now you can compile it, the effect is not bad. Next time we have to truly enter the 3D world.
OK, in order to facilitate reading, attach Tutorial2's full code:
/ / -------------------------------------------------------------------------------------------- -----------------------------
// file: vertices.cs
//
// desc: in this Tutorial, We are rendering some vertices. This introduces the
// Concept of the Vertex Buffer, A Direct3D Object Used to Store
// Vertices. Vertices Can Be defined Any Way We want by defining a
// Custom Structure and a Custom FVF (Flexible Vertex Format). In this
// tutorial, we are useful using the same area
// area Already in 2D Window Coordinates) and Lit (Meaning WE Are Not
// USING DIRECT3D LIGHTING, But Are Supplying Our OWN Colors.
//
// Copyright (c) Microsoft Corporation. All Rights Reserved.
/ / -------------------------------------------------------------------------------------------- -----------------------------
Using system;
Using system.drawing;
Using system.windows.forms;
Using Microsoft.directX;
Using Microsoft.directx.direct3d;
Namespace VerticesTutorial
{
Public Class Vertices: Form
{
// Our Global Variables for this Project
Device device = NULL; // ur rendering Device
VertexBuffer VertexBuffer = NULL;
Public vertices ()
{
// set the initial size of ot form
THIS.CLIENTSIZE = New System.drawing.size (300, 300);
// and ITS CAPTION
THIS.TEXT = "Direct3D Tutorial 2 - Vertices";
}
Public Bool Initializegraphics ()
{
Try
{
// Now let's setup company D3D stuff
PresentParameters Presentparams = New Presentparameters ();
Presentparams.windowed = true;
Presentparams.swaPeffect = swapeffect.discard;
Device = New Device (0, DeviceType.hardware, this, createflags.softwarevertexprocessing, presentparams); this.oncreateDevice (device, null);
Return True;
}
Catch (DirectxException)
{
Return False;
}
}
Public Void OncreateDevice (Object Sender, Eventargs E)
{
Device dev = (device) sender;
// now crete the VB
VertexBuffer = New VertexBuffer (TypeOf (CustomvertEx.TransformedColored), 3, DEV, 0, CustomvertEx.transformedColored.Format, pool.default;
VertexBuffer.created = New System.EventHandler (this.oncreatevertexbuffer);
This.oncreateVertexBuffer (VertexBuffer, NULL);
}
Public void oncreatevertexbuffer (Object Sender, Eventargs E)
{
VertexBuffer VB = (VertexBuffer) Sender;
GraphicsStream STM = VB.LOCK (0, 0, 0);
CustomvertEx.TransformedColored [] VERTS = New CustomvertEx.transformedColored [3];
VERTS [0] .x = 150; VERTS [0] .y = 50; VERTS [0] .z =
0.5f; VERTS [0] .RHW = 1; VERTS [0] .COLOR = system.drawing.color.aqua.toargb ();
VERTS [1] .x = 250; VERTS [1] .y = 250; VERTS [1] .z =
0.5F; VERTS [1] .RHW = 1; VERTS [1] .COLOR = system.drawing.color.brown.toargb ();
VERTS [2] .x = 50; VERTS [2] .y = 250; VERTS [2] .z =
0.5F; VERTS [2] .RHW = 1; VERTS [2] .color = system.drawing.color.lightpink.toargb ();
Stm.write (VERTS);
vb.unlock ();
}
Private void render ()
{
IF (device == null)
Return;
// Clear the Backbuffer to a blue color (argb = 000000FF)
Device.clear (Clearflags.target, System.drawing.color.blue,
1.0F, 0);
// Begin the Scene
DEVICE.BEGINSCENE ();
Device.setStreamSource (0, VertexBuffer, 0);
Device.vertexFormat = CustomvertEx.transformedColored.Format;
Device.drawPrimitives (PrimitiveType.trianglelist, 0, 1);
// end the scene
Device.endscene ();
Device.present ();
Protected Override Void Onpaint (System.Windows.Forms.Painteventargs E)
{
THIS.Render (); // render on painting
}
Protected Override Void OnKeyPress (System.Windows.Forms.KeyPressEventArgs E)
{
IF ((int) e.keychar == (int) system.windows.forms.keys.escape)
THIS.CLOSE (); // esc Was Pressed
}
///
/// The main entry point for the application.
/// summary>
Static void
Main ()
{
USING (Vertices FRM = New Vertices ())
{
IF (! frm.initializegraphics ()) // Initialize Direct3D
{
Messagebox.show ("Could Not Initialize Direct3d. This Tutorial Will EXIT.");
Return;
}
Frm.show ();
// While The Form Is Still Valid, Render and Process Messages
While (frm.created)
{
frm.render ();
Application.doevents ();
}
}
}
}
}