最近朋友建议我写一些关于微软云技术的博客留给学校下一届的学生们看,怕下一届的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. 【HDU4348】【主席树】To the moon

    Problem Description BackgroundTo The Moon is a independent game released in November 2011, it is a r ...

  2. 用arm-linux-gcc v4.3.4交叉编译Qt4.8.3

    1.解压缩 #tar zxvf  qt-everywhere-opensource-src-4.8.3.tar.gz 2. configure #mkdir buildarm-static #cd b ...

  3. 基于jQuery 的图片瀑布流实现

    解题思路: 第1步  分析问题:我这边的处理方式是以列为单位.每次滚动条滚到底部,把需要加的新的内容放在高度最小的列.如下图所示 加载后的显示 如果在继续往下滚动.新图片就会在1下边显示,如此类推. ...

  4. 前端,移动开发者,UI须懂: 不同设备的之间的尺寸

    在开发前端,移动APP,以及设计UI的时候,我们经常会去搜索不同设备之间的尺寸,来开始自己的工作,以保证显示效果达到更好,这里收集了现在常用的设备. 设备更新速度快,有些没罗列的,大家可以谷歌或者百度 ...

  5. 那些年被我坑过的Python——摩拳擦掌(第三章)

    集合类型: 集合类型中的元素是唯一的! 集合的定义与赋值: set_1 = set([1, 3, 5, 7, 2]) set_2 = set([2, 4, 6, 8, 3]) 集合的运算操作 # 交集 ...

  6. EntityFramework - Migrations

    EntityFramework  - Migrations 對項目進行EF的數據庫升級操作.分爲開發環境與部署環境.上的操作總結. 引用: Command說明https://coding.abel.n ...

  7. php开发环境安装配置(1)

    个人记录高手请勿喷! 下载xampp我这是个中文版的可以自己搜索下载安装别的版本也行. 双击下载的xampp会提示路径相当于解压到指定的路径 到对应路径去可看到如下: 打开 2.配置: 成功之后会如下 ...

  8. 【MySQL】SQL语法,between and 使用注意事项

    业务代码中有条查询学生姓名的sql: select stu_name from stu_info where stu_id between id_1 and id_2; 估计当时一时恍惚,拼接sql时 ...

  9. Building a Space Station

    poj2031:http://poj.org/problem?id=2031 题意:就是给出三维坐标系上的一些球的球心坐标和其半径,搭建通路,使得他们能够相互连通.如果两个球有重叠的部分则算为已连通, ...

  10. keil uVision4一些使用总结(汉字注释,C关键字等)

    近日心血来潮,下载了最新的版的keil,再加上protues ,想弄个虚拟环境.主要原因还是经济问题.电子元件,是要花钱的... 今天遇到些keil uVision 4使用方面的问题,记录下来,方便以 ...