Gewusst wie: Anzeigen und Auswählen von Netzen
Aktualisiert: November 2007
Sie können ein Array von Netzen erstellen und so anzeigen, dass ein Netz seine Farbe ändert, wenn es auf dem Gerät ausgewählt (angetippt) wird.
Hinweis: |
---|
Für verwaltete Direct3D Mobile-Anwendungen ist Windows Mobile, Version 5.0, für Pocket PCs und Smartphones erforderlich. Weitere Informationen über Windows Mobile-Software und SDKs finden Sie unter Externe Ressourcen für .NET Compact Framework. |
Das Formular in diesem Codebeispiel verfügt über die folgenden Objekte:
Ein Mesh-Objekt für das aktive Netz.
Ein Array von neun verschiedenfarbigen Mesh-Objekten, die ausgewählt werden können.
Eine Vector3-Struktur, die die Netzspeicherorte definiert.
Zwei Vector3-Strukturen, die das umgebende Feld definieren.
Ein Device-Objekt.
Im Konstruktor des Formulars werden Einstellungen für die PresentationParameters-Eigenschaft des Geräts festgelegt, es wird das Device-Objekt erstellt, dem DeviceReset-Ereignis des Objekts der OnDeviceReset-Ereignishandler hinzugefügt und dann die OnDeviceReset-Methode aufgerufen. Anschließend wird mit der Erstellung der Netze begonnen. In der folgenden Tabelle werden die Methoden beschrieben, mit denen die Netze dargestellt und die Benutzerinteraktion ermöglicht wird.
Methode |
Aktionen |
---|---|
OnDeviceReset |
Erstellt die Netze, fügt sie an gegebenen Positionen im umgebenden Feld ein und definiert die Transformationsmatrizen. |
OnPaint |
Beginnt die Szene, zeichnet die Netze und beendet die Szene. |
OnMouseDown |
Veranschaulicht die Auswahl eines Netzes mithilfe einer Technik, die einen Strahl im logischen 3D-Raum erzeugt und darstellt, wie dieser Strahl ein Feld kreuzt. Der Strahl stellt dar, wie der Schreibstift durch den 3D-Raum gedrückt wird. Das Feld stellt einen umgebenden Quader des 3D-Objekts dar. Wenn sich die beiden schneiden, hat der Benutzer auf eine Stelle geklickt, die im 3D-Objekt enthalten ist. |
Beispiel
Das folgende Codebeispiel stellt ein vollständiges Formular bereit. Es zeigt verschiedenfarbige Mesh-Objekte an, die ausgewählt werden können. Wenn ein Netz ausgewählt wird, ändert sich seine Farbe.
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());
}
}
}
Kompilieren des Codes
Für dieses Beispiel sind Verweise auf die folgenden Namespaces erforderlich:
Siehe auch
Konzepte
Gewusst-wie-Themen für .NET Compact Framework