【问题标题】:Managed DirectX Camera Issue托管 DirectX 相机问题
【发布时间】:2010-08-27 01:20:54
【问题描述】:

我对 DirectX 库有点陌生,我想知道是否有人可以帮助我解决相机问题。在我的主表单中,我加载了一组表示 3D 对象的多边形数据,然后将该多边形数据传递给另一个表单,并希望将多边形绘制为三角形列表。不幸的是,我似乎无法让相机达到 1)具有正确的视锥或 2)让相机正确聚焦和调整图像大小。多边形数据正在作为世界坐标数据加载。

下面是初始化二级窗体、directx、camera等的代码

#region Public Members

    /// <summary>
    /// Default Constructor.
    /// </summary>
    public STLViewer()
    {
        // Set the form size, form text, icon
        this.ClientSize = new Size(500, 500);
        this.Text = "Object Name: " + stlFile.SolidName + ", Polygon Count: " + stlFile.GetPolygons().Count;
        this.Icon = RetrieveFormIcon();

        // Change our drawing style so there is no drawing happening outside our main form
        this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);

        // Get our vertex data in a prepared format
        verts = PrepareObjectForRender();
    }

    /// <summary>
    /// This function is responsible for retrieving the specified
    /// icon from the assembly.
    /// </summary>
    /// <returns>Form icon</returns>
    private Icon RetrieveFormIcon()
    {
        Assembly assembly = Assembly.GetExecutingAssembly();
        Stream str = assembly.GetManifestResourceStream(icon);

        return new Icon(str);
    }

    #endregion

    #region Main Line

    public static void Main()
    {
        // Create our form object
        STLViewer stlViewer = new STLViewer();

        // Initialize D3D
        if (stlViewer.InitializeDirect3D() == false)
        {
            MessageBox.Show("Could not initialize Direct3D.", "Error");
            return;
        }

        // Display our form
        stlViewer.Show();

        // Main message loop
        while (stlViewer.Created)
        {
            // Keep rendering the image until the form is terminated
            //stlViewer.Render();

            // Handle aall events here: keyboard, mouse, etc.
            Application.DoEvents();
        }
    }

    #endregion

    #region Rendering

    protected override void OnPaint(PaintEventArgs e)
    {
        if (directXDevice.RenderState.FillMode == FillMode.Solid)
        {
            directXDevice.RenderState.FillMode = FillMode.WireFrame;
        }

        // Clear the window to black
        directXDevice.Clear(ClearFlags.Target, Color.Black, 1.0f, 0);

        // Setup the camera for viewing
        SetupCamera();

        // Begin the rendering process
        directXDevice.BeginScene();

        // Set the vertext format
        directXDevice.VertexFormat = CustomVertex.PositionColored.Format;

        // Draw our vertices
        directXDevice.DrawUserPrimitives(PrimitiveType.TriangleList, stlFile.GetPolygons().Count, verts);

        // End rendering and present the drawing to the screen
        directXDevice.EndScene();
        directXDevice.Present();

        // Force our form to refresh its viewing area
        this.Invalidate();
    }

    /// <summary>
    /// This function is responsible for rendering the image
    /// to the screen.
    /// </summary>
    private void Render()
    {
        // IF we cannot connect to a device then return
        if (directXDevice == null)
        {
            return;
        }

        // Get our vertex data in a prepared format
        CustomVertex.PositionColored[] verts = PrepareObjectForRender();

        // Clear the window to black
        directXDevice.Clear(ClearFlags.Target, Color.Black, 1.0f, 0);

        // Setup the camera for viewing
        SetupCamera();

        // Begin the rendering process
        directXDevice.BeginScene();

        // Set the vertext format
        directXDevice.VertexFormat = CustomVertex.PositionColored.Format;

        // Draw our vertices
        directXDevice.DrawUserPrimitives(PrimitiveType.TriangleList, stlFile.GetPolygons().Count, verts);

        // End rendering and present the drawing to the screen
        directXDevice.EndScene();
        directXDevice.Present();
    }

    /// <summary>
    /// This function is responsible for creating the necessary
    /// DirectX objects, setting the vertices and normals, colors
    /// and/or materials for the object so we can draw it in the
    /// form.
    /// </summary>
    private CustomVertex.PositionColored[] PrepareObjectForRender()
    {
        // List to hold our colored vertices
        List<CustomVertex.PositionColored> vertices = new List<CustomVertex.PositionColored>();

        // List to hold our polygons, contained within the STL file
        List<Polygon.Polygon> polygons = stlFile.GetPolygons();

        // Create a custom vertex that will be used to hold our vertices
        CustomVertex.PositionColored custVert = new CustomVertex.PositionColored();

        // Iterate through our polygons and pulled a vertex list
        for (int i = 0; i < polygons.Count; i++)
        {
            // Set the position and color of our 1st vertex in our polygon, add it to our list
            custVert.Position = new Vector3((float)polygons[i].GetDoublePoints1()[0],
                (float)polygons[i].GetDoublePoints1()[1], (float)polygons[i].GetDoublePoints1()[2]);
            custVert.Color = Color.YellowGreen.ToArgb();
            vertices.Add(custVert);

            // Set the position and color of our 2nd vertex in our polygon, add it to our list
            custVert.Position = new Vector3((float)polygons[i].GetDoublePoints2()[0],
                (float)polygons[i].GetDoublePoints2()[1], (float)polygons[i].GetDoublePoints2()[2]);
            custVert.Color = Color.YellowGreen.ToArgb();
            vertices.Add(custVert);

            // Set the position and color of our 3rd vertex in our polygon, add it to our list
            custVert.Position = new Vector3((float)polygons[i].GetDoublePoints3()[0],
                (float)polygons[i].GetDoublePoints3()[1], (float)polygons[i].GetDoublePoints3()[2]);
            custVert.Color = Color.YellowGreen.ToArgb();
            vertices.Add(custVert);
        }

        // Cast our list to an array of vertices
        CustomVertex.PositionColored[] verts = vertices.ToArray();

        return verts;
    }

    #endregion

    #region Initialization & Configuration

    private bool InitializeDirect3D()
    {
        bool retVal = false;

        try
        {
            // Create a new PresentParameters object so our device knows how to display
            PresentParameters pps = new PresentParameters();

            // Display in a windowed mode
            pps.Windowed = true;

            // After the current screen is draw, discard it from memory
            pps.SwapEffect = SwapEffect.Discard;

            // Create the new D3D Device and set our PresentParameters within
            directXDevice = new Device(0, DeviceType.Hardware, this, 
                CreateFlags.SoftwareVertexProcessing, pps);

            // Use wireframe as our drawing mode
            directXDevice.RenderState.FillMode = FillMode.WireFrame;

            retVal = true;
        }
        catch (DirectXException e)
        {
            // Display our error message
            MessageBox.Show(e.ToString(), "Error");

            retVal = false;
        }

        return retVal;
    }

    private void SetupCamera()
    {
        directXDevice.Transform.Projection = Matrix.PerspectiveFovLH(1.85f,
(float)(this.Width / this.Height), 1.0f, 1.00f);

        directXDevice.Transform.View = Matrix.LookAtLH(new Vector3(0.0f, 0.0f, 5.0f),
            new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f));

        directXDevice.RenderState.Lighting = false;
    }

    #endregion

【问题讨论】:

    标签: c# directx managed-directx


    【解决方案1】:

    有几件小事不妥,在醉鹬找到了一个我忘记的教程,帮助我完成了剩下的工作。

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows.Forms;
    using System.Drawing;
    using System.IO;
    using System.Reflection;
    using Polygon;
    using STL;
    using Microsoft.DirectX;
    using Microsoft.DirectX.Direct3D;
    
    namespace STLView
    {
        public class STLViewer : Form
        {
            #region Private Members
    
            #region DirectX Objects
    
            /// <summary>
            /// DirectX Device object that will allow us to perform drawing
            /// </summary>
            private Device directXDevice = null;
    
            /// <summary>
            /// Array of vertices that will hold our Polygon vertices
            /// </summary>
            private static CustomVertex.PositionColored[] verts;
    
            #endregion
    
            #region STL Viewer Specific Objects
    
            /// <summary>
            /// String to hold the name of the path in the assembly for our form icon
            /// </summary>
            private static string icon = "STLView.Resources.Symbol17.ico";
    
            /// <summary>
            /// STLFile object that will be used to draw the object
            /// </summary>
            public static STLFile stlFile;
    
            #endregion
    
            #endregion
    
            #region Public Members
    
            /// <summary>
            /// Default Constructor.
            /// </summary>
            public STLViewer()
            {
                // Set the form size, form text, icon
                this.ClientSize = new Size(800, 600);
                this.Text = "Object Name: " + stlFile.SolidName + ", Polygon Count: " + stlFile.GetPolygons().Count;
                this.Icon = RetrieveFormIcon();
    
                // Change our drawing style so there is no drawing happening outside our main form
                this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
    
                // Get our vertex data in a prepared format
                verts = PrepareObjectForRender();
            }
    
            /// <summary>
            /// This function is responsible for retrieving the specified
            /// icon from the assembly.
            /// </summary>
            /// <returns>Form icon</returns>
            private Icon RetrieveFormIcon()
            {
                Assembly assembly = Assembly.GetExecutingAssembly();
                Stream str = assembly.GetManifestResourceStream(icon);
    
                return new Icon(str);
            }
    
            #endregion
    
            #region Main Line
    
            public static void Main()
            {
                // Create our form object
                STLViewer stlViewer = new STLViewer();
    
                // Initialize D3D
                if (stlViewer.InitializeDirect3D() == false)
                {
                    MessageBox.Show("Could not initialize Direct3D.", "Error");
                    return;
                }
    
                // Display our form
                stlViewer.Show();
    
                // Main message loop
                while (stlViewer.Created)
                {
                    // Handle aall events here: keyboard, mouse, etc.
                    Application.DoEvents();
                }
            }
    
            #endregion
    
            #region Rendering
    
            /// <summary>
            /// This function is the overloaded OnPaint method, which is responsible
            /// for drawing our scene.
            /// </summary>
            /// <param name="e"></param>
            protected override void OnPaint(PaintEventArgs e)
            {
                // IF we have a forced switch to Solid mode switch to Wireframe
                if (directXDevice.RenderState.FillMode == FillMode.Solid)
                {
                    directXDevice.RenderState.FillMode = FillMode.WireFrame;
                }
    
                // Clear the window to black
                directXDevice.Clear(ClearFlags.Target, Color.Navy, 1.0f, 0);
    
                // Disable culling
                directXDevice.RenderState.CullMode = Cull.None;
    
                // Setup the camera for viewing
                SetupCamera();
    
                // Begin the rendering process
                directXDevice.BeginScene();
    
                // Set the vertext format
                directXDevice.VertexFormat = CustomVertex.PositionColored.Format;
    
                // Draw our vertices
                directXDevice.DrawUserPrimitives(PrimitiveType.TriangleList, stlFile.GetPolygons().Count, verts);
    
                // End rendering and present the drawing to the screen
                directXDevice.EndScene();
                directXDevice.Present();
    
                // Force our form to refresh its viewing area
                this.Invalidate();
            }
    
            /// <summary>
            /// This function is responsible for creating the necessary
            /// DirectX objects, setting the vertices and normals, colors
            /// and/or materials for the object so we can draw it in the
            /// form.
            /// </summary>
            private CustomVertex.PositionColored[] PrepareObjectForRender()
            {
                // List to hold our colored vertices
                List<CustomVertex.PositionColored> vertices = new List<CustomVertex.PositionColored>();
    
                // List to hold our polygons, contained within the STL file
                List<Polygon.Polygon> polygons = stlFile.GetPolygons();
    
                // Create a custom vertex that will be used to hold our vertices
                CustomVertex.PositionColored custVert = new CustomVertex.PositionColored();
    
                // Iterate through our polygons and pulled a vertex list
                for (int i = 0; i < polygons.Count; i++)
                {
                    // Set the position and color of our 1st vertex in our polygon, add it to our list
                    custVert.Position = new Vector3((float)polygons[i].GetDoublePoints1()[0],
                        (float)polygons[i].GetDoublePoints1()[1], (float)polygons[i].GetDoublePoints1()[2]);
                    custVert.Color = Color.YellowGreen.ToArgb();
                    vertices.Add(custVert);
    
                    // Set the position and color of our 2nd vertex in our polygon, add it to our list
                    custVert.Position = new Vector3((float)polygons[i].GetDoublePoints2()[0],
                        (float)polygons[i].GetDoublePoints2()[1], (float)polygons[i].GetDoublePoints2()[2]);
                    custVert.Color = Color.YellowGreen.ToArgb();
                    vertices.Add(custVert);
    
                    // Set the position and color of our 3rd vertex in our polygon, add it to our list
                    custVert.Position = new Vector3((float)polygons[i].GetDoublePoints3()[0],
                        (float)polygons[i].GetDoublePoints3()[1], (float)polygons[i].GetDoublePoints3()[2]);
                    custVert.Color = Color.YellowGreen.ToArgb();
                    vertices.Add(custVert);
                }
    
                // Cast our list to an array of vertices
                CustomVertex.PositionColored[] verts = vertices.ToArray();
    
                return verts;
            }
    
            #endregion
    
            #region Initialization & Configuration
    
            /// <summary>
            /// This function is responsible for initializing our Direct3D device.
            /// </summary>
            /// <returns>TRUE if successful, FALSE if not</returns>
            private bool InitializeDirect3D()
            {
                bool retVal = false;
    
                // TRY to create our Direct3D device
                // CATCH and report any errors
                try
                {
                    #region Present Parameters
    
                    // Create a new PresentParameters object so our device knows how to display
                    PresentParameters pps = new PresentParameters();
    
                    // Display in a windowed mode
                    pps.Windowed = true;
    
                    // After the current screen is draw, discard it from memory
                    pps.SwapEffect = SwapEffect.Discard;
    
                    // No Z (Depth) buffer or Stencil buffer
                    pps.EnableAutoDepthStencil = false;
    
                    // 1 Back buffer for double-buffering
                    pps.BackBufferCount = 1;
    
                    // Set our back buffer dimensions and format
                    pps.BackBufferHeight = 0;
                    pps.BackBufferWidth = 0;
                    pps.BackBufferFormat = Format.Unknown;
    
                    #endregion
    
                    // Create the new D3D Device and set our PresentParameters within
                    directXDevice = new Device(0, DeviceType.Hardware, this,
                        CreateFlags.SoftwareVertexProcessing, pps);
    
                    // Use wireframe as our drawing mode
                    directXDevice.RenderState.FillMode = FillMode.WireFrame;
    
                    retVal = true;
                }
                catch (DirectXException e)
                {
                    // Display our error message
                    MessageBox.Show(e.ToString(), "Error");
                }
    
                return retVal;
            }
    
            #endregion
    
            #region Camera
    
            /// <summary>
            /// This function is responsible for setting up the camera.
            /// </summary>
            private void SetupCamera()
            {
                #region View Matrix
    
                // This is the camera location and is commonly referred to as the "eye point"
                Vector3 eyeVector = new Vector3(0.0f, 0.0f, -500.0f);
    
                // The Look At Vector defines the point that the camera is aimed at
                Vector3 lookAtVector = new Vector3(0, 0, 0);
    
                // The "up" direction is the positive direction on the y-axis
                Vector3 upVector = new Vector3(0, 1, 0);
    
                // Register our View Matrix so it can be used to place and aim our camera
                directXDevice.Transform.View = Matrix.LookAtLH(eyeVector,
                    lookAtVector, upVector);
    
                #endregion
    
                #region Projection Matrix
    
                //45 degree field of view
                float fieldOfView = (float)Math.PI / 4.0f;
    
                //Typical aspect ratio is approximately 1.333...
                float aspectRatio = (float)ClientSize.Width / ClientSize.Height;
    
                // Register our Projection Matrix so it can be used for viewing items in
                // front of the camera
                directXDevice.Transform.Projection = Matrix.PerspectiveFovLH(fieldOfView,
                    aspectRatio, 1.0f, 1000.0f);
    
                #endregion
    
                #region World Matrix
    
                // Create a scaling matrix
                Matrix scaleMatrix = Matrix.Scaling(0.5f, 0.5f, 0.5f);
    
                // World Matrix = Scaling Matrix
                directXDevice.Transform.World = scaleMatrix;
    
                #endregion
    
                #region Lighting
    
                // Enable/Disable lighting
                directXDevice.RenderState.Lighting = false;
    
                #endregion
            }
    
            #endregion
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-22
      • 1970-01-01
      • 2010-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-20
      相关资源
      最近更新 更多