﻿<?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++博客-月下的博客-随笔分类-开发</title><link>http://www.cppblog.com/cty41/category/13040.html</link><description /><language>zh-cn</language><lastBuildDate>Thu, 10 Mar 2016 13:11:58 GMT</lastBuildDate><pubDate>Thu, 10 Mar 2016 13:11:58 GMT</pubDate><ttl>60</ttl><item><title>如何做优化</title><link>http://www.cppblog.com/cty41/archive/2016/03/10/212965.html</link><dc:creator>月下圆舞曲</dc:creator><author>月下圆舞曲</author><pubDate>Thu, 10 Mar 2016 03:33:00 GMT</pubDate><guid>http://www.cppblog.com/cty41/archive/2016/03/10/212965.html</guid><wfw:comment>http://www.cppblog.com/cty41/comments/212965.html</wfw:comment><comments>http://www.cppblog.com/cty41/archive/2016/03/10/212965.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cty41/comments/commentRss/212965.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cty41/services/trackbacks/212965.html</trackback:ping><description><![CDATA[<div>&nbsp; 最近看了同事做的优化，带alpha贴图改为RGBA444(降低50%)，判断pack的texture占用率不到50%则使用non-pot （降低50-75%）</div><div>对游戏包的优化，降低冗余，减少动画，音频的重复多份保存（大小降低均在30%+）</div><div></div><div>简单的方法，当初我也考虑过，唯一差的一层纸就是我都没去试验和实践。</div><div></div><div>造成这个差别的原因除了行动上的懒惰，经验上的差距，也是方法论上的欠缺。</div><div>我们做开发的不能光想着要求美术极限优化，更应该从技术方法上着手规模性的优化</div><div>美术的优化可以说是将m减少到n，而我们程序可以做到从100%到50%。</div><div></div><div>最后贴下milo大神归纳的优化游戏包大小的核心四大策略：</div><div>1.没被引用的数据</div><div>2.冗余数据</div><div>3.无损压缩=》如何找到秘技帮助无损压缩</div><div>4.有损压缩</div><img src ="http://www.cppblog.com/cty41/aggbug/212965.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cty41/" target="_blank">月下圆舞曲</a> 2016-03-10 11:33 <a href="http://www.cppblog.com/cty41/archive/2016/03/10/212965.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>五年感想</title><link>http://www.cppblog.com/cty41/archive/2016/03/05/212933.html</link><dc:creator>月下圆舞曲</dc:creator><author>月下圆舞曲</author><pubDate>Sat, 05 Mar 2016 00:45:00 GMT</pubDate><guid>http://www.cppblog.com/cty41/archive/2016/03/05/212933.html</guid><wfw:comment>http://www.cppblog.com/cty41/comments/212933.html</wfw:comment><comments>http://www.cppblog.com/cty41/archive/2016/03/05/212933.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/cty41/comments/commentRss/212933.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cty41/services/trackbacks/212933.html</trackback:ping><description><![CDATA[1.去年对我意义重大：试图股市赌博，大败而归。我最敬爱的亲人过世。我妻子怀孕。钱没那么重要，心才是。<br />2.工作五年，值得骄傲的事只有最早参与制作海盗IOS版，后来自己做的热血足球卖了2w套。这两个阶段我自己心中追求很明确，所以设置短期目标很重要。<br />3.进了鹅场快两年，到最近思想才开始转变，很惭愧。腾讯其实提供了很好的学习资源，这半年里接触了研发部的几位大神人物，感受到了无论是待人处事，还是技术能力上的差距<br />4.做功能，即使很小小功能也能做成花来。只要肯想肯做，但这样要投入2倍甚至3倍的时间。就像《闻香识女人》里帕西诺说的：我知道这是正确的路，但我并没有走，因为我知道这条路走起来太难了。<br />5.提意见：这个是看&#8220;创新工场&#8221;书中开篇就说到的，不要通过批评来拔高自己，提意见是善意地为了帮助对方更好的提升。这一点上，对待同事，对待家人，我都做的很差。<br />6.决定游戏成功的因素？3年前认为是态度-》4年前认为是设计-》现在转变为人<br />7.坚持记录，人的大脑擅长迸发灵感，但缺不擅长记忆他们。<br /><br /><img src ="http://www.cppblog.com/cty41/aggbug/212933.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cty41/" target="_blank">月下圆舞曲</a> 2016-03-05 08:45 <a href="http://www.cppblog.com/cty41/archive/2016/03/05/212933.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DirectX 10的State Object管理策略</title><link>http://www.cppblog.com/cty41/archive/2011/12/29/156129.html</link><dc:creator>月下圆舞曲</dc:creator><author>月下圆舞曲</author><pubDate>Thu, 29 Dec 2011 14:35:00 GMT</pubDate><guid>http://www.cppblog.com/cty41/archive/2011/12/29/156129.html</guid><wfw:comment>http://www.cppblog.com/cty41/comments/156129.html</wfw:comment><comments>http://www.cppblog.com/cty41/archive/2011/12/29/156129.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cty41/comments/commentRss/156129.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cty41/services/trackbacks/156129.html</trackback:ping><description><![CDATA[<div>
<p style="text-align: left; line-height: 150%" align="left"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp;好久没更新了。。上自己博客看了下这篇2个月前的草稿都还没写完。。的确是要荒废了快。。囧<br />&nbsp;&nbsp;&nbsp;最近上班没什么事情，所以便考虑着把自己老土的</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">d9</span><span style="line-height: 150%; font-family: 宋体">图形山寨引擎移植到</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">d10</span><span style="line-height: 150%; font-family: 宋体">上（其实可以</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'"><a href="http://www.cnblogs.com/gongminmin/"><span style="font-family: 宋体; color: blue">直接移植到</span><span style="color: blue">d11</span><span style="font-family: 宋体; color: blue">的</span></a></span><span style="line-height: 150%; font-family: 宋体">）。。我就慢半拍吧。。首先</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">d10</span><span style="line-height: 150%; font-family: 宋体">，</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">11</span><span style="line-height: 150%; font-family: 宋体">和</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">d9</span><span style="line-height: 150%; font-family: 宋体">的一大区别就是本来</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">d9</span><span style="line-height: 150%; font-family: 宋体">众多的</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">setState</span><span style="line-height: 150%; font-family: 宋体">被去除，而使用改进的</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">state object</span><span style="line-height: 150%; font-family: 宋体">，这些包括了</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">Input-Layout State</span><span style="line-height: 150%; font-family: 宋体">，</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'"> Rasterizer State</span><span style="line-height: 150%; font-family: 宋体">，</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">Depth-Stencil State</span><span style="line-height: 150%; font-family: 宋体">，</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'"> Blend State</span><span style="line-height: 150%; font-family: 宋体">，</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'"> Sampler State</span><span style="line-height: 150%; font-family: 宋体">。可以看到本来的多次</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">set</span><span style="line-height: 150%; font-family: 宋体">函数被大量简化了，而这些</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">state object</span><span style="line-height: 150%; font-family: 宋体">都是依靠对应的</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">DESC</span><span style="line-height: 150%; font-family: 宋体">（描述），来直接创建出来，用户在使用的时候只需要向驱动层传递一个句柄（也就是新的</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">set</span><span style="line-height: 150%; font-family: 宋体">函数）既可以对许多个状态进行改变，例如</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">Rasterizer State</span><span style="line-height: 150%; font-family: 宋体">的</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">DESC</span><span style="line-height: 150%; font-family: 宋体">：</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'"><br />typedef struct D3D10_RASTERIZER_DESC {<br />D3D10_FILL_MODE FillMode;<br />D3D10_CULL_MODE CullMode;<br />BOOL FrontCounterClockwise;<br />INT DepthBias;<br />FLOAT DepthBiasClamp;<br />FLOAT SlopeScaledDepthBias;<br />BOOL DepthClipEnable;<br />BOOL ScissorEnable;<br />BOOL MultisampleEnable;<br />BOOL AntialiasedLineEnable;<br />} D3D10_RASTERIZER_DESC;<br /></span><span style="line-height: 150%; font-family: 宋体">可以看到一次</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">set</span><span style="line-height: 150%; font-family: 宋体">可以一次给驱动发送以前</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">d9</span><span style="line-height: 150%; font-family: 宋体">曾经需要很多条</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">command</span><span style="line-height: 150%; font-family: 宋体">的工作，可想而知其带来的性能提升。</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'"><br /></span><span style="line-height: 150%; font-family: 宋体">但这也带来了新的问题，由于这些</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">state object</span><span style="line-height: 150%; font-family: 宋体">的创建是比较耗时的，所以便不可能像以前</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">d9</span><span style="line-height: 150%; font-family: 宋体">一样没帧都去</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">set</span><span style="line-height: 150%; font-family: 宋体">，而且由于</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">DESC</span><span style="line-height: 150%; font-family: 宋体">里有多个配置项，也无法简单的去</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">cache</span><span style="line-height: 150%; font-family: 宋体">。看到这里，我想看过</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">Christer</span><span style="line-height: 150%; font-family: 宋体">和</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">clayman</span><span style="line-height: 150%; font-family: 宋体">大人那两篇关于渲染排序文章的同学应该能想到对应的思路。那就是做一个</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">sortkey</span><span style="line-height: 150%; font-family: 宋体">，对于</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">Rasterizer State</span><span style="line-height: 150%; font-family: 宋体">来说</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">,FillMode</span><span style="line-height: 150%; font-family: 宋体">这些枚举，</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">bool</span><span style="line-height: 150%; font-family: 宋体">都是能直接做入</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">sortkey</span><span style="line-height: 150%; font-family: 宋体">的（节省比较次数），剩下的譬如</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">int</span><span style="line-height: 150%; font-family: 宋体">或者</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">float</span><span style="line-height: 150%; font-family: 宋体">则直接比较，也就是重载</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">operator==</span><span style="line-height: 150%; font-family: 宋体">和</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">!=</span></p>
<p style="text-align: left; line-height: 150%" align="left"><span style="line-height: 150%; font-family: 宋体">譬如</span><span style="line-height: 150%; font-family: 'Verdana','sans-serif'"> </span></p>
<p style="text-align: left; line-height: 150%" align="left">&nbsp;</p>
<p style="text-align: left; line-height: 150%" align="left">&nbsp;</p>
<p style="text-align: left; line-height: 150%" align="left"><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">bool operator==(const D3D10RasterState&amp; rhs)</span></p>
<p style="text-align: left; line-height: 150%" align="left"><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">{</span></p>
<p style="text-align: left; line-height: 150%" align="left">&nbsp;</p>
<p style="text-align: left; line-height: 150%; margin: 0cm 0cm 0pt 10.5pt" align="left"><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">if(SortKey == rhs.SortKey &amp;&amp; DESC.DepthBias == rhs.DESC. DepthBias &amp;&amp;</span></p>
<p style="text-align: left; line-height: 150%; text-indent: 10.5pt; margin: 0cm 0cm 0pt 10.5pt" align="left"><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">fabs(DESC. DepthBiasClamp &#8211; rhs.DESC. DepthBiasClamp) &lt; 0.000001f &amp;&amp; etc..)</span></p>
<p style="text-align: left; line-height: 150%; text-indent: 21pt; margin: 0cm 0cm 0pt -10.5pt" align="left"><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">&nbsp;&nbsp; return true;</span></p>
<p style="text-align: left; line-height: 150%; text-indent: 21pt; margin: 0cm 0cm 0pt -10.5pt" align="left">&nbsp;</p>
<p style="text-align: left; line-height: 150%; text-indent: 21pt; margin: 0cm 0cm 0pt -10.5pt" align="left"><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">&nbsp;return false;</span></p>
<p style="text-align: left; line-height: 150%; text-indent: 21pt; margin: 0cm 0cm 0pt -10.5pt" align="left"><span style="line-height: 150%; font-family: 'Verdana','sans-serif'">}</span></p>
<p>UE3<span style="font-family: 宋体">中这块大概也是这样的，不过他没有弄</span>sortkey<span style="font-family: 宋体">什么，他是很简单直接重载了</span>==<span style="font-family: 宋体">和</span>!=<span style="font-family: 宋体">的用</span>memcmp<span style="font-family: 宋体">比较</span><span style="font-family: 'Verdana','sans-serif'">State</span><span style="font-family: 宋体">的</span><span style="font-family: 'Verdana','sans-serif'">DESC</span><span style="font-family: 宋体">就完了</span><span style="font-family: 'Verdana','sans-serif'">..</span><span style="font-family: 宋体">简单易用吧。。</span></p></div><img src ="http://www.cppblog.com/cty41/aggbug/156129.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cty41/" target="_blank">月下圆舞曲</a> 2011-12-29 22:35 <a href="http://www.cppblog.com/cty41/archive/2011/12/29/156129.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Dithering-视觉的奇特现象</title><link>http://www.cppblog.com/cty41/archive/2011/07/19/dither.html</link><dc:creator>月下圆舞曲</dc:creator><author>月下圆舞曲</author><pubDate>Tue, 19 Jul 2011 14:26:00 GMT</pubDate><guid>http://www.cppblog.com/cty41/archive/2011/07/19/dither.html</guid><wfw:comment>http://www.cppblog.com/cty41/comments/151420.html</wfw:comment><comments>http://www.cppblog.com/cty41/archive/2011/07/19/dither.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/cty41/comments/commentRss/151420.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cty41/services/trackbacks/151420.html</trackback:ping><description><![CDATA[<div><font style="background-color: #cce8cf"><span style="background-color: #ffffff">&nbsp; 最早对听说Dithering这个词还是看到clayman大神推荐的dx9 pipeline图，当时也没深究，今天在openGPU上有大牛对此问题给出来</span><a href="http://www.opengpu.org/bbs/forum.php?mod=viewthread&amp;tid=5116"><span style="background-color: #ffffff">答案</span></a><span style="background-color: #ffffff">， 当时也没看懂，回来看了下wiki上关于dithering的介绍，瞬间明白了。再次借wiki的图做个小白普及吧～～（不算侵权吧。。）</span><br /><img border="0" alt="" src="http://upload.wikimedia.org/wikipedia/commons/6/6d/Dithering_example_red_blue.png" /><br /><span style="background-color: #ffffff">这就是一个很直接的dithering的例子，图中实际只用了红蓝两种颜色，但是随着像素的变小，图片逐渐呈现出紫色。</span><br /><span style="background-color: #ffffff">&nbsp; 看到这边大家应该对dither这个操作有了个理解，它就是用少量的颜色来表现更广泛的颜色的。这么做的原因，有很多方面的用途，譬如在某一些使用lcd屏幕的嵌入式设备上能显示的色域很比较小的，在这样的设备上显示图片，如果单纯的将超过色域的颜色四舍五入的话，就会产生很明显的颜色带。（如下图）这样就需要利用dithering操作来进行修正。</span><br /><img border="0" alt="" src="http://upload.wikimedia.org/wikipedia/commons/thumb/e/e3/Dithering_example_undithered.png/225px-Dithering_example_undithered.png" /><img border="0" alt="" src="http://upload.wikimedia.org/wikipedia/commons/thumb/b/be/Dithering_example_undithered_web_palette.png/225px-Dithering_example_undithered_web_palette.png" width="225" height="180" /><img border="0" alt="" src="http://upload.wikimedia.org/wikipedia/commons/thumb/6/6d/Dithering_example_dithered_web_palette.png/225px-Dithering_example_dithered_web_palette.png" /><br /><span style="background-color: #ffffff">原图&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;未经过dithering&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;经过dithering后，颜色过渡自然很多</span><br /><br /><span style="background-color: #ffffff">&nbsp; 具体的算法wiki上大概的介绍，有兴趣的同学可以看看：</span><a href="http://en.wikipedia.org/wiki/Dither"><span style="background-color: #ffffff">http://en.wikipedia.org/wiki/Dither</span></a><br /><br /><br /><br /><br /></font></div> <img src ="http://www.cppblog.com/cty41/aggbug/151420.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cty41/" target="_blank">月下圆舞曲</a> 2011-07-19 22:26 <a href="http://www.cppblog.com/cty41/archive/2011/07/19/dither.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>光照术语备忘</title><link>http://www.cppblog.com/cty41/archive/2011/06/04/148039.html</link><dc:creator>月下圆舞曲</dc:creator><author>月下圆舞曲</author><pubDate>Sat, 04 Jun 2011 03:18:00 GMT</pubDate><guid>http://www.cppblog.com/cty41/archive/2011/06/04/148039.html</guid><wfw:comment>http://www.cppblog.com/cty41/comments/148039.html</wfw:comment><comments>http://www.cppblog.com/cty41/archive/2011/06/04/148039.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cty41/comments/commentRss/148039.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cty41/services/trackbacks/148039.html</trackback:ping><description><![CDATA[&nbsp;&nbsp; 在看《Advanced Lighting And Materials With Shaders》里看到一段关于radiance几个关键字很方便的记法：<br /><div>  <p><em><span style="font-size:14.0pt">Irradiance</span></em><span style="font-size:14.0pt"> is the total amount of energy received per unit area of surface.</span></p>  <p style="margin-left: 7pt; text-indent: -7pt;"><em><span style="font-size: 14.0pt">Illuminance </span></em><span style="font-size: 14pt;">measures the amount of visible light energy in photometric terms, not included heat, and radiation.</span></p>  <p>&nbsp;&nbsp; 前两者是关于表面接收的光的属性，后两者则是表面反射出的光的属性。</p>  <p><em><span style="font-size:14.0pt">Radiance</span></em><span style="font-size: 14.0pt"> is the measure of energy that is reflected by the surface. </span></p>  <p><em><span style="font-size:14.0pt">Luminance</span></em><span style="font-size: 14.0pt"> is the measure of photometrically weighted light energy that leaves the surface, and is therefore the more interesting term in a graphics context.</span></p>  </div><img src ="http://www.cppblog.com/cty41/aggbug/148039.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cty41/" target="_blank">月下圆舞曲</a> 2011-06-04 11:18 <a href="http://www.cppblog.com/cty41/archive/2011/06/04/148039.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>从vertex shader到pixel shader</title><link>http://www.cppblog.com/cty41/archive/2011/05/08/145972.html</link><dc:creator>月下圆舞曲</dc:creator><author>月下圆舞曲</author><pubDate>Sun, 08 May 2011 11:46:00 GMT</pubDate><guid>http://www.cppblog.com/cty41/archive/2011/05/08/145972.html</guid><wfw:comment>http://www.cppblog.com/cty41/comments/145972.html</wfw:comment><comments>http://www.cppblog.com/cty41/archive/2011/05/08/145972.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cty41/comments/commentRss/145972.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cty41/services/trackbacks/145972.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;来自今天openGpu上的一个<a href="http://www.opengpu.org/bbs/forum.php?mod=viewthread&amp;tid=4503&amp;pid=34407&amp;page=1&amp;extra=#pid34407">帖子</a>，以前自己对这块也是一知半解，导致了曾经在一次面试中在这个问题上卡壳（反正最后是没过。。哭。。。），这次看到正好最近看shaderX1里有介绍，所以就一鼓作气理解下吧！！<br><img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/cty41/v2p.jpg" width=553 height=521><br>这是shaderX1里从vertex到pixelshader之前的pipeline<br><br>我具体解释下从vertex shader到pixel shader中间的部分：<br>face culling:根据triangle的两边向量叉乘得到的面法线方向来确定是顺时针还是逆时针，从而达到裁剪。<br>user clip planes：除了使用投影矩阵定义出的6个clipplane之外我们也可以额外自己定义对应的clipplane来剪裁。<br>frustum culling：视锥裁剪，不说了<br>homogeneous divide：这就是你说的除以什么w的地方，变换后的定点的xyz均会除以起w，以opengl的列为主（没记错的话。。反正就是matrix X vector的那个。。）透视投影矩阵的最后一行为0 0 1 0， 所以w值就是未经变换前的z值，所以根据透视投影的特性使得:-1=&lt;x/w&lt;=1, -1=&lt;y/w&lt;=1, -1=&lt;z/w&lt;=1。但是为何我们要这么做捏。。答案是我没看懂。。。我觉得纯粹是为了下一步。。下面说<br>viewport mapping：上一步后x,y,z现在已经是-1到1之间，上一步的齐次坐标系又被称为normalized device coordinates（NDC），那么我们要将这些顶点映射到屏幕空间就很简单了，x = NDC(x) * width + width / 2, y = NDC(y) * height + height/2。<br><br>呼。。如果有错的话还请指正哈！～～
<img src ="http://www.cppblog.com/cty41/aggbug/145972.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cty41/" target="_blank">月下圆舞曲</a> 2011-05-08 19:46 <a href="http://www.cppblog.com/cty41/archive/2011/05/08/145972.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>推荐一个查找游戏开发相关技术的网站</title><link>http://www.cppblog.com/cty41/archive/2011/05/08/145960.html</link><dc:creator>月下圆舞曲</dc:creator><author>月下圆舞曲</author><pubDate>Sun, 08 May 2011 09:46:00 GMT</pubDate><guid>http://www.cppblog.com/cty41/archive/2011/05/08/145960.html</guid><wfw:comment>http://www.cppblog.com/cty41/comments/145960.html</wfw:comment><comments>http://www.cppblog.com/cty41/archive/2011/05/08/145960.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cty41/comments/commentRss/145960.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cty41/services/trackbacks/145960.html</trackback:ping><description><![CDATA[今天google的时候搜到的，<a href="http://www.introgamedev.com/index.html" target=_blank><u><font color=#0066cc>http://www.introgamedev.com/index.html</font></u></a><br>&nbsp; &nbsp;里面并没有具体的内容，只是相关技术的索引，基本都是来自于出版的书籍，譬如game programming gems, gpu gems, shaderX等等，由于这类书籍本来就是杂烩形式，所以要看特定某一块的内容的话，这个网站就很方便了，反正大部分这些书天朝都能找到pdf～～
<img src ="http://www.cppblog.com/cty41/aggbug/145960.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cty41/" target="_blank">月下圆舞曲</a> 2011-05-08 17:46 <a href="http://www.cppblog.com/cty41/archive/2011/05/08/145960.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>沿着ogre来实现material system（一）</title><link>http://www.cppblog.com/cty41/archive/2011/04/18/144448.html</link><dc:creator>月下圆舞曲</dc:creator><author>月下圆舞曲</author><pubDate>Mon, 18 Apr 2011 15:32:00 GMT</pubDate><guid>http://www.cppblog.com/cty41/archive/2011/04/18/144448.html</guid><wfw:comment>http://www.cppblog.com/cty41/comments/144448.html</wfw:comment><comments>http://www.cppblog.com/cty41/archive/2011/04/18/144448.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/cty41/comments/commentRss/144448.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cty41/services/trackbacks/144448.html</trackback:ping><description><![CDATA[&nbsp;
<p align=left><span>自从以前看了<span>clayman</span>的<span><a href="http://www.cnblogs.com/clayman/archive/2010/05/06/1728502.html"><span><span>博客</span></span></a></span>后，就很想把自己代码里<span>dx</span>的<span>effect</span>框架替代掉。如今实习结束正好有短暂的自由时间，所以就<span>ogre</span>的<span>material</span>开刀吧。<span><br><br></span>&nbsp; 山寨代码也是有学问的，如果你想搞明白这些代码的含义的话，最后之前就对这些已经有了一定的使用经历和认知，第一步先得自己想一下<span>material</span>系统的组成：<span><br>material</span>应该包含的：<span>1Material-&gt;n Techinque-&gt;(n Pass + extra params)-&gt;(n TextureUnit + m or 0 shaderUnit + n RenderStates</span>（部分）<span>),Pass</span>里的<span>TextureUnit</span>又包含了这一组<span>texture</span>的相关信息和设置，<span>TexcoordSet, AddressMode, FilterSetting</span>等等，<span> ShaderUnit</span>则是对应于<span>vs</span>，<span>fs</span>以及新的<span>gs</span>，普通点也就最多两组。<span>shaderUnit</span>包含了具体的<span>shader</span>和其<span>shaderParams</span>，为何要把<span>shader</span>和<span>shaderParams</span>分开呢，不说设计优雅的考虑，简单的说就是方便，很多时候<span>params</span>可能会需要共享，譬如<span>shaderA</span>里用到<span>mvpMat</span>，和<span>eyePos</span>，<span> diffuse,specular,</span>可能<span>shaderB</span>也只用到这些，但是两个<span>shader</span>的内部计算并不相同。到此我们只分析了作为程序中的材质的结构，还需要考虑如果编写一个类似<span>fx</span>格式的<span>material script</span>，这也是另外一个大头，简单的说就是要做个脚本解释，然后给<span>shader</span>参数加上语义，减少大部分需要手动更新的<span>shaderParams</span>。鉴于我如今还没把这块扒完，等下次再写这块吧。<span><br><br><br></span>&nbsp;&nbsp; 当你至少能闭着眼睛想透这些了，那就可以开始看<span>ogre</span>的<span>material system</span>了，<span style="COLOR: #666699">先说句题外话，</span>我读<span>ogre</span>的代码其实读挺久了。一直觉得很难读，开始觉得是自己水平不够，但后来实习才发现很多人都有这想法，甚至<span>wolfgang</span>对此也有批评，而自己曾经写了个<span><a href="http://code.google.com/p/oolongengine/"><span>olong</span></a></span>引擎，接触过<span>ipad</span>编程的人应该对这些代码都比较熟悉～<span>ogre</span>里用了大量的设计模式，使得整个渲染流程从不同类里跳来跳去（<span>SceneMgr</span>这块看着最累了。。其实有很多地方看着都很累。。）个人觉得应该把<span>render</span>从<span>SceneMgr</span>里抽离出来做个<span>RenderMgr</span>，（记住这里的<span>RenderMgr</span>的概念和<span>ogre</span>的<span>RenderSystem</span>，后者是提供底层渲染<span>API</span>的接口，而前者是管理<span>renderData</span>并最终递交给<span>RenderSystem</span>，以前也见有别人博客讲过这个问题）让<span>SceneMgr</span>专门管理<span>Scene。。<br>&nbsp; </span>打住打住。。我是来写<span>material</span>的。。咳咳。。相当于渲染来说，<span>ogre</span>的<span>material system</span>还是相当易读的，也是因为这些模块相互关系几乎都是单向的，我们开始编写的时候可以先不考虑<span>Technique，</span>就是直接<span>1 Material-&gt;n Pass-&gt;...</span>当然甚至你都可以把<span>multi pass</span>去掉<span>,</span>就等同于<span>1</span>个<span>pass</span>，当然由于<span>pass</span>都代码实际也没多少，我们还是加上好了。<br><span><br></span>原始渲染的伪代码就是：</span><span></p>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">&nbsp;1</span><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;each&nbsp;pass<br></span><span style="COLOR: #008080">&nbsp;2</span><span style="COLOR: #000000"><img id=Codehighlighter1_14_293_Open_Image onclick="this.style.display='none'; Codehighlighter1_14_293_Open_Text.style.display='none'; Codehighlighter1_14_293_Closed_Image.style.display='inline'; Codehighlighter1_14_293_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_14_293_Closed_Image onclick="this.style.display='none'; Codehighlighter1_14_293_Closed_Text.style.display='none'; Codehighlighter1_14_293_Open_Image.style.display='inline'; Codehighlighter1_14_293_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif"></span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_14_293_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_14_293_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;3</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;setRenderStates(like&nbsp;alphe&nbsp;belnd,&nbsp;depth..)<br></span><span style="COLOR: #008080">&nbsp;4</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;each&nbsp;texture&nbsp;unit<br></span><span style="COLOR: #008080">&nbsp;5</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;setTexSettings();<br></span><span style="COLOR: #008080">&nbsp;6</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(hasVertexShader())<br></span><span style="COLOR: #008080">&nbsp;7</span><span style="COLOR: #000000"><img id=Codehighlighter1_133_186_Open_Image onclick="this.style.display='none'; Codehighlighter1_133_186_Open_Text.style.display='none'; Codehighlighter1_133_186_Closed_Image.style.display='inline'; Codehighlighter1_133_186_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_133_186_Closed_Image onclick="this.style.display='none'; Codehighlighter1_133_186_Closed_Text.style.display='none'; Codehighlighter1_133_186_Open_Image.style.display='inline'; Codehighlighter1_133_186_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;</span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_133_186_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_133_186_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;8</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;bindVertexShader();<br></span><span style="COLOR: #008080">&nbsp;9</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;setShaderParams(vs);<br></span><span style="COLOR: #008080">10</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif">&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">11</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(hasFragmentShader())<br></span><span style="COLOR: #008080">12</span><span style="COLOR: #000000"><img id=Codehighlighter1_216_271_Open_Image onclick="this.style.display='none'; Codehighlighter1_216_271_Open_Text.style.display='none'; Codehighlighter1_216_271_Closed_Image.style.display='inline'; Codehighlighter1_216_271_Closed_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="DISPLAY: none" id=Codehighlighter1_216_271_Closed_Image onclick="this.style.display='none'; Codehighlighter1_216_271_Closed_Text.style.display='none'; Codehighlighter1_216_271_Open_Image.style.display='inline'; Codehighlighter1_216_271_Open_Text.style.display='inline';" align=top src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;</span><span style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BACKGROUND-COLOR: #ffffff; DISPLAY: none; BORDER-TOP: #808080 1px solid; BORDER-RIGHT: #808080 1px solid" id=Codehighlighter1_216_271_Closed_Text><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_216_271_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">13</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;bindFragmentShader();<br></span><span style="COLOR: #008080">14</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;setShaderParams(fs);<br></span><span style="COLOR: #008080">15</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif">&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">16</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif">&nbsp;&nbsp;drawPrimitives();<br></span><span style="COLOR: #008080">17</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif">}</span></span></div>
<p align=left></span>加入的RenderQueue也是一样，只是pass和对应的renderData我们是从renderqueue里取。<br><br>看到这里你会觉得，嘿，很简单嘛，但如果你看了ogre里关于shader参数的细节，你就知道这块还是比较复杂的。我们刚只说了一个运行过程，而建立params到constant registers的关系，以及如何编写autoConstants的代码都是魔鬼的细节～～对于dx，我们可以简单点，直接使用ID3DXConstantTable，它提供了set接口。但ogre则是直接从ID3DXConstantTable中解析参数。<br><br>&nbsp;&nbsp; 设计这块的时候，脑子里先要对我整个过程有个清晰的认识：<span style="COLOR: #993300">一方面是从shader里（我们这里假设是hlsl，asm先不考虑）,另一方面则是解析参数读入材质脚本里定义的参数（</span><a style="COLOR: #993300" name=OLE_LINK13>named，autoNamed，或者index</a><span style="COLOR: #993300">），最后将两者对应上。 <br></span><br>0.类型解释<br>看过OgreGpuProgramParams.cpp/h的人都知道：GpuConstantDefinition，GpuNamedConstants，GpuLogicalIndexUse，GpuSharedParameters，GpuSharedParametersUsage，一堆的struct和class。。其实按照我们上面这个思路逐步加断点分析，代码也没那么繁琐。暂时不看GpuSharedParameters这块，大概看下GpuConstantDefinition,重点变成员是physicalIndex和<a name=OLE_LINK1>logicalIndex</a>，前者的解释是buffer中的起始地址，每个GpuProgramParameters里都包含了<a name=OLE_LINK3>vector&lt;int&gt;和vector&lt;float&gt;</a>两个buffer,他们存储了shader变量的值，而physicalIndex就是对应vector的索引。而logicalIndex则是我们后面将hlsl编译成asm后这些变量所绑定的寄存器id，而由于constant reg的size都是4，即<span style="COLOR: #993300">一个register为4个float的大小</span>，所以这些logicalIndex则不一定连续，譬如第一个uniform为float1那么第二个uniform的logicalIndex虽然是1，但实际跨过了4个float，而实际内存中我们的float（int同） buffer里，两个变量之间的则就空了3个float，这就是physicalIndex的作用，所以我们还需要建立一个从logicalIndex到physicalIndex的map，也就是两个<a name=OLE_LINK5>GpuLogicalBuffersStructPtr</a>对象（这两个对象和GpuNamedConstantsPtr在GpuProgram类和<a name=OLE_LINK11>GpuProgramParameters</a>是共享的，都是sharedPtr）</p>
<p align=left><span style="COLOR: #993300">1.解析shader的变量</span><span><br>&nbsp;&nbsp; </span><span>我们从再具体的读取代码来看，假设我们已经从脚本里读入了对应的<span>shader</span>，经过一堆调用后（略。。）在<span>D3D9HLSLProgram</span>的函数<span>buildConstantDefinitions-&gt;</span><span>processParamElement</span>将每个参数的<span>registerIndex,physicalIndex, type(</span>原子类型，即<span>float, int,),size</span>都写入<span>GpuLogicalBuffersStructPtr</span>和<a name=OLE_LINK7><span><span>GpuNamedConstantsPtr</span></span></a>对象里（后者当然是只有<span>highLevelShader</span>里才有），并会为这个定义同样在插入带下标的一对键值，以便于如果我们传入的参数是数组（譬如<span>float4x4[5]</span>），则在程序里可以通过数组下标访问对应的数组变量。再<span>constantDef</span>建立好之后，将<a name=OLE_LINK9><span><span><span>GpuNamedConstantsPtr</span></span></span></a>传入到<span>GpuProgramParameters</span>对象里，然后向其中的两个<span>vector</span>添加上述对象大小的空间，在将两个<span>LogicalToPhysicalMap</span>的指针也传到<span>shaderParams</span>里，这样整个<a name=OLE_LINK18><span><span>GpuProgramParameters</span></span></a>几乎就完工了。<br><br><span style="COLOR: #993300">2.解析材质里定义的params，并将其与前者对应上</span><br>&nbsp; 如今就差再把<span>material script</span>定义的<span>param解析出来并</span>与之前<span>shader</span>里的变量进行对应。材质脚本读出的每个变量的信息包含了<span>param</span>类型（<span>named</span>，<span>auto_named</span>，<span>index</span>，<span>auto_index</span>），<span>name,type(float,int..),autoType(auto</span>的才有<span>)</span>，初始值等。我们根据其<span>autoType</span>在全局变量<span>AutoConstantDictionary</span>中查找是否有定义，然后调用<span>set[Named]AutoConstant</span>，在这里我们在会在我们之前从<span>hlsl</span>里解析出的<a name=OLE_LINK16><span><span>GpuNamedConstantsPtr</span></span></a>里查找是否有该名字的变量（毕竟<span>shader</span>里的变量才是最终有用的，甚至由于编译器优化的关系，由于<span>shader</span>编写者可能定义了一个变量而未实际使用，在编译<span>shader</span>后，这个变量实际是会被省略的，这样在<span>GpuNamedConstantsPtr</span>也就找不到了）然后调用<span>_setRawAutoConstant</span>将这个变量加入到这个<span>GpuProgramParameters</span>对象所持有的<span>autoConstant</span>中。</span></p>
<p align=left><span>（ps：关于<span>_getFloatConstantLogicalIndexUse</span>的用途我没看懂，为何需要去在<span>mFloatLogicalToPhysical</span>里去查找这个<span>logicalIndex</span>是否存在呢，我觉得如果走到这一步肯定<span>shader</span>里肯定就是定义了的，因为这个<span>logicalIndex</span>是由<span>mNamedConstants</span>里取出，我觉得是没必要的。。）</span></p>
<p><span style="COLOR: #993300">3，更新<span>autoParamsbuffer</span>并最终在<span>DP</span>前进行更新</span></p>
<p><span>把上面的过程看懂了，下面就很好理解了。<span>GpuProgramParameters::_updateAutoParams</span>里就是对<a name=OLE_LINK20><span><span>GpuProgramParameters</span></span></a>对象所持有的<span>autoConstant</span>值进行更新，当然这是我们只是对<span>GpuProgramParameters</span>持有的<span>buffer</span>里的值做更新，最终在文章开头的伪代码中的</span><span>setShaderParams</span><span>（<span>ogre</span>里叫<span>bindGpuProgramParamters</span>）</span><span>而这里的更新就轻而易举了，我们遍历<span>logicalToPhysicalMap</span>对每个<span>param</span>取出对应的<span>logicalIndex</span>，<span>dataPointer</span>，<span>vector4ofCount</span>，然后调用<span>SetVertex/PixelShaderConstantF/I</span>即可。</span></p>
<p><span><br><br>呼。。终于把这块写完了。。上述只是一个实现自己的<span>material</span>的基本思路。关于优化的话，我开头推荐的<span>clayman</span>的文章里有很多叙述。关于怎么写<span>ogre script translator</span>，等下一篇再说。。</span></p>
<img src ="http://www.cppblog.com/cty41/aggbug/144448.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cty41/" target="_blank">月下圆舞曲</a> 2011-04-18 23:32 <a href="http://www.cppblog.com/cty41/archive/2011/04/18/144448.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ogre1.6后的的脚本大概分析</title><link>http://www.cppblog.com/cty41/archive/2011/04/12/144073.html</link><dc:creator>月下圆舞曲</dc:creator><author>月下圆舞曲</author><pubDate>Tue, 12 Apr 2011 14:31:00 GMT</pubDate><guid>http://www.cppblog.com/cty41/archive/2011/04/12/144073.html</guid><wfw:comment>http://www.cppblog.com/cty41/comments/144073.html</wfw:comment><comments>http://www.cppblog.com/cty41/archive/2011/04/12/144073.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cty41/comments/commentRss/144073.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cty41/services/trackbacks/144073.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.script先由ResourceGroupMgr在prepare函数里根据不同的后缀名选择不同的ScriptLoader的派生类来加载，这里我们就以ScriptCompilerMgr为例。（今天开始细看材质加载部分的代码才发现ogre的材质解析原来还有两套，以前的一套是MaterialSerializer，1.6之后默认使用的是ScriptCompilerMgr.）<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.调用ScriptCompilerMgr内部ScriptCompiler对象的compile函数，这里其实也没有进行实际分析，只是创建并调用了分析和编译的对象：ScriptLexer，ScriptParser，ScriptCompiler。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3.先由ScriptLexer对文本进行分析，创建一个包含了所有token信息节点的列表，注意这一步仅仅是将所有材质里的词汇单元提取出来而已，还没有生成CST，乃至AST（当然这里的CST和AST都是简化的），这里的实现比较易读在ScriptLexer::tokenize中对文本的每个字符进行遍历，查找token（在ogre里也就是譬如{ } // \&nbsp; : newline等，当然普通的字符肯定也算的），最后生成一个tokenlist。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4.&nbsp;接下来将tokenList传入ScriptParser的parse函数中，这些token节点将被根据标记符的关系，而生成一个简单有父子关系的分析树，也就是CST了。到这里你就发现之前动辄就100个的nodelist已经变成了ConcreteNodeList,当然这里的node每个都是一个树了.以最外面的{}为根.当然没有{}的部分就变成一个节点(知道找到{或者别的标记符)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5.接着，在ScriptCompiler里将之前生成的CST转化为AST（这里的具体转化的代码我还没细看。。）<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6.呼，终于要到最后了，根据每个AST的类型调用不同的ScriptTranslator，例如材质的话就取得MaterialTranslator来解释成最终的material，然后对其中的每个AST子节点再调用对应的ScriptTranslator，（例如pass就调用PassTranslator等）把所有的值都设置好，这样所有解释的工作终于完成了。<br><br>呼，的确是个很漫长的过程。。个人感觉如果把scriptLexer换成已有的什么文本解释库读取的速度会不会得到很多提升呢？譬如如今比较流行的rapidXml什么的，毕竟个人觉得这些专门优化文本库的性能还是很高的（虽然我得说尖括号啥的的确不是那么易读～）。当然我觉得ogre这么写的架势很可能有想将原来普通的脚本配置文件提升成ogre专用的脚本语言的趋势？（最早只是写了一堆Serializer而已）
<img src ="http://www.cppblog.com/cty41/aggbug/144073.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cty41/" target="_blank">月下圆舞曲</a> 2011-04-12 22:31 <a href="http://www.cppblog.com/cty41/archive/2011/04/12/144073.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>图形方面的几何笔记</title><link>http://www.cppblog.com/cty41/archive/2011/04/03/143060.html</link><dc:creator>月下圆舞曲</dc:creator><author>月下圆舞曲</author><pubDate>Sun, 03 Apr 2011 12:26:00 GMT</pubDate><guid>http://www.cppblog.com/cty41/archive/2011/04/03/143060.html</guid><wfw:comment>http://www.cppblog.com/cty41/comments/143060.html</wfw:comment><comments>http://www.cppblog.com/cty41/archive/2011/04/03/143060.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cty41/comments/commentRss/143060.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cty41/services/trackbacks/143060.html</trackback:ping><description><![CDATA[&nbsp;&nbsp; 这两天在准备面试，然后复习了下数学的东西，好多东西以前基础不好，就是走马观花的看一下，过了一段时间立马就忘记了，索性记下来的好。这里的3D空间都是右手坐标系，向量为列为主<br>一,法线变换乘WorldView矩阵的逆的转置<br>肯定不是直接乘worldView矩阵了，推导其实很简单，（像我这样脑子不行的只能看完了感慨了）设原mesh上一个顶点为v,其法线为n，WorldViewMatrix为Mwv,那么在object space里，满足v dot n == 0,以此我们可以换个形式表示，也就是(v)<sup>T</sup> * n == 0, (1x4和4x1的矩阵相乘实际就是点乘了)，那么在变换之后，设变化后的顶点为v'，变换后的法线为n'，那么同样也需要满足这个条件，<br>(v')<sup>T</sup>&nbsp;* n' == 0, 而v' = Mwv * v, <br>代入=&gt; (Mwv * v)<sup>T</sup> * n' == 0 =&gt;&nbsp; v<sup>T</sup> * Mwv<sup>T</sup> * n'&nbsp; == 0,&nbsp; 而n'等于Mn * n(我们要求的),<br>=&gt;v<sup>T</sup> * （Mwv<sup>T</sup> * Mn ）* n == 0 ，而(v)<sup>T</sup> * n == 0， 那么中间的（Mwv<sup>T</sup> * Mn ）== I =&gt; Mn = (Mwv<sup>T</sup>)<sup>-1</sup>,而因为方阵（当然得有逆的情况。。）的逆的转置等于转置的逆，所以就能证明出来咯～。我刚想了下，应该行为主的结果也是一样的，这里错了话，望纠正。<br><br><br>二，判断点是否在三角形内准备笔试的时候正好看到这道题，以前在ogre代码里也看到过，但原理没深究过，google中文搜了下，貌似没什么讲的很好的，英文一搜就搜到了很多非常详细的。这里就做个整理吧，省得和我一样的搜两次了～～。设三角形ABC，点为P，（向量我就写成行形式了～）<br>1，面积法，基本上是最直接低效的，点P如果在三角形内，则分割的三个三角形面积和等于ABC面积，这个不说了。<br>2，网上最常见的，所谓的2D叉乘法，实际上叉乘是不存在于2D空间的，只存在于3D和7D（！。。这个没细看。反正wiki还是哪里看到的），但2D空间里我们可以用一点小技巧，就是假设一个垂直于xy平面的z轴，那么2D平面的z值则一直为0，设 向量B-A为V1（x1,y1,z1）,向量P-A为V2（x2,y2,z2）,根据3D叉乘公式，(x1,y1,z1) &nbsp;X (x2,y2,z2) = (y1z2 - y2z1, x1z2-x2z1, x1y2-x2y1),由于z为0，那么x,y则为0,所以实际2d叉乘值就是z值，其实我们得到的还是一个向量，它垂直于我们2d空间的xy平面，不管是顺时针还是逆时针，我们只要按一个方向同样再对另外两边做同样的叉乘，只要得到的这三个值符号一致，这就说明点P在三角形三边的同一侧，也就是在三角形内了，其实再想想，只需要确定在两条边的同侧，那么就是在三角形内了。<br>3，重心法，从二维空间上看，我们可以把p当乘以以三角形一个顶点的两条边向量乘以两个标量权重的和，设这两个权重为u，v，只要u,v大于0，且和小于1，那么P就在三角形内，所以我们下来就是求出u,v了：<br>=&gt;P = A&nbsp;+ &nbsp;u * (C - A)+ v * (B - A), u,v这也就是三角形的重心坐标系坐标,这就是个二元一次方程，这里我们化简下，设P-A为v2， C - A为v0，B - A为v1，<br>&nbsp;=&gt;v2 = u * v0 + v*v1, 乘v0,v1我们就能得到两个方程<br>=&gt;v2&nbsp;* v0&nbsp;= (u * v0 + v*v1)* v0, (1)<br>&nbsp;&nbsp;&nbsp; v2 * v1 = (u * v0 + v*v1)* v1, (2)<br>略化简。。<br>=&gt;u = ((v1 * v1)(v2 * v0) - (v1 * v0)(v2 * v1))/(((v0 * v0)(v1 * v1) - (v0 * v1)(v1 * v0))<br>v&nbsp;= ((v0 * v0)(v2 * v1) - (v0 * v1)(v2 * v0))/(((v0 * v0)(v1 * v1) - (v0 * v1)(v1 * v0)) 
<img src ="http://www.cppblog.com/cty41/aggbug/143060.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cty41/" target="_blank">月下圆舞曲</a> 2011-04-03 20:26 <a href="http://www.cppblog.com/cty41/archive/2011/04/03/143060.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>显存知识备忘</title><link>http://www.cppblog.com/cty41/archive/2011/03/06/141202.html</link><dc:creator>月下圆舞曲</dc:creator><author>月下圆舞曲</author><pubDate>Sun, 06 Mar 2011 02:25:00 GMT</pubDate><guid>http://www.cppblog.com/cty41/archive/2011/03/06/141202.html</guid><wfw:comment>http://www.cppblog.com/cty41/comments/141202.html</wfw:comment><comments>http://www.cppblog.com/cty41/archive/2011/03/06/141202.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cty41/comments/commentRss/141202.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cty41/services/trackbacks/141202.html</trackback:ping><description><![CDATA[<p>&nbsp; 最近重写自己的图形代码，想想算是第三遍了，写道texture的pool那边，又见到了D3DPOOL_DEFAULT ，Managed, SYSMEM,对这个的理解也算第三次了，以前也大致了解过，区别主要就是在系统内存，agp内存，还有显存上，这次看这块的时候突然又有点茫茫然于是就谷歌搜之，于是就在ccanan的博客上找到了更详细的<a href="http://blog.csdn.net/ccanan/archive/2011/02/24/6204598.aspx">http://blog.csdn.net/ccanan/archive/2011/02/24/6204598.aspx</a><br>&nbsp; <br>&nbsp; 话说以前我的确没考虑过cache问题，还一直天真的觉得agp使用了内存重映射表后速度应该是和video mem一样的，如今一想，这种gapt需要软件层（或者是硬件层，不清楚）做个转换的，不考虑cache也肯定是要比原生的video mem慢一拍，只能说当时自己看这些知识的时候还不是很透彻～<br><br><br>话说：从博客查知识好归好。。。但我经常为了看一个内容然后不小心看了别的技术内容然后又看了别的。。。。这就是greedy么。。。&nbsp;</p>
<img src ="http://www.cppblog.com/cty41/aggbug/141202.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cty41/" target="_blank">月下圆舞曲</a> 2011-03-06 10:25 <a href="http://www.cppblog.com/cty41/archive/2011/03/06/141202.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>实现了简陋的Freetype2在DirectX下显示字体</title><link>http://www.cppblog.com/cty41/archive/2010/08/09/122825.html</link><dc:creator>月下圆舞曲</dc:creator><author>月下圆舞曲</author><pubDate>Mon, 09 Aug 2010 11:02:00 GMT</pubDate><guid>http://www.cppblog.com/cty41/archive/2010/08/09/122825.html</guid><wfw:comment>http://www.cppblog.com/cty41/comments/122825.html</wfw:comment><comments>http://www.cppblog.com/cty41/archive/2010/08/09/122825.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/cty41/comments/commentRss/122825.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cty41/services/trackbacks/122825.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp; 上个月开始和同学一块在做类似CS的射击游戏demo，要自己实现游戏里的简单2DOverlay和文本显示（不用具体GUI了，菜单什么的再用CEGUI），由于我这人做事慢，所以就去实现字体这种小模块～0～（学末总是很难静下心编程唉～～），本来以为网上这类资源挺多的，搜到的无非是NeHe的openGL+ft2，还有一位仁兄模仿Ogre写的一个代码（里面有些问题），多不是很系统，自己认真花了...&nbsp;&nbsp;<a href='http://www.cppblog.com/cty41/archive/2010/08/09/122825.html'>阅读全文</a><img src ="http://www.cppblog.com/cty41/aggbug/122825.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cty41/" target="_blank">月下圆舞曲</a> 2010-08-09 19:02 <a href="http://www.cppblog.com/cty41/archive/2010/08/09/122825.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>矩阵乘向量的顺序会产生悲剧的-.-!!</title><link>http://www.cppblog.com/cty41/archive/2010/05/26/116413.html</link><dc:creator>月下圆舞曲</dc:creator><author>月下圆舞曲</author><pubDate>Wed, 26 May 2010 12:19:00 GMT</pubDate><guid>http://www.cppblog.com/cty41/archive/2010/05/26/116413.html</guid><wfw:comment>http://www.cppblog.com/cty41/comments/116413.html</wfw:comment><comments>http://www.cppblog.com/cty41/archive/2010/05/26/116413.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/cty41/comments/commentRss/116413.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cty41/services/trackbacks/116413.html</trackback:ping><description><![CDATA[&nbsp; 哈哈，花了两天把POM完成，虽然我的爱机的配置很好，不过我还是按照了SM 2.0的规范写的，虽然DirecxtX sdk那个是用SM 3.0写的，效果帅多了....不过2.0的POM写得花三个Pass，比较麻烦，所以我就实现它了～～<br>&nbsp; 先传图把<br>&nbsp;<img alt=""  src="http://i965.photobucket.com/albums/ae134/cty41/right1.jpg" height="514" width="652"><br>写的过程中遇到写旧的错误，以前以为只是个小问题的，现在觉得该重视了，关于mul()函数的用法，都知道在线性代数里，矩阵和向量相乘必须首先满足矩阵的行数等于向量的列数，其次乘运算时，向量在前矩阵在后。不过在看很多shader代码的时候我发现，许多人都不注意这问题，而且在大部分情况下颠倒矩阵和向量的顺序也是没问题的。但我写的时候就悲剧了。。。<br>譬如： Out.Position = mul( g_mWorldViewProjection, inPosition );<br>于是乎，显示结果就很诡异:<br><img alt=""  src="http://i965.photobucket.com/albums/ae134/cty41/error2.jpg"><br>&nbsp;&nbsp; 我没深入考虑这现象为何出现，不过觉得肯定与乘法顺序有关，所以以后还是乖乖地按规则来了。。贴在此供路人参考了～～<br><br><br>&nbsp; 原理过两天补上，这两天想实现的东西好多，大学的破课更多。。faint。。。<br><br><br><img src ="http://www.cppblog.com/cty41/aggbug/116413.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cty41/" target="_blank">月下圆舞曲</a> 2010-05-26 20:19 <a href="http://www.cppblog.com/cty41/archive/2010/05/26/116413.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>没事拿DXUT实现了Parallax map，发帖纪念下～～</title><link>http://www.cppblog.com/cty41/archive/2010/05/22/116130.html</link><dc:creator>月下圆舞曲</dc:creator><author>月下圆舞曲</author><pubDate>Sat, 22 May 2010 13:22:00 GMT</pubDate><guid>http://www.cppblog.com/cty41/archive/2010/05/22/116130.html</guid><wfw:comment>http://www.cppblog.com/cty41/comments/116130.html</wfw:comment><comments>http://www.cppblog.com/cty41/archive/2010/05/22/116130.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cty41/comments/commentRss/116130.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cty41/services/trackbacks/116130.html</trackback:ping><description><![CDATA[&nbsp; 嘿嘿，这两天终于从写纯程序换到写图形了，重回DirectX的感觉真亲切，这两天拿DXUT把PerPixel，BumpMap, ParallaxMap都实现了，发帖纪念下：<br><img alt=""  src="http://www.cppblog.com/images/cppblog_com/cty41/ParallaxMap.jpg" height="514" width="652"><br><br><img src ="http://www.cppblog.com/cty41/aggbug/116130.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cty41/" target="_blank">月下圆舞曲</a> 2010-05-22 21:22 <a href="http://www.cppblog.com/cty41/archive/2010/05/22/116130.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>四月编写场景编辑器的总结</title><link>http://www.cppblog.com/cty41/archive/2010/05/06/114524.html</link><dc:creator>月下圆舞曲</dc:creator><author>月下圆舞曲</author><pubDate>Thu, 06 May 2010 00:38:00 GMT</pubDate><guid>http://www.cppblog.com/cty41/archive/2010/05/06/114524.html</guid><wfw:comment>http://www.cppblog.com/cty41/comments/114524.html</wfw:comment><comments>http://www.cppblog.com/cty41/archive/2010/05/06/114524.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/cty41/comments/commentRss/114524.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cty41/services/trackbacks/114524.html</trackback:ping><description><![CDATA[&nbsp;本来是想一周坚持写一篇博客来记录下自己学着写编辑器的进展的，不过总想着写好一个阶段再写一篇总的能有写&#8220;内涵&#8221;的，于是乎拖着拖着一个月又过去了，最近想想自己又不是高手，blog还是该没事就写点，不管是脑残的错误<img src="http://www.cppblog.com/CuteSoft_Client/CuteEditor/images/emdgust.gif" align="absmiddle" border="0">还是幼稚的想法都该写下来。<br><br>&nbsp; 4月中，编辑器底层大改；可以说咱的编辑器本来的大部分结构学的是Ogitor，不过实际上程序最下面的结构当时大家没学Ogitor（最下面的结构指的是Ogitor对于编辑器对象的具体属性都采用了专门的属性容器，OgitorProperty&lt;T&gt;，当时就以为ogitor只是为了解耦的），等我们把大部分基本的功能都实现了（地形，光照，实体，地形编辑，草体），回过头来想加撤销还原的时候发现不好办了，（想一想，光以基本变量（bool等原子类型，Ogre::Vector3等基本数据类型）来保存具体编辑器的编辑属性的话，根本没办法撤销还原）于是我就从底层改起了。<br>&nbsp; <span style="color: #ff4848;">1.去除过多的单件：</span><br>&nbsp;&nbsp;&nbsp;&nbsp; 这一点是我和兄弟相当赞同的，过多离散的单件往往在方便的同时破坏了整个程序的结构，改之和Ogitor已知，采用基类的ObjectList的方式来管理所有的编辑器对象实例，这样所有的类都能得到统一管理，查找指定对象只需以它的类型来查找即可，需要单独更新的对象则加入到UpdateList中，然后在迭代更新列表逐个更新即可，在不用我们自己在主体里来回添加Update语句了。（这主要是为了解耦）但我想了想有个地方还是没学ogitor，它里面每个编辑器对象都有所有的parentEditor，这样则形成一种树形结构，这样的设计更加紧凑，不过我们暂时觉得没什么太大必要加，就放弃了（开始对OgitorProperty&lt;T&gt;也是这个想法<img src="http://www.cppblog.com/CuteSoft_Client/CuteEditor/images/emunlove.gif" align="absmiddle" border="0">）。<br>&nbsp; <span style="color: #ff4848;">2. 属性注册：</span><br>&nbsp;&nbsp;&nbsp; 属性部分所有内容，我还没全看明白。一是由于撤销还原还没弄，二是信号那块我也还没加（虽然树形类的代码是全扒过来了...）。不过就我目前看的部分而言，Ogitor这帮家伙写得还真棒，利用模板trait来调用对应变量类型函数（第二次见，第一次在STL源码剖析里，就那块和开始的部分我能看懂...），光看到这个内容小菜我就兴奋不已了。注册的部分实际不难，好好看看PROPERTY_PTR和SETTER，GETTER这些个宏就能明白，无非是在对应编辑器的工厂map表里先添加定义，然后利用这些个宏为mProperties添加属性变量，以及变量相关联的设置其数值的函数。<br><br><br><span style="color: #0846ff;">调试中犯的一些搞笑错误：</span><br>&nbsp; 1.前天在重写BaseObject的GetNode函数（返回编辑器对象所在的场景节点，若是基类则为NULL，只有是NodeObject或其以上的才有值，这里没学Ogitor的parentnode），发现程序里实际调用的时候就是不调NodeObject::GetNode而是调BaseObject::GetNode()，改了会都对C++产生了疑惑。。。还专门写了测试来看看究竟调用哪个，结构也应该是NodeObject::GetNode，这问题足足花了我二十分钟的时间，才发现自己在继承方法声明上忘记加const了。。。那一刻的感慨啊。。还是得经常把Effective C++拿出来摸一摸，翻一翻的。。<br>&nbsp;<br>&nbsp; 改着改着，突然在想：当有高手源码借鉴的时候，作为我这样的小菜（指的是C++学了1年多，功底自认为不错，但缺乏实际经验的人），是改照单全理解了再写还是边理解边按自己修改的较差方法去实现呢？我觉得是后者，因为后者总是需要去修改，而在修改的过程中才是存疑解惑的过程，这个过程中小菜才能明白为何高手如此&#8220;麻烦&#8221;地绕道偏行。还有，正如tonykee说的，编辑器的确是个无底洞～～要懂得适可而止的。<br>&nbsp;<br>&nbsp; <span style="color: #0846ff;">分享点新闻：</span><br>&nbsp; 1.GoogleCode和SVN升级为2G了（具体貌似是1G更新空间，另外1G存储，这一点没太明白。。），嫌sourceForge麻烦的有福音咯～～<br>&nbsp; 2.Ogitor这帮家伙更新的越来越快了，当时还给他们提意见说应该做成简单material脚本编写的编辑器，刚说完，人家就回说：已经开始做了<img src="http://www.cppblog.com/CuteSoft_Client/CuteEditor/images/emdgust.gif" align="absmiddle" border="0">顺带一提，Ogitor有中文版了，感谢Coho的翻译，虽然有些地方还没翻译好，不过我空了也会帮帮他们忙的<img src="http://www.cppblog.com/CuteSoft_Client/CuteEditor/images/emsmiled.gif" align="absmiddle" border="0"><br>&nbsp; 3.星际7月27日预售，很期待它的银河编辑器啊～～<br><br>&nbsp; 这两天完成撤销还原后再更新吧，希望我写的乱七八糟的东西对大家有帮助。<br>&nbsp; &nbsp; <br><br>  <img src ="http://www.cppblog.com/cty41/aggbug/114524.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cty41/" target="_blank">月下圆舞曲</a> 2010-05-06 08:38 <a href="http://www.cppblog.com/cty41/archive/2010/05/06/114524.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[学习心得]跟着Ogitor学做编辑器--实现草体刷</title><link>http://www.cppblog.com/cty41/archive/2010/04/03/111514.html</link><dc:creator>月下圆舞曲</dc:creator><author>月下圆舞曲</author><pubDate>Sat, 03 Apr 2010 11:18:00 GMT</pubDate><guid>http://www.cppblog.com/cty41/archive/2010/04/03/111514.html</guid><wfw:comment>http://www.cppblog.com/cty41/comments/111514.html</wfw:comment><comments>http://www.cppblog.com/cty41/archive/2010/04/03/111514.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/cty41/comments/commentRss/111514.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cty41/services/trackbacks/111514.html</trackback:ping><description><![CDATA[<span style="font-size: 8pt;"></span><span style="font-size: 10pt;">&nbsp; 我和朋友一块在做游戏编辑器练手，鉴于大家以前都没有经验，就会写写图形。就照着开源的Ogitor学习罢。我首先负责的就是草体部分，考虑到哥是最弱的。。。所以写到现在才完工。。。讲下学习心得吧，只写下思路，具体的过程懒得写。（高手勿看了。。）<br>&nbsp; Ogitor的代码写的非常易读，要是你能编译次ogitor的话，跟着程序走一边就能很快清楚其结构。所以嘛，先提下编译，ogitor的编译其实还是有些麻烦的，尤其是对像我这种命令行菜鸟来说，ogitor的wiki上有详细的教程，[url]http://wiki.ogitor.org/Building+Ogitor&amp;structure=Development[/url]基本很完善了,不过我还是遇到许多麻烦，强烈建议装vs2008，因为Qt有专门适用08的源码包，而且记着一定按着Jacmoe写的步骤来，别先过cmake那块，先把</span><span style="font-size: 10pt;">QtPropertyBrowser弄好，设置环境变量的时候我出了个小白错误，在PATH变量后面加Qt目录前加了个空格，导致系统不接受后面的路径。（。。。悲剧的很。。）然后的步骤就没啥问题了。如果你在编译的时候出现（vs08命令行下或者Qt Creator下，后者不建议，得改qt的编译器，我反正没找到在哪里改。。。）<br>[code]</span><code>g++:
Documents\Programmer\Ogre\unstable-06e26a1bed18\qtOgitor\qtpropertybrowser-2.5\lib\libQtSolutions_PropertyBrowser-2.5d.a:
No such file or directory<br>mingw32-make[1]: *** [..\lib\QtSolutions_PropertyBrowser-2.5d.dll] Error 1<br>mingw32-make: *** [debug-all] Error 2<br>Exited with code 2.<br>Error while building project buildlib<br>When executing build step 'Make'</code><span style="font-size: 10pt;">[/code]记着肯定是你装了mingw，编译得用vs的编译器。<br><br>&nbsp; Ogitor的草体也是借由PageGemotry库(下面缩写为PG)实现的，Ogre的 Addons fourm里有详细介绍，这个库相当强大，而且使用轻便，简单的刷草体我们利用里面的GrassLoader即可，就是公告板。这块代码他们没有写在ogPageGeometry里，那块别看了，否则你们会向我一样给带跑的。Ismail（Ogitor的主要开发人员）将这块写在TerrainGroupManager里，直接和地形刷交互，仔细想想，这也是最好的方法。（我走工厂方法的歪路想了4，5天才拐回来。。之前没发现他写在</span><span style="font-size: 10pt;">TerrainGroupManager里了。。。</span><span style="font-size: 10pt;">）由于PG实现草体的加载只有两种，要么随机，要么通过加载密度纹理。不像treeLoader一样，可以直接AddEntity。（想想为什么）所以要想实现草体刷，咱就得创建一张动态纹理来实现了。我们修改每个TerrainPageObject（页地形），向其加入GrassLayer。而在TerrainGroupManager里保留具体的更新者PagedGeometry和GrassLoader。这里不做具体解释，建议去看看PG的源码，10个文件左右，（一半Header，一半Source）代码也很易懂。还有，Ogitor的工厂对象注册机制很好，（我对设计模式没什么研究不知道叫啥。。）新手这个一定得细看看，Ogitor在解耦上做的也近乎完美，面向对象的界面编程Qt加上Ismail自己写的很多基类，使得程序分离的很好，推荐看看OgitorsProperty类，里面就是照着Qt的信号机制写的，这块我也没深看。我们用的是MFC，所以这块没有写成纯面向对象的，用的还是离散型的单件。我兄弟说Ogitor那样效率差点，不过我觉得挺酷的，毕竟写的漂亮。Ogitor的工厂对象的初始化部分是写在CreateProperties里的，因为许多变量需要有用户修改，所以构造函数没有初始化所有变量。<br>&nbsp; 最后带句：Ogitor的大哥们相当热情，有问题多去他们的forum</span>里提，基本第二天就回了。（有时差）<br>&nbsp; <br><img src ="http://www.cppblog.com/cty41/aggbug/111514.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cty41/" target="_blank">月下圆舞曲</a> 2010-04-03 19:18 <a href="http://www.cppblog.com/cty41/archive/2010/04/03/111514.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[非原创]Ogre里的Plane拾取</title><link>http://www.cppblog.com/cty41/archive/2010/03/15/109760.html</link><dc:creator>月下圆舞曲</dc:creator><author>月下圆舞曲</author><pubDate>Mon, 15 Mar 2010 12:52:00 GMT</pubDate><guid>http://www.cppblog.com/cty41/archive/2010/03/15/109760.html</guid><wfw:comment>http://www.cppblog.com/cty41/comments/109760.html</wfw:comment><comments>http://www.cppblog.com/cty41/archive/2010/03/15/109760.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cty41/comments/commentRss/109760.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cty41/services/trackbacks/109760.html</trackback:ping><description><![CDATA[&nbsp; 初学Ogre的同学们都应该会怎么用SceneRayQuery来查询地形上的交点（例如，右键移动，防止物体），这也就是迭代结果里的WorldFragment，但如果是Movable Object呢？（譬如平面）这些SceneRayQuery只提供了和包围盒的交点，也就是说我们如果想要找到实际的交点还需要自食其力～～～<br>&nbsp; 我在Ogre论坛里查了会找了个非常好的实现方法，下面把这个帖子贴出：http://www.ogre3d.org/forums/viewtopic.php?t=23440&amp;highlight=<br><br><img hidden="true" style="border: medium none ; position: absolute; z-index: 2147483647; opacity: 0.6; display: none;" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAADsElEQVR4nK2VTW9VVRSGn33OPgWpYLARbKWhQlCHTogoSkjEkQwclEQcNJEwlfgD/AM6NBo1xjhx5LyJ0cYEDHGkJqhtBGKUpm3SFii3vb2956wPB/t+9raEgSs52fuus89613rftdcNH8/c9q9++oe/Vzb5P+3McyNcfm2CcPj9af9w6gwjTwzvethx3Bx3x8xwd1wNM8dMcTNUHTfFLPnX6nVmZpeIYwf3cWD/PhbrvlPkblAzVFurKS6GmmGqqComaS+qmBoTI0Ncu3mXuGvWnrJ+ZSxweDgnkHf8ndVTdbiT3M7cQp2Z31dRTecHAfqydp4ejhwazh6Zezfnu98E1WIQwB3crEuJ2Y45PBTAQUVR9X4At66AppoEVO1Q8sgAOKJJjw6Am6OquDmvHskZ3R87gW+vlHz98zpmiqphkkRVbQtsfPTOC30lJKFbFTgp83bWh7Zx/uX1B6w3hI3NkkZTqEpBRDBRzG2AQHcwcYwEkOGkTERREbLQ/8HxJwuW7zdYrzfZ2iopy4qqEspKaDYravVm33k1R91Q69FA1VBRzFIVvXbx5AgXT44A8MWP81yfu0utIR2aVK3vfCnGrcUNxp8a7gKYKiLCvY2SUvo/aNtnM3e49ucK9S3p0aDdaT0UAVsKi2tVi6IWwNL9JvdqTdihaz79/l+u/rHMxmaJVMLkS2OoKKLWacdeE3IsSxctc2D5Qcl6vUlVVgNt+fkPPcFFmTw1xruvT7SCd7nuVhDQvECzJH90h0azRKoKFRkAmP5lKTWAGRdefoZL554FQNUxB92WvYeA5UN4PtSqwB2phKqsqMpBgAunRhFR3j49zuU3jnX8k6fHEQKXzh1jbmGDuYU6s4t1rt6socUeLLZHhYO2AHSHmzt19ihTZ48O8Hzl/AmunD/BjTvrvPfNX3hWsNpwJCvwYm+ngug4UilSCSq6k8YPtxDwfA+WRawIWFbgscDiULcCEaWqBFOlrLazurupOSHLqGnEKJAY8TwBEHumqUirAjNm52vEPPRV4p01XXMPAQhUBjcWm9QZwijwokgAeYHlHYA06KR1cT6ZvoV56pDUJQEjw0KeaMgj1hPEY4vz2A4eW0/e1qA7KtQdsxTYAG0H3iG4xyK1Y+xm7XmEPOJZDiENzLi2WZHngeOjj2Pe+sMg4GRYyLAsx7ME4FnsyTD9pr0PEc8zPGRAwKXBkYOPEd96cZRvf11g9MDe7e3R4Z4Q+vyEnn3P4t0XzK/W+ODN5/kPfRLewAJVEQ0AAAAASUVORK5CYII%3D" id="myFxSearchImg" height="24" width="24"><img src ="http://www.cppblog.com/cty41/aggbug/109760.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cty41/" target="_blank">月下圆舞曲</a> 2010-03-15 20:52 <a href="http://www.cppblog.com/cty41/archive/2010/03/15/109760.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Ogitor0.4的加载改进</title><link>http://www.cppblog.com/cty41/archive/2010/02/21/108171.html</link><dc:creator>月下圆舞曲</dc:creator><author>月下圆舞曲</author><pubDate>Sun, 21 Feb 2010 14:44:00 GMT</pubDate><guid>http://www.cppblog.com/cty41/archive/2010/02/21/108171.html</guid><wfw:comment>http://www.cppblog.com/cty41/comments/108171.html</wfw:comment><comments>http://www.cppblog.com/cty41/archive/2010/02/21/108171.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cty41/comments/commentRss/108171.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cty41/services/trackbacks/108171.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/cty41/archive/2010/02/21/108171.html'>阅读全文</a><img src ="http://www.cppblog.com/cty41/aggbug/108171.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cty41/" target="_blank">月下圆舞曲</a> 2010-02-21 22:44 <a href="http://www.cppblog.com/cty41/archive/2010/02/21/108171.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>