﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-战魂小筑-随笔分类-渲染 Shader 引擎</title><link>http://www.cppblog.com/sunicdavy/category/13082.html</link><description>游戏，架构，客户端，渲染，服务器，界面，开发技巧及经验 email: sunicdavy@sina.com</description><language>zh-cn</language><lastBuildDate>Thu, 27 May 2010 04:41:06 GMT</lastBuildDate><pubDate>Thu, 27 May 2010 04:41:06 GMT</pubDate><ttl>60</ttl><item><title>由Direct3D ZBuffer引起的血案</title><link>http://www.cppblog.com/sunicdavy/archive/2010/05/26/116404.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Wed, 26 May 2010 09:01:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2010/05/26/116404.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/116404.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2010/05/26/116404.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/116404.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/116404.html</trackback:ping><description><![CDATA[
<p>今天顺利显示静态模型, 加上纹理后,发现ZBuffer好像有点不对劲</p> <p><a href="http://www.cppblog.com/images/cppblog_com/sunicdavy/WindowsLiveWriter/Direct3DZBuffer_EF41/image_2.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.cppblog.com/images/cppblog_com/sunicdavy/WindowsLiveWriter/Direct3DZBuffer_EF41/image_thumb.png" width="601" height="484"></a> </p> <p>于是检查D3DRS_ZENABLE,D3DRS_ZWRITEENABLE, 结果都是TRUE</p> <p>无奈,只有与我以前正确的Demo对比210个渲染状态. 有部分渲染不同的,使用硬代码强行纠正,结果: 无效</p> <p>怀疑顶点格式破损, 重新使用以前的模型格式,排除这个可能性, 结果:失败</p> <p>无奈中,检查设备选项, 突然注意到D3DPRESENT_PARAMETERS 结构体中的EnableAutoDepthStencil 设置是FALSE</p> <p>因为这次设备类是重写的,对比以前正确代码, 有差异,将其改为</p> <p>PresentParameters.EnableAutoDepthStencil&nbsp;&nbsp;&nbsp; = TRUE;<br>&nbsp;&nbsp;&nbsp; PresentParameters.AutoDepthStencilFormat&nbsp;&nbsp;&nbsp; = D3DFMT_D16; </p><p>以前翻阅SDK时,注意过这个选项, 这是由D3D帮你管理ZBuffer. </p> <p>测试, 问题解决.</p> <p>&nbsp;</p> <p>分析: 如果EnableAutoDepthStencil&nbsp; = FALSE, 意味着连ZBuffer都没有,那更不要说渲染状态. </p> <p><a href="http://www.cppblog.com/images/cppblog_com/sunicdavy/WindowsLiveWriter/Direct3DZBuffer_EF41/image_4.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.cppblog.com/images/cppblog_com/sunicdavy/WindowsLiveWriter/Direct3DZBuffer_EF41/image_thumb_1.png" width="290" height="339"></a> 正确结果</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/116404.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2010-05-26 17:01 <a href="http://www.cppblog.com/sunicdavy/archive/2010/05/26/116404.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DirectX 9.0 Direct3D 图形管线大图</title><link>http://www.cppblog.com/sunicdavy/archive/2010/05/26/116371.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Wed, 26 May 2010 03:35:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2010/05/26/116371.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/116371.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2010/05/26/116371.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/116371.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/116371.html</trackback:ping><description><![CDATA[<p><a href="http://www.cppblog.com/images/cppblog_com/sunicdavy/WindowsLiveWriter/DirectX9.0Direct3D_A2CC/DXpipeline-9.0_2.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="DXpipeline-9.0" border="0" alt="DXpipeline-9.0" src="http://www.cppblog.com/images/cppblog_com/sunicdavy/WindowsLiveWriter/DirectX9.0Direct3D_A2CC/DXpipeline-9.0_thumb.png" width="2758" height="3720"></a></p><img src ="http://www.cppblog.com/sunicdavy/aggbug/116371.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2010-05-26 11:35 <a href="http://www.cppblog.com/sunicdavy/archive/2010/05/26/116371.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>优化Direct3D中多流(Multistreaming)的资源分配</title><link>http://www.cppblog.com/sunicdavy/archive/2010/05/26/116368.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Wed, 26 May 2010 03:19:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2010/05/26/116368.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/116368.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2010/05/26/116368.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/116368.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/116368.html</trackback:ping><description><![CDATA[<p>转载请注明: <a href="http://www.cppblog.com/sunicdavy">战魂小筑</a></p> <p>本文翻译整理总结自<a href="http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter05.html">http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter05.html</a></p> <p>如果喜欢,请购买正版</p> <p>多流技术在渲染时能对性能和结构有一定好处.但是怎样将模型数据分配到各顶点数据流进行渲染就是一个学问. </p> <p>&nbsp;</p> <p></p> <p></p><a href="http://www.cppblog.com/images/cppblog_com/sunicdavy/WindowsLiveWriter/Direct3DMultistreaming_9F24/05_multistreaming_1_2.jpg"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="05_multistreaming_1" border="0" alt="05_multistreaming_1" src="http://www.cppblog.com/images/cppblog_com/sunicdavy/WindowsLiveWriter/Direct3DMultistreaming_9F24/05_multistreaming_1_thumb.jpg" width="454" height="678"></a>  <p>对于顶点数据可以分为这么几个大类:</p> <p>G: 多边形数据, 包含vertex position, normal, and vertex color(s).</p> <p>T: 纹理映射, 包含多层纹理坐标及tangent vectors等</p> <p>A: 动画数据, 骨骼动画中的骨骼权重及骨骼索引</p> <p>I: 用于Instance绘制的用户数据</p> <p>&nbsp;</p> <p>以下是对一些常用渲染的流搭配:</p> <p>静态模型</p> <p>&nbsp;&nbsp; 可以是: <strong>G</strong> <em>or</em> <strong>G</strong> + <strong>T</strong></p> <p>骨骼动画模型</p> <p>&nbsp;&nbsp; 可以是:<strong>G</strong> + <strong>A</strong> <em>or</em> <strong>G</strong> + <strong>T</strong> + <strong>A</strong></p> <p>Instance绘制的骨骼动画模型</p> <p>&nbsp;&nbsp; 可以是:<strong>G</strong> + <strong>I</strong> <em>or</em> <strong>G</strong> + <strong>T</strong> + <strong>I</strong> 或者动画类型的<strong>G</strong> + <strong>A</strong> + <strong>I</strong> <em>or</em> <strong>G</strong> + <strong>T</strong> + <strong>A</strong> + <strong>I</strong></p> <p>渲染Z-Pass物件</p> <p>&nbsp; 可以是<strong>G</strong>, 或者动画类型的<strong>G</strong> + <strong>A</strong> <em>or</em> <strong>G</strong> + <strong>I</strong> <em>or</em> <strong>G</strong> + <strong>A</strong> + <strong>I</strong></p><img src ="http://www.cppblog.com/sunicdavy/aggbug/116368.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2010-05-26 11:19 <a href="http://www.cppblog.com/sunicdavy/archive/2010/05/26/116368.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在VC调试器中显示CEGUI 字符串</title><link>http://www.cppblog.com/sunicdavy/archive/2010/05/14/115356.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Fri, 14 May 2010 04:01:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2010/05/14/115356.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/115356.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2010/05/14/115356.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/115356.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/115356.html</trackback:ping><description><![CDATA[<p>CEGUI的字符串类设计的初衷是以32个字符为分界点, 低于32个字符使用固定buffer, 高于才使用栈分配内存存储字符串. 不过因为CEGUI使用utf32,兼容性虽然很好,但是在VC调试器里无法显示是个很大的问题.</p> <p>这里参考了mybios博客中的<a href="http://www.cppblog.com/mybios/archive/2009/11/10/28914.html">文章</a>,给CEGUI字符串做一个patch</p> <p>然后需要找到vs2008的autoexp.dat文件</p> <p>XP下位于:C:\Program Files\Microsoft Visual Studio 9.0\Common7\Packages\Debugger\autoexp.dat</p> <p>用记事本等工具打开, 在AutoExpand段中像这样添加:</p> <p>[AutoExpand]<br>; CEGUI String<br>CEGUI::String = str =&lt;d_quickbuff,su&gt; length =&lt;d_cplength&gt; <p>即可在VC调试器中看到CEGUI字符串内容, 不过中文还是暂时无法支持</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/115356.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2010-05-14 12:01 <a href="http://www.cppblog.com/sunicdavy/archive/2010/05/14/115356.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>增强骨骼动画系统的几个要点</title><link>http://www.cppblog.com/sunicdavy/archive/2010/05/11/115080.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Tue, 11 May 2010 02:21:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2010/05/11/115080.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/115080.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2010/05/11/115080.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/115080.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/115080.html</trackback:ping><description><![CDATA[<p>要在游戏中用到强大而有扩展性的骨骼动画,有很多注意点.</p> <p>首先,我们得弃用CPU蒙皮, 虽然兼容性好,但是面对现今多核但并不提高单核速率的情况下,GPU还是王道.而且GPU蒙皮代码可能更简单,不过也有一点小缺点, 对于小引擎来说,Shader必须给静态模型和骨骼动画模型写两套.</p> <p>其次我们需要加强一个SubSkin的骨骼支持数量. 骨骼动画上的每个SubSkin都是一次Draw, 但是按照传统骨骼动画系统,每个骨头对应一个矩阵传入,那么SM2.0保守计算只能支持50根骨头. 不过在我前段时间的<a href="http://www.cppblog.com/sunicdavy/archive/2010/04/26/113578.html">文章</a>中有提到这个技术.并且已经在我的骨骼动画系统及OGRE中实现,效果很好.</p> <p>美术也许很反感一个人物做1个SubSkin, 他们更新好多个SubSkin,也就是说身体每个部分都是一个SubSkin, 这样方便修改, 同时系统支持的骨骼数量还可以有一定量的上升.不过我们还需要做一个索引工作. 传统的GPU骨骼动画中总是在渲染SubSkin前传入所有这些SubSkin需要用到的骨骼矩阵. 但是每个SubSkin并不一定能用到所有的这些矩阵,这明显是一种浪费. 因此在OGRE中做过一次索引预处理,也就是将每个SubSkin用到的骨骼统计出来, 在渲染这次SubSkin时才重新传到GPU. 很明显,这是用速度还空间和兼容性. 如果在DX10以上,有ConstantBuffer还好. DX9实在太慢了</p> <p>使用Marker点的换装系统很难处理例如贴身衣物这类物件换装. OGRE中有一种共享骨骼的技术, 可以支持, 不过从代码分析看来,这种技术对CPU端骨骼计算量实在是大的惊人. 因此我们决定将整个SubSkin(也就是SubEntity)换掉,这样由美术根据不同换装类型来将衣服在MAX中直接绑定好后直接替换原始模型中的SubSkin即可达到换装效果.可以说这是从动态计算到静态预处理的转变,效率提升很多.</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/115080.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2010-05-11 10:21 <a href="http://www.cppblog.com/sunicdavy/archive/2010/05/11/115080.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>IDirect3DDevice9::DrawIndexedPrimitiveUP 的索引个数推算</title><link>http://www.cppblog.com/sunicdavy/archive/2010/05/05/114502.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Wed, 05 May 2010 09:07:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2010/05/05/114502.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/114502.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2010/05/05/114502.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/114502.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/114502.html</trackback:ping><description><![CDATA[<p>首先参考SDK里这个函数的定义:</p> <p><b>HRESULT </b><b>DrawIndexedPrimitiveUP(</b> </p> <p><b>D3DPRIMITIVETYPE</b> <i>PrimitiveType</i><b>,</b> </p> <p><b>UINT</b> <i>MinVertexIndex</i><b>,</b> </p> <p><b>UINT</b> <i>NumVertices</i><b>,</b> </p> <p><b>UINT</b> <i>PrimitiveCount</i><b>,</b> </p> <p><b>CONST void *</b> <i>pIndexData</i><b>,</b> </p> <p><b>D3DFORMAT</b> <i>IndexDataFormat</i><b>,</b> </p> <p><b>CONST void*</b> <i>pVertexStreamZeroData</i><b>,</b> </p> <p><b>UINT</b> <i>VertexStreamZeroStride</i> </p> <p><b>)</b>;</p> <p>&nbsp;</p> <p>这里假设我们要绘制一个由2个三角形组成的面,那么参数这样设置</p> <p><i>MinVertexIndex</i> = 0;</p> <p><i>NumVertices</i> = 4;</p> <p><i>PrimitiveCount</i> = 2;</p> <p><i>pIndexData</i> = { 0,1, 2, 0, 2, 3}</p> <p><i>IndexDataFormat</i> = D3DFMT_INDEX16</p> <p><i>pVertexStreamZeroData</i><strong> =</strong> { 4个角的位置 }</p> <p><i>VertexStreamZeroStride</i>&nbsp; = { 结构体的跨度 }</p> <p>&nbsp;</p> <p>我们注意到, 没有任何一个参数用于描述<b>CONST void *</b> <em>pIndexData</em>的size 大小.</p> <p>但其实你的图元是可以正确绘制的, 但是你并没有在indexdata后面加上例如字符串0的结尾副,那么D3D是怎么知道IndexCount呢?</p> <p>我们先看下怎么根据VertexCount及 PrimitveType确定 PrimitiveCount </p> <table border="1" cellspacing="0" cellpadding="2" width="448"> <tbody> <tr> <td valign="top" width="200">PrimitveType</td> <td valign="top" width="246">公式</td></tr> <tr> <td valign="top" width="200">D3DPT_POINTLIST</td> <td valign="top" width="246">PrimitiveCount = VertexCount</td></tr> <tr> <td valign="top" width="200">D3DPT_LINELIST</td> <td valign="top" width="246">PrimitiveCount = VertexCount/2</td></tr> <tr> <td valign="top" width="200">D3DPT_LINESTRIP</td> <td valign="top" width="246">PrimitiveCount = VertexCount-1</td></tr> <tr> <td valign="top" width="200">D3DPT_TRIANGLELIST</td> <td valign="top" width="246">PrimitiveCount = VertexCount/3</td></tr> <tr> <td valign="top" width="200">D3DPT_TRIANGLESTRIP</td> <td valign="top" width="246">PrimitiveCount = VertexCount-2</td></tr></tbody></table> <p>注: D3DPT_TRIANGLEFAN在以后的驱动中已经不再使用,因此不再采用</p> <p>当使用索引缓冲时, VertexCount = IndexCount</p> <p>因此在上例中 PrimitiveCount = IndexCount/3</p> <p>也就是说 IndexCount = PrimitiveCount * 3</p> <p>代入PrimitiveCount = 2,因此 IndexCount = 6 </p> <p>&nbsp;</p> <p>因此稳定的API的函数参数设计是绝不会浪费任何一个参数的</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/114502.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2010-05-05 17:07 <a href="http://www.cppblog.com/sunicdavy/archive/2010/05/05/114502.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[原创]提高Shader Model 2.0 蒙皮骨骼动画的骨骼限制</title><link>http://www.cppblog.com/sunicdavy/archive/2010/04/26/113578.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Mon, 26 Apr 2010 05:31:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2010/04/26/113578.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/113578.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2010/04/26/113578.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/113578.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/113578.html</trackback:ping><description><![CDATA[<p>传统的蒙皮骨骼动画混合方法易于理解,但是在SM 2.0的256常量限制下,骨骼数保守计算最多50根骨头,因此对美术的工作流程以及模型渲染方法造成了很大的障碍</p> <div class="csharpcode"><pre class="alt">float4x4 matBoneArray[40]; <span class="rem">//  这是传输的瓶颈</span></pre><pre>&nbsp;</pre><pre class="alt">VS_OUTPUT vs_main( SkinnedVS_INPUT In )</pre><pre>{</pre><pre class="alt">&nbsp;</pre><pre>    VS_OUTPUT Out = (VS_OUTPUT)0;</pre><pre class="alt">&nbsp;</pre><pre>    float4x4 skinTransform = 0;</pre><pre class="alt">&nbsp;</pre><pre>    skinTransform += matBoneArray[In.BoneIndices.x] * In.BoneWeights.x;</pre><pre class="alt">    skinTransform += matBoneArray[In.BoneIndices.y] * In.BoneWeights.y;</pre><pre>    skinTransform += matBoneArray[In.BoneIndices.z] * In.BoneWeights.z;</pre><pre class="alt">    skinTransform += matBoneArray[In.BoneIndices.w] * In.BoneWeights.w;</pre><pre>    float4 localpos = mul(In.Position, skinTransform);</pre><pre class="alt">    </pre><pre>    Out.Position = mul( localpos, matViewProj ); </pre><pre class="alt">    Out.TexCoord = In.TexCoord;</pre><pre>  </pre><pre class="alt">    <span class="kwrd">return</span> Out;</pre><pre>}</pre></div>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p>matBoneArray这个数组是骨骼的LocalRot和LocalTranslation 通过以下函数build出来</p>
<div class="csharpcode"><pre class="alt">    Matrix4&amp; Matrix4::FromTranslationRotation( <span class="kwrd">const</span> Vector3&amp; translation, <span class="kwrd">const</span> Quaternion&amp; rotation )</pre><pre>    {</pre><pre class="alt">        <span class="kwrd">float</span> xx = rotation.x * rotation.x * 2.0f, yy = rotation.y * rotation.y * 2.0f, zz = rotation.z * rotation.z * 2.0f;</pre><pre>        <span class="kwrd">float</span> xy = rotation.x * rotation.y * 2.0f, zw = rotation.z * rotation.w * 2.0f, xz = rotation.x * rotation.z * 2.0f;</pre><pre class="alt">        <span class="kwrd">float</span> yw = rotation.y * rotation.w * 2.0f, yz = rotation.y * rotation.z * 2.0f, xw = rotation.x * rotation.w * 2.0f;</pre><pre>&nbsp;</pre><pre class="alt">        m[0][0] = 1.0f - yy - zz; m[0][1] =        xy + zw; m[0][2] =        xz - yw; m[0][3] = 0.0f;</pre><pre>        m[1][0] =        xy - zw; m[1][1] = 1.0f - xx - zz; m[1][2] =        yz + xw; m[1][3] = 0.0f;</pre><pre class="alt">        m[2][0] =        xz + yw; m[2][1] =        yz - xw; m[2][2] = 1.0f - xx - yy; m[2][3] = 0.0f;</pre><pre>        m[3][0] =  translation.x; m[3][1] =  translation.y; m[3][2] =  translation.z; m[3][3] = 1.0f;</pre><pre class="alt">&nbsp;</pre><pre>        <span class="kwrd">return</span> *<span class="kwrd">this</span>;</pre><pre class="alt">    }</pre></div>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p></p>
<p>从这里你可以发现, 本来每根骨头只需要2个float4 传递变换信息的,现在却需要4个float4,也就是一个矩阵来传递,矩阵中还有很多不使用的变量也被传输到GPU中,这里就是优化的点.</p>
<p>重新调整后的Shader代码:</p>
<div class="csharpcode"><pre class="alt">float4x4 BuildFromTransRot( float4 translation, float4 rot )</pre><pre>{</pre><pre class="alt">    float4 rotation = rot;</pre><pre>    </pre><pre class="alt">    <span class="kwrd">float</span> xx = rotation.x * rotation.x * 2.0f, yy = rotation.y * rotation.y * 2.0f, zz = rotation.z * rotation.z * 2.0f;</pre><pre>    <span class="kwrd">float</span> xy = rotation.x * rotation.y * 2.0f, zw = rotation.z * rotation.w * 2.0f, xz = rotation.x * rotation.z * 2.0f;</pre><pre class="alt">    <span class="kwrd">float</span> yw = rotation.y * rotation.w * 2.0f, yz = rotation.y * rotation.z * 2.0f, xw = rotation.x * rotation.w * 2.0f;</pre><pre>    float4x4 m = { </pre><pre class="alt">    {1.0f - yy - zz,             xy + zw,             xz - yw,         0},</pre><pre>    {xy - zw,              1.0f - xx - zz,             yz + xw,         0},</pre><pre class="alt">    {xz + yw,                      yz - xw,     1.0f - xx - yy,         0},</pre><pre>    {translation.x,       translation.y,       translation.z,         1}</pre><pre class="alt">    </pre><pre>    };</pre><pre class="alt">    </pre><pre>    <span class="kwrd">return</span> m;</pre><pre class="alt">}</pre><pre>&nbsp;</pre><pre class="alt">float4x4 GetBoneElement( <span class="kwrd">float</span> index )</pre><pre>{</pre><pre class="alt">    <span class="kwrd">return</span> BuildFromTransRot( vecBoneLocalTrans[index], vecBoneLocalRot[index] );</pre><pre>}</pre></div>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p></p>
<div class="csharpcode"><pre class="alt">VS_OUTPUT vs_main( SkinnedVS_INPUT In )</pre><pre>{</pre><pre class="alt">&nbsp;</pre><pre>    VS_OUTPUT Out = (VS_OUTPUT)0;</pre><pre class="alt">&nbsp;</pre><pre>    float4x4 skinTransform = 0;</pre><pre class="alt">&nbsp;</pre><pre>    skinTransform += GetBoneElement(In.BoneIndices.x) * In.BoneWeights.x;</pre><pre class="alt">    skinTransform += GetBoneElement(In.BoneIndices.y) * In.BoneWeights.y;</pre><pre>    skinTransform += GetBoneElement(In.BoneIndices.z) * In.BoneWeights.z;</pre><pre class="alt">    skinTransform += GetBoneElement(In.BoneIndices.w) * In.BoneWeights.w;</pre><pre>    float4 localpos = mul(In.Position, skinTransform);</pre><pre class="alt">    </pre><pre>    Out.Position = mul( localpos, matViewProj ); </pre><pre class="alt">    Out.TexCoord = In.TexCoord;</pre><pre>  </pre><pre class="alt">    <span class="kwrd">return</span> Out;</pre><pre>}</pre></div>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p>我们将骨头的local旋转及偏移传递至GPU,然后在GPU内重组,虽然对GPU性能计算有部分损耗,但是骨骼数量就能保守提高到100个.</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/113578.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2010-04-26 13:31 <a href="http://www.cppblog.com/sunicdavy/archive/2010/04/26/113578.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>多线程渲染的一些资料</title><link>http://www.cppblog.com/sunicdavy/archive/2010/04/15/112676.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Thu, 15 Apr 2010 08:06:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2010/04/15/112676.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/112676.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2010/04/15/112676.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/112676.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/112676.html</trackback:ping><description><![CDATA[<p>OGRE 中的3种层次实现多线程渲染的文档:</p> <p><a href="http://isdlibrary.intel-dispatch.com/vc/1632/Threading_OGRE3D.pdf">http://isdlibrary.intel-dispatch.com/vc/1632/Threading_OGRE3D.pdf</a></p> <p>&nbsp;</p> <p>ATI有关多线程效率提升的游戏比较及一些tips</p> <p><a href="http://developer.amd.com/assets/ATIMThread.pdf">http://developer.amd.com/assets/ATIMThread.pdf</a></p><img src ="http://www.cppblog.com/sunicdavy/aggbug/112676.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2010-04-15 16:06 <a href="http://www.cppblog.com/sunicdavy/archive/2010/04/15/112676.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>游戏工程里的使用C++静态库与动态库</title><link>http://www.cppblog.com/sunicdavy/archive/2010/04/07/111859.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Wed, 07 Apr 2010 08:08:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2010/04/07/111859.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/111859.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2010/04/07/111859.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/111859.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/111859.html</trackback:ping><description><![CDATA[<p>假设我们有3个工程及其工程类型：</p> <p>CORE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DLL</p> <p>ENGINE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DLL</p> <p>GAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EXE</p> <p>D3DRENDER&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DLL</p> <p>其中D3DRENDER是GAME动态载入的，其需要链接CORE,ENGINE</p> <p>这是一个很常见的模式，但是不好的是，因为CORE和ENGINE均是DLL，代码中的Symbol都被导出才可使用。任何人使用DEPENDENCE工具就可以将DLL中引用的东西查看的清楚，虽然这不至于造成技术泄漏，但从速度和DLL大小来说都是不划算的。</p> <p>现在很多游戏主exe一般都是10M+甚至20M+的大exe，这都是使用静态链接而成。但是对代码结构也必须做出一定的调整。所有工程必须都是静态库，这样才能保证像CORE这样的静态库中的全局/静态变量不至于被链接2份而造成内存段逻辑错误。</p> <p>当然，使用全静态库还需要注意一点：所有的lib都是在最后的game工程里来做链接。</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/111859.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2010-04-07 16:08 <a href="http://www.cppblog.com/sunicdavy/archive/2010/04/07/111859.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]虚幻引擎UDK开发官方视频教程</title><link>http://www.cppblog.com/sunicdavy/archive/2010/04/07/111833.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Wed, 07 Apr 2010 02:36:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2010/04/07/111833.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/111833.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2010/04/07/111833.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/111833.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/111833.html</trackback:ping><description><![CDATA[<p>转载自 <a href="http://forum.indiegame.cn/viewthread.php?tid=69&amp;from=recommend_f">独立游戏中文论坛</a> <p>UDK是unrealengine develpoment kit 的缩写，简单来说就是大名鼎鼎的虚幻３引擎的免费商业版本．不过虚幻３毕竟还是４年前的dx9的入门级引擎，在商业上取得<br>巨大成功，技术上也显得落后．目前Epic想榨干虚幻３的最后一点潜力，于是干脆发布了这个免费版本．任何人都可以用ＵＤＫ开发游戏，但是如果游戏牟利的话每年还是要向<br>Epic交纳一定数量的技术授权费用的．先不管这个，还是来看看它的官方视频教程吧．<br>　　[attach]44[/attach]<br>链接如下：　　<br><a href="http://udn.epicgames.com/Three/VideoTutorials.html">http://udn.epicgames.com/Three/VideoTutorials.html</a><br>一共５个教程　从引擎配置介绍开始，到关卡和人物编辑器，以及最后一个完整的小游戏的制作，对于入门来说完全足够了．<br>视频说的还比较详细，听力不好的同学可以对照下开发文档　<a href="http://www.udk.com/documentation">http://www.udk.com/documentation</a>　里面基本说的很详细．<br>最后附上ＵＤＫ的下载地址：　<a href="http://www.udk.com/udkdownload">March 2010 UDK Beta</a> (548 MB .exe)　<br>好了，ＵＤＫ对于初学者来说还是比较适合的．对于游戏的开发人员来说引擎的整体架构还是很值得学习的．希望你学的愉快．</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/111833.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2010-04-07 10:36 <a href="http://www.cppblog.com/sunicdavy/archive/2010/04/07/111833.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>模拟OGRE的Compositor</title><link>http://www.cppblog.com/sunicdavy/archive/2010/04/01/111312.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Thu, 01 Apr 2010 10:56:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2010/04/01/111312.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/111312.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2010/04/01/111312.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/111312.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/111312.html</trackback:ping><description><![CDATA[<p>RenderTarget完成后，开始模拟OGRE的Compositor。</p> <p>OGRE的Compositor其实就是用于解决绘制PostEffect的，简单的说，就是一种RenderTarget的流程控制脚本</p> <p>这是OGRE compositor文件的片段</p> <div class="csharpcode"><pre class="alt">compositor Bloom</pre><pre>{</pre><pre class="alt">    technique</pre><pre>    {</pre><pre class="alt">        <span class="rem">// Temporary textures</span></pre><pre>        texture rt_output target_width target_height PF_R8G8B8</pre><pre class="alt">        texture rt0 target_width_scaled 0.25 target_height_scaled 0.25 PF_R8G8B8</pre><pre>        texture rt1 target_width_scaled 0.25 target_height_scaled 0.25 PF_R8G8B8</pre><pre class="alt">&nbsp;</pre><pre>        target rt_output</pre><pre class="alt">        {</pre><pre>            <span class="rem">// Render output from previous compositor (or original scene)</span></pre><pre class="alt">            input previous</pre><pre>        }</pre><pre class="alt">&nbsp;</pre><pre>        target rt0</pre><pre class="alt">        {</pre><pre>            <span class="rem">// Start with clear texture</span></pre><pre class="alt">            input none</pre><pre>            <span class="rem">// Horizontal blur pass</span></pre><pre class="alt">            pass render_quad</pre><pre>            {</pre><pre class="alt">                <span class="rem">// Renders a fullscreen quad with a material</span></pre><pre>                material Ogre/Compositor/BrightPass2</pre><pre class="alt">                input 0 rt_output</pre><pre>            }</pre><pre class="alt">        }</pre><pre>&nbsp;</pre><pre class="alt">        target rt1</pre><pre>        {</pre><pre class="alt">            <span class="rem">// Start with clear texture</span></pre><pre>            input none</pre><pre class="alt">            <span class="rem">// Horizontal blur pass</span></pre><pre>            pass render_quad</pre><pre class="alt">            {</pre><pre>                <span class="rem">// Renders a fullscreen quad with a material</span></pre><pre class="alt">                material Ogre/Compositor/BlurV</pre><pre>                input 0 rt0</pre><pre class="alt">            }</pre><pre>        }</pre><pre class="alt">&nbsp;</pre><pre>        target rt0</pre><pre class="alt">        {</pre><pre>            <span class="rem">// Start with clear texture</span></pre><pre class="alt">            input none</pre><pre>            <span class="rem">// Horizontal blur pass</span></pre><pre class="alt">            pass render_quad</pre><pre>            {</pre><pre class="alt">                <span class="rem">// Renders a fullscreen quad with a material</span></pre><pre>                material Ogre/Compositor/BlurH</pre><pre class="alt">                input 0 rt1</pre><pre>            }</pre><pre class="alt">        }</pre><pre>&nbsp;</pre><pre class="alt">        target_output</pre><pre>        {</pre><pre class="alt">            <span class="rem">// Start with clear output</span></pre><pre>            input none</pre><pre class="alt">            <span class="rem">// Draw a fullscreen quad</span></pre><pre>            pass render_quad</pre><pre class="alt">            {</pre><pre>                <span class="rem">// Renders a fullscreen quad with a material</span></pre><pre class="alt">                material Ogre/Compositor/BloomBlend2</pre><pre>                input 0 rt_output</pre><pre class="alt">                input 1 rt0</pre><pre>            }</pre><pre class="alt">        }</pre><pre>    }</pre><pre class="alt">}</pre></div>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p>&nbsp;</p>
<p>大概我们知道，一个Compositor分为资源定义与绘制步骤（target xxx）</p>
<p>而一个绘制步骤又分别定义：</p>
<p>1. （输入）绘制的是什么东西？</p>
<p>2. （效果）绘制成什么样子？</p>
<p>3. （输出）往哪里绘制？</p>
<p>输出方式在这个例子有2种：纹理（RT）和屏幕</p>
<p>输入方式有2中：纹理及场景</p>
<p>我们可以使用一个回调来对一个绘制步骤提供绘制输入</p>
<p>绘制效果就是一大堆的Shader，这些shader都是基于一个quad来做的，也就是一个矩形，使用变换后的顶点和一个纹理坐标作为顶点定义</p>
<p>不过这里是不需要做vertexshader的，仅仅ps足矣。</p>
<p>绘制的最后，是将前面绘制的RT（纹理）混合起来</p>
<p>当然，如果步骤比较多和复杂时，RT之间跟寄存器一样，可以反复使用</p>
<p><a href="http://www.cppblog.com/images/cppblog_com/sunicdavy/WindowsLiveWriter/OGRECompositor_10A35/YR7HEX8VAB%5B67GPOWLNPIBA_2.jpg"><img title="YR7HEX8VAB[67GPOWLNPIBA" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="170" alt="YR7HEX8VAB[67GPOWLNPIBA" src="http://www.cppblog.com/images/cppblog_com/sunicdavy/WindowsLiveWriter/OGRECompositor_10A35/YR7HEX8VAB%5B67GPOWLNPIBA_thumb.jpg" width="244" border="0"></a></p>
<p>显示茶壶法线的场景加上 Blur 的PostEffect</p>
<div class="csharpcode"><pre class="alt"><span class="kwrd">&lt;?</span><span class="html">xml</span> <span class="attr">version</span><span class="kwrd">="1.0"</span> <span class="attr">encoding</span><span class="kwrd">="gb2312"</span> ?<span class="kwrd">&gt;</span></pre><pre><span class="kwrd">&lt;</span><span class="html">Compositor</span> <span class="attr">name</span> = <span class="kwrd">"bloom"</span> <span class="kwrd">&gt;</span></pre><pre class="alt">  <span class="kwrd">&lt;</span><span class="html">Resource</span><span class="kwrd">&gt;</span></pre><pre>    <span class="kwrd">&lt;</span><span class="html">RenderTarget</span> <span class="attr">name</span> <span class="kwrd">="rt_source"</span> <span class="attr">size</span><span class="kwrd">="screenquad"</span> <span class="kwrd">/&gt;</span></pre><pre class="alt">    <span class="kwrd">&lt;</span><span class="html">RenderTarget</span> <span class="attr">name</span> <span class="kwrd">="rt0"</span> <span class="attr">size</span><span class="kwrd">="screenquad"</span> <span class="kwrd">/&gt;</span></pre><pre>    <span class="kwrd">&lt;</span><span class="html">RenderTarget</span> <span class="attr">name</span> <span class="kwrd">="rt1"</span> <span class="attr">size</span><span class="kwrd">="screenquad"</span> <span class="kwrd">/&gt;</span></pre><pre class="alt">  <span class="kwrd">&lt;/</span><span class="html">Resource</span><span class="kwrd">&gt;</span></pre><pre>  <span class="kwrd">&lt;</span><span class="html">Step</span> <span class="attr">target</span><span class="kwrd">="rt_source"</span><span class="kwrd">&gt;</span></pre><pre class="alt">    <span class="kwrd">&lt;</span><span class="html">Geometry</span> <span class="attr">type</span> <span class="kwrd">="callback"</span> <span class="attr">callback</span> = <span class="kwrd">"rt_input"</span><span class="kwrd">/&gt;</span></pre><pre>  <span class="kwrd">&lt;/</span><span class="html">Step</span><span class="kwrd">&gt;</span></pre><pre class="alt">  <span class="kwrd">&lt;</span><span class="html">Step</span> <span class="attr">target</span><span class="kwrd">="rt0"</span><span class="kwrd">&gt;</span></pre><pre>    <span class="kwrd">&lt;</span><span class="html">Geometry</span> <span class="attr">type</span> = <span class="kwrd">"screenquad"</span><span class="kwrd">/&gt;</span></pre><pre class="alt">    <span class="kwrd">&lt;</span><span class="html">Effect</span> <span class="attr">name</span> <span class="kwrd">="material\blurH.xml"</span><span class="kwrd">&gt;</span></pre><pre>      <span class="kwrd">&lt;</span><span class="html">Texture</span> <span class="attr">name</span> <span class="kwrd">="mTexture"</span> <span class="attr">value</span> <span class="kwrd">="rt_source"</span> <span class="kwrd">/&gt;</span></pre><pre class="alt">    <span class="kwrd">&lt;/</span><span class="html">Effect</span><span class="kwrd">&gt;</span></pre><pre>  <span class="kwrd">&lt;/</span><span class="html">Step</span><span class="kwrd">&gt;</span></pre><pre class="alt">  <span class="kwrd">&lt;</span><span class="html">Step</span> <span class="attr">target</span><span class="kwrd">="rt1"</span><span class="kwrd">&gt;</span></pre><pre>    <span class="kwrd">&lt;</span><span class="html">Geometry</span> <span class="attr">type</span> = <span class="kwrd">"screenquad"</span><span class="kwrd">/&gt;</span></pre><pre class="alt">    <span class="kwrd">&lt;</span><span class="html">Effect</span> <span class="attr">name</span> <span class="kwrd">="material\blurV.xml"</span><span class="kwrd">&gt;</span></pre><pre>      <span class="kwrd">&lt;</span><span class="html">Texture</span> <span class="attr">name</span> <span class="kwrd">="mTexture"</span> <span class="attr">value</span> <span class="kwrd">="rt_source"</span> <span class="kwrd">/&gt;</span></pre><pre class="alt">    <span class="kwrd">&lt;/</span><span class="html">Effect</span><span class="kwrd">&gt;</span></pre><pre>  <span class="kwrd">&lt;/</span><span class="html">Step</span><span class="kwrd">&gt;</span></pre><pre class="alt">  <span class="kwrd">&lt;</span><span class="html">Step</span><span class="kwrd">&gt;</span></pre><pre>    <span class="kwrd">&lt;</span><span class="html">Geometry</span> <span class="attr">type</span> = <span class="kwrd">"screenquad"</span><span class="kwrd">/&gt;</span></pre><pre class="alt">    <span class="kwrd">&lt;</span><span class="html">Effect</span> <span class="attr">name</span> <span class="kwrd">="material\combine.xml"</span><span class="kwrd">&gt;</span></pre><pre>      <span class="kwrd">&lt;</span><span class="html">Texture</span> <span class="attr">name</span> <span class="kwrd">="mTexture1"</span> <span class="attr">value</span> <span class="kwrd">="rt0"</span> <span class="kwrd">/&gt;</span></pre><pre class="alt">      <span class="kwrd">&lt;</span><span class="html">Texture</span> <span class="attr">name</span> <span class="kwrd">="mTexture2"</span> <span class="attr">value</span> <span class="kwrd">="rt1"</span> <span class="kwrd">/&gt;</span></pre><pre>    <span class="kwrd">&lt;/</span><span class="html">Effect</span><span class="kwrd">&gt;</span></pre><pre class="alt">  <span class="kwrd">&lt;/</span><span class="html">Step</span><span class="kwrd">&gt;</span></pre><pre><span class="kwrd">&lt;/</span><span class="html">Compositor</span><span class="kwrd">&gt;</span></pre></div>这是我的引擎里的Compositor脚本，还在慢慢加强功能，希望能有一天达到OGRE的Compositor功能
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style><img src ="http://www.cppblog.com/sunicdavy/aggbug/111312.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2010-04-01 18:56 <a href="http://www.cppblog.com/sunicdavy/archive/2010/04/01/111312.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>3D引擎设计：支持多RenderTarget及多Viewport</title><link>http://www.cppblog.com/sunicdavy/archive/2010/03/29/110895.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Mon, 29 Mar 2010 10:16:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2010/03/29/110895.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/110895.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2010/03/29/110895.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/110895.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/110895.html</trackback:ping><description><![CDATA[<p>如果让你的引擎结构支持多个RenderTarget绘制及多个Viewport？这里是我的简单设计：</p> <p>同样适用我的文本设计图标准(+为包含,&nbsp; &lt;为派生)</p> <p>&nbsp;</p> <p>RenderTexture</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RenderTarget</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ScreenTarget(引擎启动时，初始化屏幕大小的Viewport)</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +RenderView (对于一个RT，可以是屏幕，可以是纹理RT，所以可以拥有 1~n个切分视图 )</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +Camera</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +Viewport</p> <p>&nbsp;</p> <p>以下是多View绘制的类XNA伪代码</p> <p>&nbsp;</p> <div class="csharpcode"><pre class="alt">Engine.Run()</pre><pre>{</pre><pre class="alt">    Device.Clear()</pre><pre>&nbsp;</pre><pre class="alt">    <span class="rem">// 保存当前全屏Viewport</span></pre><pre>    ScreenViewport = Device.CurrentViewport</pre><pre class="alt">&nbsp;</pre><pre>    Device.BeginScene()    </pre><pre class="alt">&nbsp;</pre><pre>    <span class="rem">// 遍历当前屏幕RT下的所有View</span></pre><pre class="alt">    <span class="kwrd">foreach</span> RenderView <span class="kwrd">in</span> ScreenRT</pre><pre>    {</pre><pre class="alt">        <span class="rem">// 未激活的View不用绘制</span></pre><pre>        <span class="kwrd">if</span> RenderView not active then <span class="kwrd">continue</span></pre><pre class="alt">&nbsp;</pre><pre>        <span class="rem">// 将View对应的Viewport提交到设备        </span></pre><pre class="alt">        RenderView.CommitViewport()</pre><pre>&nbsp;</pre><pre class="alt">        <span class="rem">// 渲染回调</span></pre><pre>        <span class="kwrd">foreach</span> RenderEventListener <span class="kwrd">in</span> RenderEventListenerList</pre><pre class="alt">        {</pre><pre>            RenderEventListener.OnRenderFrame()</pre><pre class="alt">        }</pre><pre>    }</pre><pre class="alt">&nbsp;</pre><pre>    Device.EndScene()</pre><pre class="alt">&nbsp;</pre><pre>     Device.Present()</pre><pre class="alt">&nbsp;</pre><pre>    Device.CurrentViewport = ScreenViewport <span class="rem">// 恢复全屏viewport</span></pre><pre class="alt">}</pre></div>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p>&nbsp;</p>
<p>&nbsp;</p>
<p>以下是RT间嵌套绘制的伪代码：</p>
<div class="csharpcode"><pre class="alt">RenderView.SwitchRenderTarget(stage, RenderTarget)</pre><pre>{</pre><pre class="alt">    <span class="rem">// 保存绘制前的RT</span></pre><pre>    PreTarget = Device.GetRenderTarget()</pre><pre class="alt">    <span class="rem">// 设置为当前的RT</span></pre><pre>    Device.SetRenderTarget( RenderTarget )</pre><pre class="alt">&nbsp;</pre><pre>    <span class="rem">// 更新RT摄像机</span></pre><pre class="alt">    RenderTarget.UpdateCamera()    </pre><pre>    </pre><pre class="alt">    <span class="rem">// 清空RT</span></pre><pre>    Device.Clear()</pre><pre class="alt">&nbsp;</pre><pre>    <span class="rem">// 绘制回调</span></pre><pre class="alt">    RenderTarget.OnRender( )</pre><pre>&nbsp;</pre><pre class="alt">    <span class="rem">// 恢复之前的RT</span></pre><pre>    Device.SetRenderTarget( PreTarget  );</pre><pre class="alt">}</pre></div>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style><img src ="http://www.cppblog.com/sunicdavy/aggbug/110895.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2010-03-29 18:16 <a href="http://www.cppblog.com/sunicdavy/archive/2010/03/29/110895.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>讨论：shader与矩阵转置</title><link>http://www.cppblog.com/sunicdavy/archive/2010/03/17/109879.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Wed, 17 Mar 2010 03:08:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2010/03/17/109879.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/109879.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2010/03/17/109879.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/109879.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/109879.html</trackback:ping><description><![CDATA[<p>完成自己的shader系统后，翻出之前写过的代码中发现有一个地方很奇怪</p> <p>我的矩阵定义跟OGRE的没什么区别</p> <div class="csharpcode"><pre class="alt">        union </pre><pre>        {</pre><pre class="alt">            <span class="kwrd">struct</span></pre><pre>            {</pre><pre class="alt">                <span class="kwrd">float</span> m11, m12, m13, m14;</pre><pre>                <span class="kwrd">float</span> m21, m22, m23, m24;</pre><pre class="alt">                <span class="kwrd">float</span> m31, m32, m33, m34;</pre><pre>                <span class="kwrd">float</span> m41, m42, m43, m44;</pre><pre class="alt">            };</pre><pre>            <span class="kwrd">float</span> m[4][4];</pre><pre class="alt">        };</pre></div>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p>&nbsp;&nbsp; 乘法也跟OGRE的一模一样，但在将view及project乘好的矩阵送给HLSL时，却必须转置下，才能得到正确的结果</p>
<div class="csharpcode"><pre class="alt">mSkinnedEffect.mMatrix.mValue = (camera.mViewMatrix * camera.mProjectMatrix).Transpose();</pre></div>
<p>shader:</p>
<div class="csharpcode"><pre class="alt">float4 localpos = mul(In.Position, skinTransform);</pre></div>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; OGRE中有这么一段代码及注释:</p>
<div class="csharpcode"><pre class="alt">    <span class="kwrd">const</span> Matrix4&amp; AutoParamDataSource::getProjectionMatrix(<span class="kwrd">void</span>) <span class="kwrd">const</span></pre><pre>    {</pre><pre class="alt">        <span class="kwrd">if</span> (mProjMatrixDirty)</pre><pre>        {</pre><pre class="alt">            <span class="rem">// NB use API-independent projection matrix since GPU programs</span></pre><pre>            <span class="rem">// bypass the API-specific handedness and use right-handed coords</span></pre><pre class="alt">            <span class="kwrd">if</span> (mCurrentRenderable &amp;&amp; mCurrentRenderable-&gt;getUseIdentityProjection())</pre><pre>            {</pre><pre class="alt">                <span class="rem">// Use identity projection matrix, still need to take RS depth into account.</span></pre><pre>                RenderSystem* rs = Root::getSingleton().getRenderSystem();</pre><pre class="alt">                rs-&gt;_convertProjectionMatrix(Matrix4::IDENTITY, mProjectionMatrix, <span class="kwrd">true</span>);</pre><pre>            }</pre><pre class="alt">            <span class="kwrd">else</span></pre><pre>            {</pre><pre class="alt">                mProjectionMatrix = mCurrentCamera-&gt;getProjectionMatrixWithRSDepth();</pre><pre>            }</pre><pre class="alt">            <span class="kwrd">if</span> (mCurrentRenderTarget &amp;&amp; mCurrentRenderTarget-&gt;requiresTextureFlipping())</pre><pre>            {</pre><pre class="alt">                <span class="rem">// Because we're not using setProjectionMatrix, this needs to be done here</span></pre><pre>                <span class="rem">// Invert transformed y</span></pre><pre class="alt">                mProjectionMatrix[1][0] = -mProjectionMatrix[1][0];</pre><pre>                mProjectionMatrix[1][1] = -mProjectionMatrix[1][1];</pre><pre class="alt">                mProjectionMatrix[1][2] = -mProjectionMatrix[1][2];</pre><pre>                mProjectionMatrix[1][3] = -mProjectionMatrix[1][3];</pre><pre class="alt">            }</pre><pre>            mProjMatrixDirty = <span class="kwrd">false</span>;</pre><pre class="alt">        }</pre><pre>        <span class="kwrd">return</span> mProjectionMatrix;</pre><pre class="alt">    }</pre></div>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p>貌似是跟左右手这个恶心的东西有关系</p>
<p>回看DirectXSDK中提供的BasicHLSL例子</p>
<div class="csharpcode"><pre class="alt">        mWorld = g_mCenterWorld * *g_Camera.GetWorldMatrix();</pre><pre>        mProj = *g_Camera.GetProjMatrix();</pre><pre class="alt">        mView = *g_Camera.GetViewMatrix();</pre><pre>&nbsp;</pre><pre class="alt">        mWorldViewProjection = mWorld * mView * mProj;</pre><pre>&nbsp;</pre><pre class="alt">        V( g_pEffect-&gt;SetMatrix( <span class="str">"g_mWorldViewProjection"</span>, &amp;mWorldViewProjection ) );</pre></div>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p></p>
<p>shader：</p><pre class="csharpcode">Output.Position = mul(vAnimatedPos, g_mWorldViewProjection);</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p>丝毫无需转置矩阵,Effect接口中也提供有SetMatrixTranspose这类方法。所以排除内部有自动转置的嫌疑。</p>
<p>询问过野猪这个问题，野猪答曰:"转置后传输至需要传3个vector, 最后一个是[0 0 0 1]” </p>
<p>有达人知道的，可以指点下迷津 :)</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/109879.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2010-03-17 11:08 <a href="http://www.cppblog.com/sunicdavy/archive/2010/03/17/109879.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一套可扩充的游戏模型系统</title><link>http://www.cppblog.com/sunicdavy/archive/2010/03/12/109538.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Fri, 12 Mar 2010 08:13:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2010/03/12/109538.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/109538.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2010/03/12/109538.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/109538.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/109538.html</trackback:ping><description><![CDATA[<p>本人的设计图可以方便在文本编辑器里查看(&gt;为派生 +为包含)  <p>MAX插件导出的模型资源分：Mesh/Skin, Skeleton, Animation <p>不同动作按照不同的动画文件保存 <p>&nbsp; <p>ResourceHandle 包含基本id<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &gt;NamedResourceHandle 带有名称资源，包含hashA, hashB， 使用暴雪hash函数生成<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &gt;ModelHandle&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &gt;MeshHandle&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &gt;SkeletonHandle&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &gt;AnimationHandle  <p>获取资源，如果资源不存在时，自动加载<br>ModelMaster.ManualCache( &amp;ModelHandle )  <p>直接资源访问：<br>RawSkeleton = ModelMaster.ManualCache( &amp;SkeletonHandle("a.skl") )<br>RawSkeleton-&gt;GetMarker(...)  <p>异步资源加载，异步id保存于ModelHandle中，在callback中根据id确认<br>ModelMaster.AsyncCache( &amp;ModelHandle )  <p>获取资源指针，未加载时，返回空<br>ModelResource = ModelMaster.Fetch( &amp;ModelHandle )  <p>模型资源加载器<br>&nbsp;&nbsp;&nbsp; 在模型句柄中绑定对应加载器<br>&nbsp;&nbsp;&nbsp; 可以自行编写带换装的ModelLoader，通过读取自己的配置文件，自行加载资源后生成RawModel<br>ModelLoader<br>&nbsp;&nbsp;&nbsp; ModelHandle&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ---mapping---&gt;&nbsp;&nbsp;&nbsp; ModelLoader&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ---generate--&gt; RawModel<br>&nbsp;&nbsp;&nbsp; MeshHandle&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ---mapping---&gt;&nbsp;&nbsp;&nbsp; MeshLoader&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ---generate--&gt; RawMesh<br>&nbsp;&nbsp;&nbsp; SkeletonHandle&nbsp;&nbsp;&nbsp;&nbsp; ---mapping---&gt;&nbsp;&nbsp;&nbsp; SkeletonLoader&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ---generate--&gt; RawSkeleton<br>&nbsp;&nbsp;&nbsp; AnimationHandle&nbsp;&nbsp;&nbsp; ---mapping---&gt;&nbsp;&nbsp;&nbsp; AnimationLoader&nbsp;&nbsp; ---generate--&gt; RawAnimation  <p>引用计数类&nbsp;&nbsp;&nbsp; <br>ModelResource<br>&nbsp;&nbsp;&nbsp; &gt;RawModel<br>&nbsp;&nbsp;&nbsp; &gt;RawMesh<br>&nbsp;&nbsp;&nbsp; &gt;RawSkeleton<br>&nbsp;&nbsp;&nbsp; &gt;RawAnimation  <p>RawModel中不保留Handle，只保留指针<br>RawModel<br>&nbsp;&nbsp;&nbsp; +MeshVB&nbsp;&nbsp;&nbsp; 从模型文件中直接读取顶点格式，包含 静态,GPU,CPU类型顶点<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +RawMesh<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +MeshIB&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一次性填充IB<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &gt;GPUMeshVB&nbsp;&nbsp;&nbsp; 一次性填充VB<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &gt;CPUMeshVB&nbsp;&nbsp;&nbsp; 每帧计算<br>&nbsp;&nbsp;&nbsp; +Animation&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 运行期数据（时间/帧）<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +RawAnimation&nbsp;&nbsp;&nbsp; 原始动画内容<br>&nbsp;&nbsp;&nbsp; +Skeleton<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +RawSkeleton</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/109538.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2010-03-12 16:13 <a href="http://www.cppblog.com/sunicdavy/archive/2010/03/12/109538.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Direct3D9 Fx/HLSL的若干条有用的笔记</title><link>http://www.cppblog.com/sunicdavy/archive/2010/03/05/108962.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Fri, 05 Mar 2010 06:26:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2010/03/05/108962.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/108962.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2010/03/05/108962.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/108962.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/108962.html</trackback:ping><description><![CDATA[<p>Direct3D中的Shader是这样的：</p> <p>1. ASM Shader是最元老的也是DX8主要使用Shader</p> <p>2. fxc编译器可以同时编译ASM,HLSL和fx脚本,其中HLSL和fx可以查看编译后的GPU汇编代码</p> <p>3. D3D9中，fx是HLSL的一种渲染脚本，简化了HLSL设置及常量绑定，并且附带RenderStateBlock及设置</p> <p>但只能用于制作简单的Shader</p> <p>4. DirectXSDK中有一个概念混淆：C++例子中的BasicHLSL使用的其实还是fx，HLSLwithoutEffects例子才是真正的纯HLSL</p> <p>5.fx与HLSL程序鉴别：</p> <p>使用fx程序必定含有：D3DXCreateEffectXXX 系列函数， ID3DXEffect对象，渲染中能看到SetTechnique，BeginPass，EndPass之类的字眼</p> <p>使用纯HLSL程序含有：D3DXCompileShader，ID3DXConstantTable对象，GetConstantByName，GetConstantDesc之类的字眼</p> <p>6. 在fx中包含有 VertexShader，PixelShader代码及profile，entry，RenderState设置及简单的绘制过程(pass)。一次编译后，VS,PS,Texture,Sampler及常量都是在ID3DXEffect对象中自动完成，无需手动设置。</p> <p>7. HLSL可以将VS及PS代码写入1个.hlsl文件。注意，以下这种代码可以在HLSL中编译过，但实际没有任何效果</p> <div class="csharpcode"><pre class="alt"><span class="lnum">   1:  </span>sampler_state</pre><pre><span class="lnum">   2:  </span>{</pre><pre class="alt"><span class="lnum">   3:  </span>    Texture = &lt;tex&gt;;</pre><pre><span class="lnum">   4:  </span>    MipFilter = LINEAR;</pre><pre class="alt"><span class="lnum">   5:  </span>    MinFilter = LINEAR;</pre><pre><span class="lnum">   6:  </span>    MagFilter = LINEAR;</pre><pre class="alt"><span class="lnum">   7:  </span>};</pre></div>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p>这点可以参考AMD RenderMonkey中只在shader中使用sampler而忽略texture。</p>
<p>8. fx中往shader设置纹理使用的是ID3DXBaseEffect::SetTexture下的这个函数</p>
<div class="csharpcode"><pre class="alt"><span class="lnum">   1:  </span>HRESULT SetTexture(</pre><pre><span class="lnum">   2:  </span>  D3DXHANDLE hParameter,</pre><pre class="alt"><span class="lnum">   3:  </span>  LPDIRECT3DBASETEXTURE9 pTexture</pre><pre><span class="lnum">   4:  </span>);</pre></div>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p> 但是在HLSL中，这点就变得很麻烦，需要手动设置，可以参考这篇<a href="http://www.cppblog.com/liangairan/articles/57971.html">文章</a></p>
<p>Shader代码片段：</p>
<div class="csharpcode"><pre class="alt"><span class="lnum">   1:  </span>sampler Samp0 = sampler_state</pre><pre><span class="lnum">   2:  </span>{</pre><pre class="alt"><span class="lnum">   3:  </span>    Texture = &lt;Tex0&gt;;</pre><pre><span class="lnum">   4:  </span>    MipFilter = LINEAR;</pre><pre class="alt"><span class="lnum">   5:  </span>    MinFilter = LINEAR;</pre><pre><span class="lnum">   6:  </span>    MagFilter = LINEAR;</pre><pre class="alt"><span class="lnum">   7:  </span>};</pre></div>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p>编译HLSL代码后得到ConstantTable，然后取出句柄：</p>
<div class="csharpcode"><pre class="alt"><span class="lnum">   1:  </span>ScalarHandle = pixelConstTable-&gt;GetConstantByName(0, <span class="str">"Scalar"</span>);</pre><pre><span class="lnum">   2:  </span>&nbsp;</pre><pre class="alt"><span class="lnum">   3:  </span>Samp0Handle = pixelConstTable-&gt;GetConstantByName(0, <span class="str">"Samp0"</span>);</pre><pre><span class="lnum">   4:  </span>&nbsp;</pre><pre class="alt"><span class="lnum">   5:  </span>Samp1Handle = pixelConstTable-&gt;GetConstantByName(0, <span class="str">"Samp1"</span>);</pre></div>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p>再从句柄取出symbol的描述：</p>
<div class="csharpcode"><pre class="alt"><span class="lnum">   1:  </span>UINT count;</pre><pre><span class="lnum">   2:  </span>&nbsp;</pre><pre class="alt"><span class="lnum">   3:  </span>pixelConstTable-&gt;GetConstantDesc(Samp0Handle, &amp; Samp0Desc, &amp;count);</pre><pre><span class="lnum">   4:  </span>&nbsp;</pre><pre class="alt"><span class="lnum">   5:  </span>pixelConstTable-&gt;GetConstantDesc(Samp1Handle, &amp; Samp1Desc, &amp;count);</pre></div>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p>通过上面的描述，将纹理变量的寄存器偏移作为纹理的stage</p>
<p>8.&nbsp; 优化常量设置速度的方法一般就是根据字符串取出句柄，以后每次渲染时，只通过句柄设置。但ID3DXConstantTable最后还是通过</p>
<p>IDirect3DDevice9::SetPixelShaderConstantX 系列函数来实现的</p>
<div class="csharpcode"><pre class="alt"><span class="lnum">   1:  </span>HRESULT SetPixelShaderConstantF(</pre><pre><span class="lnum">   2:  </span>  UINT StartRegister,</pre><pre class="alt"><span class="lnum">   3:  </span>  CONST <span class="kwrd">float</span> * pConstantData,</pre><pre><span class="lnum">   4:  </span>  UINT Vector4fCount</pre><pre class="alt"><span class="lnum">   5:  </span>);</pre></div>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p>9. HLSL将一段包含VS和PS代码编译完成后，将得到VS和PS两个单独的ID3DXConstantTable</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/108962.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2010-03-05 14:26 <a href="http://www.cppblog.com/sunicdavy/archive/2010/03/05/108962.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>枚举反射对象和结构体反射填充</title><link>http://www.cppblog.com/sunicdavy/archive/2010/02/26/108509.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Fri, 26 Feb 2010 09:58:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2010/02/26/108509.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/108509.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2010/02/26/108509.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/108509.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/108509.html</trackback:ping><description><![CDATA[<pre class="csharpcode">&nbsp;</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p>最近在写D3D9模拟D3D10接口的渲染系统中碰到大量的渲染状态对象，不仅成员多，枚举也多的要命。</p>
<p>&nbsp;</p><pre class="csharpcode">    <span class="kwrd">struct</span> CORE_API RasterizerState : ResourceHandle            
    {
        eFillMode            mFillMode;        
        eCullMode            mCullMode;
        <span class="kwrd">bool</span>                mFrontFaceCCW;
        <span class="kwrd">float</span>                mDepthBias;
        <span class="kwrd">float</span>                mSlopeScaledDepthBias;
        <span class="kwrd">bool</span>                mDepthClipEnable;
        <span class="kwrd">bool</span>                mScissorEnable;
        <span class="kwrd">bool</span>                mMultisampleEnable;

        RasterizerState();
    };
</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p>而要从配置文件中读取数据并填充到这个结构体，对于C++来说完全就是吃力不讨好的，写出来的代码也是极为过程，修改和扩展极为麻烦的。</p>
<p>因此决定使用反射的方法来填充数据，先总结一下我的C++反射系统</p>
<blockquote><pre class="csharpcode"><span class="kwrd">class</span> RTTIObject <span class="rem">// 动态类型识别对象基类，对象通过一些宏后可以很方便的通过字符串创建出类实例，并且可以查询注册时的类型和其他绑定信息</span>
<span class="kwrd">class</span> NameRef  <span class="rem">// 名字表，类似于虚幻中的FName，可以定义Const和普通Name，比较和拷贝只是一个dword耗费的时间</span>
value_parse，value_tostring，value_typename // 一系列类型模板函数，提供对类型的ToString，Parse及类型名查询</pre></blockquote>
<p>&nbsp;</p>
<p>首先需要处理的是枚举查询，这里将枚举通过宏做成一个个枚举对象，并可以通过名字创建实例</p>
<blockquote><pre class="csharpcode"><span class="preproc">#define</span> DECLARE_ENUMOBJECT( TEnum ) \
    <span class="kwrd">struct</span> EnumObject_##TEnum : EnumObject\
    {\
    DECLARE_RTTIOBJECT( EnumObject_##TEnum );\
    EnumObject_##TEnum( );\
    };


<span class="preproc">#define</span> IMPLEMENT_ENUMOBJECT_BEGIN( TEnum, TEnum_prefixoffset, TMember_prefixoffset ) \
    IMPLEMENT_RTTIOBJECT_STRING( EnumObject_##TEnum, #TEnum + TEnum_prefixoffset, #TEnum + TEnum_prefixoffset, <span class="str">"EnumObject"</span> )\
    EnumObject_##TEnum::EnumObject_##TEnum(){ <span class="kwrd">const</span> <span class="kwrd">int</span> member_prefixoffset = TMember_prefixoffset;

<span class="preproc">#define</span> ENUMOBJECT_ADD( enumkey ) AddMember( #enumkey + member_prefixoffset, (dword)enumkey );

<span class="preproc">#define</span> IMPLEMENT_ENUMOBJECT_END }

<span class="preproc">#define</span> ENUMOBJECT_STATICINIT( TEnum ) EnumObject_##TEnum::StaticInit();
</pre></blockquote>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p>EnumObject 中通过宏将枚举的名称和值保存在这个对象中</p>
<blockquote><pre class="csharpcode">IMPLEMENT_ENUMOBJECT_BEGIN( eFillMode, 1, 3 )  <span class="rem">// 这里的1，3是将eFillMode及FM_Point转成字符串后去掉前缀</span>
    ENUMOBJECT_ADD( FM_Point )
    ENUMOBJECT_ADD( FM_Line )
    ENUMOBJECT_ADD( FM_Fill )
IMPLEMENT_ENUMOBJECT_END

<span class="rem">// 注册到RTTIObject系统</span>

ENUMOBJECT_STATICINIT( eFillMode )
</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p>&nbsp;</p><pre class="csharpcode"><span class="rem">// 通过枚举对象可以查找到字符串对应的值</span>
dword v;
EnumObject::GetEnumValue( <span class="str">"FillMode"</span>, <span class="str">"Point"</span>, v )</pre></blockquote><pre class="csharpcode"></pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p>下一步是将结构体成员信息记录</p><pre class="csharpcode">    <span class="kwrd">void</span> SettingObject::BindMember( <span class="kwrd">const</span> NameRef&amp; objname, <span class="kwrd">void</span>* instancePtr, <span class="kwrd">void</span>* dataPtr, SettingProxy* proxy )
    {
        proxy-&gt;mOffset = dword(dataPtr) - dword(instancePtr);

        MemberList&amp; memberlist = mSettingMap[ objname ];
        memberlist[ proxy-&gt;mName ] = proxy;
    }<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style></pre>
<p>这里记录的是结构体成员的内存偏移</p>
<p>使用大量的宏，可以让结构体绑定变得漂亮</p>
<blockquote><pre class="csharpcode"><span class="preproc">#define</span> BIND_SETTINGOBJECT_BEGIN( TClass ) \
    { <span class="kwrd">const</span> NameRef&amp; soname = TClass::StaticGetClassInfo()-&gt;mClassName;TClass soobj;

<span class="preproc">#define</span> BIND_SO_MEMBER( TMemberType, TMember ) \
    so.BindMember( soname, &amp;soobj, &amp;soobj.TMember, <span class="kwrd">new</span> TSettingElement&lt;TMemberType&gt;(#TMember + 1 ) );

<span class="preproc">#define</span> BIND_SO_MEMBER_NAME( TMemberType, TMember, TName ) \
    so.BindMember( soname, &amp;soobj, &amp;soobj.TMember, <span class="kwrd">new</span> TSettingElement&lt;TMemberType&gt;(TName) );

<span class="preproc">#define</span> BIND_SO_ENUM( TEnumType, TMember ) \
    so.BindMember( soname, &amp;soobj, &amp;soobj.TMember, <span class="kwrd">new</span> TSettingEnum(#TMember + 1, #TEnumType + 1) );

<span class="preproc">#define</span> BIND_SO_ENUM_NAME( TEnumType, TMember, TName ) \
    so.BindMember( soname, &amp;soobj, &amp;soobj.TMember, <span class="kwrd">new</span> TSettingEnum(TName, #TEnumType + 1) );

<span class="preproc">#define</span> BIND_SETTINGOBJECT_END }</pre></blockquote>
<p>绑定代码如下</p><pre class="csharpcode">        BIND_SETTINGOBJECT_BEGIN( RasterizerState )
            BIND_SO_ENUM    ( eFillMode    , mFillMode )
            BIND_SO_ENUM    ( eCullMode    , mCullMode )
            BIND_SO_MEMBER    ( <span class="kwrd">bool</span>        , mFrontFaceCCW )
            BIND_SO_MEMBER    ( <span class="kwrd">float</span>        , mDepthBias )
            BIND_SO_MEMBER    ( <span class="kwrd">float</span>        , mSlopeScaledDepthBias)
            BIND_SO_MEMBER    ( <span class="kwrd">bool</span>        , mDepthClipEnable)
            BIND_SO_MEMBER    ( <span class="kwrd">bool</span>        , mScissorEnable)
            BIND_SO_MEMBER    ( <span class="kwrd">bool</span>        , mMultisampleEnable)
        BIND_SETTINGOBJECT_END</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p>&nbsp;</p>
<p>所有结构体的信息被记录在SettingObject中，读取配置文件填充结构体的任务就变得异常的简单了</p>
<blockquote><pre class="csharpcode">    SettingObject settings;
<span class="rem">// 将所有的结构体信息记录</span>
    InitRenderStateObjectSetting( settings );

    <span class="kwrd">const</span> NameRef&amp; rzname = DepthStencilState::StaticGetClassInfo()-&gt;mClassName;

    DepthStencilState a;
 <span class="rem">// 这里就是将配置文件的信息填充到结构体</span>
    settings.SetMember( rzname, &amp;a, <span class="str">"BackFace.StencilFunc"</span>, <span class="str">"Equal"</span> );</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
</blockquote><pre class="csharpcode">&nbsp;</pre><img src ="http://www.cppblog.com/sunicdavy/aggbug/108509.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2010-02-26 17:58 <a href="http://www.cppblog.com/sunicdavy/archive/2010/02/26/108509.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>设计D3D9 HLSL渲染脚本</title><link>http://www.cppblog.com/sunicdavy/archive/2010/02/15/107911.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Mon, 15 Feb 2010 15:18:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2010/02/15/107911.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/107911.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2010/02/15/107911.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/107911.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/107911.html</trackback:ping><description><![CDATA[<p>最近翻出很早之前自己写的一套使用Direct3D 9&nbsp; Effect系统的纯shader 3d引擎，打算使用最新技术重写。重写的主要修改在于：</p> <p>1. 去掉Effect系统，改用HLSL + 渲染脚本</p> <p>2. 优化渲染接口，使用材质统一shader和渲染状态</p> <p>随即参考了DirectX SDK的Graphics部分文档：DirectX9 时代的Effect系统纯粹只是一个HLSL的简单渲染脚本实现，除了DXUT，FXComposer等极少程序使用这套东西外，大型的引擎很少使用这种半成品系统。到了DirectX10甚至11，因为架构更改，去掉固定管线，因此Effect成为较为高效和便捷的渲染脚本，如果不是要求较高的3d引擎，一般的游戏使用DirectX10的Effect渲染脚本还是很不错的。</p> <p>DX10的fx脚本与DX9的差异在于</p> <p>渲染状态，采样器状态等都变为对象，并与API高度统一</p> <p>在脚本与API中均可以设置</p> <p>DepthStencilState EnableDepth<br>{<br>&nbsp;&nbsp;&nbsp; DepthEnable = TRUE;<br>&nbsp;&nbsp;&nbsp; DepthWriteMask = ALL;<br>&nbsp;&nbsp;&nbsp; DepthFunc = LESS_EQUAL;<br>};  <p>BlendState NoBlending<br>{<br>&nbsp;&nbsp;&nbsp; AlphaToCoverageEnable = FALSE;<br>&nbsp;&nbsp;&nbsp; BlendEnable[0] = FALSE;<br>}; <p>technique10 Render<br>{<br>&nbsp;&nbsp;&nbsp; pass P0<br>&nbsp;&nbsp;&nbsp; {</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SetDepthStencilState( EnableDepth, 0 );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );<br>&nbsp;&nbsp;&nbsp; }<br>}</p> <p>本人觉得，这样的设计让图形API更为敏捷与归类化，另外，也便于StateManager或者自己做渲染状态转移及差异比较时更为高效 <p>&nbsp; <p>Vista操作系统推出很久后，DX10的显卡也占有了大量的市场份额。但是由于DX10仍然是一个过渡API（类似于DX8)，因此，很多3D游戏要么仍然支持DX9，要不然即支持DX9也支持DX10，甚至DX11. <p>&nbsp;&nbsp; 看博客上有达人组团编写类似DX10接口和系统的软渲染，DX10的设计是优秀的。因此，在DX9 HLSL基础上，结合自己编写的渲染脚本会是非常好的选择。 <p>&nbsp;&nbsp;&nbsp; 渲染脚本我的设计思路是这样的： <p> 1. 只是一种预处理脚本，并非实时运行脚本。 <p>编译器将文本解析后，转化为一些运行指令，比如：本pass使用一块小纹理，下一pass的target是这个纹理，并且开启哪些渲染状态。 <p>2. 自定义格式的解析脚本。 <p>使用lua，python等脚本其实也是可以的。但是在出现错误时，报出的错可能会让不熟悉这个脚本语言的人莫名其妙。 <p>使用松鼠sq脚本语言？可惜其在lua基础上，对table的slot初次赋值时必须使用&lt;-而不是统一使用=，因此会让你的脚本稀奇古怪 <p>XML脚本？ XML可以避免复杂的语法检查，写完就是归整的，但也是罗嗦的，本来Texture[2]可以表达完毕的，非要&lt;Texture index = 2/&gt;来罗嗦下。 <p>OGRE的compositor脚本和材质脚本就是自己解析的，不过出乎预料的使用了BNF范式这类较为正规的方法。这就是说，需要先解析BNF表达式，然后再输入脚本解析，编写过程和系统复杂度会变得异常复杂。 <p>最终选择还是使用自己解析的脚本，使用一些具体代码结构来替代BNF这类高深的东西 <p>决定以后，下一步需要制定渲染脚本具体各部分及制作过程 <p>1. 基本lexer <p>&nbsp;&nbsp; 从文本得到各种token <p>1. 渲染状态对象 <p>&nbsp;&nbsp; 照着DX10抄就好 <p>2. Shader导入口 <p>&nbsp;&nbsp;&nbsp;&nbsp; shader文件来自于何处，入口怎样定义 <p>3. 渲染脚本VM及指令 <p>&nbsp; 决定一个纹理怎样设置，RenderTarget怎样使用等的指令 <img src ="http://www.cppblog.com/sunicdavy/aggbug/107911.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2010-02-15 23:18 <a href="http://www.cppblog.com/sunicdavy/archive/2010/02/15/107911.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>