//
-----------------------------------------------------------------------------
//
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 using vertices that are transformed (meaning they
//
are 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
;
//
Our rendering device
VertexBuffer vertexBuffer
=
null
;
public
Vertices()
{
//
Set the initial size of our 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 our 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 Create 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.Red.ToArgb();
verts[
1
].X
=
250
;verts[
1
].Y
=
250
;verts[
1
].Z
=
0.5f
; verts[
1
].Rhw
=
1
; verts[
1
].Color
=
System.Drawing.Color.Yellow.ToArgb();
verts[
2
].X
=
50
;verts[
2
].Y
=
250
;verts[
2
].Z
=
0.5f
; verts[
2
].Rhw
=
1
; verts[
2
].Color
=
System.Drawing.Color.SkyBlue.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
)(
byte
)e.KeyChar
==
(
int
)System.Windows.Forms.Keys.Escape)
this
.Close();
//
Esc was pressed
}
/**/
///
<summary>
///
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();
}
}
}
}
}
1 定义 VertexBuffer vb = null;
2 创建 VertexBuffer
public void OnCreateDevice(object sender, EventArgs e)
{
Device dev = (Device)sender;
// Now create the vertex buffer
vertexBuffer = new VertexBuffer(
typeof(CustomVertex.TransformedColored), 3, dev, 0,
CustomVertex.TransformedColored.Format, Pool.Default);
vertexBuffer.Created +=
new System.EventHandler(this.OnCreateVertexBuffer);
this.OnCreateVertexBuffer(vb, null);
}
public void OnCreateVertexBuffer(object sender, EventArgs e)
{
VertexBuffer vb = (VertexBuffer)sender;
GraphicsStream stm = vb.Lock(0, 0, 0); //Lock() 保证cpu能够直接访问 VertexBuffer ,必须和unlock()一起使用
CustomVertex.TransformedColored[] verts =
new CustomVertex.TransformedColored[3];
.
.
.
vb.Unlock();
}
3
GraphicsStream对象直接访问vertexbuffer, 或者说把vertexbuffer的内容放到Graphicsstream中以合适的大小.
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);
4 render device
private void Render()
{
if (device == null)
return;
// Clear the back buffer to a blue color (ARGB = 000000ff)
device.Clear(ClearFlags.Target, System.Drawing.Color.Blue, 1.0f, 0);
// Begin the scene
device.BeginScene();
// New for Tutorial 2
device.SetStreamSource(0, vertexBuffer, 0); //设置stream源用vertexbuffer.
device.VertexFormat = CustomVertex.TransformedColored.Format; //设置render格式
device.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);
// End the scene
device.EndScene();
device.Present();
}
Read and Write VertexBuffer and IndexBuffer Data With GraphicsStreams
using System;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
public struct PositionNormalTexVertex
{
public Vector3 Position;
public Vector3 Normal;
public float Tu0, Tv0;
public static readonly VertexFormats FVF = VertexFormats.Position | VertexFormats.Texture1;
}
public class Example
{
public unsafe void GraphicsStreamReadWrite()
{
//Create a vertex buffer in the managed pool
VertexBuffer vb = new VertexBuffer(typeof(PositionNormalTexVertex), 100, device, Usage.None, PositionNormalTexVertex.FVF, Pool.Managed);
//First, fill an array of PositionNormalTexVertex elements with data.
PositionNormalTexVertex[] vertices = new PositionNormalTexVertex[50];
for(int i=0; i<50; i++)
{
//fill the vertices with some data
vertices[i].Position = new Vector3(3f,4f,5f);
}
//The size of the verticies are 32-bytes each (float3 (12) + float3 (12) + float(4) + float(4))
//To lock 50 verticies, the size of the lock would be 1600 (32 * 50)
GraphicsStream vbData = vb.Lock(0,1600, LockFlags.None);
//copy the vertex data into the vertex buffer
vbData.Write(vertices);
//Unlock the VB
vb.Unlock();
//This time, lock the entire VertexBuffer
vbData = vb.Lock(0, 3200, LockFlags.None);
//Cast the InternalDataPointer (a void pointer) to an array of verticies
PositionNormalTexVertex* vbArray = (PositionNormalTexVertex*) vbData.InternalDataPointer;
for(int i=0; i<100; i++)
{
//perform some operations on the data
vbArray[i].Tu0 = i;
vbArray[i].Tv0 = vbArray[i].Tu0 * 2;
Console.WriteLine(vbArray[i].Tv0.ToString());
}
//Unlock the buffer
vb.Unlock();
vb.Dispose();
}
} Read and Write VertexBuffer Data With Arrays
using System;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
public struct PositionNormalTexVertex
{
public Vector3 Position;
public Vector3 Normal;
public float Tu0, Tv0;
public static readonly VertexFormats FVF = VertexFormats.Position | VertexFormats.Texture1;
}
public class Example
{
public void ArrayBasedReadWrite()
{
//Create a vertex buffer in the managed pool
VertexBuffer vb = new VertexBuffer(typeof(PositionNormalTexVertex), 100, device, Usage.None, PositionNormalTex1Vertex.FVF, Pool.Managed);
//Fill an array of the appropriate type with the VB data using Lock()
PositionNormalTexVertex[] vbData = (PositionNormalTexVertex[]) vb.Lock(0, typeof(PositionNormalTexVertex), LockFlags.None, 50);
for(int i=0; i<50; i++)
{
//set your vertices to something
vbData[i].Position = new Vector3(2f,2f,2f);
vbData[i].Normal = new Vector3(1f,0f,0f);
vbData[i].Tu0 = i;
vbData[i].Tv0 = i;
}
//Unlock the vb before you can use it elsewhere
vb.Unlock();
//This lock overload simply locks the entire VB -- setting ReadOnly can improve perf when reading a vertexbuffer
vbData = (PositionNormalTexVertex[]) vb.Lock(0, LockFlags.ReadOnly);
for(int i=0; i<100; i++)
{
//read some vertex data
Console.WriteLine("Vertex " + i + "Tu: " + vbData[i].Tu0 + " , Tv: " + vbData[i].Tv0);
}
//Unlock the buffer
vb.Unlock();
vb.Dispose();
}
}