Gewusst wie: Erstellen eines Netzes
Aktualisiert: November 2007
Es gibt vier verschiedene einfache Möglichkeiten, ein Netz zu erstellen:
Durch Laden der Netzdaten aus einer Datei.
Durch Klonen oder Optimieren eines vorhandenen Netzes.
Durch Verwenden einer Formerstellungsfunktion und Angeben der Größe und der Anzahl von Dreiecken, die zum Erstellen der Form verwendet werden.
Durch Verwenden des Mesh-Konstruktors.
Hinweis: |
---|
Für verwaltete Direct3D Mobile-Anwendungen ist Windows Mobile, Version 5.0, für Pocket PCs und Smartphones erforderlich. Informationen über Windows Mobile-Software und SDKs finden Sie unter Externe Ressourcen für .NET Compact Framework. |
So erstellen Sie ein Netz aus einer Datei
- Laden Sie die Netzdaten aus einer Datei, und füllen Sie anschließend ein Netz mit den Daten. Das Laden eines Netzes aus einer Datei wird von .NET Compact Framework nicht direkt unterstützt, in dem Direct3D Mobile Meshes-Beispiel wird jedoch eine Klasse zum Laden eines Netzes definiert.
So erstellen Sie ein Netz aus einem vorhandenen Netz
Verwenden Sie die Optimize-Methode, um ein neues Netz mit optimierten Daten zu erstellen.
- oder -
Verwenden Sie die OptimizeInPlace-Methode, um das aktuelle Netz zu optimieren.
Klonen wird vor allem dazu verwendet, das Netz vom Gleitkomma- in das Festkommaformat zu konvertieren. Die Optimierung wird vor allem dazu verwendet, ein Netz zu erstellen, das sich schneller zeichnen lässt. Bei der Netzoptimierung werden die Dreiecke im Netz neu angeordnet, damit Zeichnungsaufrufe des Netzes schneller durchgeführt werden. Bei der Netzoptimierung wird auch eine Attributtabelle erzeugt, die verwendet wird, um Bereiche des Netzes zu identifizieren, die mit verschiedenen Texturen gezeichnet werden müssen, sowie um den Zustand und die Materialien zu rendern.
So erstellen Sie ein Netz unter Verwendung einer Formerstellungsfunktion
Verwenden Sie eine der folgenden statischen Methoden der Mesh-Klasse, um ein Netz zu erstellen, wobei Position und Normalen als Gleitkommawerte angegeben werden:
So erstellen Sie ein Netz mithilfe des Netzkonstruktors
Rufen Sie den Mesh-Konstruktor mit den gewünschten Argumenten auf.
Legen Sie den Indexpuffer, den Vertexpuffer und Attributtabellendaten fest. Die Daten werden in diesem Fall häufig zur Laufzeit generiert. Im folgenden Beispiel werden die Schritte dargestellt, mit denen auf diese Weise ein Netz erstellt wird.
Beispiel
Mit dem folgenden Codebeispiel wird auf der x-y-Ebene ein Höhenfeldnetz erstellt, wobei die z-Koordinate die vertikale Dimension darstellt. Das erstellte Netz erstreckt sich von (0/0) bis (1/1), und seine Höhe wird durch die GetHeight-Methode angegeben. Das gesamte Netz ist zudem mit einer einzigen Textur versehen. Mit dem durch das Beispiel definierten tessellation-Parameter wird gesteuert, wie viele Punkte entlang der Netzkante verwendet werden.
Class Form1
Private Sub New()
MyBase.New()
' In this example, initialize the mesh with
' 4 tessellations
Me.InitializeMesh(4)
End Sub
Private Sub InitializeMesh(ByVal tessellation As Integer)
Dim mesh1 As Mesh = CreateHeightfieldMesh(tessellation)
End Sub
Private Function GetHeight(ByVal x As Single, ByVal y As Single) As Single
Return 0
End Function
Private Function CreateHeightfieldMesh(ByVal tessellation As Integer) As Mesh
Dim mesh As Mesh
Dim device As Device = Nothing
Dim arrayIndices((tessellation - 1) * (tessellation - 1) * 6) As Short
Dim arrayVertices(tessellation * tessellation) As CustomVertex.PositionTextured
Dim attributeRange As New AttributeRange()
' Create mesh with desired vertex format and desired size.
mesh = New Mesh(arrayIndices.Length / 3, arrayVertices.Length, MeshFlags.SystemMemory, CustomVertex.PositionTextured.Format, device)
' For each point in the height field calculate the x, y, z and
' texture coordinates.
Dim y As Integer
For y = 0 To tessellation
Dim x As Integer
For x = 0 To tessellation
Dim arrayIndex As Integer = y * tessellation + x
Dim xCoordinate As Single = System.Convert.ToSingle(x) / System.Convert.ToSingle(tessellation - 1)
Dim yCoordinate As Single = System.Convert.ToSingle(y) / System.Convert.ToSingle(tessellation - 1)
Dim vertex As New CustomVertex.PositionTextured(xCoordinate, yCoordinate, GetHeight(xCoordinate, yCoordinate), xCoordinate, yCoordinate)
arrayVertices(arrayIndex) = vertex
Next x
Next y
' Calculate the index buffer.
Dim z As Integer
For z = 0 To (tessellation - 1)
Dim x As Integer
For x = 0 To (tessellation - 1)
Dim arrayIndex As Integer = (z * (tessellation - 1) + x) * 6
Dim vertexIndex As Integer = z * tessellation + x
arrayIndices(arrayIndex) = Fix(vertexIndex)
arrayIndices((arrayIndex + 1)) = Fix(vertexIndex + 1)
arrayIndices((arrayIndex + 2)) = Fix(vertexIndex + tessellation)
arrayIndices((arrayIndex + 3)) = Fix(vertexIndex + tessellation)
arrayIndices((arrayIndex + 4)) = Fix(vertexIndex + 1)
arrayIndices((arrayIndex + 5)) = Fix(vertexIndex + tessellation + 1)
Next x
Next z
' There is only one attribute value for this mesh.
' By specifying an attribute range the DrawSubset function
' does not have to scan the entire mesh for all faces that are
' are marked with a particular attribute ID.
attributeRange.AttributeId = 0
attributeRange.FaceStart = 0
attributeRange.FaceCount = arrayIndices.Length / 3
attributeRange.VertexStart = 0
attributeRange.VertexCount = arrayVertices.Length
mesh.VertexBuffer.SetData(arrayVertices, 0, LockFlags.None)
mesh.IndexBuffer.SetData(arrayIndices, 0, LockFlags.None)
mesh.SetAttributeTable(New AttributeRange() {attributeRange})
Return mesh
End Function
Public Shared Sub Main()
Try
Dim Form1 As New Form()
Application.Run(Form1)
Catch e As NotSupportedException
MsgBox("Your device does not have the " + _
"needed 3d support to run this sample")
Catch e As DriverUnsupportedException
MsgBox("Your device does not have the " + _
"needed 3d driver support to run this sample")
Catch e As Exception
MsgBox("The sample has run into an error and " + _
"needs to close: " + e.Message)
End Try
End Sub
End Class
class Form1
{
Form1()
{
// In this example, initialize the Mesh object
// with 4 tessellations
this.InitializeMesh(4);
}
private void InitializeMesh(int tessellation)
{
Mesh mesh1 = CreateHeightfieldMesh(tessellation);
}
private float GetHeight(float x, float y)
{
return 0;
//TODO: fill in this function
}
private Mesh CreateHeightfieldMesh(int tessellation)
{
Mesh mesh;
Device device = null; // TODO: initialize this
short[] arrayIndices = new short[(tessellation - 1) * (tessellation - 1) * 6];
CustomVertex.PositionTextured[] arrayVertices =
new CustomVertex.PositionTextured[tessellation * tessellation];
AttributeRange attributeRange = new AttributeRange();
// Create mesh with desired vertex format and desired size
mesh = new Mesh(arrayIndices.Length / 3, arrayVertices.Length, MeshFlags.SystemMemory,
CustomVertex.PositionTextured.Format, device);
// For each point in the height field calculate the x, y, z and
// texture coordinates.
for (int y = 0; y < tessellation; y++)
{
for (int x = 0; x < tessellation; x++)
{
int arrayIndex = y * tessellation + x;
float xCoordinate = (float)x / (float)(tessellation - 1);
float yCoordinate = (float)y / (float)(tessellation - 1);
CustomVertex.PositionTextured vertex = new CustomVertex.PositionTextured
(xCoordinate, yCoordinate, GetHeight(xCoordinate, yCoordinate), xCoordinate, yCoordinate);
arrayVertices[arrayIndex] = vertex;
}
}
// Calculate the index buffer.
for (int y = 0; y < (tessellation - 1); y++)
{
for (int x = 0; x < (tessellation - 1); x++)
{
int arrayIndex = (y * (tessellation - 1) + x) * 6;
int vertexIndex = y * tessellation + x;
arrayIndices[arrayIndex] = (short)vertexIndex;
arrayIndices[arrayIndex + 1] = (short)(vertexIndex + 1);
arrayIndices[arrayIndex + 2] = (short)(vertexIndex + tessellation);
arrayIndices[arrayIndex + 3] = (short)(vertexIndex + tessellation);
arrayIndices[arrayIndex + 4] = (short)(vertexIndex + 1);
arrayIndices[arrayIndex + 5] = (short)(vertexIndex + tessellation + 1);
}
}
// There is only one attribute value for this mesh.
// By specifying an attribute range the DrawSubset function
// does not have to scan the entire mesh for all faces that are
// are marked with a particular attribute id.
attributeRange.AttributeId = 0;
attributeRange.FaceStart = 0;
attributeRange.FaceCount = arrayIndices.Length / 3;
attributeRange.VertexStart = 0;
attributeRange.VertexCount = arrayVertices.Length;
mesh.VertexBuffer.SetData(arrayVertices, 0, LockFlags.None);
mesh.IndexBuffer.SetData(arrayIndices, 0, LockFlags.None);
mesh.SetAttributeTable(new AttributeRange[] { attributeRange });
return (mesh);
}
public static void Main()
{
try
{
Form Form1 = new Form();
Application.Run(Form1);
}
catch (NotSupportedException)
{
MessageBox.Show("Your device does not have the needed 3d " +
"support to run this sample");
}
catch (DriverUnsupportedException)
{
MessageBox.Show("Your device does not have the needed 3d " +
"driver support to run this sample");
}
catch (Exception e)
{
MessageBox.Show("The sample has run into an error and " +
"needs to close: " + e.Message);
}
}
}
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