代码改变世界

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.0f0.0f0.0f);
            vertices[
0].Normal = new Vector3(-1.0f0.0f0.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.0f0.0f0.0f);
            vertices2[
0].Normal = new Vector3(1.0f0.0f0.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 / 4this.Width / this.Height, 1.0f100.0f);
            device.Transform.View 
= Matrix.LookAtLH(new Vector3(005.0f), new Vector3(), new Vector3(010));
            device.RenderState.Lighting 
= false;
        }



        
public void SetLight()
        
{
            
//将光照打开
            device.RenderState.Lighting = true;
            
//设置光源为平行光
            device.Lights[0].Type = LightType.Directional;
            
//设置光源的漫射光的值
            device.Lights[0].DiffuseColor = new ColorValue(0.0f0.0f1.0f);
            
//设置光源的环境光的值
            device.Lights[0].AmbientColor = new ColorValue(0.0f1.0f0.0f0.5f);
            
//设置光源的方向
            device.Lights[0].Direction = new Vector3(-1.0f-1.0f0.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.0f1.0f1.0f1.0f);
            
//设置材质
            device.Material = material;
        }


        
public void SetMaterial2()
        
{
            
//初始化材质
            Material material = new Material();
            
//初始化材质的环境色和漫射光颜色
            material.AmbientColor = material.DiffuseColor = new ColorValue(0.5f0.5f0.5f0.5f);
            
//设置材质
            device.Material = material;
        }



        
private void Form1_Paint(object sender, PaintEventArgs e)
        
{
            
if (device != null)
            
{
                
//用Color.CornflowerBlue清除渲染目标
                device.Clear(ClearFlags.Target, Color.CornflowerBlue, 1.0f0);

                
//设置照相机
                SetupCamera();
                
                
//开始绘制场景
                device.BeginScene();
                
//设置光照
                SetLight();
                
//设置材质
                SetMaterial();
                
//设置设备的顶点格式
                device.VertexFormat = CustomVertex.PositionNormal.Format;
                
//将顶点缓冲绑定到设备数据流
                device.SetStreamSource(0, buffer, 0);
                
//绘制图元
                device.DrawPrimitives(PrimitiveType.TriangleFan, 030);
                
//设置材质
                SetMaterial2();
                
//将顶点缓冲绑定到设备数据流
                device.SetStreamSource(0, buffer2, 0);
                
//绘制图元
                device.DrawPrimitives(PrimitiveType.TriangleFan, 030);
                
//结束场景
                device.EndScene();
                
//将后备缓冲区中的场景显示到窗体上
                device.Present();
                
//刷新
                this.Invalidate();
            }

        }

    }

}
最后得到的是一个如下的旋转着的圆锥