MDX 学习笔记2
2006-11-24 10:02 老博客哈 阅读(801) 评论(3) 编辑 收藏 举报简单的学习了一下材质,光源和如何绘制图元。
下面是绘制圆锥的一个例子, 写了许多注释,就不多说了哈!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.DirectX.Direct3D;
using Microsoft.DirectX;
namespace DrawTaper
{
/// <summary>
/// 本程序是利用图元绘制一个高为2,地面半径为1的圆锥
/// </summary>
public partial class Form1 : Form
{
//创建设备
private Device device = null;
//创建第一个顶点缓冲
private VertexBuffer buffer = null;
//创建第二个顶点缓冲
private VertexBuffer buffer2 = null;
//为了让圆锥能够旋转,加入角度变量
private float angle = 0.0f;
//第一个具有位置和法线的顶点数组
private CustomVertex.PositionNormal[] vertices;
//第二个具有位置和法线的顶点数组
private CustomVertex.PositionNormal[] vertices2;
public Form1()
{
InitializeComponent();
//初始化顶点缓冲函数
InitializeGraphics();
//设置窗体自汇其本身,而不是由操作系统来做;设置窗体忽略WM_ERASEBKGND,防止闪烁;设置窗体以不透明状态绘制,并且不绘制背景
this.SetStyle(ControlStyles.UserPaint| ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
}
public void InitializeGraphics()
{
//与第一篇笔记中,如何创建device一致
PresentParameters presentParams = new PresentParameters();
presentParams.Windowed = true;
presentParams.SwapEffect = SwapEffect.Discard;
device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams);
//初始化第一个顶点缓冲
buffer = new VertexBuffer(typeof(CustomVertex.PositionNormal), 32, device, Usage.Dynamic | Usage.WriteOnly, CustomVertex.PositionNormal.Format, Pool.Default);
buffer.Created += new EventHandler(this.OnCreateBuffer);
OnCreateBuffer(buffer, null);
//初始化第二个顶点缓冲
buffer2 = new VertexBuffer(typeof(CustomVertex.PositionNormal),32,device, Usage.Dynamic | Usage.WriteOnly,
CustomVertex.PositionNormal.Format, Pool.Default);
buffer2.Created += new EventHandler(this.OnCreateBuffer2);
OnCreateBuffer2(buffer2, null);
}
void OnCreateBuffer(object sender, EventArgs e)
{
VertexBuffer buffer = (VertexBuffer)sender;
//创建32个顶点,用来构建圆锥的扇面,vertices[0]为圆锥顶点
vertices = new CustomVertex.PositionNormal[32];
vertices[0].Position = new Vector3(-1.0f, 0.0f, 0.0f);
vertices[0].Normal = new Vector3(-1.0f, 0.0f, 0.0f);
for (int i = 1; i < 32; i++)
{
float y = (float)Math.Sin(Math.PI / 180.0 * 12.0 * (i + 1));
float z = (float)Math.Cos(Math.PI / 180.0 * 12.0 * (i + 1));
vertices[i].Position = new Vector3(1.0f, y, z);
vertices[i].Normal = new Vector3(0.0f, y, z);
}
buffer.SetData(vertices, 0, LockFlags.None);
}
void OnCreateBuffer2(object sender, EventArgs e)
{
VertexBuffer buffer2 = (VertexBuffer)sender;
//创建32个底面圆上的点
vertices2 = new CustomVertex.PositionNormal[32];
vertices2[0].Position = new Vector3(1.0f, 0.0f, 0.0f);
vertices2[0].Normal = new Vector3(1.0f, 0.0f, 0.0f);
for (int i = 1; i < 32; i++)
{
//考虑底面的正反面,和vertices中的顶点方向恰好相反
vertices2[i].Position = vertices[32 - i].Position;
vertices2[i].Normal = vertices[32 - i].Normal;
}
buffer2.SetData(vertices2, 0, LockFlags.None);
}
private void SetupCamera()
{
//设置状态场景中的相关参数
device.Transform.World = Matrix.RotationAxis(new Vector3(angle / ((float)Math.PI * 2.0f), angle / ((float)Math.PI * 4.0f), angle / ((float)Math.PI * 6.0f)), angle / (float)Math.PI);
angle += 0.1f;
device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, this.Width / this.Height, 1.0f, 100.0f);
device.Transform.View = Matrix.LookAtLH(new Vector3(0, 0, 5.0f), new Vector3(), new Vector3(0, 1, 0));
device.RenderState.Lighting = false;
}
public void SetLight()
{
//将光照打开
device.RenderState.Lighting = true;
//设置光源为平行光
device.Lights[0].Type = LightType.Directional;
//设置光源的漫射光的值
device.Lights[0].DiffuseColor = new ColorValue(0.0f, 0.0f, 1.0f);
//设置光源的环境光的值
device.Lights[0].AmbientColor = new ColorValue(0.0f, 1.0f, 0.0f, 0.5f);
//设置光源的方向
device.Lights[0].Direction = new Vector3(-1.0f, -1.0f, 0.0f);
//设置光源的范围
device.Lights[0].Range = 1000.0f;
//打开第0号光源
device.Lights[0].Enabled = true;
}
public void SetMaterial()
{
//初始化材质
Material material = new Material();
//初始化材质的环境色和漫射光颜色
material.AmbientColor = material.DiffuseColor = new ColorValue(1.0f, 1.0f, 1.0f, 1.0f);
//设置材质
device.Material = material;
}
public void SetMaterial2()
{
//初始化材质
Material material = new Material();
//初始化材质的环境色和漫射光颜色
material.AmbientColor = material.DiffuseColor = new ColorValue(0.5f, 0.5f, 0.5f, 0.5f);
//设置材质
device.Material = material;
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
if (device != null)
{
//用Color.CornflowerBlue清除渲染目标
device.Clear(ClearFlags.Target, Color.CornflowerBlue, 1.0f, 0);
//设置照相机
SetupCamera();
//开始绘制场景
device.BeginScene();
//设置光照
SetLight();
//设置材质
SetMaterial();
//设置设备的顶点格式
device.VertexFormat = CustomVertex.PositionNormal.Format;
//将顶点缓冲绑定到设备数据流
device.SetStreamSource(0, buffer, 0);
//绘制图元
device.DrawPrimitives(PrimitiveType.TriangleFan, 0, 30);
//设置材质
SetMaterial2();
//将顶点缓冲绑定到设备数据流
device.SetStreamSource(0, buffer2, 0);
//绘制图元
device.DrawPrimitives(PrimitiveType.TriangleFan, 0, 30);
//结束场景
device.EndScene();
//将后备缓冲区中的场景显示到窗体上
device.Present();
//刷新
this.Invalidate();
}
}
}
}
最后得到的是一个如下的旋转着的圆锥using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.DirectX.Direct3D;
using Microsoft.DirectX;
namespace DrawTaper
{
/// <summary>
/// 本程序是利用图元绘制一个高为2,地面半径为1的圆锥
/// </summary>
public partial class Form1 : Form
{
//创建设备
private Device device = null;
//创建第一个顶点缓冲
private VertexBuffer buffer = null;
//创建第二个顶点缓冲
private VertexBuffer buffer2 = null;
//为了让圆锥能够旋转,加入角度变量
private float angle = 0.0f;
//第一个具有位置和法线的顶点数组
private CustomVertex.PositionNormal[] vertices;
//第二个具有位置和法线的顶点数组
private CustomVertex.PositionNormal[] vertices2;
public Form1()
{
InitializeComponent();
//初始化顶点缓冲函数
InitializeGraphics();
//设置窗体自汇其本身,而不是由操作系统来做;设置窗体忽略WM_ERASEBKGND,防止闪烁;设置窗体以不透明状态绘制,并且不绘制背景
this.SetStyle(ControlStyles.UserPaint| ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
}
public void InitializeGraphics()
{
//与第一篇笔记中,如何创建device一致
PresentParameters presentParams = new PresentParameters();
presentParams.Windowed = true;
presentParams.SwapEffect = SwapEffect.Discard;
device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams);
//初始化第一个顶点缓冲
buffer = new VertexBuffer(typeof(CustomVertex.PositionNormal), 32, device, Usage.Dynamic | Usage.WriteOnly, CustomVertex.PositionNormal.Format, Pool.Default);
buffer.Created += new EventHandler(this.OnCreateBuffer);
OnCreateBuffer(buffer, null);
//初始化第二个顶点缓冲
buffer2 = new VertexBuffer(typeof(CustomVertex.PositionNormal),32,device, Usage.Dynamic | Usage.WriteOnly,
CustomVertex.PositionNormal.Format, Pool.Default);
buffer2.Created += new EventHandler(this.OnCreateBuffer2);
OnCreateBuffer2(buffer2, null);
}
void OnCreateBuffer(object sender, EventArgs e)
{
VertexBuffer buffer = (VertexBuffer)sender;
//创建32个顶点,用来构建圆锥的扇面,vertices[0]为圆锥顶点
vertices = new CustomVertex.PositionNormal[32];
vertices[0].Position = new Vector3(-1.0f, 0.0f, 0.0f);
vertices[0].Normal = new Vector3(-1.0f, 0.0f, 0.0f);
for (int i = 1; i < 32; i++)
{
float y = (float)Math.Sin(Math.PI / 180.0 * 12.0 * (i + 1));
float z = (float)Math.Cos(Math.PI / 180.0 * 12.0 * (i + 1));
vertices[i].Position = new Vector3(1.0f, y, z);
vertices[i].Normal = new Vector3(0.0f, y, z);
}
buffer.SetData(vertices, 0, LockFlags.None);
}
void OnCreateBuffer2(object sender, EventArgs e)
{
VertexBuffer buffer2 = (VertexBuffer)sender;
//创建32个底面圆上的点
vertices2 = new CustomVertex.PositionNormal[32];
vertices2[0].Position = new Vector3(1.0f, 0.0f, 0.0f);
vertices2[0].Normal = new Vector3(1.0f, 0.0f, 0.0f);
for (int i = 1; i < 32; i++)
{
//考虑底面的正反面,和vertices中的顶点方向恰好相反
vertices2[i].Position = vertices[32 - i].Position;
vertices2[i].Normal = vertices[32 - i].Normal;
}
buffer2.SetData(vertices2, 0, LockFlags.None);
}
private void SetupCamera()
{
//设置状态场景中的相关参数
device.Transform.World = Matrix.RotationAxis(new Vector3(angle / ((float)Math.PI * 2.0f), angle / ((float)Math.PI * 4.0f), angle / ((float)Math.PI * 6.0f)), angle / (float)Math.PI);
angle += 0.1f;
device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, this.Width / this.Height, 1.0f, 100.0f);
device.Transform.View = Matrix.LookAtLH(new Vector3(0, 0, 5.0f), new Vector3(), new Vector3(0, 1, 0));
device.RenderState.Lighting = false;
}
public void SetLight()
{
//将光照打开
device.RenderState.Lighting = true;
//设置光源为平行光
device.Lights[0].Type = LightType.Directional;
//设置光源的漫射光的值
device.Lights[0].DiffuseColor = new ColorValue(0.0f, 0.0f, 1.0f);
//设置光源的环境光的值
device.Lights[0].AmbientColor = new ColorValue(0.0f, 1.0f, 0.0f, 0.5f);
//设置光源的方向
device.Lights[0].Direction = new Vector3(-1.0f, -1.0f, 0.0f);
//设置光源的范围
device.Lights[0].Range = 1000.0f;
//打开第0号光源
device.Lights[0].Enabled = true;
}
public void SetMaterial()
{
//初始化材质
Material material = new Material();
//初始化材质的环境色和漫射光颜色
material.AmbientColor = material.DiffuseColor = new ColorValue(1.0f, 1.0f, 1.0f, 1.0f);
//设置材质
device.Material = material;
}
public void SetMaterial2()
{
//初始化材质
Material material = new Material();
//初始化材质的环境色和漫射光颜色
material.AmbientColor = material.DiffuseColor = new ColorValue(0.5f, 0.5f, 0.5f, 0.5f);
//设置材质
device.Material = material;
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
if (device != null)
{
//用Color.CornflowerBlue清除渲染目标
device.Clear(ClearFlags.Target, Color.CornflowerBlue, 1.0f, 0);
//设置照相机
SetupCamera();
//开始绘制场景
device.BeginScene();
//设置光照
SetLight();
//设置材质
SetMaterial();
//设置设备的顶点格式
device.VertexFormat = CustomVertex.PositionNormal.Format;
//将顶点缓冲绑定到设备数据流
device.SetStreamSource(0, buffer, 0);
//绘制图元
device.DrawPrimitives(PrimitiveType.TriangleFan, 0, 30);
//设置材质
SetMaterial2();
//将顶点缓冲绑定到设备数据流
device.SetStreamSource(0, buffer2, 0);
//绘制图元
device.DrawPrimitives(PrimitiveType.TriangleFan, 0, 30);
//结束场景
device.EndScene();
//将后备缓冲区中的场景显示到窗体上
device.Present();
//刷新
this.Invalidate();
}
}
}
}