방법: 망상 조직 만들기

업데이트: 2007년 11월

다음 네 가지 기본 방법으로 망상 조직을 만들 수 있습니다.

  • 파일에서 망상 조직 데이터를 로드합니다.

  • 기존 망상 조직을 복제하거나 최적화합니다.

  • 모양 만들기 함수를 사용하고 모양을 만드는 데 사용할 삼각형의 크기와 개수를 지정합니다.

  • Mesh 생성자를 사용합니다.

참고:

관리되는 Direct3D 모바일 응용 프로그램을 사용하려면 Pocket PC 및 Smartphone용 Windows Mobile 버전 5.0 소프트웨어가 필요합니다. Windows Mobile 소프트웨어 및 SDK에 대한 내용은 .NET Compact Framework용 외부 리소스를 참조하십시오.

파일에서 망상 조직을 만들려면

  • 파일에서 망상 조직 데이터를 로드한 후 해당 데이터로 망상 조직을 채웁니다. .NET Compact Framework를 사용하여 파일에서 망상 조직을 직접 로드할 수는 없지만 Direct3D 모바일 망상 조직 샘플에는 망상 조직을 로드할 수 있는 클래스가 정의되어 있습니다.

기존 망상 조직에서 망상 조직을 만들려면

  • Optimize 메서드를 사용하여 최적화된 데이터로 망상 조직을 새로 만듭니다.

    - 또는 -

    OptimizeInPlace 메서드를 사용하여 현재 망상 조직을 최적화합니다.

    복제의 주된 용도는 망사 조직을 부동 소수점 형식에서 고정 소수점 형식으로 변환하는 것이고, 최적화의 주된 용도는 빠르게 그릴 수 있는 망상 조직을 만드는 것입니다. 망상 조직을 최적화하면 망상 조직에 대한 그리기 호출이 더 빠르게 수행되도록 망상 조직의 삼각형이 다시 정렬됩니다. 또한 망상 조직에서 다른 질감, 렌더링 상태 및 재료를 사용하여 그려야 하는 영역을 식별하는 데 사용되는 특성 테이블도 생성됩니다.

모양 만들기 함수를 사용하여 망상 조직을 만들려면

  • Mesh 클래스의 다음 정적 메서드 중 하나를 사용하여 부동 소수점 수식에 지정된 위치 및 법선으로 망상 조직을 만듭니다.

망상 조직 생성자를 사용하여 망상 조직을 만들려면

  1. 원하는 인수를 사용하여 Mesh 생성자를 호출합니다.

  2. 인덱스 버퍼, 꼭지점 버퍼 및 특성 테이블 데이터를 설정합니다. 이 경우의 데이터는 주로 런타임에 생성됩니다. 다음 예제에서는 이러한 방식으로 망상 조직을 만드는 단계를 보여 줍니다.

예제

다음 코드 예제에서는 z 좌표가 세로 크기를 나타내는 x-y 평면에 높이 필드 망상 조직을 만듭니다. 만들어진 특정 망상 조직은 (0, 0)에서 (1, 1)까지 이어지며 GetHeight 메서드로 지정된 높이를 갖습니다. 또한 이 망상 조직은 전체 망상 조직에서 단일 질감으로 표현됩니다. 예제에 정의된 tessellation 매개 변수는 망상 조직 가장자리에 사용되는 점의 수를 제어하는 데 사용됩니다.

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);
        }
    }
}

코드 컴파일

이 예제에는 다음과 같은 네임스페이스에 대한 참조가 필요합니다.

참고 항목

개념

.NET Compact Framework 방법 항목

기타 리소스

.NET Compact Framework의 모바일 Direct3D 프로그래밍