空间中的物体需要使用三维坐标来描述,而显示器是一个二维的表面,所以在屏幕上渲染一个三维场景时,首先需要将描述空间物体的三维坐标变换为二维坐标(世界坐标到屏幕坐标),这在Direct3D中称为顶点坐标变换。顶点坐标变换通常通过矩阵来完成。可以把顶点坐标变换想象成摄像过程,三维世界的景物通过摄像机的拍摄显示在二维的相片上,所不同的是把相片换成了屏幕。
顶点坐标变换和光照流水线概述
Direct3D中渲染三维对象的过程可分为两个阶段。第一阶段称为坐标变换和光照(Transforming
and Lighting T&L)阶段。在这个阶段,每个对象的顶点被从一个抽象的、浮点坐标空间转换到基于像素的屏幕空间(坐标变换不仅包含物体顶点位置的坐标变换,它还可能包含顶点法线、纹理坐标等的坐标变换),并根据场景中光源和物体表面的材质对物体顶点应用不同类型的光照效果。还有其他一些比较重要的任务,如裁剪和视口缩放也在第一阶段进行。第二阶段称为光栅化处理阶段,Direct3D将经过T&L处理的顶点组织以点、线、面为基础的图元,应用纹理贴图和物体顶点的颜色属性,根据相应渲染状态设置(如着色模式),决定每个像素的最终颜色值,并在屏幕上显示出来。
有时根据特殊的需要,可以跳过其中的某些步骤。如果愿意,也可以提供自己的坐标变换和光照过程,并将处理后的顶点直接传给Direct3D光栅化处理程序,而绕过Direct3D的T&L阶段。
T&L的过程在Direct3D中通常称为顶点变换流水线,在这个过程中,未经过变换和光照的顶点从一端进入,在内部这些顶点将完成几个连续操作,然后经过转换和光照的顶点从另一端出来。应用程序通过指定几个矩阵、视口以及所使用的光线来建立T&L流水线,然后应用程序将顶点送入流水线,对这些顶点进行变换、照明和裁剪,将其投影到屏幕空间,并根据视口的规定对其进行缩放。我们认为经过流水线的顶点是已经经过处理的,并且已经准备好传送给光栅化处理程序。
下面首先介绍T&L流水线涉及到的一些基本概念:
(1)世界变换和世界坐标系:物体在三维空间的运动和变形过程称为世界变换,如平移、旋转、缩放等。物体在其中运动的三维空间称为世界空间,它的三维坐标系表示称为世界坐标系,物体顶点在世界坐标系里的坐标变换称为世界变换。
(2)取景变换和观察坐标系:把图形显示想象成摄像过程,取景变换就像摄像机中摄像机的摆放一样,在三维图形显示中,需要设置一个虚拟摄像机,屏幕显示的图形就是虚拟摄像机拍摄在胶片上的景物。以摄像机位置为参考原点,摄像机观察的方向为坐标轴,建立的坐标系称为观察坐标系,物体在观察坐标系中的相对坐标称为观察坐标,顶点从世界坐标到观察坐标的转换称为取景变换。
(3)投影坐标和投影坐标系:物体从世界坐标描述转换到观察坐标后,可将三维物体投影到二维表面上,即投影到虚拟摄像机的胶片上,这个过程就是投影变换。以胶片中心为参考原点的空间坐标系称为投影坐标系,物体在投影坐标系中的坐标称为投影坐标。
(4)视区变换和屏幕坐标系:物体在投影坐标系中的表示为浮点坐标,通过定义屏幕显示区域(一般为显示窗口大小),将浮点坐标转化为像素坐标的过程称为视区变换,该像素坐标值称为屏幕坐标。例如,如果定义视区大小为宽640像素、高480像素,那么投影坐标(1.0f,
0.5f)经过视区变换后的屏幕坐标为(640, 240),如果定义视区大小为宽1024像素、高800像素,经过视区变换后的屏幕坐标为(1204,
400)。
世界空间的三维物体顶点坐标经过世界变换、取景变换、投影变换和视区变换,转化为以像素为单位的屏幕坐标,就可以进行光栅化显示了。在Direct3D程序中,只要定义并设置好相应的变换矩阵和视区信息,即构建好T&L流水线,剩余的各种顶点变换操作由Direct3D自动完成。
IDirect3DDevice9::SetTransform()函数用来设置顶点变换矩阵,该函数的声明如下:
Sets a single device transformation-related state.
HRESULT SetTransform(
D3DTRANSFORMSTATETYPE State,
CONST D3DMATRIX * pMatrix
);
Parameters
- State
- [in] Device-state variable that is being modified.
This parameter can be any member of the D3DTRANSFORMSTATETYPE enumerated
type, or the D3DTS_WORLDMATRIX macro.
- pMatrix
- [in] Pointer to a D3DMATRIX structure that
modifies the current transformation.
Return Values
If the method succeeds, the return value is D3D_OK.
D3DERR_INVALIDCALL is returned if one of the arguments is invalid.
D3DTRANSFORMSTATETYPE
Defines constants that describe transformation state
values.
typedef enum D3DTRANSFORMSTATETYPE
{
D3DTS_VIEW = 2,
D3DTS_PROJECTION = 3,
D3DTS_TEXTURE0 = 16,
D3DTS_TEXTURE1 = 17,
D3DTS_TEXTURE2 = 18,
D3DTS_TEXTURE3 = 19,
D3DTS_TEXTURE4 = 20,
D3DTS_TEXTURE5 = 21,
D3DTS_TEXTURE6 = 22,
D3DTS_TEXTURE7 = 23,
D3DTS_FORCE_DWORD = 0x7fffffff,
} D3DTRANSFORMSTATETYPE, *LPD3DTRANSFORMSTATETYPE;
Constants
- D3DTS_VIEW
- Identifies the transformation matrix being set as
the view transformation matrix. The default value is NULL (the identity
matrix).
- D3DTS_PROJECTION
- Identifies the transformation matrix being set as
the projection transformation matrix. The default value is NULL (the
identity matrix).
- D3DTS_TEXTURE0
- Identifies the transformation matrix being set for
the specified texture stage.
- D3DTS_TEXTURE1
- Identifies the transformation matrix being set for
the specified texture stage.
- D3DTS_TEXTURE2
- Identifies the transformation matrix being set for
the specified texture stage.
- D3DTS_TEXTURE3
- Identifies the transformation matrix being set for
the specified texture stage.
- D3DTS_TEXTURE4
- Identifies the transformation matrix being set for
the specified texture stage.
- D3DTS_TEXTURE5
- Identifies the transformation matrix being set for
the specified texture stage.
- D3DTS_TEXTURE6
- Identifies the transformation matrix being set for
the specified texture stage.
- D3DTS_TEXTURE7
- Identifies the transformation matrix being set for
the specified texture stage.
- D3DTS_FORCE_DWORD
- Forces this enumeration to compile to 32 bits in
size. Without this value, some compilers would allow this enumeration to
compile to a size other than 32 bits. This value is not used.
Remarks
The transform states in the range 256 through 511 are
reserved to store up to 256 world matrices that can be indexed using the
D3DTS_WORLDMATRIX and D3DTS_WORLD macros.
Macros |
|
D3DTS_WORLD |
Equivalent to
D3DTS_WORLDMATRIX(0). |
D3DTS_WORLDMATRIX (index) |
Identifies the
transform matrix to set for the world matrix at index. Multiple world
matrices are used only for vertex blending. Otherwise only D3DTS_WORLD
is used. |
IDirect3DDevice9::SetViewport()函数用来设置视区信息,该函数声明如下:
Sets the viewport parameters for the device.
HRESULT SetViewport(
CONST D3DVIEWPORT9 * pViewport
);
Parameters
- pViewport
- [in] Pointer to a D3DVIEWPORT9 structure,
specifying the viewport parameters to set.
Return Values
If the method succeeds, the return value is D3D_OK. If
the method fails, it will return D3DERR_INVALIDCALL. This will happen if
pViewport is invalid, or if pViewport describes a region that cannot exist
within the render target surface.
Remarks
Direct3D sets the following default values for the
viewport.
D3DVIEWPORT9 vp;
vp.X = 0;
vp.Y = 0;
vp.Width = RenderTarget.Width;
vp.Height = RenderTarget.Height;
vp.MinZ = 0.0f;
vp.MaxZ = 1.0f;
IDirect3DDevice9::SetViewport can be used to draw on
part of the screen. Make sure to call it before any geometry is drawn so the
viewport settings will take effect.
To draw multiple views within a scene, repeat the
IDirect3DDevice9::SetViewport and draw geometry sequence for each view.