📄 可编程数据流模型 (programmable stream model).htm
字号:
style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></SPAN>
</LI></UL>
<P class=MsoNormal
style="TEXT-ALIGN: left; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-pagination: widow-orphan; mso-outline-level: 2"
align=left><B><SPAN
style="FONT-SIZE: 18pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">数据流的使用<SPAN
lang=EN-US><o:p></o:p></SPAN></SPAN></B></P>
<P class=MsoNormal
style="TEXT-ALIGN: left; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-pagination: widow-orphan"
align=left><SPAN lang=EN-US
style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">Microsoft®
DirectX®
8.0引入了数据流的概念,用来把数据绑定到着色器使用的输入寄存器。一个数据流是一个成员数据的数组,每个成员由一个或多个元素构成,这些元素代表单个实体,如位置、法向、颜色等等。数据流使图形芯片能并行地从多个顶点缓存执行直接内存访问(DMA)操作,同时也降低了多重纹理的开销。可以这样理解数据流:<o:p></o:p></SPAN></P>
<UL type=disc>
<LI class=MsoNormal
style="TEXT-ALIGN: left; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-pagination: widow-orphan; tab-stops: list 36.0pt; mso-list: l0 level1 lfo2"><SPAN
style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">一个顶点由<SPAN
lang=EN-US>n个数据流组成。<o:p></o:p></SPAN></SPAN>
<LI class=MsoNormal
style="TEXT-ALIGN: left; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-pagination: widow-orphan; tab-stops: list 36.0pt; mso-list: l0 level1 lfo2"><SPAN
style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">一个数据流由<SPAN
lang=EN-US>m个元素组成。<o:p></o:p></SPAN></SPAN>
<LI class=MsoNormal
style="TEXT-ALIGN: left; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-pagination: widow-orphan; tab-stops: list 36.0pt; mso-list: l0 level1 lfo2"><SPAN
style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">一个元素是<SPAN
lang=EN-US>[位置、颜色、法向、纹理坐标]。<o:p></o:p></SPAN></SPAN> </LI></UL>
<P class=MsoNormal
style="TEXT-ALIGN: left; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-pagination: widow-orphan"
align=left><U><SPAN lang=EN-US
style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">IDirect3DDevice9::SetStreamSource</SPAN></U><SPAN
style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">方法把一个顶点缓存绑定到一个设备数据流,这样就在顶点数据和一个顶点数据流端口之间建立了联系,有多个数据流端口用来给图元处理函数输入数据。对数据流中的数据的真正引用只有在调用诸如<U><SPAN
lang=EN-US>IDirect3DDevice9::DrawPrimitive</SPAN></U>之类的绘制方法时才发生。<SPAN
lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal
style="TEXT-ALIGN: left; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-pagination: widow-orphan"
align=left><SPAN
style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">从输入顶点元素到可编程顶点着色器使用的顶点输入寄存器的映射是在着色器声明中定义的,但是输入顶点元素并没有专门的语义来描述它们的使用。对输入顶点元素的解释通过着色器指令进行编程。顶点着色器函数由一个指令数组定义,这些指令会应用于每个顶点。顶点输出寄存器用着色器函数中的指令显式地写入。<SPAN
lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal
style="TEXT-ALIGN: left; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-pagination: widow-orphan"
align=left><SPAN
style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">本节的讨论较少关注从元素到寄存器的语义映射,而更侧重于“为什么要使用数据流?”和“数据流可以解决什么问题?”这些问题。数据流的最大好处是消除了原来和多重纹理有关的顶点数据的开销。在引入数据流之前,为了处理单纹理和多重纹理的情况,用户要么复制两份顶点数据,每份顶点数据中都没有用不到的数据;要么在一份顶点数据中包含所有的数据元素,但其中一部分数据除了多重纹理的情况以外不会被用到。<SPAN
lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal
style="TEXT-ALIGN: left; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-pagination: widow-orphan"
align=left><SPAN
style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">这里是一个使用两份顶点数据的示例,一份用于单纹理,另一份用于多重纹理。<SPAN
lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P><SPAN class=SpellE><SPAN class=GramE><SPAN lang=EN-US
style="FONT-SIZE: 10pt">struct</SPAN></SPAN></SPAN><SPAN lang=EN-US
style="FONT-SIZE: 10pt"> CUSTOMVERTEX_TEX1<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt">{<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN
style="mso-spacerun: yes"> </SPAN>FLOAT x, y, z;<SPAN
style="mso-spacerun: yes"> </SPAN>//
未经变换的顶点位置<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN
style="mso-spacerun: yes"> </SPAN>DWORD <SPAN
class=SpellE>diffColor</SPAN>;<SPAN style="mso-spacerun: yes">
</SPAN>// 顶点的漫反射色<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN
style="mso-spacerun: yes"> </SPAN>DWORD <SPAN
class=SpellE>specColor</SPAN>;<SPAN style="mso-spacerun: yes">
</SPAN>// 顶点的镜面反射色<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN
style="mso-spacerun: yes"> </SPAN>float tu_1, tv_1;<SPAN
style="mso-spacerun: yes"> </SPAN>// 单纹理的纹理坐标<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt">};<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN
style="mso-spacerun: yes"> </SPAN><o:p></o:p></SPAN></P>
<P><SPAN class=SpellE><SPAN class=GramE><SPAN lang=EN-US
style="FONT-SIZE: 10pt">struct</SPAN></SPAN></SPAN><SPAN lang=EN-US
style="FONT-SIZE: 10pt"> CUSTOMVERTEX_TEX2<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt">{<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN
style="mso-spacerun: yes"> </SPAN>FLOAT x, y, z;<SPAN
style="mso-spacerun: yes"> </SPAN>//
未经变换的顶点位置<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN
style="mso-spacerun: yes"> </SPAN>DWORD <SPAN
class=SpellE>diffColor</SPAN>;<SPAN style="mso-spacerun: yes">
</SPAN>// 顶点的漫反射色<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN
style="mso-spacerun: yes"> </SPAN>DWORD <SPAN
class=SpellE>specColor</SPAN>;<SPAN style="mso-spacerun: yes">
</SPAN>// 顶点的镜面反射色<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN
style="mso-spacerun: yes"> </SPAN>float tu_2, tv_2;<SPAN
style="mso-spacerun: yes"> </SPAN>// 多重纹理的纹理坐标<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt">};<o:p></o:p></SPAN></P>
<P>另一种方法是在一个顶点元素中包含全部两组纹理坐标。</P>
<P><SPAN class=SpellE><SPAN class=GramE><SPAN lang=EN-US
style="FONT-SIZE: 10pt">struct</SPAN></SPAN></SPAN><SPAN lang=EN-US
style="FONT-SIZE: 10pt"> CUSTOMVERTEX_TEX2<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt">{<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN
style="mso-spacerun: yes"> </SPAN>FLOAT x, y, z;<SPAN
style="mso-spacerun: yes"> </SPAN>//
未经变换的顶点位置<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN
style="mso-spacerun: yes"> </SPAN>DWORD <SPAN
class=SpellE>diffColor</SPAN>;<SPAN style="mso-spacerun: yes">
</SPAN>// 顶点的漫反射色<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN
style="mso-spacerun: yes"> </SPAN>DWORD <SPAN
class=SpellE>specColor</SPAN>;<SPAN style="mso-spacerun: yes">
</SPAN>// 顶点的镜面反射色<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN
style="mso-spacerun: yes"> </SPAN>float tu_1, tv_1;<SPAN
style="mso-spacerun: yes"> </SPAN>// 单纹理的纹理坐标<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN
style="mso-spacerun: yes"> </SPAN>float tu_2, tv_2;<SPAN
style="mso-spacerun: yes"> </SPAN>// 多重纹理的纹理坐标<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt">};<o:p></o:p></SPAN></P>
<P>如果使用这份顶点数据,那么只要在内存中保存一份顶点和颜色数据,代价是在渲染过程中保存了全部两组纹理坐标,甚至在单纹理的情况下也是如此。</P>
<P>现在这其中的权衡已经很清楚了,数据流为这种左右为难的情况提供了一种极好的解决方案。这里提供了一套顶点定义,用来支持三个数据流:一个数据流包含位置和颜色,一个数据流包含第一组纹理坐标,另一个数据流包含第二组纹理坐标。</P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt">// 多数据流顶点<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt">// 数据流0, 位置, 漫反射色,
镜面反射色<o:p></o:p></SPAN></P>
<P><SPAN class=SpellE><SPAN class=GramE><SPAN lang=EN-US
style="FONT-SIZE: 10pt">struct</SPAN></SPAN></SPAN><SPAN lang=EN-US
style="FONT-SIZE: 10pt"> POSCOLORVERTEX<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt">{<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN
style="mso-spacerun: yes"> </SPAN>FLOAT x, y,
z;<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN
style="mso-spacerun: yes"> </SPAN>DWORD <SPAN
class=SpellE>diffColor</SPAN>, <SPAN
class=SpellE>specColor</SPAN>;<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt">};<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt">#define D3DFVF_POSCOLORVERTEX
(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_SPECULAR)<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt">// 数据流1,
纹理坐标组0<o:p></o:p></SPAN></P>
<P><SPAN class=SpellE><SPAN class=GramE><SPAN lang=EN-US
style="FONT-SIZE: 10pt">struct</SPAN></SPAN></SPAN><SPAN lang=EN-US
style="FONT-SIZE: 10pt"> TEXC0VERTEX<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt">{<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN
style="mso-spacerun: yes"> </SPAN>FLOAT tu1,
tv1;<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt">};<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt">#define D3DFVF_TEXC0VERTEX
(D3DFVF_TEX1)<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt">// 数据流2,
纹理坐标组1<o:p></o:p></SPAN></P>
<P><SPAN class=SpellE><SPAN class=GramE><SPAN lang=EN-US
style="FONT-SIZE: 10pt">struct</SPAN></SPAN></SPAN><SPAN lang=EN-US
style="FONT-SIZE: 10pt"> TEXC1VERTEX<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt">{<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN
style="mso-spacerun: yes"> </SPAN>FLOAT tu2,
tv2;<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt">};<o:p></o:p></SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10pt">#define D3DFVF_TEXC1VERTEX
(D3DFVF_TEX0)<o:p></o:p></SPAN></P>
<P>顶点定义为:</P>
<P class=MsoNormal style="TEXT-ALIGN: left; mso-pagination: widow-orphan"
align=left><SPAN lang=EN-US
style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">//
多重纹理 – 多重数据流<o:p></o:p></SPAN></P>
<P class=MsoNormal style="TEXT-ALIGN: left; mso-pagination: widow-orphan"
align=left><SPAN lang=EN-US
style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p> </o:p></SPAN></P>
<P class=MsoNormal style="TEXT-ALIGN: left; mso-pagination: widow-orphan"
align=left><SPAN lang=EN-US
style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">D3DVERTEXELEMENT9
<SPAN class=GramE>dwDecl3[</SPAN>] = <o:p></o:p></SPAN></P>
<P class=MsoNormal style="TEXT-ALIGN: left; mso-pagination: widow-orphan"
align=left><SPAN lang=EN-US
style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="TEXT-ALIGN: left; mso-pagination: widow-orphan"
align=left><SPAN lang=EN-US
style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><SPAN
style="mso-tab-count: 1"> </SPAN><SPAN class=GramE>{ 0</SPAN>,
0,<SPAN style="mso-spacerun: yes"> </SPAN>D3DDECLTYPE_FLOAT3,<SPAN
style="mso-spacerun: yes"> </SPAN>D3DDECLMETHOD_DEFAULT,
D3DDECLUSAGE_POSITION, 0 },<o:p></o:p></SPAN></P>
<P class=MsoNormal style="TEXT-ALIGN: left; mso-pagination: widow-orphan"
align=left><SPAN lang=EN-US
style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><SPAN
style="mso-tab-count: 1"> </SPAN><SPAN class=GramE>{ 0</SPAN>, 12,
D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,<SPAN
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -