【原创】斌伯的DirectX学习笔记(3)--DirectX的图形渲染

Tutorial2-- Rendering Vertices

Direct 3D的方法渲染一个三角形,所以的三维形体其实都是由三角形组成的三角形网格(triangle mesh)逼近表示的。

代码如下:

using System;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace VerticesTutorial
{
    
public class Vertices : Form
    {
        
// Our global variables for this project
        Device device = null// Our rendering device
        VertexBuffer vertexBuffer = null;

        
public Vertices()
        {
            
// Set the initial size of our form
            this.ClientSize = new System.Drawing.Size(300,300);
            
// And its caption
            this.Text = "Direct3D Tutorial 2 - Vertices";
        }
        
        
public bool InitializeGraphics()
        {
            
try
            {
                
// Now let's setup our D3D stuff
                PresentParameters presentParams = new PresentParameters();
                presentParams.Windowed
=true;
                presentParams.SwapEffect 
= SwapEffect.Discard;
                device 
= new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams);
                
this.OnCreateDevice(device, null);
                
return true;
            }
            
catch (DirectXException)
            { 
                
return false
            }
        }

        
public void OnCreateDevice(object sender, EventArgs e)
        {
            Device dev 
= (Device)sender;
            
// Now Create the VB
            vertexBuffer = new VertexBuffer(typeof(CustomVertex.TransformedColored), 3, dev, 0, CustomVertex.TransformedColored.Format, Pool.Default);
            vertexBuffer.Created 
+= new System.EventHandler(this.OnCreateVertexBuffer);
            
this.OnCreateVertexBuffer(vertexBuffer, null);
        }
        
public void OnCreateVertexBuffer(object sender, EventArgs e)
        {
            VertexBuffer vb 
= (VertexBuffer)sender;
            GraphicsStream stm 
= vb.Lock(000);
            CustomVertex.TransformedColored[] verts 
= new CustomVertex.TransformedColored[3];

            verts[
0].X=150; verts[0].Y=50; verts[0].Z=0.5f; verts[0].Rhw=1; verts[0].Color = System.Drawing.Color.Red.ToArgb();
            verts[
1].X=250; verts[1].Y=250; verts[1].Z=0.5f; verts[1].Rhw=1; verts[1].Color = System.Drawing.Color.Yellow.ToArgb();
            verts[
2].X=50; verts[2].Y=250; verts[2].Z=0.5f; verts[2].Rhw=1; verts[2].Color = System.Drawing.Color.Green.ToArgb();
            stm.Write(verts);
            vb.Unlock();
        }
        
private void Render()
        {
            
if (device == null
                
return;

            
//Clear the backbuffer to a blue color (ARGB = 000000ff)
            device.Clear(ClearFlags.Target, System.Drawing.Color.Blue, 1.0f0);
            
//Begin the scene
            device.BeginScene();
            
            device.SetStreamSource( 
0, vertexBuffer, 0);
            device.VertexFormat 
= CustomVertex.TransformedColored.Format;
            device.DrawPrimitives(PrimitiveType.TriangleList, 
01);
            
//End the scene
            device.EndScene();
            device.Present();
        }
        
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            
this.Render(); // Render on painting
        }
        
protected override void OnKeyPress(System.Windows.Forms.KeyPressEventArgs e)
        {
            
if ((int)(byte)e.KeyChar == (int)System.Windows.Forms.Keys.Escape)
                
this.Close(); // Esc was pressed
        }

        
/// <summary>
        
/// The main entry point for the application.
        
/// </summary>
        static void Main() 
        {

            
using (Vertices frm = new Vertices())
            {
                
if (!frm.InitializeGraphics()) // Initialize Direct3D
                {
                    MessageBox.Show(
"Could not initialize Direct3D.  This tutorial will exit.");
                    
return;
                }
                frm.Show();

                
// While the form is still valid, render and process messages
                while(frm.Created)
                {
                    frm.Render();
                    Application.DoEvents();
                }
            }
        }

    }
}

这里频繁出现了一个类-- VertexBuffer ,顶点缓存。还有一些相关的类,方法接下来谈一下。

VertexBuffer 操作存储顶点的缓存,和相关的资源

属性

Description

VertexBufferDescription

得到关于VertexBuffer的信息

公共方法

VertexBuffer

VertexBuffer类的构造函数,无参数

Lock

锁定缓存,返回顶点集合供用户进行读写操作

UnLock

解除对缓存的锁定

* Description VertexBufferDescription类。VertexBufferDescription类的属性就是与关于VertexBuffer的信息,包括Pool(容纳缓存的内存池),Size(缓存的大小),Usage(缓存使用的附属信息)等。

* VertexBuffer方法有多个参数,其中有:

public VertexBuffer(Device, int, Usage, VertexFormats, Pool); 

public VertexBuffer(Type, int, Device, Usage, VertexFormats, Pool);

TypeVertex的类型

int:缓存所能够储存的顶点个数

Usage:是enum,用于设定一些缓存使用的附加信息

Dynamic所创建的是动态缓存(dynamic buffer),动态缓存一般储存在AGP储存区中,其内容可以迅速更新,但数据的绘制就不如在显存(video memory)的快;与之相对应的是静态缓存(static buffer),静态缓存一般储存在显存中,这样能够加快处理的速度,但相应的数据的更新速度就慢下来了。根据上述的特性,静态缓存适合储存一些不会经常修改的数据,如地形,城市建筑的相关数据;而动态缓存,就适合储存一些频繁更新的数据。粒子系统就是一个好例子。值得注意的是Usage并没有Static这一选择,这是因为只要没有选择Dynamic,系统就认为你选择的是Static

VertexFormats:顶点格式,定义缓存中单个顶点的格式,类似C++中的FVF(灵活顶点格式)。

Pool:定义容纳缓存的内存池

* LockUnLock

public GraphicsStream Lock(int, int, LockFlags);

public Array Lock(int, LockFlags);

public Array Lock(int, Type, LockFlags, int[]);

public void Unlock();

为了访问缓存中的数据,就要使用到Lock来得到缓存中某一系列顶点的集合(而在C++中,通过Lock得到的是一个指向缓存内部储存区的指针)。得到这些顶点的集合(GraphicsStream或者Array),我们就可以对其进行读写操作。

那么,究竟什么是“锁定”缓存呢?它其实就是允许CPU直接访问资源中一定范围内数据的操作。你不能直接访问图形硬件,因此需要一种方法来控制程序中的顶点数据,而锁存就是用来完成这个任务的。(

其中LockFlags是定义锁定类型的enum,常用的如下:

Discard:仅可用于动态缓存,它指示硬件将缓存内容丢弃,并返回新分配的缓存空间(对于动态的纹理,缓存会被重写),使得丢弃了的缓存能被重新利用,这样数据的处理就不会停滞。

NoOverWrite

ReadOnly

很重要的一点是对缓存访问完毕时,必须对缓存解锁,只需调用Unlock()这个方法即可。

CustomVertex 用于定义制定多种固定格式的顶点类型的类,这个类包含了很多结构体。

结构体

Structures

Transformed


Structures

TransformedColored


Structures

TransformedTextured


Structures

PositionColored


……

* CustomVertex有多种类型的顶点结构体类似于C++FVF(灵活顶点格式,Flexible Vertex Format)。它是一个结构体集合的类,里面包含着大量的结构体。里面结构体基本上都包含点信息,但大部分在点的空间信息上进行了扩展,例如,法线方向,纹理等。点是计算机图形学里面最基本的元素。

至于各种格式顶点的区别和用法,我还没有弄清楚,暂时只知道通过这些结构体可以修改顶点的空间属性、rhwreciprocal homogeneous w齐次W的倒数,计算机图形学的东西 网上查到说,指该顶点包含已经进行光照、坐标转换后的数据)、颜色纹理等附加属性。

我看了一下,各种的结构体主要分为Position打头的和Transformed打头的,试了一下Position打头的应该只处理点,而Transformed打头的应该处理点与周围空间的。这个以后还需要再看。

三角网 VertexIndex

构成场景(Scene)各种各样的模型,都可以由三角形网格(triangle mesh)逼近表示。三角形网格是构成模型的基本单元。

顶点是指一个多边形中相邻的两边的交汇点。在描述一个三角形单元,就需要3个顶点。

顶点除了空间信息,还包括其它的附加信息,如颜色,法线等(详细见CustomVertex各种结构体)

C#中的DrawPrimitives BeginSence EndScencePresent


前后台缓冲区与Swap Chain的关系



Clayman的Managed DirectX Kick Start翻译――以C#入门DirectX好东西

posted @ 2008-02-13 10:57  斌伯  阅读(1035)  评论(0编辑  收藏  举报