Comment : créer un maillage
Mise à jour : novembre 2007
Il existe quatre façons principales de créer un maillage :
en chargeant les données de maillage à partir d'un fichier ;
en clonant ou en optimisant un maillage existant ;
en utilisant une fonction de création de formes et en spécifiant la taille et le nombre de triangles qui seront utilisés pour créer la forme ;
en utilisant le constructeur Mesh.
Remarque : |
---|
Les applications Direct3D mobiles managées requièrent le logiciel Windows Mobile version 5.0 pour les appareils de type Pocket PC et Smartphone. Consultez Ressources externes pour le .NET Compact Framework pour plus d'informations sur le logiciel Windows Mobile et les Kits de développement logiciel. |
Pour créer un maillage à partir d'un fichier
- Chargez les données de maillage à partir d'un fichier, puis remplissez un maillage avec les données. Le .NET Compact Framework ne prend pas directement en charge le chargement d'un maillage à partir d'un fichier, mais l'exemple Direct3D Mobile Meshes définit une classe pour charger un maillage.
Pour créer un maillage à partir d'un maillage existant
Utilisez la méthode Optimize pour créer un nouveau maillage avec les données optimisées.
- ou -
Utilisez la méthode OptimizeInPlace pour optimiser le maillage actuel.
Le clonage consiste à convertir le maillage de format à virgule flottante au format à virgule fixe. L'optimisation consiste à créer un maillage plus rapide à dessiner. L'optimisation du maillage réorganise les triangles afin de dessiner les appels plus rapidement sur le maillage. L'optimisation du maillage génère également une table d'attributs utilisée pour identifier les zones du maillage devant être dessinées avec des textures, des états de rendus et des matières différents.
Pour créer un maillage en utilisant une fonction de création de formes
Utilisez l'une des méthodes statiques suivantes de la classe Mesh pour créer un maillage avec une position et des normales spécifiées dans une opération mathématique à virgule flottante :
Pour créer un maillage en utilisant le constructeur de maillage
Appelez le constructeur Mesh avec les arguments voulus.
Définissez le tampon d'index, la mémoire tampon de vertex et les données de la table des attributs. Dans ce cas, les données sont souvent générées pendant l'exécution. L'exemple suivant affiche les étapes pour créer un maillage de cette manière.
Exemple
L'exemple de code suivant crée un maillage de champ hauteur sur le plan x-y avec la coordonnée z représentant la dimension verticale. Le maillage particulier créé est exécuté de (0, 0) à (1, 1) et a une hauteur spécifiée par la méthode GetHeight. L'intégralité du maillage possède par ailleurs une seule texture. Le paramètre tessellation, défini par l'exemple, est utilisé pour contrôler le nombre de points utilisés le long du bord du maillage.
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);
}
}
}
Compilation du code
Cet exemple nécessite des références aux espaces de noms suivants :
Voir aussi
Concepts
.Rubriques Comment relatives au .NET Compact Framework
Autres ressources
Programmation Direct3D Mobile dans le .NET Compact Framework