HOW TO:顯示和選取網狀結構
更新:2007 年 11 月
您可以建立和顯示網狀結構的陣列,如此在裝置上選取 (點選) 網狀結構時,它就會變更色彩。
注意事項: |
---|
Managed Direct3D Mobile 應用程式需要適用於 Pocket PC 和 Smartphone 的 Windows Mobile 5.0 版軟體。如需 Windows Mobile 軟體和 SDK 的詳細資訊,請參閱 .NET Compact Framework 的外部資源。 |
此程式碼範例的表單具有下列物件:
表單的建構函式會指定裝置 PresentationParameters 屬性的設定、建立 Device 物件、將 OnDeviceReset 事件處理常式加入裝置的 DeviceReset 事件,然後呼叫 OnDeviceReset 方法,開始建立網狀結構。下表說明呈現網狀結構和啟用使用者互動的方法。
方法 |
動作 |
---|---|
OnDeviceReset |
建立網狀結構、將這些網狀結構放在週框方塊中的位置,並定義轉換矩陣。 |
OnPaint |
開始場景、繪製網狀結構,並結束場景。 |
OnMouseDown |
使用建立穿過邏輯 3D 空間的光線,並執行方塊與光線交集的技巧,來示範網狀結構的選取。 光線代表按著尖筆穿過 3D 空間。方塊代表圍繞 3D 物件的週框方塊。如果兩者產生交集,就表示使用者已經在含有 3D 物件的位置按了一下。 |
範例
下列程式碼範例會提供完整的表單。這份表單會顯示可選取之不同色彩的 Mesh 物件。在選取網狀結構時,其色彩就會變更。
Imports System
Imports System.Drawing
Imports System.Windows.Forms
Imports Microsoft.WindowsMobile.DirectX
Imports Microsoft.WindowsMobile.DirectX.Direct3D
Imports Microsoft.VisualBasic
Class MeshPickingHowto
Inherits Form
Private Const numberOfMeshes As Integer = 9
Private meshes() As Mesh
Private meshColors() As Color = {Color.Green, Color.Orange, Color.Purple, Color.Pink, Color.Violet, Color.Blue, Color.Yellow, Color.Brown, Color.Aquamarine}
Private meshLocations() As Vector3
Private meshBoundingBoxMinValues() As Vector3
Private meshBoundingBoxMaxValues() As Vector3
Private activeMesh As Mesh
Private device As Device
Public Sub New()
Dim present As PresentParameters
Me.Text = "Mesh Picking"
' Enable the form to be closed.
' This is required so that Hwnd of the form changes.
Me.MinimizeBox = False
present = New PresentParameters()
present.Windowed = True
present.AutoDepthStencilFormat = DepthFormat.D16
present.EnableAutoDepthStencil = True
present.SwapEffect = SwapEffect.Discard
device = New Device(0, DeviceType.Default, Me, CreateFlags.None, present)
AddHandler device.DeviceReset, AddressOf OnDeviceReset
OnDeviceReset(Nothing, EventArgs.Empty)
End Sub
Private Sub OnDeviceReset(ByVal sender As Object, ByVal e As EventArgs)
' Meshes must be recreated whenever the device
' is reset, no matter which pool they are created in.
meshes = New Mesh(numberOfMeshes) {}
meshLocations = New Vector3(numberOfMeshes) {}
meshBoundingBoxMinValues = New Vector3(numberOfMeshes) {}
meshBoundingBoxMaxValues = New Vector3(numberOfMeshes) {}
activeMesh = Nothing
' Create several meshes and associated data.
Dim i As Integer
For i = 0 To numberOfMeshes
Dim vertexData As GraphicsStream
meshes(i) = Mesh.Box(device, 1F, 1F, 1F)
' Arrange the boxes in a grid, with each
' successive box farther in the distance.
meshLocations(i) = New Vector3((i Mod 3) * 2 - 2, i / 3 * 2 - 2, i)
' Compute the bounding box for a mesh.
Dim description As VertexBufferDescription = meshes(i).VertexBuffer.Description
vertexData = meshes(i).VertexBuffer.Lock(0, 0, LockFlags.ReadOnly)
Geometry.ComputeBoundingBox(vertexData, meshes(i).NumberVertices, description.VertexFormat, meshBoundingBoxMinValues(i), meshBoundingBoxMaxValues(i))
meshes(i).VertexBuffer.Unlock()
Next i
' Set the transformation matrices.
device.Transform.Projection = Matrix.PerspectiveFovRH(System.Convert.ToSingle(Math.PI) / 4F, System.Convert.ToSingle(Me.ClientSize.Width) / System.Convert.ToSingle(Me.ClientSize.Height), 0.001F, 40)
device.Transform.View = Matrix.LookAtRH(New Vector3(0, 2, - 7), New Vector3(0, 0, 0), New Vector3(0, 1, 0))
device.RenderState.Ambient = Color.White
End Sub
Protected Overrides Sub OnPaintBackground(ByVal e As PaintEventArgs)
' Do nothing.
End Sub
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
Dim material As New Material()
' Begin the scene and clear the back buffer to black.
device.BeginScene()
device.Clear(ClearFlags.Target Or ClearFlags.ZBuffer, Color.Black, 1F, 0)
' Draw each mesh to the screen.
' The active mesh is drawn in red.
Dim i As Integer
For i = 0 To numberOfMeshes
If activeMesh Is meshes(i) Then
material.Ambient = Color.Red
Else
material.Ambient = meshColors(i)
End If
device.Transform.World = Matrix.Translation(meshLocations(i))
device.Material = material
meshes(i).DrawSubset(0)
Next i
' Finish the scene and present it on the screen.
device.EndScene()
device.Present()
End Sub
' This method demonstrates picking.
Protected Overrides Sub OnMouseDown(ByVal e As MouseEventArgs)
' The technique used here is to create a ray through the entire
' logical 3-D space, and then perform an intersection test
' for the bounding box and ray.
Dim i As Integer
For i = 0 To numberOfMeshes
Dim nearVector As New Vector3(e.X, e.Y, 0)
Dim farVector As New Vector3(e.X, e.Y, 1)
' Create ray.
nearVector.Unproject(device.Viewport, device.Transform.Projection, device.Transform.View, Matrix.Translation(meshLocations(i)))
farVector.Unproject(device.Viewport, device.Transform.Projection, device.Transform.View, Matrix.Translation(meshLocations(i)))
farVector.Subtract(nearVector)
' Perform intersection test for the bounding box and ray.
If Geometry.BoxBoundProbe(meshBoundingBoxMinValues(i), meshBoundingBoxMaxValues(i), nearVector, farVector) Then
' Perform operation on detection of click on mesh object.
' In this case, you designate the mesh as the active
' mesh and invalidate the window so that it is redrawn.
activeMesh = meshes(i)
Me.Invalidate()
Exit For
End If
Next i
End Sub
Shared Sub Main()
Application.Run(New MeshPickingHowto())
End Sub
End Class
using System;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.WindowsMobile.DirectX;
using Microsoft.WindowsMobile.DirectX.Direct3D;
namespace MeshPick
{
class MeshPickingHowto : Form
{
const int numberOfMeshes = 9;
Mesh [] meshes;
Color [] meshColors = new Color [] { Color.Green, Color.Orange,
Color.Purple, Color.Pink, Color.Violet, Color.Blue, Color.Yellow,
Color.Brown, Color.Aquamarine };
Vector3 [] meshLocations;
Vector3 [] meshBoundingBoxMinValues;
Vector3 [] meshBoundingBoxMaxValues;
Mesh activeMesh;
Device device;
public MeshPickingHowto()
{
PresentParameters present;
this.Text = "Mesh Picking";
// Enable the form to be closed.
// This is required so that Hwnd of the form changes.
this.MinimizeBox = false;
present = new PresentParameters();
present.Windowed = true;
present.AutoDepthStencilFormat = DepthFormat.D16;
present.EnableAutoDepthStencil = true;
present.SwapEffect = SwapEffect.Discard;
device = new Device(0, DeviceType.Default, this,
CreateFlags.None, present);
device.DeviceReset += new EventHandler(OnDeviceReset);
OnDeviceReset(null, EventArgs.Empty);
}
private void OnDeviceReset(object sender, EventArgs e)
{
// Meshes must be recreated whenever the device
// is reset, no matter which pool they are created in.
meshes = new Mesh[numberOfMeshes];
meshLocations = new Vector3[numberOfMeshes];
meshBoundingBoxMinValues = new Vector3[numberOfMeshes];
meshBoundingBoxMaxValues = new Vector3[numberOfMeshes];
activeMesh = null;
// Create several meshes and associated data.
for (int i = 0; i < numberOfMeshes; i++)
{
GraphicsStream vertexData;
meshes[i] = Mesh.Box(device, 1.0f, 1.0f, 1.0f);
// Arrange the boxes in a grid, with each
// successive box farther in the distance.
meshLocations[i] = new Vector3(((i % 3) * 2) - 2,
((i / 3) * 2) - 2, i);
// Compute the bounding box for a mesh.
VertexBufferDescription description =
meshes[i].VertexBuffer.Description;
vertexData = meshes[i].VertexBuffer.Lock
(0, 0, LockFlags.ReadOnly);
Geometry.ComputeBoundingBox(vertexData,
meshes[i].NumberVertices,description.VertexFormat,
out meshBoundingBoxMinValues[i],
out meshBoundingBoxMaxValues[i]);
meshes[i].VertexBuffer.Unlock();
}
// Set the transformation matrices.
device.Transform.Projection = Matrix.PerspectiveFovRH(
(float)Math.PI/4.0F,
(float)this.ClientSize.Width / (float)this.ClientSize.Height,
0.001f, 40);
device.Transform.View = Matrix.LookAtRH(new Vector3(0, 2, -7),
new Vector3(0, 0, 0), new Vector3(0, 1, 0));
device.RenderState.Ambient = Color.White;
}
protected override void OnPaintBackground(PaintEventArgs e)
{
// Do nothing.
}
protected override void OnPaint(PaintEventArgs e)
{
Material material = new Material();
// Begin the scene and clear the back buffer to black.
device.BeginScene();
device.Clear(ClearFlags.Target | ClearFlags.ZBuffer,
Color.Black, 1.0f, 0);
// Draw each mesh to the screen.
// The active mesh is drawn in red.
for (int i = 0; i < numberOfMeshes; i++)
{
if (activeMesh == meshes[i])
material.Ambient = Color.Red;
else
material.Ambient = meshColors[i];
device.Transform.World = Matrix.Translation(meshLocations[i]);
device.Material = material;
meshes[i].DrawSubset(0);
}
// Finish the scene and present it on the screen.
device.EndScene();
device.Present();
}
// This method demonstrates picking.
protected override void OnMouseDown(MouseEventArgs e)
{
// The technique used here is to create a ray through the entire
// logical 3-D space, and then perform an intersection test
// for the bounding box and ray.
for (int i = 0; i < numberOfMeshes; i++)
{
Vector3 nearVector = new Vector3(e.X, e.Y, 0);
Vector3 farVector = new Vector3(e.X, e.Y, 1);
// Create ray.
nearVector.Unproject(device.Viewport,
device.Transform.Projection,
device.Transform.View,
Matrix.Translation(meshLocations[i]));
farVector.Unproject(device.Viewport,
device.Transform.Projection,
device.Transform.View,
Matrix.Translation(meshLocations[i]));
farVector.Subtract(nearVector);
// Perform intersection test for the bounding box and ray.
if (Geometry.BoxBoundProbe(meshBoundingBoxMinValues[i],
meshBoundingBoxMaxValues[i], nearVector, farVector))
{
// Perform operation on detection of click on mesh object.
// In this case, you designate the mesh as the active
// mesh and invalidate the window so that it is redrawn.
activeMesh = meshes[i];
this.Invalidate();
break;
}
}
}
static void Main()
{
Application.Run(new MeshPickingHowto());
}
}
}
編譯程式碼
這個範例需要下列命名空間的參考:
請參閱
概念
.NET Compact Framework HOW TO 主題