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

  1. Appelez le constructeur Mesh avec les arguments voulus.

  2. 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