다음을 통해 공유


방법: 망상 조직 표시 및 선택

업데이트: 2007년 11월

장치에서 망상 조직을 눌러 선택할 때 색이 바뀌도록 망상 조직 배열을 만들어 표시할 수 있습니다.

참고:

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

이 코드 예제의 폼에는 다음 개체가 포함되어 있습니다.

  • 활성 망상 조직에 대한 Mesh 개체

  • 선택할 수 있는 다양한 색을 갖는 9개의 Mesh 개체 배열

  • 망상 조직 위치를 정의하는 Vector3 구조체

  • 경계 상자를 정의하는 2개의 Vector3 구조체

  • Device 개체

이 폼의 생성자는 장치의 PresentationParameters 속성 설정을 지정하고, Device 개체를 만들고, DeviceReset 이벤트에 OnDeviceReset 이벤트 처리기를 추가한 후 OnDeviceReset 메서드를 호출하여 망상 조직을 만들기 시작합니다. 다음 표에서는 망상 조직을 렌더링하고 사용자 상호 작용을 가능하게 하는 메서드에 대해 설명합니다.

메서드

작업

OnDeviceReset

망상 조직을 만들고 경계 상자의 특정 위치에 배치한 후 변형 매트릭스를 정의합니다.

OnPaint

장면을 시작하고 망상 조직을 그린 후 장면을 끝냅니다.

OnMouseDown

논리적 3D 공간을 통과하는 빛을 만든 후 상자와 빛을 교차시키는 기법을 사용하여 망상 조직을 선택하는 방법을 보여 줍니다.

이 빛은 3D 공간을 통과하여 스타일러스로 누르는 상태를 나타냅니다. 상자는 3D 개체 둘레의 경계 상자를 나타냅니다. 이러한 빛과 상자가 교차하면 3D 개체가 있는 위치를 클릭한 것입니다.

예제

다음 코드 예제에서는 완전한 폼을 제공합니다. 이 예제는 선택할 수 있는 다양한 색을 갖는 Mesh 개체를 표시합니다. 망상 조직을 선택하면 해당 색이 바뀝니다.

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

코드 컴파일

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

참고 항목

개념

.NET Compact Framework 방법 항목

기타 리소스

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