DirectX游戏编程入门——第二部分(游戏编程工具箱) ——3D渲染基础

本系列文章由 net_assassin 整理编写,转载请注明出处。

http://blog.csdn.net/net_assassin/article/category/1100363


作者:net_assassin 邮箱: [email protected] 期待着与志同道合的朋友们相互交流



3D编程介绍

如今,每个人都有一块3D加速的视频卡,这早已是定论。

3D编程的关键组成部分

在Direct3D中渲染一个场景,有三个关键组成部分:
  1. 世界变换 在“世界”中移动3D对象,“世界”这个词描述的是整个场景。换句话说,世界变化导致场景中的物体移动、旋转和缩放(一次一个对象)。
  2. 试图变换 打个比方说,这是照相机,它定义用户在屏幕上所看到的内容。这个照相机可以放置在“世界”中的任何地方。如果想移动照相机,只需进行视图变换即可。
  3. 投影变换 这是最后一步,在这里将视图变换的结果(照相机看到的对象)绘制到屏幕上,形成由像素组成的平面2D图像。投影确定已渲染的场景上样子(无论定义的屏 幕纵横比如何影响输出)。

3D场景

  1. 顶点 为视频卡增加性能的高级3D图形芯片看到的只有顶点。视频卡本身实际上只看形成每个三角形的三个角的顶点。填充由这三个顶点所形成的空三角形是视频卡的工 作。

顶点缓冲区

顶点缓冲区其实只是偶们储存组成多边形的点的地方,从而Direct3D可以绘制多边形。在程序中,只要需要,从技术上说可以有许多顶点缓冲区-每个三角形一个。
为了清除的描述,安排每个对象都有其自己的顶点缓冲区,然后就此来介绍获得屏幕上的3D对象的方法。由于本章内容是以四边形(由两个排成一条的三角形组成)的概念为基础的,所以为场景中的每个四边形都创建一个顶点缓冲区,以帮助大家理解这里的内容。让每个四边形都有一个顶点缓冲区可以清楚明白地说明渲染四边形时所发生的一切。

强大的3D引擎也使用所谓的纹理缓存,以便共享同一纹理的多边形重用它们。因为3D卡一次只能“使用”一个纹理,然后再场景中任何需要这一纹理的多边形上使用这个纹理,接下来再处理下一个纹理,这样的做法会更有效率。

创建顶点缓冲区

首先必须为顶点缓冲区定义一个变量:
LPDIRECT3DVERTEXBUFFER9 buffer;

通过CreateVertexBuffer函数来创建顶点缓冲区
HRESULT CreateVertexBuffer(
      UINT      Length,  //指定定点缓冲区的尺寸
      DWORD  Usage,  //指定访问定点缓冲区的方法,通常是只写。
      DWORD  FVF,       //指定Direct3D将要接收的顶点流的类型,D3DFVF_XYZ|D3DFVF_TEX1
      D3DPOOL Pool,    
      IDirect3DVertexBuffer9** ppVertexBuffer,//指定顶点缓冲区指针
      HANDLE*  pSharedHandle   //NULL
);
exp:
#define D3DFVF_MYVERTEX(D3DFVF_XYZ|D3DFVF_TEX1)
d3ddev->CreateVertexBuffer(
     4*sizeof(VERTEX),
     D3DUSAGE_WRITEONLY,
     D3DFVF_MYVERTEX,
     D3DPOOL_DEFAULT,
     &buffer,
     NULL
);

填写顶点缓冲区

QUAD结构的定义:
struct QUAD
{
VERTEX vertices[4];
LPDIRECT3FVERTEXBUFFER9 buffer;
LPDIRECT3DTEXTURE9 texture;
}

可以用CreateVertex函数为一个四边形设置默认值:
vertices[0] = CreateVertex(-1.0f,1.0f,0.0f,0.0f,0.0f);
这只是将数据填入顶点的一种方式。可以在程序的某个地方定义不同类型的多边形或者从文件装载3D形状(下一章提到)。

有了顶点数据之后,可以将其放入顶点缓冲区中。在放的过程中必须锁住(Lock)顶点缓冲区,并将顶点复制到顶点缓冲区中,然后对顶点缓冲区解锁(Unlock)。
void *temp = NULL;
buffer->Lock(0,sizeof(vertices),(void**)&temp,0);
memcpy(temp,vertices,sizeof(vertices));
buffer->Unlock();

渲染顶点缓冲区

在初始化顶点缓冲区之后,就为Direct3D图形管线做好了准备,源顶点就不再有用了。这成为“设置”,而且是最近几年被移出Direct3D驱动程序,转而由GPU来实现的功能之一。让硬编码的芯片从顶点缓冲区中将顶点和纹理放到场景中要比软件快得多。

  1. 首先设置要使用的纹理。 D3D一次只处理一个纹理,所以我们每次更换纹理时必须告诉D3D。 d3ddev->SetTexture(0,texture);
  2. 接下来,设置流源,以便D3D知道顶点的来源及需要渲染的有多少。 d3ddev->SetStreamSource(0,q.buffer,0,sizeof(VERTEX));
  3. 最后,绘制流源指定的基元(primitive),包括渲染方法、起始顶点及要绘制的多边形数量: d3ddev->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2);
显然这三个函数可一起放入到一个可重用的Draw函数中。

绘制对象有两种方法:

  1. 独立绘制每一个多边形的三角形列表,每个由三个一组的顶点组成。
  2. 一个三角形条绘制许多通过共享顶点连接在一起的多个多边形。
for循环本身不实际占用人哈处理器时间,需要重点考虑的是for循环执行的代码。

带纹理的立方体示例

对于3D系统而言三角形是至关重要的,但如果只有一个三角形则没什么用处。只有将三角形组合起来,才使事情变得有趣。
直角三角形是3D图形的首选形状,如果不为视频卡提供直角三角形,那么它会把奇形怪状的三角形分解为两个或更多直角三角形!



你可能感兴趣的:(DirectX游戏编程入门——第二部分(游戏编程工具箱) ——3D渲染基础)