在Microsoft® DirectX® 8.x之前,Microsoft® Direct3D®以固定功能流水线的方式运作,把三维几何体渲染到屏幕上的像素。用户设置流水线的属性,以控制Direct3D变换、光照和渲染像素的方式。固定功能顶点格式用来确定输入顶点的格式,在编译时定义。一旦定义,用户就无法在运行的时候控制流水线的改变。
通过允许在运行的时候进行变换、光照和渲染的功能,可编程着色器将图形流水线带入了一个新的高度。着色器是在运行时定义的,但是当完成以后,用户可以改变要激活哪个着色器,并使用数据流动态地控制着色器。这在渲染像素的方法上,给了用户更高的灵活性。
顶点着色器文件包含顶点着色器指令。顶点着色器可以控制顶点颜色和把纹理应用于顶点的方式。也可以通过使用顶点着色器指令加入光照。着色器指令文件包含的是ASCII文本,因此它是可读的,并且看起来有点象汇编语言。顶点着色器在任何DrawPrimitive或DrawIndexedPrimitive之后被调用。用SetVertexShader指定新的着色器文件可以动态地切换着色器,也可以用数据流输入改变ASCII文本的着色器文件中的指令。Vertex_Shader_1_1中包含了着色器指令的完全列表。
指令集的变化非常快。为避免在使用指令时出现问题,请查阅硬件开发商的网站。或者,也可以使用高级着色器语言,这样就可以得到由Direct3D扩展(D3DX)编译得到的着色器指令。
本示例创建一个顶点着色器,把一固定颜色应用于物体。本示例将会给出着色器文件的内容,以及为了在应用程序中使用该着色器而设置Microsoft® Direct3D®流水线所需的代码。
如果读者已经知道如何构建并运行Direct3D示例,那么可以从本示例中复制代码并粘贴到已有的应用程序中。
本文讨论了以下几个步骤。
本示例使用由两个三角形构成的四边形。顶点数据包含(x,y,z)位置和漫反射色。顶点数据在一个全局顶点数组(g_Vertices)中声明。四个顶点以原点为中心。
// 声明顶点数据结构。struct CUSTOMVERTEX
{ FLOAT x, y, z;}; // 声明顶点位置和漫反射色。CUSTOMVERTEX g_Vertices[]={ // x y z { -1.0f, -1.0f, 0.0f }, { +1.0f, -1.0f, 0.0f }, { +1.0f, +1.0f, 0.0f }, { -1.0f, +1.0f, 0.0f }, };
该着色器将一固定颜色应用于每个顶点。以下为着色器文件VertexShader.vsh:
vs_1_1 // 版本指令dcl_position v0 // 说明位置数据在寄存器v0中
m4x4 oPos, v0, c0 // 用视/投影矩阵变换顶点mov oD0, c4 // 载入固定颜色
该文件包含了三条数据运算指令和一个寄存器定义。着色器文件的第一条指令必须是着色器版本声明。vs指令用来声明顶点着色器的版本,此处为1_1。
dcl_position指令把寄存器v0定义为顶点位置数据的源。m4x4指令用视/投影矩阵对物体的顶点进行变换。矩阵被载入并保存在常量寄存器c0, c1, c2, c3(如下所示)中。Mov指令把寄存器c4中的固定颜色复制到输出漫反射色寄存器oD0中。这导致输出顶点的颜色被改变。
在使用顶点着色器之前,可以查询驱动程序对顶点着色器的支持。
D3DCAPS9 caps;m_pd3dDevice->GetDeviceCaps(&caps); // 在使用前初始化m_pd3dDeviceif( caps.VertexShaderVersion < D3DVS_VERSION(1,1) )
return E_FAIL;
在调用IDirect3DDevice9::GetDeviceCaps后,caps结构会返回硬件可用的能力。应该用D3DVS_VERSION宏测试硬件支持的版本号。如果版本号小于1_1,那么该调用将会失败。这个方法的结果应该被应用程序用来控制是否使用顶点着色器。
顶点声明用来描述顶点数据。
// 创建着色器声明。
D3DVERTEXELEMENT9 decl[] = { { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, D3DDECL_END()};
这个声明说明了以下这些:数据来自数据流0,从数据流起始位置起偏移量为0处的位置开始,声明位置数据为三个浮点数(D3DDECLTYPE_FLOAT3),告诉tessellator复制顶点数据(D3DDECLMETHOD_DEFAULT),定义数据的用途为顶点数据(D3DDECLUSAGE_POSITION),并说明用途索引为0。
D3DDECLEND()宏用来结束顶点声明。
下一步汇编并创建着色器。
LPDIRECT3DPIXELSHADER9 m_pVertexShader;TCHAR strShaderPath[512];LPD3DXBUFFER pCode; // 包含经过汇编的着色器代码的缓存LPD3DXBUFFER pErrorMsgs; // 包含错误信息的缓存DXUtil_FindMediaFileCb( strShaderPath, sizeof(strShaderPath),
_T("VertexShader.vsh") ); D3DXAssembleShaderFromFile( strPixelShaderPath, NULL, NULL, 0,
&pCode, &pErrorMsgs, NULL ); m_pd3dDevice->CreateVertexShader((DWORD*)pCode->GetBufferPointer(), &m_pVertexShader)pCode->Release();
pErrorMsgs->Release()
在定位了着色器文件后,D3DXAssembleShaderFromFile读取并验证着色器指令。然后IDirect3DDevice9::CreateVertexShader对指令进行汇编并创建着色器。该方法会返回用于绘制时调用的着色器对象。
CreateVertexShader用于创建一个可编程着色器。
这里是一份代码示例,可以用在渲染循环中用顶点着色器来渲染物体。由于三维场景的变化,渲染循环不断更新顶点着色器常数,并调用IDirect3DDevice9::DrawPrimitive绘制输出顶点。
// 用视/投影矩阵更新顶点着色器常数。D3DXMATRIX mat, matView, matProj; D3DXMatrixMultiply( &mat, &matView, &matProj );
D3DXMatrixTranspose( &mat, &mat );
m_pd3dDevice->SetVertexShaderConstantF( 0, (float*)&mat, 4 ); // 声明并定义固定的顶点颜色。float color[4] = {0,1.0,0,0};
m_pd3dDevice->SetVertexShaderConstantF( 4, (float*)&color, 1 ); // 关闭镜面反射光,因为顶点着色器没有输出镜面反射光。m_pd3dDevice->SetRenderState( D3DRS_SPECULAR, FALSE ); // 渲染输出。m_pd3dDevice->SetStreamSource( 0, m_pQuadVB, sizeof(CUSTOMVERTEX) );m_pd3dDevice->SetVertexShader( m_pVertexShader );m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 2 );
视和投影矩阵包含了摄像机的位置和方向的数据。因为场景可能在渲染得到的帧之间变化,所以渲染循环中要得到最新的数据,并用这些数据更新着色器的常量寄存器
IDirect3DDevice9::DrawPrimitive照常使用IDirect3DDevice9::SetStreamSource提供的数据渲染输出数据。IDirect3DDevice9::SetVertexShader是用来告诉Direct3D要使用顶点着色器。顶点着色器的结果如下图,它显示了在平面物体上的固定颜色。

本示例把顶点数据中的顶点颜色应用于物体。顶点数据包含了位置和漫反射色。这些数据如下所示:
struct CUSTOMVERTEX_POS_COLOR
{ float x, y, z; DWORD diffuseColor;}; // 创建包含位置和纹理坐标的顶点数据。CUSTOMVERTEX_POS_COLOR g_Vertices[]={ // x y z 漫反射色 { -1.0f, 0.25f, 0.0f, 0xffff0000, }, // 右下 – 红 { 0.0f, 0.25f, 0.0f, 0xff00ff00, }, // 左下 – 绿 { 0.0f, 1.25f, 0.0f, 0xff0000ff, }, // 左上 – 蓝 { -1.0f, 1.25f, 0.0f, 0xffffffff, }, // 右上 – 白};
顶点着色器声明也需要反映位置和颜色数据。
// 创建着色器声明。D3DVERTEXELEMENT9 decl[] = {{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
{ 0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 },
D3DDECL_END()};
着色器得到变换矩阵的一种方法是通过常量寄存器,常量寄存器是通过调用SetVertexShaderConstant设置的。
D3DXMATRIX mat;
D3DXMatrixMultiply( &mat, &m_matView,
&m_matProj );
D3DXMatrixTranspose( &mat, &mat );
hr = m_pd3dDevice->SetVertexShaderConstantF(
1, (float*)&mat, 4 );
if(FAILED(hr))
return hr;
该声明声明了一个包含了位置和颜色数据的数据流。颜色数据被指定到寄存器1。以下是着色器代码。
vs_1_1
; 版本指令
m4x4 oPos, v0, c0 ; 用视/投影矩阵变换顶点
mov oD0, v1
; 从寄存器1载入颜色并赋给漫反射色
这个着色器包含三条指令。第一条总是版本指令。第二条指令用来变换顶点。第三条指令用来把顶点寄存器中的颜色复制到输出漫反射色寄存器中。结果是输出顶点使用了顶点的颜色数据。
得到的输出看起来如下所示:

本示例将一张纹理贴图应用于物体。
顶点数据包含了物体的位置和纹理坐标(uv)。这导致了顶点声明的改变。下面还显示了顶点数据。
struct CUSTOMVERTEX_POS_TEX1
{ float x, y, z; // 物体位置 float tu1, tv1; // 纹理坐标}; CUSTOMVERTEX_POS_TEX1 g_Vertices[]={ // x y z u1 v1 { -0.75f, -0.5f, 0.0f, 0.0f, 0.0f }, // 右下 – 红 { 0.25f, -0.5f, 0.0f, 1.0f, 0.0f }, // 左下 – 绿 { 0.25f, 0.5f, 0.0f, 1.0f, -1.0f }, // 左上 – 蓝 { -0.75f, 0.5f, 0.0f, 0.0f, -1.0f }, // 右上 – 白}; D3DUtil_CreateTexture( m_pd3dDevice, TEXT("earth.bmp"), &m_pTexture0, D3DFMT_R5G6B5 );
必须先载入纹理的图像。在本例中,文件"earth.bmp"包含了地球的二维纹理贴图,并将被用来给物体着色。
顶点着色器声明需要反映出顶点位置和纹理坐标数据。
// 创建着色器声明。D3DVERTEXELEMENT9 decl[] = {{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
{ 0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
D3DDECL_END()};
该声明声明了一个包含顶点位置和纹理坐标的数据流。
渲染代码告诉Microsoft® Direct3D®到何处去得到数据流和着色器,因为使用了纹理贴图,所以还要设置纹理层。
m_pd3dDevice->SetStreamSource( 0, m_pQuadVB, sizeof(CUSTOMVERTEX_POS_TEX1) );m_pd3dDevice->SetVertexShader( m_pVertexShader ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );m_pd3dDevice->SetTexture( 0, m_pTexture0 );m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 2 );m_pd3dDevice->SetTexture( 0, NULL );
因为使用了一个纹理,所以需要设置纹理层0的纹理层状态。上面调用的方法告诉Direct3D纹理的texel值用来给物体的顶点提供漫反射色。换句话说,二维纹理贴图的使用就象贴花纸一样。
这里是着色器代码。
vs_1_1 // 版本指令dcl_position v0 // 声明位置寄存器
dcl_texcoord v8 // 声明纹理坐标寄存器
def c4, 1, 1, 1, 1 // 初始化常量m4x4 oPos, v0, c0 // 用视/投影矩阵变换顶点mov oD0, c4 // 把漫反射色赋给输出颜色寄存器
mov oT0, v8 // 把纹理的颜色赋给纹理寄存器
着色器文件包含的这些指令会产生一个贴上了纹理的物体,如下所示。

本实例使用了一个顶点着色器,将纹理贴图和光照应用于场景。这里使用的物体是一个球体,示例代码把地球的纹理贴图应用于球体,并用漫反射光照来模拟昼夜。
Shader3实例给贴上了纹理的物体添加了光照。关于如何载入纹理和设置纹理层状态的信息,请参阅Shader3。
在示例框架中有关于框架的示例代码的详细说明。读者可以复制这里的示例代码并粘贴到示例框架中去,这样就可以很快得到一个能运行的示例。
为了包含顶点法向,需要修改Shader3实例中的顶点数据。要产生光照,物体必须有顶点法向。修改后的顶点数据的数据结构如下所示。
struct CUSTOMVERTEX_POS_NORM_COLOR1_TEX1
{ float x, y, z; // 位置 float nx, ny, nz; // 法向 DWORD color1; // 漫反射色 float tu1, tv1; // 纹理坐标};
着色器声明定义了输入顶点寄存器以及和它们关联的数据。
// 创建着色器声明。
D3DVERTEXELEMENT9 decl[] = {{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
{ 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
{ 0, 24, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 },
{ 0, 28, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
D3DDECL_END()};
这里声明了一个数据流,其中包含了顶点位置,法向,漫反射色和纹理坐标。
下一步是创建着色器。可以用一个ASCII文本字符串创建着色器,也可以从包含相同指令的着色器文件中载入。本示例使用着色器文件。
// v7 用于光照的顶点漫反射色// v8 纹理// c4 视/投影矩阵// c12 光的方向 vs_1_1 // 版本指令dcl_position v0 // 声明寄存器数据
dcl_normal v4 // v0为位置,v4为法向
dcl_color0 v7 // v7为漫反射色dcl_texcoord0 v8 // v8为纹理坐标m4x4 oPos, v0, c4 // 用视/投影矩阵变换顶点dp3 r0, v4, c12 // 执行世界空间中的光照计算N dot Lmul oD0, r0.x , v7 // 根据光强度和经插值的顶点漫反射色计算像素的最终颜色
mov oT0.xy , v8 // 将纹理坐标得到到输出
第一条总是版本指令,最后一条指令把纹理数据复制到输出寄存器oT0。写完了着色器指令后,就可以用来创建着色器。
LPDIRECT3DPIXELSHADER9 m_pVertexShader;TCHAR strShaderPath[512];LPD3DXBUFFER pCode; // 包含汇编后的着色器代码的缓存LPD3DXBUFFER pErrorMsgs; // 包含错误信息的缓存DXUtil_FindMediaFileCb( strShaderPath, sizeof(strShaderPath),
_T("VertexShader3.vsh") ); D3DXAssembleShaderFromFile( strPixelShaderPath, NULL, NULL, 0,
&pCode, &pErrorMsgs, NULL ); m_pd3dDevice->CreateVertexShader((DWORD*)pCode->GetBufferPointer(), &m_pVertexShader)pCode->Release();
pErrorMsgs->Release();
在定位了文件后,Microsoft® Direct3D®会创建顶点着色器并返回着色器对象。本示例用了一个着色器文件,这样调用一个方法就可以创建着色器。另一种方法是创建一个包含着色器指令的ASCII文本字符串。
可以在着色器外定义顶点着色器常量,如以下示例所示。此处,常量用来给着色器提供视/投影矩阵,漫反射光颜色RGBA和光的方向向量。
float constants[4] = {0, 0.5f, 1.0f, 2.0f};
m_pd3dDevice->SetVertexShaderConstantF( 0, (float*)&constants, 1 ); D3DXMATRIX mat;D3DXMatrixMultiply( &mat, &m_matView, &m_matProj );
D3DXMatrixTranspose( &mat, &mat );
m_pd3dDevice->SetVertexShaderConstantF( 4, (float*)&mat, 4 ); float color[4] = {1,1,1,1};
m_pd3dDevice->SetVertexShaderConstantF( 8, (float*)&color, 1 ); float lightDir[4] = {-1,0,1,0}; // fatter slice
m_pd3dDevice->SetVertexShaderConstantF( 12, (float*)&lightDir, 1 );
也可以在着色器内部用def指令定义常量。
在写完着色器指令后,要将顶点数据与正确的顶点寄存器连接并初始化常量,然后渲染输出。渲染代码告诉Direct3D到哪里去得到顶点缓存的数据流,并给Direct3D提供着色器的句柄。因为使用了纹理,所以还必须设置纹理层以告诉Direct3D如何使用纹理数据。
// 设置顶点缓存的数据源。m_pd3dDevice->SetStreamSource(0, m_pVB, sizeof(CUSTOMVERTEX_POS_NORM_COLOR1_TEX1));// 设置着色器。m_pd3dDevice->SetVertexShader( m_pVertexShader ); // 设置用到的纹理和纹理层状态。m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );m_pd3dDevice->SetTexture( 0, m_pTexture0 ); // 绘制物体。DWORD dwNumSphereVerts = 2 * m_dwNumSphereRings*(m_dwNumSphereSegments + 1);m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, dwNumSphereVerts - 2);
下面是输出的图像。

贴了纹理后,球体看起来像是地球。光照在球体表面产生了从亮到暗的变化。
在Microsoft® DirectX® 9.0中,顶点着色器和顶点声明不再是在创建顶点着色器(CreateVertexShader)的时候绑定在一起。对着色器的验证已经被分成两部分,一部分在顶点着色器创建时执行,另一部分在绘制(DrawPrimitive)时执行。
顶点着色器和顶点声明都由相应的对象表示。为了使之能与DirectX 8.x驱动程序一起工作,Direct3D进行了一些高速缓存。在“绘制的时候”,运行库会检查是否存在一个组合着色器对象,该对象封装了当前声明和着色器。如果存在,那么运行库会将它送给驱动程序,反之,运行库会为当前着色器和声明的组合创建一个新的组合着色器对象。另外,为了解决API的可用性问题,9.0版增加了一个与SetVertexDeclaration调用等价的SetFVF调用。这是一个有用的函数,当调用这个函数时,新的FVF会取代当前的顶点声明,反之亦然。如果驱动程序是DirectX 8.0之前的版本(NumStream为0),那么对于那些不能被转换成弹性顶点格式(FVF)的顶点声明,SetVertexDeclaration可能会失败并返回错误码。
在DirectX 8.x驱动程序(numstrems不为零,但不支持数据流偏移量)上允许使用声明的一个子集,只能创建那些可被转换为
DirectX 8.x风格的声明。由于这个原因,如果声明不能被转换,那么CreateVertexDeclaration调用可能会失败。对混合模式设备来说,此类失败会发生在Drawxxx的时候,因为只有这时候才能知道着色器是被用于硬件还是软件顶点处理。表中概括了这类转换。
在DirectX 8.0之前的驱动程序(numstreams为零)上允许使用一个更小的子集,只能使用那些可被转换为FVF的声明。如果无法进行转换,那么CreateVertexDeclaration可能会失败。对混合模式设备来说,此类失败会发生在Drawxxx的时候,因为只有这时候才能知道着色器是被用于硬件还是软件顶点处理。表中概括了这类转换。只能使用数据流0(显然可以从MaxStreams设备能力中看出)。
顶点元素的顺序应该和FVF码相对应,D3DDECLUSAGE_POSITION和D3DDECLUSAGE_NORMAL的用途索引应该为零。使用混合顶点处理的设备时,如果要切换顶点处理模式,那么无需重置所有的输入顶点(和索引)数据流,顶点声明和顶点函数。不能用NULL作为SetVertexDeclaration的输入。在使用软件顶点处理时,可编程顶点流水线的着色器代码中用到的用途也应该存在于在绘制的时候与之绑定的声明(或FVF)中。
符合以下规则的声明可以用来在固定功能流水线(假设不需要tessellation)中进行渲染。
|
DirectX 8.x |
DirectX 9.0 用途 |
DirectX 9.0 用途索引 |
|
D3DVSDE_POSITION |
D3DDECLUSAGE_POSITION |
0 |
|
D3DVSDE_POSITION2 |
D3DDECLUSAGE_POSITION |
1 |
|
D3DVSDE_NORMAL |
D3DDECLUSAGE_NORMAL |
0 |
|
D3DVSDE_NORMAL2 |
D3DDECLUSAGE_NORMAL |
1 |
|
D3DVSDE_BLENDWEIGHT |
D3DDECLUSAGE_BLENDWEIGHT |
0 |
|
D3DVSDE_BLENDINDICES |
D3DDECLUSAGE_BLENDINDICES |
0 |
|
D3DVSDE_PSIZE |
D3DDECLUSAGE_PSIZE |
0 |
|
D3DVSDE_DIFFUSE |
D3DDECLUSAGE_COLOR |
0 |
|
D3DVSDE_SPECULAR |
D3DDECLUSAGE_COLOR |
1 |
|
D3DVSDE_TEXCOORDn |
D3DDECLUSAGE_TEXCOORD |
n |
|
FVF |
数据类型 |
用途 |
用途索引 |
|
D3DFVF_XYZ |
D3DDECLTYPE_FLOAT3 |
D3DDECLUSAGE_POSITION |
0 |
|
D3DFVF_XYZRHW |
D3DDECLTYPE_FLOAT4 |
D3DDECLUSAGE_POSITIONT |
0 |
|
D3DFVF_XYZW |
D3DDECLTYPE_FLOAT4 |
D3DDECLUSAGE_POSITIONT |
0 |
|
D3DFVF_XYZB5 and
D3DFVF_LASTBETA_UBYTE4 |
D3DVSDT_FLOAT3,
D3DVSDT_FLOAT4, D3DVSDT_UBYTE4 |
D3DDECLUSAGE_POSITION,
D3DDECLUSAGE_BLENDWEIGHT, D3DDECLUSAGE_BLENDINDICES |
0 |
|
D3DFVF_XYZB5 |
D3DDECLTYPE_FLOAT3,
D3DDECLTYPE_FLOAT4, D3DDECLTYPE_FLOAT1 |
D3DDECLUSAGE_POSITION,
D3DDECLUSAGE_BLENDWEIGHT, D3DDECLUSAGE_BLENDINDICES |
0 |
|
D3DFVF_XYZBn
(n=1..4) |
D3DDECLTYPE_FLOAT3
D3DDECLTYPE_FLOATn |
D3DDECLUSAGE_POSITION,
D3DDECLUSAGE_BLENDWEIGHT |
0 |
|
D3DFVF_XYZBn
(n=1..4) and D3DFVF_LASTBETA_UBYTE4 |
D3DDECLTYPE_FLOAT3
D3DDECLTYPE_FLOAT(n-1) D3DDECLTYPE_UBYTE4 |
D3DDECLUSAGE_POSITION,
D3DDECLUSAGE_BLENDWEIGHT, D3DDECLUSAGE_BLENDINDICES |
0 |
|
D3DFVF_NORMAL |
D3DDECLTYPE_FLOAT3 |
D3DDECLUSAGE_NORMAL |
0 |
|
D3DFVF_PSIZE |
D3DDECLTYPE_FLOAT1 |
D3DDECLUSAGE_PSIZE |
0 |
|
D3DFVF_DIFFUSE |
D3DDECLTYPE_D3DCOLOR |
D3DDECLUSAGE_COLOR |
0 |
|
D3DFVF_SPECULAR |
D3DDECLTYPE_D3DCOLOR |
D3DDECLUSAGE_COLOR |
1 |
|
D3DFVF_TEXCOORDSIZEm(n) |
D3DDECLTYPE_FLOATm |
D3DDECLUSAGE_TEXCOORD |
n |
|
用途 |
用途索引 |
DirectX decl |
|
D3DDECLUSAGE_POSITION |
0 |
D3DVSDE_POSITION |
|
D3DDECLUSAGE_POSITION |
1 |
D3DVSDE_POSITION2 |
|
D3DDECLUSAGE_BLENDWEIGHT |
0 |
D3DVSDE_BLENDWEIGHT |
|
D3DDECLUSAGE_BLENDINDICES |
0 |
D3DVSDE_BLENDINDICES |
|
D3DDECLUSAGE_NORMAL |
0 |
D3DVSDE_NORMAL |
|
D3DDECLUSAGE_NORMAL |
1 |
D3DVSDE_NORMAL2 |
|
D3DDECLUSAGE_PSIZE |
0 |
D3DVSDE_PSIZE |
|
D3DDECLUSAGE_COLOR |
0 |
D3DVSDE_DIFFUSE |
|
D3DDECLUSAGE_COLOR |
1 |
D3DVSDE_SPECULAR |
|
D3DDECLUSAGE_TEXCOORD |
n |
D3DVSDE_TEXTUREn, n <= 7 |
在DirectX 8.0及以后的驱动程序上,更多的类型可以成功地被转换为有效的声明,因此可以被用于固定功能顶点处理。