最近朋友建议我写一些关于微软云技术的博客留给学校下一届的学生们看,怕下一届的MSTC断档。于是我也觉的有这个必要。写了几篇博客之后,我觉得也有必要把这一年的学习内容放在博客做个纪念,就这样写了本篇博客。

第一步:判断显卡是否支持

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms; namespace 综合举例
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Form1 frm = new Form1();
if (frm.InitializeGraphics() == false)
{
MessageBox.Show("显卡不支持3D或者未安装配套的显卡驱动程序!");
return;
}
Application.Run(frm);
}
}
}

第二步:程序源码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms; using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D; namespace 综合举例
{
public partial class Form1 : Form
{
private Device device = null;
private Microsoft.DirectX.Direct3D.Font d3dfont;
private string helpString;
private bool showHelpString = true;
private float angle = 0;
private bool enableRotator = true;
private int rotatorXYZ = 0;
private float rotateSpeed = 0.01f; //旋转速度
private bool enableSolidMode = true;
private bool enableCullMode = true;
private Mesh[] sphereMeshs;
private float sphereRadius = 1.5f; //小球半径
private int sphereNumber = 18;
private Matrix[] spherePositions; //原始位置变换矩阵
private float xRadius = 15.0f; //x方向圆的半径
private int ySpacing = 10; //y方向相对空间大小
private VertexBuffer vertexBuffer = null; //顶点缓冲
private Material[] sphereMaterial; //小球材质
private Material[] lineMaterial; //线的材质
private bool enableEmissive = false; //是否允许物体本身发光
private Material commonSphereMaterial = new Material();
private Material commonLineMaterial = new Material();
private bool multiMaterial = true;
private bool isPointLight = false;
private bool enableLight = true; public Form1()
{
InitializeComponent();
}
public bool InitializeGraphics()
{
try
{
PresentParameters presentParams = new PresentParameters();
presentParams.Windowed = true;
presentParams.SwapEffect = SwapEffect.Discard;
presentParams.AutoDepthStencilFormat = DepthFormat.D16;
presentParams.EnableAutoDepthStencil = true;
device = new Device(0, DeviceType.Hardware, this,
CreateFlags.SoftwareVertexProcessing, presentParams);
device.RenderState.ZBufferEnable = true;
return true;
}
catch (DirectXException)
{
return false;
}
}
public void BuildScene()
{
this.buildMeshs(); //创建Mesh对象
this.BuildspherePositions(); //构造小球位置
this.BuildLineVertexBuffer(); //创建小球间的连线顶点缓冲
BuildMaterials(); //创建材质
}
private void buildMeshs()
{
//一定要及时释放资源,不能靠垃圾回收自动回收,
//否则退出后会很长时间无反应,像死机一样
if (sphereMeshs != null)
{
for (int i = 0; i < sphereMeshs.Length; i++)
{
sphereMeshs[i].Dispose();
}
}
sphereMeshs = new Mesh[sphereNumber];
for (int i = 0; i < sphereNumber; i++)
{
sphereMeshs[i] = Mesh.Sphere(device, sphereRadius, 30, 15);
}
}
private void BuildspherePositions()
{
spherePositions = new Matrix[sphereNumber];
float alfa = 360.0f / (sphereNumber - 2);
for (int i = 0; i < sphereNumber; i++)
{
if (i == 0)
{
spherePositions[i] = Matrix.Translation(0, ySpacing + 5, 0);
}
else if (i == sphereNumber - 1)
{
spherePositions[i] = Matrix.Translation(0, -ySpacing, 0);
}
else
{
//将小球按圆周在水平面平均分布
float xx = (float)(xRadius * Math.Sin(i * alfa * Math.PI / 180.0f));
float zz = (float)(xRadius * Math.Cos(i * alfa * Math.PI / 180.0f));
spherePositions[i] = Matrix.Translation(xx, 0, zz);
}
}
}
private void BuildLineVertexBuffer()
{
vertexBuffer = new VertexBuffer(typeof(CustomVertex.PositionOnly),
(sphereNumber - 2) * 4 + 2,
device, 0, CustomVertex.PositionOnly.Format, Pool.Default);
vertexBuffer.Created += new System.EventHandler(this.OnCreateVertexBuffer);
this.OnCreateVertexBuffer(vertexBuffer, null);
}
public void OnCreateVertexBuffer(object sender, EventArgs e)
{
VertexBuffer buffer = (VertexBuffer)sender;
CustomVertex.PositionOnly[] verts =
(CustomVertex.PositionOnly[])buffer.Lock(0, 0);
Random random = new Random();
for (int i = 0; i < sphereNumber - 2; i++)
{
Vector3 vector = new Vector3(spherePositions[i + 1].M41,
spherePositions[i + 1].M42, spherePositions[i + 1].M43);
verts[i * 2].Position = vector;
verts[i * 2 + 1].Position = new Vector3(0, ySpacing, 0);
verts[2 * (sphereNumber - 2) + (i * 2)].Position = vector;
verts[2 * (sphereNumber - 2) + (i * 2 + 1)].Position =
new Vector3(0, -ySpacing, 0);
}
verts[sphereNumber - 1].Position = new Vector3(spherePositions[0].M41,
spherePositions[0].M42, spherePositions[0].M43);
verts[sphereNumber - 2].Position = new Vector3(0, ySpacing, 0);
vertexBuffer.Unlock();
}
private void SetupCamera()
{
float fieldOfView = (float)Math.PI / 4;
float aspectRatio = (float)this.Width / (float)this.Height;
float nearPlane = 1.0f;
float farPlane = 200.0f;
device.Transform.Projection =
Matrix.PerspectiveFovLH(fieldOfView, aspectRatio, nearPlane, farPlane);
Vector3 cameraPosition = new Vector3(0, 0, -50.0f);
Vector3 cameraTarget = new Vector3(0, 0, 0);
Vector3 upDirection = new Vector3(0, 1, 0);
device.Transform.View = Matrix.LookAtLH(cameraPosition, cameraTarget, upDirection);
device.RenderState.FillMode = (enableSolidMode ? FillMode.Solid : FillMode.WireFrame);
device.RenderState.CullMode = (enableCullMode ? Cull.CounterClockwise : Cull.None);
}
private void BuildMaterials()
{
Random random = new Random();
Color color;
sphereMaterial = new Material[sphereNumber];
for (int i = 0; i < sphereNumber; i++)
{
color = Color.FromArgb(random.Next(byte.MaxValue),
random.Next(byte.MaxValue), random.Next(byte.MaxValue));
sphereMaterial[i].Diffuse = color;
//注意:设置Emissive的目的是为了让物体本身发光,以方便演示光照效果
//如果不设置此属性,物体看起来会更逼真
if (enableEmissive == true)
{
sphereMaterial[i].Emissive = color;
}
}
int lines = (sphereNumber - 2) * 2 + 1;
lineMaterial = new Material[lines];
for (int i = 0; i < lines; i++)
{
color = Color.FromArgb(random.Next(byte.MaxValue),
random.Next(byte.MaxValue), random.Next(byte.MaxValue));
lineMaterial[i].Ambient = color;
}
}
private void SetupLights()
{
device.RenderState.Ambient = Color.White;
if (isPointLight == false)
{
device.Lights[0].Type = LightType.Directional;
device.Lights[0].Direction = new Vector3(0, 0, 1); //指向z轴正方向
}
else
{
device.Lights[0].Type = LightType.Point;
device.Lights[0].Position = new Vector3(6, 0, 0); //旋转轴中心位置
}
device.Lights[0].Range = 500.0f;
device.Lights[0].Enabled = enableLight;
} public void RendScene()
{
if (enableRotator)
{
angle += rotateSpeed;
}
////画小球
for (int i = 0; i < sphereNumber; i++)
{
//设置材质
if (multiMaterial)
{
device.Material = sphereMaterial[i];
}
else
{
device.Material = commonSphereMaterial;
}
SetWorldTransform(spherePositions[i].M41, spherePositions[i].M42, spherePositions[i].M43);
sphereMeshs[i].DrawSubset(0);
}
//重新进行矩阵变换
SetWorldTransform(0, 0, 0);
//画线
int lines = (sphereNumber - 2) * 2 + 1;
device.SetStreamSource(0, vertexBuffer, 0);
device.VertexFormat = CustomVertex.PositionOnly.Format;
for (int i = 0; i < lines; i++)
{
if (multiMaterial)
{
device.Material = lineMaterial[i];
}
else
{
device.Material = commonLineMaterial;
}
device.DrawPrimitives(PrimitiveType.LineList, i * 2, 1);
}
if (showHelpString == true)
{
d3dfont.DrawText(null, helpString, 25, this.Height - 290, Color.White);
}
}
private void SetWorldTransform(float x, float y, float z)
{
Vector3 world;
if (rotatorXYZ == 0)
{
world = new Vector3(angle, 0, 0);
}
else if (rotatorXYZ == 1)
{
world = new Vector3(0, angle, 0);
}
else
{
world = new Vector3(0, 0, angle);
}
device.Transform.World =
Matrix.Translation(x, y, z) *
Matrix.RotationAxis(world, angle) * Matrix.Translation(6, 0, 0);
} private void Form1_Load(object sender, EventArgs e)
{
this.Width = 700;
this.Height = 520;
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
this.KeyPreview = true;//↑↓←→
helpString = "<Esc>:退出\n\n" +
"<F1>:显示/隐藏提示信息\n" +
"<F2>:实心/线框\n" +
"<F3>:背面剔除/不剔除\n" +
"<F4>:旋转/不旋转\n" +
"<F5>:旋转轴(x轴、y轴、z轴)\n\n" +
"<0>:物体本身发光/物体本身不发光\n" +
"<1>:关闭/打开灯光\n" +
"<2>:直射光\n" +
"<3>:点光源\n" +
"<4>:单一材质/多种材质\n" +
"<5>:变换小球和连线材质\n\n" +
"上下左右箭头键:增加、减少小球个数\n" +
"<Alt>+箭头键 :提高、降低旋转速度\n" +
"<Ctrl>+箭头键 :增加、减少大圆半径\n" +
"<Shift>+箭头键:增加、减少小球半径";
System.Drawing.Font winFont = new System.Drawing.Font("宋体", 9, FontStyle.Regular);
d3dfont = new Microsoft.DirectX.Direct3D.Font(device, winFont);
d3dfont.PreloadText(helpString);
BuildScene(); //创建小球及连线
device.RenderState.Lighting = true;
//设置环境光颜色
device.RenderState.Ambient = Color.White;
//单一材质时,所有小球使用漫射光,受有方向的光照影响
commonSphereMaterial.Diffuse = Color.Red;
commonSphereMaterial.Ambient = Color.Black;
//单一材质时,所有连线均使用连线材质的环境反射色
//当环境光为白色时,连线的颜色就是指定的环境反射色(此句中连线也使用白色)
commonLineMaterial.Ambient = Color.White;
SetupLights(); //设置灯光 } private void Form1_Paint(object sender, PaintEventArgs e)
{
device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.DarkSeaGreen, 1.0f, 0);
SetupCamera();
device.BeginScene();
this.RendScene();
device.EndScene();
device.Present();
if (WindowState != FormWindowState.Minimized)
{
this.Invalidate();
} } private void Form1_KeyDown(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Escape:
this.Close(); break;
case Keys.F1:
showHelpString = !showHelpString; break;
case Keys.F2:
enableSolidMode = !enableSolidMode; break;
case Keys.F3:
enableCullMode = !enableCullMode; break;
case Keys.F4:
enableRotator = !enableRotator; break;
case Keys.F5:
rotatorXYZ = (rotatorXYZ + 1) % 3; break;
case Keys.D0:
enableEmissive = !enableEmissive;
BuildMaterials();
break;
case Keys.D1:
enableLight = !enableLight; SetupLights(); break;
case Keys.D2:
isPointLight = false; SetupLights(); break;
case Keys.D3:
isPointLight = true; SetupLights(); break;
case Keys.D4:
multiMaterial = !multiMaterial; break;
case Keys.D5:
BuildMaterials(); break;
case Keys.Up:
case Keys.Right:
if (e.Alt == true) rotateSpeed += 0.005f;
else if (e.Shift == true) sphereRadius += 0.05f;
else if (e.Control == true) xRadius += 0.5f;
else sphereNumber += 2;
if (e.Alt == false)
{
BuildScene();
}
break;
case Keys.Down:
case Keys.Left:
if (e.Alt == true)
rotateSpeed =
(rotateSpeed > 0.01 ? rotateSpeed - 0.005f : rotateSpeed);
else if (e.Shift == true)
sphereRadius =
(sphereRadius > 0.1f ? sphereRadius - 0.05f : sphereRadius);
else if (e.Control == true)
xRadius = (xRadius > 0.5f ? xRadius - 0.5f : xRadius);
else
sphereNumber = (sphereNumber > 6 ? sphereNumber - 2 : sphereNumber);
if (e.Alt == false)
{
BuildScene();
}
break;
} } }
}

Directx 3D编程实例:多个3D球的综合Directx实例的更多相关文章

  1. 近中期3D编程研究目标

    近几年一直在用业余时间研究3D编程,研究的中期目标是建立一个实用的开源3D编程框架.3D编程技术最直接的应用是开发游戏,所以3D编程框架也就是3D游戏开发框架.在我看来,游戏是否好玩的关键是能否为玩家 ...

  2. DirectX API 编程起步 #01 项目设置

    =========================================================== 目录: DirectX API 编程起步 #02 窗口的诞生 DirectX A ...

  3. 开始3D编程前需注意的十件事

    http://www.csdn.net/article/2013-06-21/2815949-3d-programming 原文作者Vasily Tserekh是名3D编程爱好者,他发表了一篇博文&l ...

  4. UWP简单示例(二):快速开始你的3D编程

    准备 IDE:Visual Studio 2015 了解并学习:SharpDx官方GitHub 推荐Demo:SharpDX_D3D12HelloWorld 第一节 世界 世界坐标系是一个特殊的坐标系 ...

  5. UWP简单示例(二):快速开始你的3D编程

    准备 IDE:Visual Studio 开源库:GitHub.SharpDx 入门示例:SharpDX_D3D12HelloWorld 为什么选择 SharpDx? SharpDx 库与 UWP 兼 ...

  6. QT Graphics-View 3D编程例子- 3D Model Viewer

    学习在Graphics-View框架中使用opengl进行3D编程,在网上找了一个不错的例子“3D Model Viewer”,很值得学习. 可以在http://www.oyonale.com/acc ...

  7. WPF 3D编程介绍

    原文:WPF 3D编程介绍 上一篇文章简单的介绍了WPF编程的相关的内容,也推荐了本书.今天要来讲一下在WPF如何开展3D编程. 使用的xmal 和C#开发的时候:需要使用如下的关键要素: 1:摄像机 ...

  8. 3D编程模式:依赖隔离模式

    大家好~本文提出了"依赖隔离"模式 系列文章详见: 3D编程模式:开篇 本文相关代码在这里: 相关代码 目录 编辑器需要替换引擎 设计意图 定义 应用 扩展 最佳实践 更多资料推荐 ...

  9. 3-Highcharts 3D图之3D柱状图分组叠堆3D图

    <!DOCTYPE> <html lang='en'> <head> <title>3-Highcharts 3D图之3D柱状图分组叠堆3D图</ ...

随机推荐

  1. printf 缓冲区问题

    突然发现printf的问题,看了这个很有意思,学习一下 转自:http://blog.csdn.net/shanshanpt/article/details/7385649 昨天在做Linux实验的时 ...

  2. wordpress version

    version info /readme.html /wp-includes/version.php remove copyright 1.wp-login.php //<h1><a ...

  3. string相关

    1.find相关 string s="abcd"; size_t pos0 = s.find_first_of("dcb");         1    //返 ...

  4. html5本地数据库(一)

    本地数据库 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important ...

  5. AJAX编程模板

    AJAX一直以来没怎么接触,主要是做JSON数据在服务器和客户端之间传递的时候,被玩坏了,对它莫名的不可爱,最近心理阴影小了,于是又来看看它....... AJAX即“Asynchronous Jav ...

  6. Python自动化运维之27、Django(一)

    一.概述 1.什么是框架? 框架,即framework,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用框架可以帮你快速开发特定的系统,简单说就是使用别人搭好的舞台,你来做表演. 2.常 ...

  7. iOS的app 中的 埋点

    埋点 就是 挖个坑把 种子埋到土里 然后浇水  等待发芽 埋点就是 ,鬼子要进村,我们埋下地雷 埋点就是 小说中 作者欲扬先抑  或者欲擒故纵  设下的伏笔... 好了,用文学的手法很好的  解释了一 ...

  8. adb设备,根据serial获取vid pid

    使用adb devices命令,可以轻松获取到所有连接到PC的adb设备的serial值. 但是adb命令无法获取adb usb设备的vendor id和product id. 本程序根据adb协议, ...

  9. VS快捷键和技巧

    1. 怎样调整代码排版的格式? 选择:编辑->高级->设置文档的格式或编辑->高级->设置选中代码的格式. 格式化cs代码:Ctrl+k+f 格式化aspx代码:Ctrl+k+ ...

  10. [BZOJ 1055] [HAOI2008] 玩具取名 【记忆化搜索】

    题目链接:BZOJ - 1055 题目分析 这种类似区间 DP 的记忆化搜索都是很相近的,比如字符串压缩和字符串扩展都差不多. 都是将现在 Solve 的区间分成子区间,再求解子区间. 这道题 Sol ...