• Directx3d绘制包围体并控制光照效果


    directx下载地址:https://download.microsoft.com/download/A/E/7/AE743F1F-632B-4809-87A9-AA1BB3458E31/DXSDK_Jun10.exe

    安装出现错误:s1023时候,

    http://support.microsoft.com/kb/2728613

    cmd执行

    MsiExec.exe /passive /X{F0C3E5D1-1ADE-321E-8167-68EF0DE699A5}
    
    MsiExec.exe /passive /X{1D8E6291-B0D5-35EC-8441-6616F567A0F7}

    代码:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using Microsoft.DirectX.Direct3D;
    using Microsoft.DirectX;
    namespace 包围体
    {
        public partial class Form1 : Form
        {
            private Device device = null;
            private CustomVertex.PositionTextured[] vertics;//点集合,用来绘制四边形
            private float angleY = 0.1f;//绕y轴旋转变量
            private Vector3 cameraPosition = new Vector3(8, 15, 8);//摄像机位置
            private Vector3 cameraTarget = new Vector3(10, 10, 10);
            private Vector3 camereUpVector = new Vector3(0, 1, 0);
            private Mesh mesh;
            private Material meshMaterial1;
            private Material meshMaterial2;
            //  Texture texture;//图片纹理
            /// <summary>
            /// 是否暂停
            /// </summary>
            bool pause = false;
            public Form1()
            {
                InitializeComponent();
            }
    
            /// <summary>
            /// 实例化device,在progress里调用
            /// </summary>
            /// <returns></returns>
            public bool InitializeGraphics()
            {
                try
                {
                    PresentParameters presentParams = new PresentParameters();
                    presentParams.Windowed = true;//窗口显示
                    presentParams.SwapEffect = SwapEffect.Discard;//后备缓存的交换方式
                    presentParams.EnableAutoDepthStencil = true;//自动深度测试
                    presentParams.AutoDepthStencilFormat = DepthFormat.D16;//缓冲区单元为16位二进制数
                    device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams);
                    device.DeviceReset += new EventHandler(this.OnResetDevice);
    
    
                    this.OnCreateDevice(device, null);
                    this.OnResetDevice(device, null);
                }
                catch (DirectXException)
                {
                    return false;
                }
                return true;
    
            }
            public void OnResetDevice(object sender, EventArgs e)
            {
                VertexDeclaration();
                device.Lights[0].Type = LightType.Directional;
                device.Lights[0].Direction = new Vector3(0, 0, 1);
                device.Lights[0].Diffuse = Color.Red;
                device.Lights[0].Ambient = Color.Cyan;
                device.Lights[0].Enabled = true;
                device.Lights[0].Update();
            }
    
            public void OnCreateDevice(object sender, EventArgs e)
            {
                //   texture = TextureLoader.FromFile(device, "..\..\CTGU.jpg");
                device.SamplerState[0].MagFilter = TextureFilter.Anisotropic;
                mesh = Mesh.Teapot(device);
                meshMaterial1 = new Material();
                meshMaterial1.Diffuse = Color.White;
                meshMaterial1.Ambient = Color.Green;
                meshMaterial2 = new Material();
                meshMaterial2.Diffuse = Color.White;
                meshMaterial2.Ambient = Color.Blue;
            }
    
            //生成点集合
            private void VertexDeclaration()
            {
                vertics = new CustomVertex.PositionTextured[4];
                vertics[0].Position = new Vector3(9, 9, 10);
                vertics[0].Tu = 0;
                vertics[0].Tv = 1f;
                vertics[1].Position = new Vector3(9, 11, 10);
                vertics[1].Tu = 0;
                vertics[1].Tv = 0;
                vertics[2].Position = new Vector3(11, 11, 10);
                vertics[2].Tu = 1f;
                vertics[2].Tv = 0;
                vertics[3].Position = new Vector3(11, 9, 10);
                vertics[3].Tu = 1f;
                vertics[3].Tv = 1f;
            }
    
            //设置视角
            private void SetCamera()
            {
                device.Transform.View = Matrix.LookAtLH(cameraPosition, cameraTarget, camereUpVector);
                device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, 1.33f, 1, 10000f);
            }
    
            public void Render()
            {
    
                if (device == null)
                {
                    return;
                }
                if (pause)
                {
                    return;
                }
                device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0);//第一个参数,指定要初始化目标窗口和深度缓冲区
                device.BeginScene();
                /**** 开始渲染*************************************************************************/
    
                SetCamera();//改变摄像机位置
                device.RenderState.CullMode = Cull.None;
                device.RenderState.Lighting = true;
                device.Transform.World = Matrix.Scaling(0.5f, 0.5f, 0.5f) * Matrix.Translation(cameraTarget.X, cameraTarget.Y, cameraTarget.Z);
                device.Material = meshMaterial1;
                mesh.DrawSubset(0);//绘制茶壶
    
                //绘制包围盒
                device.RenderState.FillMode = FillMode.WireFrame;
                GraphicsStream gs = mesh.VertexBuffer.Lock(0, 0, LockFlags.None);
                Vector3 minVector, maxVector;
                Geometry.ComputeBoundingBox(gs, mesh.NumberVertices, mesh.VertexFormat, out minVector, out maxVector);
                Mesh Box = Mesh.Box(device, maxVector.X - minVector.X, maxVector.Y - minVector.Y, maxVector.Z - minVector.Z);
                // Box.DrawSubset(0);
    
                //绘制包围球
                Vector3 center = new Vector3();
                float radius = Geometry.ComputeBoundingSphere(gs, mesh.NumberVertices, mesh.VertexFormat, out center);
                Mesh sphere = Mesh.Sphere(device, radius * 100, 100, 100);
                device.Material = meshMaterial2;
                sphere.DrawSubset(0);
    
    
                //  device.Transform.World = Matrix.Identity;
                //device.SetTexture(0, texture);
                //device.VertexFormat = CustomVertex.PositionTextured.Format;
                //device.DrawUserPrimitives(PrimitiveType.TriangleFan, 2, vertics);
    
                /****结束渲染*************************************************************************/
                device.EndScene();
                device.Present();//更新显示缓冲区
            }
            protected override void OnPaint(PaintEventArgs e)
            {
                this.Render();
            }
            protected override void OnKeyDown(KeyEventArgs e)
            {
                Vector3 lastPosition = cameraPosition;//记录上一次摄像机的位置,即没旋转前的位置!
                Vector4 tempV4;
                Matrix currentView = device.Transform.View;//当前摄像机的视图矩阵
                switch (e.KeyCode)
                {
                    case Keys.Left://y轴旋转++
                        cameraPosition.Subtract(cameraTarget);//向量相减,得到以目标点为起点的向量
                        tempV4 = Vector3.Transform(cameraPosition, Matrix.RotationQuaternion(Quaternion.RotationAxis(new Vector3(currentView.M12, currentView.M22, currentView.M32), -angleY)));
                        cameraPosition.X = tempV4.X + cameraTarget.X;
                        cameraPosition.Y = tempV4.Y + cameraTarget.Y;
                        cameraPosition.Z = tempV4.Z + cameraTarget.Z;
                        break;
                    case Keys.Right://y轴旋转--
                        cameraPosition.Subtract(cameraTarget);
                        tempV4 = Vector3.Transform(cameraPosition, Matrix.RotationQuaternion(Quaternion.RotationAxis(new Vector3(currentView.M12, currentView.M22, currentView.M32), angleY)));
                        cameraPosition.X = tempV4.X + cameraTarget.X;
                        cameraPosition.Y = tempV4.Y + cameraTarget.Y;
                        cameraPosition.Z = tempV4.Z + cameraTarget.Z;
                        break;
                    case Keys.Up://x轴旋转++
                        cameraPosition.Subtract(cameraTarget);
                        tempV4 = Vector3.Transform(cameraPosition,
                        Matrix.RotationQuaternion(
                        Quaternion.RotationAxis(new
                        Vector3(device.Transform.View.M11
                        , device.Transform.View.M21, device.Transform.View.M31),
                        -angleY)));
                        cameraPosition.X = tempV4.X + cameraTarget.X;
                        cameraPosition.Y = tempV4.Y + cameraTarget.Y;
                        cameraPosition.Z = tempV4.Z + cameraTarget.Z;
                        Vector3 directionV3 = cameraPosition - lastPosition;//旋转方向
                        camereUpVector = -directionV3;//改变y方向位置
                        break;
                    case Keys.Down://x轴旋转--
                        cameraPosition.Subtract(cameraTarget);
                        tempV4 = Vector3.Transform(cameraPosition,
                        Matrix.RotationQuaternion(
                        Quaternion.RotationAxis(new
                        Vector3(device.Transform.View.M11
                        , device.Transform.View.M21, device.Transform.View.M31),
                        angleY)));
                        cameraPosition.X = tempV4.X + cameraTarget.X;
                        cameraPosition.Y = tempV4.Y + cameraTarget.Y;
                        cameraPosition.Z = tempV4.Z + cameraTarget.Z;
                        Vector3 direction2V3 = cameraPosition - lastPosition;//旋转方向
                        camereUpVector = direction2V3;
                        break;
                    case Keys.Add://放大,按加号键
                        cameraPosition.Subtract(cameraTarget);
                        cameraPosition.Scale(0.95f);
                        cameraPosition.Add(cameraTarget);
                        break;
                    case Keys.Subtract://缩小,减号键
                        cameraPosition.Subtract(cameraTarget);
                        cameraPosition.Scale(1.05f);
                        cameraPosition.Add(cameraTarget);
                        break;
                }
                Matrix viewMatrix = Matrix.LookAtLH(cameraPosition, cameraTarget, camereUpVector);
                device.Transform.View = viewMatrix;
            }
    
            private int mouseLastX, mouseLastY;//记录鼠标按下时的坐标位置
            private bool isRotateByMouse = false;//记录是否由鼠标控制旋转
            private bool isMoveByMouse = false;//记录是否由鼠标控制摄像机 移动
    
            protected override void OnMouseDown(MouseEventArgs e)
            {
                if (e.Button == MouseButtons.Left)
                {
                    mouseLastX = e.X;
                    mouseLastY = e.Y;
                    isRotateByMouse = true;
                }
                else if (e.Button == MouseButtons.Middle)
                {
                    mouseLastX = e.X;
                    mouseLastY = e.Y;
                    isMoveByMouse = true;
                }
    
            }
    
            protected override void OnMouseMove(MouseEventArgs e)
            {
                if (isRotateByMouse)
                {
                    Matrix currentView = device.Transform.View;//当前摄像机的视图矩阵
                    float tempAngleY = 2 * (float)(e.X - mouseLastX) / this.Width;
                    cameraPosition.Subtract(cameraTarget);
                    Vector4 tempV4 = Vector3.Transform(cameraPosition, Matrix.RotationQuaternion(Quaternion.RotationAxis(new Vector3(currentView.M12, currentView.M22, currentView.M32), tempAngleY)));
                    cameraPosition.X = tempV4.X;
                    cameraPosition.Y = tempV4.Y;
                    cameraPosition.Z = tempV4.Z;//旋转y轴得到新的摄像机临时坐标
                    Vector3 tempCameraPosition = cameraPosition;//记录一下上一次摄像机的位置
                    float tempAngleX = 4 * (float)(e.Y - mouseLastY) / this.Height;
                    tempV4 = Vector3.Transform(cameraPosition, Matrix.RotationQuaternion(Quaternion.RotationAxis(new Vector3(currentView.M11, currentView.M21, currentView.M31), tempAngleX)));
                    if (tempAngleX > 0)//大于零说明x轴左手系中,取负值旋转,因此摄像机向上方向与摄像机移动位置方向相反
                    {
                        camereUpVector = new Vector3(-cameraPosition.X + tempV4.X, -cameraPosition.Y + tempV4.Y, -cameraPosition.Z + tempV4.Z);
                    }
                    else if (tempAngleX < 0)
                    {
                        camereUpVector = new Vector3(cameraPosition.X - tempV4.X, cameraPosition.Y - tempV4.Y, cameraPosition.Z - tempV4.Z);
                    }
                    cameraPosition.X = tempV4.X + cameraTarget.X;
                    cameraPosition.Y = tempV4.Y + cameraTarget.Y;
                    cameraPosition.Z = tempV4.Z + cameraTarget.Z;
                    Matrix viewMatrix = Matrix.LookAtLH(cameraPosition, cameraTarget, camereUpVector);
                    device.Transform.View = viewMatrix;
                    mouseLastX = e.X;
                    mouseLastY = e.Y;
                }
    
                else if (isMoveByMouse)
                {
                    Matrix currentView = device.Transform.View;//当前摄像机的视图矩阵
                    float moveFactor = 0.01f;
                    cameraTarget.X += -moveFactor * ((e.X - mouseLastX) * currentView.M11
                    - (e.Y - mouseLastY) * currentView.M12);
                    cameraTarget.Y += -moveFactor * ((e.X - mouseLastX) * currentView.M21
                    - (e.Y - mouseLastY) * currentView.M22);
                    cameraTarget.Z += -moveFactor * ((e.X - mouseLastX) * currentView.M31
                    - (e.Y - mouseLastY) * currentView.M32);
                    Matrix viewMatrix = Matrix.LookAtLH(cameraPosition, cameraTarget, camereUpVector);
                    device.Transform.View = viewMatrix;
                    mouseLastX = e.X;
                    mouseLastY = e.Y;
                }
            }
    
            //鼠标滚轮控制摄像机放大缩小
            protected override void OnMouseWheel(MouseEventArgs e)
            {
                float scaleFactor = -(float)e.Delta / 2000 + 1f;
                cameraPosition.Subtract(cameraTarget);
                cameraPosition.Scale(scaleFactor);
                cameraPosition.Add(cameraTarget);
                Matrix viewMatrix = Matrix.LookAtLH(cameraPosition, cameraTarget, camereUpVector);
                device.Transform.View = viewMatrix;
            }
            protected override void OnMouseUp(MouseEventArgs e)
            {
                isRotateByMouse = false;
                isMoveByMouse = false;
            }
        }
    }

    效果图:



    源码地址下载:https://files.cnblogs.com/files/congqiandehoulai/2021-1-13-Directx3d%E7%BB%98%E5%88%B6%E5%8C%85%E5%9B%B4%E4%BD%93%E5%B9%B6%E6%8E%A7%E5%88%B6%E5%85%89%E7%85%A7%E6%95%88%E6%9E%9C.rar
  • 相关阅读:
    008——MATLAB-xlswrite的使用方法
    006——转载-MATLAB数字与字符之间的转换
    013——C# chart控件时间作为X轴(附教程)
    012——C#打开ecxel修改数据(附教程)
    010——C#选择文件路径
    011——C#创建ecxel文件(附教程)
    009——C#全局变量定义
    008——转载——c#获取当前日期时间
    007——转载——C#将字符串转换为整型的三种方法的总结
    006——C#关闭窗口 添加FormClosing事件
  • 原文地址:https://www.cnblogs.com/congqiandehoulai/p/5571557.html
Copyright © 2020-2023  润新知