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