setstreamsource:SetStreamSource函数和数据流的使用



Microsoft®DirectX®8.0引入了数据流概念用来把数据绑定到着色器使用输入寄存器个数据流是个成员数据每个成员由个或多个元素构成这些元素代表单个实体如位置、法向、颜色等等数据流使图形芯片能并行地从多个顶点缓存Cache执行直接内存访问(DMA)操作同时也降低了多重纹理开销可以这样理解数据流:

个顶点由n个数据流组成
个数据流由m个元素组成
个元素是[位置、颜色、法向、纹理坐标]

IDirect3DDevice9::SetStreamSource思路方法把个顶点缓存Cache绑定到个设备数据流这样就在顶点数据和个顶点数据流端口的间建立了联系有多个数据流端口用来给图元处理输入数据对数据流中数据真正引用只有在诸如IDirect3DDevice9::DrawPrimitive的类绘制思路方法时才发生www.

从输入顶点元素到可编程顶点着色器使用顶点输入寄存器映射是在着色器声明中定义但是输入顶点元素并没有专门语义来描述它们使用对输入顶点元素解释通过着色器指令进行编程顶点着色器个指令定义这些指令会应用于每个顶点顶点输出寄存器用着色器指令显式地写入

本节讨论较少关注从元素到寄存器语义映射而更侧重于“为什么要使用数据流?”和“数据流可以解决什么问题?”这些问题数据流最大好处是消除了原来和多重纹理有关顶点数据开销在引入数据流的前为了处理单纹理和多重纹理情况用户要么复制两份顶点数据每份顶点数据中都没有用不到数据;要么在份顶点数据中包含所有数据元素但其中部分数据除了多重纹理情况以外不会被用到

这里是个使用两份顶点数据举例份用于单纹理份用于多重纹理

structCUSTOMVERTEX_TEX1
{
FLOATx,y,z;//未经变换顶点位置
DWORDdfColor;//顶点漫反射色
DWORDspecColor;//顶点镜面反射色
floattu_1,tv_1;//单纹理纹理坐标
};

structCUSTOMVERTEX_TEX2
{
FLOATx,y,z;//未经变换顶点位置
DWORDdfColor;//顶点漫反射色
DWORDspecColor;//顶点镜面反射色
floattu_2,tv_2;//多重纹理纹理坐标
};

种思路方法是在个顶点元素中包含全部两组纹理坐标

structCUSTOMVERTEX_TEX2
{
FLOATx,y,z;//未经变换顶点位置
DWORDdfColor;//顶点漫反射色
DWORDspecColor;//顶点镜面反射色
floattu_1,tv_1;//单纹理纹理坐标
floattu_2,tv_2;//多重纹理纹理坐标 [Page]
};

如果使用这份顶点数据那么只要在内存中保存份顶点和颜色数据代价是在渲染过程中保存了全部两组纹理坐标甚至在单纹理情况下也是如此

现在这其中权衡已经很清楚了数据流为这种左右为难情况提供了种极好解决方案这里提供了套顶点定义用来支持 3个数据流:个数据流包含位置和颜色个数据流包含第组纹理坐标个数据流包含第 2组纹理坐标

//多数据流顶点
//数据流0,位置,漫反射色,镜面反射色
structPOSCOLORVERTEX
{
FLOATx,y,z;
DWORDdfColor,specColor;
};

#D3DFVF_POSCOLORVERTEX(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_SPECULAR)

//数据流1,纹理坐标组0
structTEXC0VERTEX
{
FLOATtu1,tv1;
};

#D3DFVF_TEXC0VERTEX(D3DFVF_TEX1)

//数据流2,纹理坐标组1
structTEXC1VERTEX
{
FLOATtu2,tv2;
};

#D3DFVF_TEXC1VERTEX(D3DFVF_TEX0)

顶点定义为:

//多重纹理–多重数据流
D3DVERTEXELEMENT9dwDecl3=
{
{0,0,D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_POSITION,0},
{0,12,D3DDECLTYPE_D3DCOLOR,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_COLOR,0},
{0,28,D3DDECLTYPE_D3DCOLOR,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_COLOR,1},
{1,0,D3DDECLTYPE_FLOAT2,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_TEXCOORD,0},
{2,0,D3DDECLTYPE_FLOAT2,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_TEXCOORD,0},
D3DDECL_END
};

现在创建顶点声明对象如下所示:



LPDIRECT3DVERTEXDECLARATION9m_pVertexDeclaration;
g_d3dDevice->CreateVertexDeclaration(dwDecl3,m_pVertexDeclaration);

组合举例
个数据流只使用漫反射色
只用漫反射色渲染顶点声明和数据流设置看起来会如下所示:

D3DVERTEXELEMENT9dwDecl3=
{
{0,0,D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_POSITION,0},
{0,12,D3DDECLTYPE_D3DCOLOR,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_COLOR,0},
{0,28,D3DDECLTYPE_D3DCOLOR,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_COLOR,1}, [Page]
D3DDECL_END
};

m_pd3dDevice->SetStreamSource(0,m_pVBVertexShader0,0,(CUSTOMVERTEX));
m_pd3dDevice->SetStreamSource(1,NULL,0,0);
m_pd3dDevice->SetStreamSource(2,NULL,0,0);

两个数据流使用颜色和纹理

使用单纹理进行渲染顶点声明和数据流设置看起来会如下所示:

D3DVERTEXELEMENT9dwDecl3=
{
{0,0,D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_POSITION,0},
{0,12,D3DDECLTYPE_D3DCOLOR,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_COLOR,0},
{0,28,D3DDECLTYPE_D3DCOLOR,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_COLOR,1},
{1,0,D3DDECLTYPE_FLOAT2,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_TEXCOORD,0},
D3DDECL_END
};

m_pd3dDevice->SetStreamSource(0,m_pVBPosColor,0,(POSCOLORVERTEX));
m_pd3dDevice->SetStreamSource(1,m_pVBTexC0,0,(TEXC0VERTEX));
m_pd3dDevice->SetStreamSource(2,NULL,0,0);

3个数据流使用颜色和两张纹理

使用两张纹理进行多重纹理渲染顶点声明和数据流设置看起来会如下所示

D3DVERTEXELEMENT9dwDecl3=
{
{0,0,D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_POSITION,0},
{0,12,D3DDECLTYPE_D3DCOLOR,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_COLOR,0},
{0,28,D3DDECLTYPE_D3DCOLOR,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_COLOR,1},
{1,0,D3DDECLTYPE_FLOAT2,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_TEXCOORD,0},
{2,0,D3DDECLTYPE_FLOAT2,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_TEXCOORD,0},
D3DDECL_END
};

m_pd3dDevice->SetStreamSource(0,m_pVBPosColor,0,(POSCOLORVERTEX));
m_pd3dDevice->SetStreamSource(1,m_pVBTexC0,0,(TEXC0VERTEX));
m_pd3dDevice->SetStreamSource(2,m_pVBTexC1,0,(TEXC1VERTEX));

以上所有 3种情况都可以以下IDirect3DDevice9::DrawPrimitive [Page]

m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN,0,NUM_TRIS);

这个例子显示了数据流在解决重复数据/冗余数据在总线上传输(也就是说带宽浪费)问题上灵活性
Tags:  excel函数的使用 if函数的使用 excel函数使用 setstreamsource

延伸阅读

最新评论

发表评论