图形设备接口DirectX 图形接口指南
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
图形设备接口:DirectX 图形接口指南
疯狂代码 / ĵ:
http://GameDevelopment/Article35957.html
译者申明:
这些指南是我在阅读 DirectX8.1 SDK 中逐步翻译出来对于初次接触 DirectX Graphics 编程者而言这应该是很好上手资料其实本人就是从这些指南开始深入 Direct3D8.1 ;由于这是本人第次翻译英文材料言语不通词不达意的处定很多些术语也译得很勉强请见谅
此外需要转载此文者请保留以下部分:
-----------------------------------------------------------------------
DirectX图形接口指南 译者:In355Hz 电子邮箱: In355Hz@
-----------------------------------------------------------------------
DirectX 图形接口指南:
(应用于 DirectX 8.1 版 C/C 编程)
本区域指南将介绍说明如何在 C/C 中使用 Microsoft Direct3D 和 Direct3DX 完成些普通工作这些工作总是被分解成若干个必要步骤在某些情况下为了使表达更清楚些步骤还被细分成几个子步骤
本区域提供指南有:
· 指南:创建设备
· 指南 2:演示顶点
· 指南 3:使用矩阵
· 指南 4:创建和使用光源
· 指南 5:使用纹理映射
· 指南 6:使用Mesh模型
提示:指南中出现举例代码来自于每个指南具体提供路径里源文件
这些指南中源代码是用 C 写成如果使用C编译器你必须适当改变这些文件使它们能够编译通过最少你需要加入vtable 然后用它引用接口
包含在举例代码中些注解可能和来自 Microsoft Platform Software Development Kit (SDK) 中源代码区别这些改变仅仅为了简化表述并且只限于注解中这样能够防止举例行为被改变
指南:创建设备
为了使用 Microsoft Direct3D你首先需要创建个应用窗口并紧接着创建和化 Direct3D 对象你应该使用这些对象提供 COM 接口来操纵它们以及创建描绘个场景所必需其它对象本指南包含 CreateDevice 举例将例示并介绍说明以下几个工作:创建 Direct3D 设备并且绘制个简单蓝色屏幕
这个指南使用以下步骤:化 Direct3D绘制场景以及最后清理和关闭
·步骤:创建个窗口
·步骤 2:化 Direct3D
·步骤 3:处理系统消息
·步骤 4:绘制和显示场景
·步骤 5:关闭和清除
注意:CreateDevice 举例路径在:
(SDK root)\\Samples\\Multimedia\\Direct3D\\Tutorials\\Tut01_CreateDevice.
步骤:创建个窗口
任何 Microsoft Windows 执行中必须要作第件事就是创建个应用窗口并将其显示给用户为做到这点CreateDevice 例程将首先实现它 WinMain 以下举例代码完成了窗口化
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
// Register the window .
WNDCLASSEX wc = { (WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
"D3D Tutorial", NULL };
RegisterClassEx( &wc );
// Create the application's window.
HWND hWnd = CreateWindow( "D3D Tutorial", "D3D Tutorial 01: CreateDevice",
WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,
GetDesktopWindow, NULL, wc.hInstance, NULL );
前述举例代码是标准 Windows 编程例子开始时定义和注册了个窗口类名为 "D3D Tutorial"类注册以后举例代码使用已注册类创建了个基本顶层(top-level)窗口客户区域为 300 像素宽300 像数高这个窗口没有菜单或子窗口举例使用了 WS_OVERLAPPEDWINDOW 属性创建个包括最大化最小化以及关闭按钮普通窗口(如果该例程将运行在全屏模式下首选窗口属性应该是WS_EX_TOPMOST它指定创建窗口置于并且保持在所有非最高(non-topmost)窗口的前甚至在窗口失活情况下)旦窗口创建完成例代码标准 Microsoft Win32 显示和更新窗口
在应用窗口准备好以后你就能开始设置具体 Microsoft Direct3D 对象了
请见:步骤 2:化 Direct3D
步骤 2:化 Direct3D
CreateDevice 举例在 WinMain 中创建窗口的后该定义 InitD3D 完成 Microsoft Direct3D 化过程在创建窗口的后已经准备好化你将用来绘制场景 Direct3D 对象了这个过程包括创建个 Direct3D 对象设置Present Parameters以及最后创建 Direct3D 设备
创建完 Direct3D 对象的后你可以立即使用 IDirect3D8::CreateDevice 思路方法创建 Direct3D 设备你也能够使用 Direct3D 对象枚举设备类型模式以及其他东西这些工作代码段应位于使用 Direct3DCreate8 创建Direct3D 对象的后
( NULL ( g_pD3D = Direct3DCreate8( D3D_SDK_VERSION ) ) )
E_FAIL;
传递给 Direct3DCreate8 唯参数应该始终是 D3D_SDK_VERSION它告诉 Direct3D 当前使用头文件信息无论如何头文件或者其他变化将导致这个值增加并强制使用该值应用重新编译如果此版本不匹配 Direct3DCreate8将失败
下个步骤是使用 IDirect3D8::GetAdapterDisplayMode 接口找到当前显示模式代码如下:
D3DDISPLAYMODE d3ddm;
( FAILED( g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ) ) )
E_FAIL;
D3DDISPLAYMODE 结构中 Format 变量将被用于创建 Direct3D 设备如果是运行于窗口模式下话Format 参数通常用来创建个和适配器当前模式相匹配后背缓冲 (Back buffer)
在给 D3DPRESENT_PARAMETERS 各参数赋值时你必须指定你应用在3D下工作方式本 CreateDevice 例程设置D3DPRESENT_PARAMETERS结构中 Windowed 为 TRUESwapEffect 为
D3DSWAPEFFECT_DISCARDBackBufferFormat 为 d3ddm.Format
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, (d3dpp) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = d3ddm.Format;
最后步是利用 IDirect3D8::CreateDevice 创建 Direct3D 设备代码如下:
( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &g_pd3dDevice ) ) )
前述代码使用 D3DADAPTER_DEFAULT 标志创建了个使用省缺适配器设备在非常多数情况下系统只有个适配器除非它安装了多个图形加速卡通过把 DeviceType 参数设成 D3DDEVTYPE_HAL表示你希望获得个实际硬件设备 (hardware device) 而不是软件Software虚拟设备 (software device)举例代码还使用
D3DCREATE_SOFTWARE_VERTEXPROCESSING 标志通知系统使用软件Software顶点处理 (software vertex processing)注意如果你指定 D3DCREATE_HARDWARE_VERTEXPROCESSING 标志通知系统使用硬件顶点处理 (hardware vertex processing),你可以在支持硬件顶点处理图形加速卡上得到大幅度性能提升
现在 Direct3D 已经化完毕下步是确保你具有个机制用来来处理系统消息
见下文:步骤 3:处理系统消息
步骤 3:处理系统消息
完成创建窗口以及化 Direct3D 以后你已经准备好绘制场景 (Render scene)大多数情况下Microsoft Windows 在它们消息循环里监视系统消息并且在队列里没有消息时绘制画面帧然而CreateDevice 例程仅仅在等到个WM_PAINT出现在队列里时才通知应用重绘窗口所有部分
// The message loop.
MSG msg;
while( GetMessage( &msg, NULL, 0, 0 ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
当每循环次DispatchMessage MsgProc后者负责处理队列里消息当 WM_PAINT 消息进队时该自身定义Render它将负责重绘窗口然后 Microsoft Win32 ValidateRect 执行并将整个客户区域设为有效
消息处理例代码如下:
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) {
switch( msg )
{
WM_DESTROY:
PostQuitMessage( 0 );
0;
WM_PAINT:
Render;
ValidateRect( hWnd, NULL );
0;
}
DefWindowProc( hWnd, msg, wParam, lParam );
}
现在应用处理了系统消息接着步是绘制显示见:步骤 4:绘制和显示场景
步骤 4:绘制和显示场景
为了描绘和显示需要场景本例程在这步把后背缓冲 (back buffer) 填充为蓝色然后将此后背缓冲内容传给前景缓冲 (front buffer), 并且将前景缓冲提交至屏幕
清除表面应 IDirect3DDevice8::Clear :
// Clear the back buffer to a blue color
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );
Clear 接受前两个参数通知 Microsoft Direct3D 被清除矩形区域基址和大小该矩形区域描述了绘制目标表面(render target surface) 里需要清除区域
在大多数情况下只使用单个矩形覆盖整个绘制目标表面这样你只需设置第个参数为 0 及第 2个参数为 NULL第3个参数将决定思路方法行为你可以通过设置特定标志用来清除绘制目标表面 (render target surface)关联Z缓冲 (associated depth buffer)模版缓冲 (stencil buffer)以及任意这 3者混合本指南不使用Z缓冲所以仅仅使用了 D3DCLEAR_TARGET 标志最后 3个参数分别用于设置对应绘制目标表面、Z缓冲和模版缓冲清除填充值(reflect clearing values)该 CreateDevice 例程将绘制目表面清除填充色设置为蓝色
(D3DCOLOR_XRGB(0,0,255)由于相应标志没有设置最后两个参数被 Clear 忽略
在清除了视口 (viewport) 的后CreateDevice 例程告知 Direct3D 绘图将要开始然后立即通知这次绘制完成见以下代码段:
// Begin the scene.
g_pd3dDevice->BeginScene;
// Rendering of scene objects happens here.
// End the scene.
g_pd3dDevice->EndScene;
当绘制开始或完成时IDirect3DDevice8::BeginScene 和 IDirect3DDevice8::EndScene 将用信号通知系统你只能在这两的间其它绘图即使绘图失败你也应该在重新 BeginScene 的前 EndScene
绘制完的后 IDirect3DDevice8::Present显示该场景:
g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
Present 接受前两个参数是原始矩形和目标矩形在这步例程设置这两个参数为 NULL 并把整个后备缓冲提交到前景缓冲第 3个参数用于设置该次提交目标窗口这个参数被设为 NULL实际使用窗口是
D3DPRESENT_PARAMETERS hWndDeviceWindow 成员第 4个是 DirtyRegion 参数在绝大多数情况下应该设为 NULL
本指南最终步骤是关闭应用见:步骤 5:关闭和清除
步骤 5:关闭和清除
在执行若干时刻你应用必须立即关闭关闭个 Direct3D 应用中不只是意味着你必须销毁窗口并且你还要释放中使用过任何 Direct3D 对象并且无效化它们指针当收到个 WM_DESTROY 消息时CreateDevice 例程通过个本地定义 Cleanup 来处理这些工作
VOID Cleanup
{
( g_pd3dDevice != NULL)
g_pd3dDevice->Release;
( g_pD3D != NULL)
g_pD3D->Release;
}
上述对每个对象 IUnknown::Release 思路方法来释放它们自身由于DirectX遵循 COM 规则大多数对象当其引用计数降为0时DirectX会自动从内存中释放这个对象
对于其他关闭情况可能发生在平常执行中——比如用户改变了桌面参数或色深——此时你可能需要撤销和重建使用中 Microsoft Direct3D 对象因此个好主意就是将你释放代码放到起以便能在需要时随时它
本指南已经介绍说明了如何创建个设备指南 2:演示顶点(Render Vertex) 将告诉你如何用顶点(Vertex)创建几何形体
指南 2:演示顶点(Render Vertex)
Microsoft Direct3D 写应用使用顶点(Vertex)构造几何物体每个 3维空间 (3D) 场景包括个或几个这样几何物体Vertices 例程构造简单物体个 3角形并且将它绘制到显示屏上
本指南介绍说明如何采用以下步骤从顶点构造个 3角形:
·第步:定义个自定义顶点类型
·第 2步:设置顶点缓冲
·第 3步:绘制至显示屏
注意:Vertices 举例路径为:
(SDK root)\\Samples\\Multimedia\\Direct3D\\Tutorials\\Tut02_Vertices.
Vertices 举例代码和 CreateDevice 代码大部分相同本“演示顶点(Render Vertex)”指南仅仅关注于那些独特有关顶点代码而不包括化 Direct3D处理 Microsoft Windows 消息绘图和清理等工作如要得到有关这些任务信息请参考 指南:创建设备
第步:定义个自定义顶点类型
Vertices 例程使用 3个顶点构造个 2D 3角形这里提及了顶点缓冲概念这是用于保存和演示大量顶点 Microsoft Direct3D 对象通过指定个自定义顶点结构和相应可变向量格式 (FVF)顶点能够采用很多思路方法定义本Vertices 例程使用顶点格式定义于以下代码片断中
struct CUSTOMVERTEX
{
FLOAT x, y, z, rhw; // The transformed position for the vertex.
DWORD color; // The vertex color.
};
上面结构体介绍说明了自定义顶点类型格式下步是定义 FVF 以描述顶点缓冲区中顶点内容以下代码片段定义了个 FVF 并符合此上建立自定义顶点类型
# D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)
可变顶点格式标记描述了使用中自定义顶点类型前述举例代码使用了 D3DFVF_XYZRHW 和
D3DFVF_DIFFUSE 标志这将告诉顶点缓冲自定义顶点类型包含组转换过点坐标并紧跟着个颜色参数
现在自定义向量格式和 FVF 已经被指定好了下步将使用顶点填充顶点缓冲区请参看:第 2步:设置顶点缓冲
注意:Vertices 例程中顶点是转换过用另句话说它们已经在 2D 窗口坐标系下这意味着座标点 (0,0) 位于左上角且正 x 半轴向右正 y 半轴向下这些顶点同样也是光照过这介绍说明它们着色不通过 Direct3D 照明而由它们自己颜色代替
第 2步:设置顶点缓冲
现在自定义顶点格式已经完成化顶点时候到了 Vertices 例程创建了必需 Microsoft Direct3D 对象的后本内部定义 InitVB 进行这个工作以下代码段将化 3个自定义顶点值
CUSTOMVERTEX g_Vertices =
{
{ 150.0f, 50.0f, 0.5f, 1.0f, 0xffff0000, }, // x, y, z, rhw, color
{ 250.0f, 250.0f, 0.5f, 1.0f, 0xff00ff00, },
{ 50.0f, 250.0f, 0.5f, 1.0f, 0xff00ffff, },
};
前述代码片段采用 3角形 3个顶点填充 3个Vertex并指定了每个顶点散射光颜色第个顶点位于 (150,50) 散射红色 (0xffff0000)第 2个顶点位于 (250,250) 为绿色 (0xff00ff00)第 3点位于 (50,250) 并散射蓝绿色
(0xff00ffff)每点都具有相同 0.5 Z值及 1.0 RHW 参数有关这些矢量格式其它信息见 SDK: Transformed and Lit Vertices
下步将 IDirect3DDevice8::CreateVertexBuffer 创建顶点缓冲区如以下代码段所示:
( FAILED( g_pd3dDevice->CreateVertexBuffer( 3*(CUSTOMVERTEX),
0 /* Usage */, D3DFVF_CUSTOMVERTEX,
D3DPOOL_DEFAULT, &g_pVB ) ) )
E_FAIL;
CreateVertexBuffer 头两个参数告诉 Direct3D 新顶点缓冲区预计大小和使用方法紧跟两个参数指定新缓冲区矢量格式及存储位置这里向量格式是 D3DFVF_CUSTOMVERTEX就是例程先前定义 FVF 值
D3DPOOL_DEFAULT 标记告诉 Direct3D 在最合适位置创建此顶点缓冲区最后个参数返回创建完成顶点缓冲区对象地址
创建了顶点缓冲区的后如以下代码段所示开始采用自定义格式顶点填充缓冲区中数据
VOID* pVertices;
( FAILED( g_pVB->Lock( 0, (g_Vertices), (BYTE**)&pVertices, 0 ) ) )
E_FAIL;
memcpy( pVertices, g_Vertices, (g_Vertices) );
g_pVB->Unlock;
首先 IDirect3DVertexBuffer8::Lock 锁定顶点缓冲区第个参数是锁定顶点数据偏移量按字节计算第 2个参数是需锁定顶点数据长度同样按字节计算第 3个参数是个 BYTE 类型指针地址用于返回指向顶点数据地址第 4个参数告知顶点缓冲区如何锁定数据
通过使用 memcpy顶点被复制到顶点缓冲区里将顶点放入缓冲区的后次 IDirect3DVertexBuffer8::Unlock 以解锁顶点缓冲区这个锁定——解锁机制是必需正在使用顶点缓冲区可能位于设备内存中
现在顶点缓冲区已经填入顶点绘制到显示时候到了见描述:第 3步:绘制至显示屏
第 3步:绘制至显示屏
现在缓冲区已经填入顶点现在需要把它绘制到显示屏上在绘制到屏幕的前先将背景清除为蓝色并 BeginScene
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,255), 1.0f, 0L );
g_pd3dDevice->BeginScene;
从顶点缓冲区绘制顶点数据需要些步骤首先你需要设置流数据源;在当前情况下使用第 0 个流 流数据源是通过IDirect3DDevice8::SetStreamSource 设置
g_pd3dDevice->SetStreamSource( 0, g_pVB, (CUSTOMVERTEX) );
SetStreamSource 第个参数告诉 Microsoft Direct3D 设备设置数据流索引第 2个参数是绑定在该数据流上顶点缓冲区第 3个参数是数据单元大小用字节数表示在上面举例代码中将使用CUSTOMVERTEX 大小作为数据单元大小
下步通过 IDirect3DDevice8::SetVertexShader 使 Direct3D 了解使用中顶点处理器(Vertex Shader)就整体而言自定义顶点处理器是种高级话题但是在绝大多数情况下顶点处理器仅仅等于 FVF 代码这能够让 Direct3D 知道处理中顶点类型以下代码片段将FVF设置为当前顶点处理器:
g_pd3dDevice->SetVertexShader( D3DFVF_CUSTOMVERTEX );
SetVertexShader 唯参数是当前设置顶点处理器句柄这个参数值可以是从
IDirect3DDevice8::CreateVertexShader 返回句柄或者是 FVF 代码在这儿使用参数是定义为
D3DFVF_CUSTOMVERTEX FVF 代码
有关顶点处理器更多信息请见 SDK: Vertex Shader 章
下步使用 IDirect3DDevice8::DrawPrimitive 绘制顶点缓冲区中顶点见以下代码片段:
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 1 );
DrawPrimitive 接受第个参数是个标记它通知 Direct3D 绘制哪种类型物件(Primitive)本例程使用
D3DPT_TRIANGLELIST 标记指定为 3角形序列第 2个参数是第个顶点索引第 3个参数通知绘制物件数目本例子只画个 3角形这个值为 1
有关区别种类物件更多信息可见 SDK: 3-D Primitive
最后步是结束场景并立即将后背缓冲提交为前景缓冲这些写在以下代码片段中:
g_pd3dDevice->EndScene;
g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
当后背缓冲被提交为前景缓冲后客户窗口将显示出个 3个点颜色各异 3角形
本指南已经指导你如何使用顶点构造几何外形了指南 3:使用矩阵 将介绍矩阵概念以及如何使用它们
指南 3:使用矩阵
本指南介绍矩阵概念及演示如何使用它们Vertices 例程通过呈递2D顶点画出了个 3角形然而在这个指南中你将通过顶点变换在 3-D 环境下工作矩阵和变换也同样用于设置摄影头和视口(Viewport)
在 Matrices 例程呈递几何物体的前它自定义 SetupMatrices 创建并设置用于演示 3-D 3角形矩阵变换作为代表 3种类型变换同时被设置到个 3-D 场景创建这些典型变换步骤如下表:
·第步:定义世界变换矩阵
·第 2步:定义观察变换矩阵
·第 3步:定义映射变换矩阵
注意:Matrices 举例路径为:
(SDK root)\\Samples\\Multimedia\\Direct3D\\Tutorials\\Tut03_Matrices.
创建这 3种变换顺序并不影响场景元素输出无论如何Direct3D 都使用以下顺序依次将矩阵作用于场景:(1) 世界(2) 观察(3) 映射
Matrices 工程举例代码几乎和 Vertices 工程代码相同该“使用矩阵”指南仅仅关注那些有关矩阵独特代码而不重复化 Direct3D处理 Microsoft Windows 消息演示以及清除有关这些工作信息请见 指南:创建设备
本指南使用自定义顶点格式和单个顶点缓冲区呈递几何模型有关更多有关选择自定义顶点类型以及执行顶点缓冲区信息见 指南 2:演示顶点
第步:定义世界变换矩阵(World Transformation Matrix)
世界变换矩阵定义了怎样转换、缩放、以及旋转 3-D 模拟空间中几何物体
以下代码片段为 Microsoft Direct3D 设备设置当前世界变换并且使 3角形绕 y-轴 旋转
D3DXMATRIX matWorld;
D3DXMatrixRotationY( &matWorld, timeGetTime/150.0f );
g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
第步是通过 D3DXMatrixRotationY 使 3角形绕 y-轴 旋转第个参数是指向 D3DMATRIX 结构指针用于返回操作结果第 2个参数是以弧度表示旋转角度
下步是 IDirect3DDevice8::SetTransform 给 Direct3D 设备设置世界变换SetTransform 接受第个参数通知Direct3D 被设置是哪个转换这个例子用 D3DTS_WORLD 宏指定被设置是世界变换第 2个参数是个指向被设为当前变换的矩阵指针
有关世界变换更多信息见:SDK: World Transformation
定义完场景世界变换后你可以准备观察变换矩阵了再次请注意:定义任变换顺序不是关键无论如何Direct3D 采用以下顺序将这些矩阵作用于场景:(1) 世界(2) 观察(3) 映射
定义观察变换矩阵请参看 第 2步:定义观察变换矩阵
第 2步:定义观察变换矩阵(View Transformation Matrix)
观察变换矩阵定义了观察位置和旋转角度此观察矩阵就相当于场景摄影机
以下代码片段创建了个观察变换矩阵并将其设置为 Microsoft Direct3D 设备当前观察矩阵
D3DXMATRIX matView;
D3DXMatrixLookAtLH( &matView, &D3DXVECTOR3( 0.0f, 3.0f,-5.0f ),
&D3DXVECTOR3( 0.0f, 0.0f, 0.0f ),
&D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) );
g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
第步是通过 D3DXMatrixLookAtLH 定义观察矩阵第个参数是个指向 D3DXMATRIX 结构指针用来接受操作结果第 2、 3、 4个参数定义了观察点、注视点、以及方向“上”这儿设置观察点为沿 Z-轴 反方向 5 单位再往上3 单位注视点为原点以及作为“上”方向为 Y-轴
下步是 IDirect3DDevice8::SetTransform 给 Direct3D 设备设置观察矩阵SetTransform 接受第个参数通知Direct3D 哪个变换将要被设置该例程使用 D3DTS_VIEW 标记指定为观察矩阵第 2个参数是个指向矩阵指针它被设为当前变换
有关观察矩阵更多信息见:SDK: View Transformation
定义了场景世界变换后你可以开始准备映射变换矩阵了再次提醒定义每变换顺序不是关键性无论如何Direct3D 总是采用以下顺序将矩阵应用于场景:(1) 世界(2) 观察(3) 映射
定义映射变换矩阵工作被描述在 第 3步:定义映射变换矩阵
第 3步:定义映射变换矩阵(Projection Transformation Matrix)
映射变换矩阵定义了将 3-D 观察空间转换为 2-D 视口空间几何学思路方法
以下代码片段创建映射变换矩阵并将其设为 Microsoft Direct3D 设备当前映射变换
D3DXMATRIX matProj;
D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f );
g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
第步是 D3DXMatrixPerspectiveFovLH 设置映射矩阵第个参数是个指向 D3DXMATRIX 结构用于接受操作结果第 2个参数定义视场它介绍说明物体如何随着距离而缩小个典型视场是 1/4 π就像这个例子使用样第 3个参数定义了屏幕纵横比本举例采用典型纵横比 1第 4和第 5个参数定义最近和最远剪切平面这是用于确定位于何种距离的外几何物体无需再绘制本 Matrices 举例设置它最近剪切平面为 1最远剪切平面为 100
下步是 IDirect3DDevice8::SetTransfrom 对 Direct3D 应用变换SetTransfrom 接受第个参数通知 Direct3D 何种变换被设置本例程使用 D3DTS_PROJECTION 标志指定映射变换将被设置第 2个参数是个指向矩阵指针它将被设置为当前变换
有关映射变换更多信息参见:“映射变换”
本指南已经提示你如何使用矩阵指南 4:创建和使用光源 将揭示如何在你场景中添加光源以增加真实性
指南 4:创建和使用光源
Microsoft Direc3D 光照系统给 3-D 物体提供更多真实性当使用它时每个场景中几何对象将被照亮基于它们位置和使用光源类型这个指南例程将介绍有关光照和材质主题
本指南包含以下步骤用于创建材质和光照:
·第步:创始化场景几何
·第 2步:设置材置和光照
注意:Lights 举例路径为:
(SDK root)\\Samples\\Multimedia\\Direct3D\\Tutorials\\Tut04_Lights.
注意:Lights 例程中代码和 Matrices 例程代码几乎完全样“创建和使用光源”指南仅仅关注于有关创建和使用光照独特代码而并不重复有关设置 Direct3D处理 Microsoft Windows 消息绘制或者清理内容有关这些任务其他信息见:指南:创建设备
本指南使用自定义顶点和顶点缓冲区呈递几何形体有关选择个自定义顶点格式并执行顶点缓冲更多信息见:指南2:演示顶点
本指南采用矩阵变换几何对象有关矩阵和变换更多信息参见:指南 3:使用矩阵
第步:创始化场景几何
使用光照个前提是每个表面都应该有法向量为此Lights 例程使用个稍微区别自定义顶点格式新自定义顶点格式具有个 3-D 位置坐标和个表面法向量这个表面法向量被用于 Microsoft Direct3D 光照计算核心
struct CUSTOMVERTEX
{
D3DXVECTOR3 position; // The 3-D position for the vertex.
D3DXVECTOR3 normal; // The surface normal for the vertex.
};
// Custom FVF.
# D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL)
现在适当矢量格式定义好了Lights 例程 InitGeometry个自定义以创建个圆柱体最初步骤是创建个顶点缓冲区并用它保存这个圆柱体各点如以下例代码所示:
// Create the vertex buffer.
( FAILED( g_pd3dDevice->CreateVertexBuffer( 50*2*(CUSTOMVERTEX),
0 /* Usage */, D3DFVF_CUSTOMVERTEX,
D3DPOOL_DEFAULT, &g_pVB ) ) )
E_FAIL;
下步是使用圆柱体顶点填充顶点缓冲区注意下面举例代码每个点都被定义了个位置和个法向量
for( DWORD i=0; i<50; i )
{
FLOAT theta = (2*D3DX_PI*i)/(50-1);
pVertices[2*i+0].position = D3DXVECTOR3( sinf(theta),-1.0f, cosf(theta) );
pVertices[2*i+0].normal = D3DXVECTOR3( sinf(theta), 0.0f, cosf(theta) );
pVertices[2*i+1].position = D3DXVECTOR3( sinf(theta), 1.0f, cosf(theta) );
pVertices[2*i+1].normal = D3DXVECTOR3( sinf(theta), 0.0f, cosf(theta) );
}
在前述例程使用圆柱体顶点填充了顶点缓冲区的后这个顶点缓冲区已经准备好用于呈递了但是首先这个场景材质和光照必须在绘制圆柱体的前被设置这些描述在 第 2步:设置材质和光照
第 2步:设置材质和光照
为了在 Microsoft Direct3D 中使用光照你必须创建个或多个光源为了确定个几何物体放射何种颜色光线材质必须被创建于绘制几何对象在绘制这个场景的前Lights 例程 SetupLights个自定义来设置材质和个方向性光源
创建种材质
材质被定义为当束光照到几何物体表面后反射出颜色以下代码片段使用 D3DMATERIAL8 结构来创建个黄色材质
D3DMATERIAL8 mtrl;
ZeroMemory( &mtrl, (D3DMATERIAL8) );
mtrl.Dfuse.r = mtrl.Ambient.r = 1.0f;
mtrl.Dfuse.g = mtrl.Ambient.g = 1.0f;
mtrl.Dfuse.b = mtrl.Ambient.b = 0.0f;
mtrl.Dfuse.a = mtrl.Ambient.a = 1.0f;
g_pd3dDevice->SetMaterial( &mtrl );
这个材质漫射光颜色和环境光颜色都被设为黄色对 IDirect3DDevice8::SetMaterial 将应用此材质到用于绘制场景 Microsoft Direct3D 设备SetMaterial 接受唯参数是设置材质指针在这个完成以后每个物件都将使用这个材质绘制直到另次对 SetMaterial 指定了个区别材质为止
现在材质已经被应用到场景下个步骤是创建光源
创建个光源
Microsoft Direct3D 里有 3种可用光源:点光源方向形光源和聚光灯光源本举例代码创建个方向形光源它向个方向发光并且不停变换发光方向
下列代码片段使用 D3DLIGHT8 结构创建个方向性光源
D3DXVECTOR3 vecDir;
D3DLIGHT8 light;
ZeroMemory( &light, (D3DLIGHT8) );
light.Type = D3DLIGHT_DIRECTIONAL;
下列代码片设置光源漫射光为白色
light.Dfuse.r = 1.0f;
light.Dfuse.g = 1.0f;
light.Dfuse.b = 1.0f;
以下代码片在个环内旋转光源方向
vecDir = D3DXVECTOR3(cosf(timeGetTime/360.0f),
0.0f,
sinf(timeGetTime/360.0f) );
D3DXVec3Normalize( (D3DXVECTOR3*)&light.Direction, &vecDir );
对 D3DXVec3Normalize 将归化方向矢量并化光源方向
可以设置个范围告诉 Direct3D 此光源能影响多远距离这个成员参数对方向性光源无效以下代码片指定此光源范围为 1000 单位
light.Range = 1000.0f;
下面代码片将这个光源分配到当前 Direct3D 设备通过 IDirect3DDevice8::SetLight
g_pd3dDevice->SetLight( 0, &light );
SetLight 接受第个参数是此光源被分配索引号注意如果在此索引已存在个光源它将被新光源覆盖第 2个参数是个指向新定义光源数据结构指针本 Lights 例程设置这个光源位于 0 号索引
下列代码片激活这个光源通过 IDirect3DDevice8::LightEnable
g_pd3dDevice->LightEnable( 0, TRUE);
LightEnable 接受第个参数是激活光源索引第 2个参数是个布尔量通知此光源是开 (TRUE) 还是闭 (FALSE)在上面例程中索引 0 上光源被打开
以下代码片通知 Direct3D 呈递此光源通过 IDirect3DDevice8::SetRenderState
g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
SetRenderState 接受头两个参数是哪个设备状态变量被改写以及写入何种值本例程设置 D3DRS_LIGHTING 设备变量为 TRUE这将使设备能够演示光照效果
本例程最后步是通过再次 SetRenderState 打开环境照明光
g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0x00202020 );
当前代码段设置 D3DRS_AMBIENT 设备变量为种浅灰色 (0x00202020)环境照明将使用所给颜色照亮所有物体
有关照明及材质更多信息参见 SDK: Lights and Materials
本例程向你介绍说明了如何使用照明和材质指南 5:使用纹理映射 将向你介绍说明如何将纹理添加到物体表面上
指南 5:使用纹理映射
尽管光照和材质大大增加了场景真实感但没有比在表面上添加纹理更能增加真实感了纹理能够被想象为层紧紧包装在表面贴纸你能在个立方体上放置层木质纹理使它看起来就象用木头制成样本 Texture 例程将在 指南 4:创建和使用光照 中构造圆柱上添加幅类似香蕉纹理此指南介绍内容包括如何载入纹理设置纹理和呈递带有纹理物体
本指南采用以下步骤实现纹理:
·第步:定义个定制顶点格式
·第 2步:化屏幕几何
·第 3步:演示场景。