<?xml version="1.0" encoding="utf-8" ?>
<!-- generator="FEEDCREATOR_VERSION" -->
<rss version="2.0" xmlns:sns="http://blog.sina.com.cn/sns">
    <channel>
        <title>Aear's Game Development</title>
        <description></description>
        <link>http://blog.sina.com.cn/aear</link>
        <lastBuildDate>Thu, 21 Aug 2008 05:35:22 GMT+8</lastBuildDate>
        <generator>FEEDCREATOR_VERSION</generator>
        <language>zh-cn</language>
        <copyright>Copyright 1996 - 2008 SINA Inc. All Rights Reserved.</copyright>
        <pubDate>Wed, 20 Aug 2008 21:35:22 GMT+8</pubDate>
        <item>
            <title>GDC 2008 笔记</title>
            <link>http://blog.sina.com.cn/s/blog_4b3173c501008mqj.html</link>
            <description><![CDATA[<div>GDC
2008一些Presentation的笔记，因为就在家门口开的，所以去逛了逛。这里写的有我自己的笔记，也有同事写的：<br/>

<br/>
<b><font FACE="Arial" SIZE="2"><span STYLE="font-weight: bold; font-size: 10pt; font-family: Arial;">Harnessing
the power of multiple GPUs - AMD<br/></SPAN></FONT></B><font FACE="Arial" SIZE="2"><span STYLE="font-size: 10pt; font-family: Arial;">&nbsp;&nbsp;&nbsp;
1. 主要讲了2种使用多个GPU的方式，SFP( Split Frame Rendering ).
也就是一贞数据放在2个GPU上同时计算，使用动态平衡。</SPAN></FONT><br/>

&nbsp; 2. AFR （ Alternate Frame Rendering )
每个GPU渲染不同的贞。这种方式比较流行，但是也有很多问题。比如很难解决上一贞和下一贞之间的依赖关系，motion
blur就是的例子。<br/>
<br/>
<b><font FACE="Arial" SIZE="2"><span STYLE="font-weight: bold; font-size: 10pt; font-family: Arial;">The
technology of Uncharted: Drake’s Fortune<br/></SPAN></FONT></B>
<font FACE="Arial" SIZE="2"><span STYLE="font-size: 10pt; font-family: Arial;">&nbsp;&nbsp;&nbsp;
这个主要是讲Drake's Fortune PS3
游戏的。主要是分2个部分，下面是一些比较有趣的要点:<br/>
&nbsp;&nbsp;&nbsp; 1.
所有的static light information都是存在vertex
buffer里的，只有dynamic light使用一个grid object management system
管理<br/>
&nbsp;&nbsp;&nbsp; 2.
所有的level data分成多个固定大小的data block,
用来减少内存碎片，使loading 更快（我很喜欢这个优化）<br/>
&nbsp;&nbsp;&nbsp; 3.
使用自己写的texture memory defragmentation.
当然PC上都是dx管理拉，所以用不到。<br/>
&nbsp;&nbsp;&nbsp; 4. Physic
System, 很普通。。。。没啥好说的<br/>
&nbsp;&nbsp;&nbsp; 5. Scene
management: PVS ( SPU version ), Sorting on PPU<br/>
<br/></SPAN></FONT><b><font FACE="Arial" SIZE="2"><span STYLE="font-weight: bold; font-size: 10pt; font-family: Arial;">Stupid
spherical harmonics tricks
(看下面的link吧。差不多就这些）<br/></SPAN></FONT></B><font FACE="Arial" SIZE="2"><span STYLE="font-size: 10pt; font-family: Arial;">&nbsp;&nbsp;&nbsp;
1.</SPAN></FONT> <font FACE="Arial" SIZE="2"><span STYLE="font-size: 10pt; font-family: Arial;"><a TITLE="http://www.ppsloan.org/publications/StupidSH35.pdf" HREF="http://www.ppsloan.org/publications/StupidSH35.pdf">http://www.ppsloan.org/publications/StupidSH35.pdf</A><br/>

<br/></SPAN></FONT><b><font FACE="Arial" SIZE="2"><span STYLE="font-weight: bold; font-size: 10pt; font-family: Arial;">Insomniac’s
SPU programming practices<br/></SPAN></FONT></B><font FACE="Arial" SIZE="2"><span STYLE="font-size: 10pt; font-family: Arial;">&nbsp;&nbsp;&nbsp;
又是PS3的SPU,看来PS3可能要崛起了.<br/>
&nbsp;&nbsp;&nbsp; 1. 对SPU
programming 来说，Data layout是最关键的。<br/>
&nbsp;&nbsp;&nbsp; 2.
尽量少用Synchronization,<br/>
&nbsp;&nbsp;&nbsp; 3. 把data
block size 定在 16 bytes, 128 bytes aligned<br/>
&nbsp;&nbsp;&nbsp; 4.
code和data是一样的，对于SPU programming来说，可以把code当作data
来看待。如果SPU需要run不固定的code,直接从main
memory传code过去就是了。<br/>
&nbsp;&nbsp;&nbsp; 5. SPU run
shader是个很不错的主意。<br/>
<br/></SPAN></FONT><b><font FACE="Arial" SIZE="2"><span STYLE="font-weight: bold; font-size: 10pt; font-family: Arial;">Procedural
data generation in Far Cry 2 -
Ubisoft<br/></SPAN></FONT></B><font FACE="Arial" SIZE="2"><span STYLE="font-size: 10pt; font-family: Arial;">&nbsp;&nbsp;&nbsp;
Nothing special,<br/>
&nbsp;&nbsp;&nbsp; 1.
他们的经验就是procedural
terrain非常难调试，一个小的参数变化会引起无数个bug。汗个，虽然procedural
map很先进。。。。没想到这么恐怖。<br/>
<br/></SPAN></FONT><b><font FACE="Arial" SIZE="2"><span STYLE="font-weight: bold; font-size: 10pt; font-family: Arial;">GPU
optimization with the latest Nvidia performance
tools</SPAN></FONT></B> <font FACE="Arial" SIZE="2"><span STYLE="font-size: 10pt; font-family: Arial;">- Nvidia<br/>
&nbsp;&nbsp;&nbsp;
Nvidia每年固定的广告presentation, 内容应该都在这里：<br/>
&nbsp;&nbsp;&nbsp;</SPAN></FONT>
<font FACE="Arial" SIZE="2"><span STYLE="font-size: 10pt; font-family: Arial;"><a TITLE="http://developer.download.nvidia.com/shaderlibrary/webpages/shader_library.html" HREF="http://developer.download.nvidia.com/shaderlibrary/webpages/shader_library.html">
http://developer.download.nvidia.com/shaderlibrary/webpages/shader_library.html</A><br/>

<br/></SPAN></FONT><b><font FACE="Arial" SIZE="2"><span STYLE="font-weight: bold; font-size: 10pt; font-family: Arial;">Crysis
next-gen effects</SPAN></FONT></B> <font FACE="Arial" SIZE="2"><span STYLE="font-size: 10pt; font-family: Arial;"><br/>
&nbsp;&nbsp;&nbsp;
这个是我最感兴趣的，不过看过以后发现实在没啥特别的：不过扔在3年前他们开始做的时候，还是很厉害，下面是一些水面效果的tips:<br/>

&nbsp;&nbsp;&nbsp; 1.
Tessendorf model, using render to texture and vertex
displacement<br/>
&nbsp;&nbsp;&nbsp; 2. Simulated
reflection<br/>
&nbsp;&nbsp;&nbsp; 3.
Refraction做的不错，使用上一贞的数据做输入，mask
out所有水面上的东西<br/>
&nbsp;&nbsp;&nbsp; 4.
Procedural caustics， 使用单独一个pass<br/>
&nbsp;&nbsp;&nbsp; 5. "God"
rays for under water effect<br/>
&nbsp;<br/></SPAN></FONT> <b><font FACE="Arial" SIZE="2"><span STYLE="font-weight: bold; font-size: 10pt; font-family: Arial;">Practical
light and color</SPAN></FONT></B> <font FACE="Arial" SIZE="2"><span STYLE="font-size: 10pt; font-family: Arial;"><br/>
&nbsp;&nbsp;&nbsp;
3个link，感觉很象他的个人广告:<br/>
&nbsp;&nbsp;&nbsp;</SPAN></FONT>
<a TITLE="http://www.thegnomonworkshop.com/dvds/jvi01.html" HREF="http://www.thegnomonworkshop.com/dvds/jvi01.html">http://www.thegnomonworkshop.com/dvds/jvi01.html</A><br/>

&nbsp; <a TITLE="http://www.amazon.com/Vision-Art-Margaret-S-Livingstone/dp/0810904063" HREF="http://www.amazon.com/Vision-Art-Margaret-S-Livingstone/dp/0810904063">
http://www.amazon.com/Vision-Art-Margaret-S-Livingstone/dp/0810904063</A><br/>

&nbsp; <a TITLE="http://www.jermilex.com/Jermilex.com/Home.html" HREF="http://www.jermilex.com/Jermilex.com/Home.html">http://www.jermilex.com/Jermilex.com/Home.html</A><br/>

<font FACE="Arial" SIZE="2"><span STYLE="font-size: 10pt; font-family: Arial;"><br/>
</SPAN></FONT><b><font FACE="Arial" SIZE="2"><span STYLE="font-weight: bold; font-size: 10pt; font-family: Arial;">Lightmap
compression in Halo 3<br/></SPAN></FONT></B><font FACE="Arial" SIZE="2"><span STYLE="font-size: 10pt; font-family: Arial;">&nbsp;&nbsp;&nbsp;
懒的写了，都在这:<br/>
&nbsp;&nbsp;&nbsp;</SPAN></FONT>
<font FACE="Arial" SIZE="2"><span STYLE="font-size: 10pt; font-family: Arial;"><a TITLE="http://www.bungie.net/images/Inside/publications/presentations/Lightmap_Compression_2008_02_22.pptx" HREF="http://www.bungie.net/images/Inside/publications/presentations/Lightmap_Compression_2008_02_22.pptx">
http://www.bungie.net/images/Inside/publications/presentations/Lightmap_Compression_2008_02_22.pptx</A><br/>

<br/></SPAN></FONT><b><font FACE="Arial" SIZE="2"><span STYLE="font-weight: bold; font-size: 10pt; font-family: Arial;">Advanced
visual effects with direct3d
主要是DX10<br/></SPAN></FONT></B><font FACE="Arial" SIZE="2"><span STYLE="font-size: 10pt; font-family: Arial;">&nbsp;&nbsp;&nbsp;
1. Optimization tips:<br/>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; -
不要同时使用多过3,4个constant buffer, 如果要更改constant
buffer里的内容（dx9是static buffer)
最好是创建一个新的buffer来替换旧的。因为如果使用lock/copy/unlock(注意是第2次，第一次数据初始化不会）,
驱动会把video memory里的buffer移动到system memory里。变成dynamic
buffer.<br/>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; - 尽量压缩Vertex Size<br/>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; - 如果Pixel
shader很慢，使用Depth prepass. (先render depth
buffer，这样可以利用Z-Pre-rejection )<br/>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; - 尽量少用temp
register,虽然temp
register很多，但是你用的越多，能同时并行运行的shader
code就越少。所以少用能增加并行。<br/>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; - 不要用 D24_UNORM_S8_UINT
format ，非常慢。<br/>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; -
使用1x1的texture来检查是不是texture sampling bottle neck<br/>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; - int 和
float的之间的转换非常慢，尽量不要用。<br/>
&nbsp;&nbsp;
&nbsp;&nbsp;
http://ati.amd.com/developer/gdc/2008/Ultimate_Graphics_Performance_for_DirectX_10_Hardware.pdf<br/>

http://ati.amd.com/developer/gdc/2008/DirectX10.1.pdf<br/>
<br/>
xbox360懒的写了。<br/>
<br/>
<br/>
<br/></SPAN></FONT><font FACE="Arial" SIZE="2"><span STYLE="font-size: 10pt; font-family: Arial;">&nbsp;&nbsp;&nbsp;<br/>
</SPAN>
&nbsp;&nbsp;&nbsp;<br/></FONT></DIV>
]]></description>
            <author>aear</author>
            <category>游戏业界咨询</category>
            <comments>http://blog.sina.com.cn/s/blog_4b3173c501008mqj.html#comment</comments>
            <pubDate>Wed, 05 Mar 2008 18:13:03 GMT+8</pubDate>
            <guid>http://blog.sina.com.cn/s/blog_4b3173c501008mqj.html</guid>
        </item>
        <item>
            <title>CMU一位老兄做的Wii的东西,太厉害了.</title>
            <link>http://blog.sina.com.cn/s/blog_4b3173c501007x4j.html</link>
            <description><![CDATA[<div>&nbsp;<a HREF="http://tw.youtube.com/watch?v=Jd3-eiid-Uw" TARGET="_blank">http://tw.youtube.com/watch?v=Jd3-eiid-Uw</A></DIV>
<div>&nbsp;</DIV>
<div>是关于Wii的, 有兴趣的人可以去看看。</DIV>
]]></description>
            <author>aear</author>
            <comments>http://blog.sina.com.cn/s/blog_4b3173c501007x4j.html#comment</comments>
            <pubDate>Sat, 22 Dec 2007 02:52:41 GMT+8</pubDate>
            <guid>http://blog.sina.com.cn/s/blog_4b3173c501007x4j.html</guid>
        </item>
        <item>
            <title>偶的新游戏</title>
            <link>http://blog.sina.com.cn/s/blog_4b3173c501000aza.html</link>
            <description><![CDATA[<DIV>NBA 2K8<br/>
类型：运动类<br/>
平台：XBOX360 PS2 PS3<br/>
<br/>
这里是一些图片和视频：<br/>
<P CLASS="MsoNormal"><SPAN STYLE="font-size: 10pt; font-family: Arial;"><A HREF="http://media.xbox360.ign.com/media/866/866314/imgs_1.html">http://media.xbox360.ign.com/media/866/866314/imgs_1.html</A></SPAN></P>
<P CLASS="MsoNormal"><SPAN STYLE="font-size: 10pt; font-family: Arial;"><A HREF="http://media.xbox360.ign.com/media/866/866314/vids_1.html">http://media.xbox360.ign.com/media/866/866314/vids_1.html</A></SPAN></P>
<br/>
<br/></DIV>
]]></description>
            <author>aear</author>
            <comments>http://blog.sina.com.cn/s/blog_4b3173c501000aza.html#comment</comments>
            <pubDate>Wed, 03 Oct 2007 16:19:00 GMT+8</pubDate>
            <guid>http://blog.sina.com.cn/s/blog_4b3173c501000aza.html</guid>
        </item>
        <item>
            <title>对于render system的一点思考</title>
            <link>http://blog.sina.com.cn/s/blog_4b3173c501000ag2.html</link>
            <description><![CDATA[<DIV>
<P>
1.&nbsp;每个material的id&nbsp;最好用一个&nbsp;64位&nbsp;unsigned&nbsp;int&nbsp;表示。当然如果你用&nbsp;128位&nbsp;unsigned&nbsp;int，&nbsp;使用__mm128关键字，&nbsp;也可以。这样可以相对减少排序复杂度。</P>
<P><br/></P>
<P>2.&nbsp;
对于游戏里所有的texture和effect,最好分别有个&nbsp;texture&nbsp;manager和effect&nbsp;manager,&nbsp;对于相同的
texture和effect，给一个相同的&nbsp;id：&nbsp;分别是&nbsp;texture&nbsp;id&nbsp;和&nbsp;effect&nbsp;id。&nbsp;每个id是个8位的&nbsp;byte就足够
了。同时支持256个effect和texture在内存中差不多是极限。</P>
<P><br/></P>
<P>
3.&nbsp;关于material&nbsp;的&nbsp;id，&nbsp;还需要包含物体的一些信息和到camera的距离，一般来说，&nbsp;大概的定义如下：<br/>

union{<br/>
&nbsp;&nbsp;struct&nbsp;{<br/>
&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp;objectType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;8;<br/>

&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp;effectID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;8;<br/>

&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp;textureStage1&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;8;<br/>

&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp;textureStage2&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;8;<br/>

&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp;textureStage3&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;8;<br/>

&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp;textureStage4&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;8;<br/>

&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp;distanceToCamera&nbsp;:&nbsp;8;<br/>

&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp;renderstate&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;8;<br/>

&nbsp;&nbsp;}<br/>
&nbsp;&nbsp;unsigned&nbsp;__int64&nbsp;&nbsp;matId;<br/>

}<br/>
上面的结构只支持4个texturestage，如果要支持更多，可以适当的修改。</P>
<P>里
边的objectType可以用来区分opaque,&nbsp;transparent&nbsp;和&nbsp;hud.&nbsp;比如opaque&nbsp;的id&nbsp;是&nbsp;1000,
&nbsp;transparent是&nbsp;0100,&nbsp;hud是&nbsp;0010,&nbsp;这样排序时候可以保证是先渲染&nbsp;opaque,&nbsp;然后transparent，然后是
hud.&nbsp;</P>
<P>
对于effect&nbsp;和&nbsp;texture&nbsp;哪个放在前面，主要是看哪种资源更换的更频繁。这个需要具体测试才知道。关于距离的问
题，对于opaque，需要做位反操作，因为是从近到远排序。&nbsp;同时对于transparent的物体，distance可能要和effect或者
texture&nbsp;stage&nbsp;1的位置换以下，因为从远到近排序更重要一些。</P>
<P>
还有对于material的内部const&nbsp;value或者render&nbsp;state排列，很多时候是在build&nbsp;time进行的。</P>
<P><br/></P>
<P>4.&nbsp;
只考虑了material的系统。也可以算是effect&nbsp;system.&nbsp;但是effect&nbsp;system的话还是缺少
&nbsp;post&nbsp;effect&nbsp;的支持。&nbsp;其次是光靠这里排序是不够的，因为很多effect内部可以改变render&nbsp;states.&nbsp;因此还需要增加一
个effect&nbsp;states&nbsp;manager，DX里边就有这个.
具体结构可
以参考&nbsp;shader&nbsp;X4里边&nbsp;"tips&nbsp;and&nbsp;tricks&nbsp;for&nbsp;d3dx&nbsp;effects-based&nbsp;renderers".</P>
<br/>
5.&nbsp;最后，如果没有scene&nbsp;management,&nbsp;和&nbsp;scene&nbsp;graph，&nbsp;还不能算是完整的render&nbsp;system.<br/>
</DIV>
]]></description>
            <author>aear</author>
            <comments>http://blog.sina.com.cn/s/blog_4b3173c501000ag2.html#comment</comments>
            <pubDate>Mon, 20 Aug 2007 17:36:49 GMT+8</pubDate>
            <guid>http://blog.sina.com.cn/s/blog_4b3173c501000ag2.html</guid>
        </item>
        <item>
            <title>最近读的一些好paper</title>
            <link>http://blog.sina.com.cn/s/blog_4b3173c501000aar.html</link>
            <description><![CDATA[<DIV>Dx10:<br/>
<A REL="nofollow" TARGET="_blank" HREF="http://www.microsoft.com/downloads/thankyou.aspx?familyId=96cd28d5-4c15-475e-a2dc-1d37f67fa6cd&amp;displayLang=en">
<FONT FACE="Arial" SIZE="2">http://www.microsoft.com/downloads/thankyou.aspx?familyId=96cd28d5-4c15-475e-a2dc-1d37f67fa6cd&amp;displayLang=en</FONT></A><br/>

<br/>
<P CLASS="MsoNormal">Terrain Rendering:</P>
<P CLASS="MsoNormal"><FONT FACE="Arial" SIZE="2"><SPAN STYLE="font-size: 10pt; font-family: Arial;"><A REL="nofollow" TARGET="_blank" HREF="http://www.gamedev.net/reference/articles/article1936.asp">http://www.gamedev.net/reference/articles/article1936.asp</A></SPAN></FONT></P>
<P CLASS="MsoNormal"><FONT FACE="Arial" SIZE="2"><SPAN STYLE="font-size: 10pt; font-family: Arial;"><A REL="nofollow" TARGET="_blank" HREF="http://www2.imm.dtu.dk/pubdb/personal/showbasket.php?cmd=full_view&amp;id=53&amp;title=Publications&amp;header=&amp;footer=&amp;css=&amp;f=1&amp;b=1&amp;e=1&amp;year=&amp;fmt=html&amp;order=year">
http://www2.imm.dtu.dk/pubdb/personal/showbasket.php?cmd=full_view&amp;id=53&amp;title=Publications&amp;header=&amp;footer=&amp;css=&amp;f=1&amp;b=1&amp;e=1&amp;year=&amp;fmt=html&amp;order=year</A></SPAN></FONT></P>
<P CLASS="MsoNormal"></P>
<P CLASS="MsoNormal"><SPAN STYLE="font-size: 10pt; font-family: Arial;"><A HREF="http://research.microsoft.com/%7Ehoppe/">http://research.microsoft.com/~hoppe/</A></SPAN></P>
<P CLASS="MsoNormal"><br/></P>
<P CLASS="MsoNormal">Texture:<br/></P>
<P CLASS="MsoNormal"><SPAN STYLE="font-size: 10pt; font-family: Arial;"><A HREF="http://ati.amd.com/developer/NormalMapCompression.pdf">http://ati.amd.com/developer/NormalMapCompression.pdf</A></SPAN></P>
<br/>
Atmospheric Effect:<br/>
<P CLASS="MsoNormal"><A HREF="http://ati.amd.com/developer/dx9/ATI-LightScattering.pdf">http://ati.amd.com/developer/dx9/ATI-LightScattering.pdf</A></P>
<FONT FACE="Arial" SIZE="2"><A REL="nofollow" TARGET="_blank" HREF="http://developer.amd.com/assets/D3DTutorial_Crytek.pdf">http://developer.amd.com/assets/D3DTutorial_Crytek.pdf</A><br/>
</FONT>
<DIV CLASS="Section1">
<P CLASS="MsoNormal"><FONT FACE="Arial" SIZE="2"><SPAN STYLE="font-size: 10pt; font-family: Arial;"><A REL="nofollow" TARGET="_blank" HREF="http://portal.acm.org/citation.cfm?id=1185827">http://portal.acm.org/citation.cfm?id=1185827</A></SPAN></FONT></P>
<P CLASS="MsoNormal"><FONT FACE="Arial" SIZE="2"><SPAN STYLE="font-size: 10pt; font-family: Arial;"><A REL="nofollow" TARGET="_blank" HREF="http://portal.acm.org/citation.cfm?id=602099.602108&amp;coll=ACM&amp;dl=ACM&amp;CFID=15151515&amp;CFTOKEN=6184618">
http://portal.acm.org/citation.cfm?id=602099.602108&amp;coll=ACM&amp;dl=ACM&amp;CFID=15151515&amp;CFTOKEN=6184618</A></SPAN></FONT></P>
</DIV>
<br/>
Scene Management:<br/>
<FONT FACE="Arial" SIZE="2"><SPAN STYLE="font-size: 10pt; font-family: Arial;"><A REL="nofollow" TARGET="_blank" HREF="http://developer.nvidia.com/docs/IO/9078/Modern-Graphics-Engine-Design.pdf">
http://developer.nvidia.com/docs/IO/9078/Modern-Graphics-Engine-Design.pdf</A></SPAN></FONT>
<P CLASS="MsoNormal"><FONT FACE="Arial" SIZE="2"><SPAN STYLE="font-size: 10pt; font-family: Arial;"><A REL="nofollow" TARGET="_blank" HREF="http://www.gamedev.net/community/forums/topic.asp?topic_id=183462">
http://www.gamedev.net/community/forums/topic.asp?topic_id=183462</A></SPAN></FONT></P>
<P CLASS="MsoNormal"><FONT FACE="Arial" SIZE="2"><SPAN STYLE="font-size: 10pt; font-family: Arial;"><A REL="nofollow" TARGET="_blank" HREF="http://www.delphi3d.net/articles/viewarticle.php?article=stateman.htm">
http://www.delphi3d.net/articles/viewarticle.php?article=stateman.htm</A></SPAN></FONT></P>
<P CLASS="MsoNormal"><FONT FACE="Arial" SIZE="2"><SPAN STYLE="font-size: 10pt; font-family: Arial;"><A REL="nofollow" TARGET="_blank" HREF="http://www.gamedev.net/community/forums/topic.asp?topic_id=183462">
http://www.gamedev.net/community/forums/topic.asp?topic_id=183462</A></SPAN></FONT></P>
&nbsp;</DIV>
]]></description>
            <author>aear</author>
            <comments>http://blog.sina.com.cn/s/blog_4b3173c501000aar.html#comment</comments>
            <pubDate>Fri, 10 Aug 2007 23:37:48 GMT+8</pubDate>
            <guid>http://blog.sina.com.cn/s/blog_4b3173c501000aar.html</guid>
        </item>
        <item>
            <title>Post-mortems of my last project</title>
            <link>http://blog.sina.com.cn/s/blog_4b3173c501000a9c.html</link>
            <description><![CDATA[<DIV>
<OL STYLE="MARGIN-TOP: 0in" TYPE="1">
<LI CLASS="MsoNormal"><FONT FACE="Times New Roman" SIZE="3"><SPAN STYLE="FONT-SIZE: 12pt">All resource needs to be
carefully managed, the best way to do that is using IUnkown like
interface. Every time a resource is acquired, the code increases
the reference count internally, and the client releases the
resource externally, which decrease the reference
count.</SPAN></FONT></LI>
<LI CLASS="MsoNormal"><FONT FACE="Times New Roman" SIZE="3"><SPAN STYLE="FONT-SIZE: 12pt">Basic stuffs need to be thread
safe, things like basic data structures: queue, link list, etc. and
memory allocation functions. All lock-free algorithms are very good
candidates but it’s very hard to get it correct; Anyway, it’s
worth it. For the lock-free ABA problem, an iterator can be used to
indicate an element is referenced by a client. When the iterator
moves away ( ++ or -- ), or get deleted, the reference count of the
element can be decreased. This provides good way to manage the
delete items for non-managed code.</SPAN></FONT></LI>
<LI CLASS="MsoNormal"><FONT FACE="Times New Roman" SIZE="3"><SPAN STYLE="FONT-SIZE: 12pt">for the memory management,
several points need to be taken into account:</SPAN></FONT>
<OL STYLE="MARGIN-TOP: 0in" TYPE="a">
<LI CLASS="MsoNormal"><FONT FACE="Times New Roman" SIZE="3"><SPAN STYLE="FONT-SIZE: 12pt">It’s useful to remember the
caller thread ids,&nbsp; source filename, and line
numbers for each memory allocation in debug mode. So it’s very
easy to find out where the memory leakage
happens.</SPAN></FONT></LI>
<LI CLASS="MsoNormal"><FONT FACE="Times New Roman" SIZE="3"><SPAN STYLE="FONT-SIZE: 12pt">An allocated memory needs two
memory guard bytes, one at the beginning, and one at the end. It
helps to find out memory overflow problem</SPAN></FONT></LI>
<LI CLASS="MsoNormal"><FONT FACE="Times New Roman" SIZE="3"><SPAN STYLE="FONT-SIZE: 12pt">Memory reference count and
allocation&nbsp;count is very important. It’s the
first place to detect memory leakage.</SPAN></FONT></LI>
</OL>
</LI>
<LI CLASS="MsoNormal"><FONT FACE="Times New Roman" SIZE="3"><SPAN STYLE="FONT-SIZE: 12pt">For a good game editor here are
several points:</SPAN></FONT>
<OL STYLE="MARGIN-TOP: 0in" TYPE="a">
<LI CLASS="MsoNormal"><FONT FACE="Times New Roman" SIZE="3"><SPAN STYLE="FONT-SIZE: 12pt">It should be a MVC architecture,
and use the events to update the view from the controller, not the
model!!!!!!!</SPAN></FONT></LI>
<LI CLASS="MsoNormal"><FONT FACE="Times New Roman" SIZE="3"><SPAN STYLE="FONT-SIZE: 12pt">The model data should be like an
object database, for all objects in the database, they should share
a common interface for object management. And each object should
have sibling and children data structure support for maintaining a
well-defined, flexible object database
structure.</SPAN></FONT></LI>
<LI CLASS="MsoNormal"><FONT FACE="Times New Roman" SIZE="3"><SPAN STYLE="FONT-SIZE: 12pt">All tools logic should be
happened in the controller. But&nbsp;the controller can
be separated into two parts: a command line based controller, and
GUI based controller. These two parts can be independent from each
other, or the GUI based controller is based on the command line
controller.</SPAN></FONT></LI>
<LI CLASS="MsoNormal"><FONT FACE="Times New Roman" SIZE="3"><SPAN STYLE="FONT-SIZE: 12pt">The rendering is really not a big
deal, but the key problem is the events that require to update the
UI element from the controller may overwhelm the graphics
capability. So the good way to design the view is maintaining an
update requests cache and only do one update for the UI element if
there are several same update requests from the
controller.</SPAN></FONT></LI>
<LI CLASS="MsoNormal"><FONT FACE="Times New Roman" SIZE="3"><SPAN STYLE="FONT-SIZE: 12pt">C# is the best choice for game
editor (This is the really my point! )</SPAN></FONT></LI>
</OL>
</LI>
<LI CLASS="MsoNormal"><FONT FACE="Times New Roman" SIZE="3"><SPAN STYLE="FONT-SIZE: 12pt">For the graphics pipeline, there
are the things are necessary at the build time:</SPAN></FONT>
<OL STYLE="MARGIN-TOP: 0in" TYPE="a">
<LI CLASS="MsoNormal"><FONT FACE="Times New Roman" SIZE="3"><SPAN STYLE="FONT-SIZE: 12pt">Collapse model, which made a
single vertex buffer and index buffer for all the models in a
scene. So this may introduce some limitations, but it can reduce
draw calls a lot.</SPAN></FONT></LI>
<LI CLASS="MsoNormal"><FONT FACE="Times New Roman" SIZE="3"><SPAN STYLE="FONT-SIZE: 12pt">Vertex sharing is very very
important. But I really want to know the different between using
one stream and the using multiple streams for the vertex data
sharing. Just don’t have enough time to try.</SPAN></FONT></LI>
<LI CLASS="MsoNormal"><FONT FACE="Times New Roman" SIZE="3"><SPAN STYLE="FONT-SIZE: 12pt">Materials need to be merged and
sorted first, same material with different parameters needs to be
grouped together to minimize the states changes.</SPAN></FONT></LI>
<LI CLASS="MsoNormal"><FONT FACE="Times New Roman" SIZE="3"><SPAN STYLE="FONT-SIZE: 12pt">All the data binding, for
example: the material, and the textures this material use, should
be indicated by a string CRC token, rather than the direct pointer
or index whatever. This gives flexibility that resource can be
managed by different software module. For example, models can be
managed by model manager, and texture can be managed by texture
manager. The pointer can be obtained at the initialization time to
allow fast resource access.</SPAN></FONT></LI>
<LI CLASS="MsoNormal"><FONT FACE="Times New Roman" SIZE="3"><SPAN STYLE="FONT-SIZE: 12pt">Animations needs to be optimized,
unnecessary animation keys should be removed.</SPAN></FONT></LI>
<LI CLASS="MsoNormal"><FONT FACE="Times New Roman" SIZE="3"><SPAN STYLE="FONT-SIZE: 12pt">After that, the triangle strip
needs to be created at the build time.</SPAN></FONT></LI>
<LI CLASS="MsoNormal"><FONT FACE="Times New Roman" SIZE="3"><SPAN STYLE="FONT-SIZE: 12pt">All light maps should be
generated at the build time or scene creation time, different light
map can use different channels in one texture to save the memory
space.</SPAN></FONT></LI>
<LI CLASS="MsoNormal"><FONT FACE="Times New Roman" SIZE="3"><SPAN STYLE="FONT-SIZE: 12pt">Within the pipeline, the fx file
should be exist in ASCII format rather than the compiled binary
format. This gives the flexibility to post process the fx code and
make it portable on different platform.</SPAN></FONT></LI>
<LI CLASS="MsoNormal"><FONT FACE="Times New Roman" SIZE="3"><SPAN STYLE="FONT-SIZE: 12pt">Vertex data should be compressed
to save the video memory and bandwidth.</SPAN></FONT></LI>
</OL>
</LI>
<LI CLASS="MsoNormal"><FONT FACE="Times New Roman" SIZE="3"><SPAN STYLE="FONT-SIZE: 12pt">For the run-time
graphics:</SPAN></FONT>
<OL STYLE="MARGIN-TOP: 0in" TYPE="a">
<LI CLASS="MsoNormal"><FONT FACE="Times New Roman" SIZE="3"><SPAN STYLE="FONT-SIZE: 12pt">Instancing with LOD really sucks.
I think the instancing can be obtained by pre-generate an index
buffer and vertex buffer with multiple objects of the same model
and use draw index call to control how many instance should be
rendered. Each instance individual data (like position) can be
obtained from a matrix in a matrix list sent from the CPU to GPU.
The index of the matrix in the matrix list should be stored in the
vertex data ( one byte should be enough. )</SPAN></FONT></LI>
<LI CLASS="MsoNormal"><FONT FACE="Times New Roman" SIZE="3"><SPAN STYLE="FONT-SIZE: 12pt">Rendering order should be take
care. Opaque first, then transparent stuffs, then HUD. A good way
to do this is using 3 display lists, and each display list is for
one type of rendering only.</SPAN></FONT></LI>
<LI CLASS="MsoNormal"><FONT FACE="Times New Roman" SIZE="3"><SPAN STYLE="FONT-SIZE: 12pt">The render should be sorted by
effect | material | texture | distance …….. For each sub-object
in an object’s materials, and id should be generated for sorting.
The id can be a 64 bits number with: effect id ( 63 – 58 ) |
material id ( 57 – 50 ) | texture id for all stages (49 – 20 ) |
distance 18 – 6 | other ids ( 5 – 0 ). A quick sort would be
enough to sort all sub-objects. The order of each element in the id
can be changed to reflect different priorities.</SPAN></FONT></LI>
<LI CLASS="MsoNormal"><FONT FACE="Times New Roman" SIZE="3"><SPAN STYLE="FONT-SIZE: 12pt">Multi-thread should be used: one
thread to calling rendering api, one for updating game objects, one
for updating partcles, clouds, waters, trees and non-important
environments etc…… So all the game world should be separated into
two parts, one part is the object that can affect the game-play,
another part is not.</SPAN></FONT></LI>
</OL>
</LI>
</OL>
<P CLASS="MsoNormal"><FONT FACE="Times New Roman" SIZE="3"><SPAN STYLE="FONT-SIZE: 12pt">&nbsp;</SPAN></FONT></P>
<P CLASS="MsoNormal" STYLE="MARGIN-LEFT: 0.5in"><FONT FACE="Times New Roman" SIZE="3"><SPAN STYLE="FONT-SIZE: 12pt">That’s
all that I can remember right now, I will add more stuffs if I get
something.</SPAN></FONT></P>
&nbsp;</DIV>
]]></description>
            <author>aear</author>
            <comments>http://blog.sina.com.cn/s/blog_4b3173c501000a9c.html#comment</comments>
            <pubDate>Wed, 08 Aug 2007 20:58:31 GMT+8</pubDate>
            <guid>http://blog.sina.com.cn/s/blog_4b3173c501000a9c.html</guid>
        </item>
        <item>
            <title>Siggraph 07 paper 3</title>
            <link>http://blog.sina.com.cn/s/blog_4b3173c501000a9b.html</link>
            <description><![CDATA[<DIV>
<H2><A HREF="http://www.siggraph.org/s2007/attendees/papers/8.html">Illustration
&amp; Sculpture</A></H2>
<DL>
<DT><A HREF="http://www.cgl.uwaterloo.ca/%7Ecsk/papers/siggraph2007.html">Image-guided
maze construction</A> (<A HREF="http://www.cgl.uwaterloo.ca/%7Ecsk/projects/mazes/">project
page</A>)</DT>
<DD><A HREF="http://www.cgl.uwaterloo.ca/%7Ejiexu/">Jie Xu</A>,
<A HREF="http://www.cgl.uwaterloo.ca/%7Ecsk/">Craig S. Kaplan</A>
(<A HREF="http://www.cgl.uwaterloo.ca/">University of
Waterloo</A>)</DD>
<DT>Dynamic Planar Map Illustration</DT>
<DD>Paul Asente Mike Schuster Teri Pettit (<A HREF="http://www.adobe.com/">Adobe Systems Incorporated</A>)</DD>
<DT><A HREF="http://www.cs.washington.edu/homes/wilmotli/work/work.htm">Interactive
cutaway illustrations of complex 3D models</A> (<A HREF="http://grail.cs.washington.edu/projects/cutaways/">project
page</A>)</DT>
<DD><A HREF="http://www.cs.washington.edu/homes/wilmotli/">Wilmot
Li</A>, <A HREF="http://www.cs.washington.edu/homes/lritter">Lincoln Ritter</A>
(<A HREF="http://grail.cs.washington.edu/">University of
Washington</A>), <A HREF="http://graphics.stanford.edu/%7Emaneesh/">Maneesh Agrawala</A>
(<A HREF="http://www.cs.berkeley.edu/">University of California,
Berkeley</A>), <A HREF="http://www.cs.washington.edu/homes/curless">Brian Curless</A>,
<A HREF="http://www.cs.washington.edu/homes/salesin">David
Salesin</A> (<A HREF="http://grail.cs.washington.edu/">University
of Washington</A>)</DD>
<DT><A HREF="http://www.cs.princeton.edu/gfx/pubs/Weyrich_2007_DBF/index.php">Digital
Bas-Relief From 3D Scenes</A></DT>
<DD><A HREF="http://www.cs.princeton.edu/%7Etweyrich/">Tim
Weyrich</A>, Jia Deng, Connely Barnes, <A HREF="http://www.cs.princeton.edu/%7Esmr/">Szymon Rusinkiewicz</A>,
<A HREF="http://www.cs.princeton.edu/%7Eaf/">Adam Finkelstein</A>
(<A HREF="http://www.cs.princeton.edu/">Princeton
University</A>)</DD>
</DL>
<H2><A HREF="http://www.siggraph.org/s2007/attendees/papers/9.html">Performance
Capture</A></H2>
<DL>
<DT><A HREF="http://graphics.ethz.ch/%7Ebickelb/publications.html">Multi-Scale
Capture of Facial Geometry and Motion</A></DT>
<DD><A HREF="http://graphics.ethz.ch/%7Ebickelb/">Bernd Bickel</A>,
<A HREF="http://graphics.ethz.ch/%7Embotsch/">Mario Botsch</A>
Roland Angst, (<A HREF="http://graphics.ethz.ch/">ETH Zürich</A>),
<A HREF="http://people.csail.mit.edu/wojciech">Wojciech Matusik</A>
(<A HREF="http://www.merl.com/">Mitsubishi Electric Research
Laboratories (MERL)</A>), <A HREF="http://graphics.ethz.ch/%7Eotmiguel/">Miguel A. Otaduy</A>
(<A HREF="http://graphics.ethz.ch/">ETH Zürich</A>), <A HREF="http://www.merl.com/people/pfister/">Hanspeter Pfister</A>
(<A HREF="http://www.merl.com/">Mitsubishi Electric Research
Laboratories (MERL)</A>), <A HREF="http://graphics.ethz.ch/%7Egrossm">Markus Gross</A> (<A HREF="http://graphics.ethz.ch/">ETH Zürich</A>)</DD>
<DT><A HREF="http://www.ryanmwhite.com/research/cloth_cap.html">Capturing and
Animating Occluded Cloth</A></DT>
<DD><A HREF="http://www.cs.berkeley.edu/%7Eryanw/">Ryan White</A>
(<A HREF="http://www.cs.berkeley.edu/">University of California,
Berkeley</A> and <A HREF="http://www.cs.uiuc.edu/">University of
Illinois at Urbana-Champaign</A>), <A HREF="http://www.acm.uiuc.edu/%7Ekcrane/www/">Keenan Crane</A>, <A HREF="http://luthuli.cs.uiuc.edu/%7Edaf/">David Forsyth</A> (<A HREF="http://graphics.cs.uiuc.edu/">University of Illinois at
Urbana-Champaign</A>)</DD>
<DT><A HREF="http://people.csail.mit.edu/jovan/">Practical Motion
Capture in Everyday Surroundings</A></DT>
<DD><A HREF="http://people.csail.mit.edu/drdaniel">Daniel
Vlasic</A> (<A HREF="http://graphics.lcs.mit.edu/">Massachusetts
Institute of Technology</A>), Rolf Adelsberger (<A HREF="http://www.merl.com/">Mitsubishi Electric Research Laboratories
(MERL)</A> and <A HREF="http://graphics.ethz.ch/">ETH Zürich</A>),
Giovanni Vannucci, <A HREF="http://www.merl.com/people/barnwell/">John Barnwell</A> (<A HREF="http://www.merl.com/">Mitsubishi Electric Research Laboratories
(MERL)</A>), <A HREF="http://graphics.ethz.ch/%7Egrossm">Markus
Gross</A> (<A HREF="http://graphics.ethz.ch/">ETH Zürich</A>),
<A HREF="http://people.csail.mit.edu/wojciech">Wojciech Matusik</A>
(<A HREF="http://www.merl.com/">Mitsubishi Electric Research
Laboratories (MERL)</A>), <A HREF="http://people.csail.mit.edu/jovan/">Jovan Popovi]]></description>
            <author>aear</author>
            <comments>http://blog.sina.com.cn/s/blog_4b3173c501000a9b.html#comment</comments>
            <pubDate>Wed, 08 Aug 2007 20:57:51 GMT+8</pubDate>
            <guid>http://blog.sina.com.cn/s/blog_4b3173c501000a9b.html</guid>
        </item>
        <item>
            <title>Siggraph 07 paper 2</title>
            <link>http://blog.sina.com.cn/s/blog_4b3173c501000a9a.html</link>
            <description><![CDATA[<DIV>
<H2><A HREF="http://www.siggraph.org/s2007/attendees/papers/4.html">Squish,
Bounce, and Collide</A></H2>
<DL>
<DT><A HREF="http://graphics.stanford.edu/%7Eirving/">Volume-Conserving Finite
Element Simulation of Deformable Models</A></DT>
<DD><A HREF="http://graphics.stanford.edu/%7Eirving/">Geoffrey
Irving</A>, (<A HREF="http://graphics.stanford.edu/">Stanford
University</A> and <A HREF="http://www.pixar.com/">Pixar Animation
Studios</A>), <A HREF="http://graphics.stanford.edu/%7Ecas43/">Craig Schroeder</A>
(<A HREF="http://graphics.stanford.edu/">Stanford University</A>)
<A HREF="http://graphics.stanford.edu/%7Efedkiw/">Ron Fedkiw</A>
(<A HREF="http://graphics.stanford.edu/">Stanford University</A>
and <A HREF="http://www.ilm.com/">Industrial Light &amp;
Magic</A>)</DD>
<DT><A HREF="http://graphics.cs.cmu.edu/projects/mwb/">Many-Worlds
Browsing for Control of Multibody Dynamics</A></DT>
<DD><A HREF="http://www.cs.cmu.edu/%7Ecdtwigg/">Christopher D.
Twigg</A> (<A HREF="http://graphics.cs.cmu.edu/">Carnegie Mellon
University</A>) <A HREF="http://www.cs.cornell.edu/%7Edjames/">Doug
L. James</A> (<A HREF="http://www.cs.cornell.edu/">Cornell
University</A>)</DD>
<DT><A HREF="http://graphics.ewha.ac.kr/CATCH/">Continuous
Collision Detection for Articulated Models using Taylor Models and
Temporal Culling</A></DT>
<DD><A HREF="http://graphics.ewha.ac.kr/people/zhangxy/index.htm">Xinyu
Zhang</A> (<A HREF="http://graphics.ewha.ac.kr/">Ewha Womans
University</A>), <A HREF="http://i3d.inrialpes.fr/people/redon/">Stephane Redon</A>
(<A HREF="http://www.inrialpes.fr/index_eng.html">INRIA</A>),
Minkyoung Lee, <A HREF="http://home.ewha.ac.kr/%7Ekimy">Young J.
Kim</A> (<A HREF="http://graphics.ewha.ac.kr/">Ewha Womans
University</A>)</DD>
<DD><br/></DD>
<DT><A HREF="http://graphics.cs.cmu.edu/projects/Bargteil-2007-AFE/">A
Finite-Element Method for Animating Large Viscoplastic
Flow</A></DT>
<DD><A HREF="http://www.cs.cmu.edu/%7Eadamwb/">Adam W. Bargteil</A>
(<A HREF="http://graphics.cs.cmu.edu/">Carnegie Mellon
University</A>) <A HREF="http://www.cc.gatech.edu/%7Ewojtan/">Chris
Wojtan</A> (<A HREF="http://www.cc.gatech.edu/">Georgia Institute
of Technology</A>) <A HREF="http://www.cs.cmu.edu/%7Ejkh/">Jessica
K. Hodgins</A> (<A HREF="http://graphics.cs.cmu.edu/">Carnegie
Mellon University</A>) <A HREF="http://www-static.cc.gatech.edu/%7Eturk/">Greg Turk</A> (<A HREF="http://www.cc.gatech.edu/">Georgia Institute of
Technology</A>)</DD>
</DL>
<H2><A HREF="http://www.siggraph.org/s2007/attendees/papers/5.html">Shape
Depiction and Stylization</A></H2>
<DL>
<DT><A HREF="http://www.olm.co.jp/en/rd/research/locostysh/">Locally
Controllable Stylized Shading</A></DT>
<DD><A HREF="http://www-ui.is.s.u-tokyo.ac.jp/%7Etd-rg7/index.html">Hideki
Todo</A> (<A HREF="http://www-ui.is.s.u-tokyo.ac.jp/">The
University of Tokyo</A>), <A HREF="http://www.olm.co.jp/rd/anjyo/index.html">Ken Anjyo</A>, <A HREF="http://www.olm.co.jp/rd/bill/index.html">William Baxter</A>
(<A HREF="http://www.olm.co.jp/">OLM Digital, Inc</A>), <A HREF="http://www-ui.is.s.u-tokyo.ac.jp/%7Etakeo/">Takeo Igarashi</A>
(<A HREF="http://www-ui.is.s.u-tokyo.ac.jp/">The University of
Tokyo</A>)</DD>
<DT><A HREF="http://graphics.eecs.umich.edu/proj/line-drawing-2007/">Line
Drawings Via Abstracted Shading</A></DT>
<DD><A HREF="http://www.eecs.umich.edu/%7Eyunjin/">Yunjin Lee</A>,
<A HREF="http://www.eecs.umich.edu/%7Esapo/">Lee Markosian</A>
(<A HREF="http://graphics.eecs.umich.edu/">University of
Michigan</A>), <A HREF="http://www.postech.ac.kr/%7Eleesy/">Seungyong Lee</A> (<A HREF="http://www.postech.ac.kr/department/cse">POSTECH</A>) <A HREF="http://www.cs.brown.edu/%7Ejfh/">John F. Hughes</A> (<A HREF="http://www.cs.brown.edu/">Brown University</A>)</DD>
<DT><A HREF="http://people.csail.mit.edu/tjudd/research.html">Apparent Ridges
for Line Drawing</A></DT>
<DD><A HREF="http://people.csail.mit.edu/tjudd/">Tilke Judd</A>,
<A HREF="http://graphics.csail.mit.edu/%7Efredo/">Frédo Durand</A>
(<A HREF="http://www.csail.mit.edu/">Massachusetts Institute of
Technology, Computer Science and Artificial Intelligence
Laboratory</A>) <A HREF="http://web.mit.edu/persci/people/adelson/index.html">Edward H.
Adelson</A> (<A HREF="http://web.mit.edu/bcs/">Massachusetts
Institute of Technology, Department of Brain and Cognitive
Science</A> and <A HREF="http://www.csail.mit.edu/">Computer
Science and Artificial Intelligence Laboratory</A>)</DD>
<DT><A HREF="http://graphics.eecs.umich.edu/proj/d2d-2007/">Dynamic
2D Patterns for Shading 3D Scenes</A></DT>
<DD><A HREF="http://www.breslav.com/">Simon Breslav</A> Karol
Szerszen, <A HREF="http://www.eecs.umich.edu/%7Esapo/">Lee
Markosian</A> (<A HREF="http://graphics.eecs.umich.edu/">University
of Michigan</A>), <A HREF="http://artis.imag.fr/Membres/Pascal.Barla/">Pascal Barla</A>,
<A HREF="http://artis.imag.fr/Membres/Joelle.Thollot/">Jo雔le
Thollot</A> (<A HREF="http://www.inpg.fr/">INRIA Grenoble
University</A>)</DD>
</DL>
<H2><A HREF="http://www.siggraph.org/s2007/attendees/papers/6.html">Point
Sets</A></H2>
<DL>
<DT><A HREF="http://www.cs.princeton.edu/gfx/pubs/Brown_2007_GNA/index.php">Global
Non-Rigid Alignment of 3-D Scans</A></DT>
<DD><A HREF="http://www.cs.princeton.edu/%7Ebjbrown/">Benedict J.
Brown</A>, <A HREF="http://www.cs.princeton.edu/%7Esmr/">Szymon
Rusinkiewicz</A> (<A HREF="http://www.cs.princeton.edu/">Princeton
University</A>)</DD>
<DT><A HREF="http://www.math.tau.ac.il/%7Elipmanya/">Parameterization-free
Projection for Geometry Reconstruction</A></DT>
<DD><A HREF="http://www.math.tau.ac.il/%7Elipmanya/">Yaron
Lipman</A>, <A HREF="http://www.cs.tau.ac.il/%7Edcor/">Daniel
Cohen-Or</A>, <A HREF="http://www.math.tau.ac.il/%7Elevin/">David
Levin</A> (<A HREF="http://www.tau.ac.il/">Tel Aviv
University</A>), Hillel Tal-Ezer (Academic College of Tel-Aviv
Yaffo)</DD>
<DT><A HREF="http://graphics.ethz.ch/%7Eggael/APSS_sig07.php">Algebraic Point
Set Surfaces</A></DT>
<DD><A HREF="http://graphics.ethz.ch/%7Eggael/">Ga雔
Guennebaud</A>, <A HREF="http://graphics.ethz.ch/%7Egrossm">Markus
Gross</A> (<A HREF="http://graphics.ethz.ch/">ETH Zürich</A>)</DD>
<DT><A HREF="http://www.ee.technion.ac.il/%7Eayellet/papers.html">Direct
Visibility of Point Sets</A></DT>
<DD><A HREF="http://www.technion.ac.il/%7Esagikatz/">Sagi Katz</A>,
<A HREF="http://www.ee.technion.ac.il/%7Eayellet/">Ayellet Tal</A>
(<A HREF="http://www.technion.ac.il/">Technion</A>), <A HREF="http://www.wisdom.weizmann.ac.il/%7Eronen/">Ronen Basri</A>
(<A HREF="http://www.wisdom.weizmann.ac.il/">The Weizmann Institute
of Science</A>)</DD>
</DL>
<H2><A HREF="http://www.siggraph.org/s2007/attendees/papers/7.html">Lighting</A></H2>
<DL>
<DT><A HREF="http://people.csail.mit.edu/jrk/lightspeed/">The
Lightspeed Automatic Interactive Lighting Preview System</A></DT>
<DD><A HREF="http://people.csail.mit.edu/jrk">Jonathan
Ragan-Kelley</A> (<A HREF="http://graphics.lcs.mit.edu/">Massachusetts Institute of
Technology</A>) Charlie Kilpatrick, Brian Smith (<A HREF="http://www.ilm.com/">Industrial Light &amp; Magic</A>), Doug Epps
(<A HREF="http://www.tippett.com/">Tippett Studio</A>), <A HREF="http://people.csail.mit.edu/green/">Paul Green</A> (<A HREF="http://graphics.lcs.mit.edu/">Massachusetts Institute of
Technology, Computer Science and Artificial Intelligence
Laboratory</A>), Christophe Hery (<A HREF="http://www.ilm.com/">Industrial Light &amp; Magic</A>), <A HREF="http://people.csail.mit.edu/fredo">Frédo Durand</A> (<A HREF="http://graphics.lcs.mit.edu/">Massachusetts Institute of
Technology, Computer Science and Artificial Intelligence
Laboratory</A>)</DD>
<DT><A HREF="http://www.cs.dartmouth.edu/%7Efabio/publications.html">Matrix
Row-Column Sampling for the Many-Light Problem</A></DT>
<DD><A HREF="http://www.cs.cornell.edu/%7Emhasan/">Milos Hasan</A>
(<A HREF="http://www.cs.cornell.edu/">Cornell University</A>),
<A HREF="http://www.cs.dartmouth.edu/%7Efabio/">Fabio Pellacini</A>
(<A HREF="http://www.cs.dartmouth.edu/">Dartmouth College</A>),
<A HREF="http://www.cs.cornell.edu/%7Ekb/">Kavita Bala</A>
(<A HREF="http://www.cs.cornell.edu/">Cornell University</A>)</DD>
<DT><A HREF="http://research.microsoft.com/users/kunzhou/">Interactive
Relighting with Dynamic BRDFs</A></DT>
<DD>Xin Sun (<A HREF="http://www.cad.zju.edu.cn/">Zhejiang
University</A>), <A HREF="http://research.microsoft.com/users/kunzhou/">Kun Zhou</A>, Yanyun
Chen, <A HREF="http://research.microsoft.com/%7Estevelin/">Stephen
Lin</A> (<A HREF="http://research.microsoft.com/aboutmsr/labs/asia/default.aspx">Microsoft
Research Asia</A>), <A HREF="http://www.cad.zju.edu.cn/home/jyshi/">Jiaoying Shi</A> (<A HREF="http://www.cad.zju.edu.cn/">Zhejiang University</A>), <A HREF="http://research.microsoft.com/users/bainguo/">Baining Guo</A>
(<A HREF="http://research.microsoft.com/aboutmsr/labs/asia/default.aspx">Microsoft
Research Asia</A>)</DD>
<DT><A HREF="http://www.cs.columbia.edu/cg/normalmap/">Frequency
Domain Normal Map Filtering</A></DT>
<DD><A HREF="http://www.cs.columbia.edu/%7Echarhan">Charles
Han</A>, <A HREF="http://www.cs.columbia.edu/%7Ebosun">Bo Sun</A>,
<A HREF="http://www.cs.columbia.edu/%7Eravir/">Ravi
Ramamoorthi</A>, <A HREF="http://www1.cs.columbia.edu/%7Eeitan/">Eitan Grinspun</A>
(<A HREF="http://www1.cs.columbia.edu/">Columbia
University</A>)</DD>
</DL>
<br/></DIV>
]]></description>
            <author>aear</author>
            <comments>http://blog.sina.com.cn/s/blog_4b3173c501000a9a.html#comment</comments>
            <pubDate>Wed, 08 Aug 2007 20:57:09 GMT+8</pubDate>
            <guid>http://blog.sina.com.cn/s/blog_4b3173c501000a9a.html</guid>
        </item>
        <item>
            <title>Siggraph 07 papers</title>
            <link>http://blog.sina.com.cn/s/blog_4b3173c501000a99.html</link>
            <description><![CDATA[<DIV>Here is the original link of the source:
http://trowley.org/sig2007.html . I copy it here just in case there
page is not available in some case.<br/>
<br/>
<br/>
<br/>
<A HREF="http://www.siggraph.org/s2007/attendees/papers/1.html">Image
Analysis &amp; Enhancement</A>
<DL>
<DT><A HREF="http://research.microsoft.com/%7Ejiansun/">Image
Deblurring with Blurred/Noisy Image Pairs</A></DT>
<DD>Lu Yuan (<A HREF="http://www.cs.ust.hk/">The Hong Kong
University of Science and Technology</A>), <A HREF="http://research.microsoft.com/%7Ejiansun/">Jian Sun</A> (<A HREF="http://research.microsoft.com/aboutmsr/labs/asia/default.aspx">Microsoft
Research Asia</A>), <A HREF="http://www.cs.ust.hk/faculty/quan/">Long Quan</A> (<A HREF="http://www.cs.ust.hk/">The Hong Kong University of Science and
Technology</A>), <A HREF="http://research.microsoft.com/users/hshum/">Heung-Yeung Shum</A>
(<A HREF="http://research.microsoft.com/aboutmsr/labs/asia/default.aspx">Microsoft
Research Asia</A>)</DD>
<DT><A HREF="http://johanneskopf.de/publications/solid/index.html">Solid
Texture Synthesis from 2D Exemplars</A></DT>
<DD><A HREF="http://johanneskopf.de/">Johannes Kopf</A> (<A HREF="http://www.inf.uni-konstanz.de/cgmi">Universit鋞 Konstanz</A>),
<A HREF="http://www.cse.ust.hk/%7Ecwfu/">Chi-Wing Fu</A> (<A HREF="http://www.cse.ust.hk/">The Hong Kong University of Science and
Technology</A>), <A HREF="http://www.math.tau.ac.il/%7Edcor/">Daniel Cohen-Or</A> (<A HREF="http://www.tau.ac.il/">Tel Aviv University</A>), <A HREF="http://graphics.uni-konstanz.de/mitarbeiter/deussen.php?language=english">
Oliver Deussen</A> (<A HREF="http://www.inf.uni-konstanz.de/cgmi">Universit鋞 Konstanz</A>),
<A HREF="http://www.cs.huji.ac.il/%7Edanix/">Dani Lischinski</A>
(<A HREF="http://www.cs.huji.ac.il/">The Hebrew University</A>),
<A HREF="http://www.cs.cuhk.edu.hk/%7Ettwong/">Tien-Tsin Wong</A>
(<A HREF="http://www.cse.ust.hk/">The Chinese University of Hong
Kong</A>)</DD>
<DT><A HREF="http://graphics.cs.cmu.edu/projects/photoclipart/">Photo Clip
Art</A></DT>
<DD><A HREF="http://www.ri.cmu.edu/people/lalonde_jean_francois.html">Jean-Fran鏾is
Lalonde</A>, <A HREF="http://www.cs.cmu.edu/%7Edhoiem/">Derek
Hoiem</A>, <A HREF="http://www.cs.cmu.edu/%7Eefros/">Alexei A.
Efros</A> (<A HREF="http://graphics.cs.cmu.edu/">Carnegie Mellon
University</A>) <A HREF="http://research.microsoft.com/%7Ecarrot/">Carsten Rother</A>,
<A HREF="http://johnwinn.org/">John Winn</A>, <A HREF="http://research.microsoft.com/%7Eantcrim/">Antonio Criminisi</A>
(<A HREF="http://research.microsoft.com/">Microsoft Research
Cambridge</A>)</DD>
<DT><A HREF="http://graphics.cs.cmu.edu/projects/scene-completion/">Scene
Completion Using Millions of Photographs</A></DT>
<DD><A HREF="http://www.cs.cmu.edu/%7Ejhhays/">James Hays</A>,
<A HREF="http://www.cs.cmu.edu/%7Eefros/">Alexei A. Efros</A>
(<A HREF="http://graphics.cs.cmu.edu/">Carnegie Mellon
University</A>)</DD>
</DL>
<H2><A HREF="http://www.siggraph.org/s2007/attendees/papers/2.html">Character
Animation I</A></H2>
<DL>
<DT><A HREF="http://grail.cs.washington.edu/projects/active-learn-controller/">Active
Learning for Real-Time Motion Controllers</A></DT>
<DD><A HREF="http://www.cs.washington.edu/homes/scooper/">Seth
Cooper</A> (<A HREF="http://grail.cs.washington.edu/">University of
Washington</A>), <A HREF="http://www.dgp.toronto.edu/%7Ehertzman/index.html">Aaron
Hertzmann</A> (<A HREF="http://www.dgp.toronto.edu/">University of
Toronto</A>), <A HREF="http://www.cs.washington.edu/homes/zoran/">Zoran Popovi</A></DD>
</DL>
</DIV>
]]></description>
            <author>aear</author>
            <comments>http://blog.sina.com.cn/s/blog_4b3173c501000a99.html#comment</comments>
            <pubDate>Wed, 08 Aug 2007 20:52:55 GMT+8</pubDate>
            <guid>http://blog.sina.com.cn/s/blog_4b3173c501000a99.html</guid>
        </item>
        <item>
            <title>终于搞定了!</title>
            <link>http://blog.sina.com.cn/s/blog_4b3173c5010009f4.html</link>
            <description><![CDATA[<DIV>
连续加了将近半年的班，最近总算全部搞定了。下面是Aear参与制作的新游戏
<P>
名称：&nbsp;Fantastic&nbsp;Four&nbsp;2:&nbsp;rise&nbsp;of&nbsp;the&nbsp;silver&nbsp;surfer&nbsp;（也就是传说中的神气4傻2）<br/>

类型：&nbsp;ACT<br/>
网站：&nbsp;<A HREF="http://www.2kgames.com/riseofthesilversurfer/" TARGET="_blank">http://www.2kgames.com/riseofthesilversurfer/</A><br/>
视频：&nbsp;<A HREF="http://www.youtube.com/watch?v=UDTEcguwaYI" TARGET="_blank">http://www.youtube.com/watch?v=UDTEcguwaYI</A><br/>
平台：&nbsp;XBOX&nbsp;XBOX360&nbsp;PS2&nbsp;PS3&nbsp;GameCube&nbsp;Wii&nbsp;.....&nbsp;(&nbsp;就是无PC&nbsp;)</P>
其
实就是个movie&nbsp;game,　个人感觉也就一般，就跟金庸小说改编的电视剧一样好不哪里去。整个游戏做了３年，２年引擎，一年的GamePlay。主
要是电影拍的太快了，为了能和电影同时发行没有太多的时候做内容。公司估计投了可能有2000W$吧，　个人感觉不卖个200W&nbsp;份copy是赚不回来
的。基本上亏本是很有可能了。不管怎么说，总算搞定了。大家有钱的捧个钱场，没钱的捧个BT，Emule场。。。。。对了，我只参与制作了
xbox360&nbsp;和&nbsp;ps3的版本，　所以其他的平台版本都不是很好，就不要玩了。<br/>

<br/>
下面是一些游戏画面：<br/>
<br/>
<br/>
<IMG SRC="file:///C:/DOCUME%7E1/zpeng/LOCALS%7E1/Temp/moz-screenshot.jpg" ALT=""><IMG SRC="file:///C:/DOCUME%7E1/zpeng/LOCALS%7E1/Temp/moz-screenshot-1.jpg" ALT=""><IMG STYLE="cursor: -moz-zoom-out; width: 500px; height: 281px;" ALT="http://www.2kgames.com/riseofthesilversurfer/screens/batcha/bata_scrn_9_xxx.jpg" SRC="http://www.2kgames.com/riseofthesilversurfer/screens/batcha/bata_scrn_9_xxx.jpg"><br/>

<IMG STYLE="cursor: -moz-zoom-in; width: 500px; height: 281px;" ALT="http://www.2kgames.com/riseofthesilversurfer/screens/batchb/batb_scrn_1_xxx.jpg" SRC="http://www.2kgames.com/riseofthesilversurfer/screens/batchb/batb_scrn_1_xxx.jpg" WIDTH="944"><br/>
<IMG STYLE="cursor: -moz-zoom-in; width: 500px; height: 281px;" ALT="http://www.2kgames.com/riseofthesilversurfer/screens/batchb/batb_scrn_8_xxx.jpg" SRC="http://www.2kgames.com/riseofthesilversurfer/screens/batchb/batb_scrn_8_xxx.jpg" WIDTH="944"><br/></DIV>
]]></description>
            <author>aear</author>
            <comments>http://blog.sina.com.cn/s/blog_4b3173c5010009f4.html#comment</comments>
            <pubDate>Thu, 14 Jun 2007 16:25:26 GMT+8</pubDate>
            <guid>http://blog.sina.com.cn/s/blog_4b3173c5010009f4.html</guid>
        </item>
        <item>
            <title>最新的开发画面</title>
            <link>http://blog.sina.com.cn/s/blog_4b3173c5010007w2.html</link>
            <description><![CDATA[不是很多，就5张，还是比较次的。。。。。大家将就下看吧。<br/>
<br/>
原图看这里：<br/>
http://www.1up.com/do/media?cId=3154980&amp;sec=IMAGES<br/>
<br/>
<br/>
<IMG STYLE="width: 520px; height: 292px;" SRC="http://media.1up.com/media?id=3212096&amp;type=lg" ALT="" BORDER="0" WIDTH="800"><br/>
<br/>
<IMG STYLE="width: 520px; height: 292px;" SRC="http://media.1up.com/media?id=3212095&amp;type=lg" ALT="" BORDER="0" WIDTH="800"><br/>
<br/>
<IMG STYLE="width: 520px; height: 292px;" SRC="http://media.1up.com/media?id=3212094&amp;type=lg" ALT="" BORDER="0" WIDTH="800"><br/>
<br/>
&nbsp; 
<DIV CLASS="subhead" STYLE="text-align: center; padding-top: 5px; padding-bottom: 5px;">
<A HREF="http://www.1up.com/do/gameOverview?cId=3154980" CLASS="subhead">Fantastic Four: Rise of the Silver Surfer</A> (Xbox
360)<br/></DIV>
<TABLE BORDER="0" CELLPADDING="2" CELLSPACING="0">
<TBODY>
<TR>
<TD>
<FORM NAME="Rating" METHOD="post" ACTION="/do/slideshow" ID="Rating"></FORM>
</TD>
<TD CLASS="bold" COLSPAN="2" STYLE="font-size: 10px;"><INPUT NAME="mediaId" VALUE="3212093" TYPE="hidden"></INPUT> <INPUT NAME="type" VALUE="SCREENSHOT" TYPE="hidden"></INPUT> <INPUT NAME="gameId" VALUE="3154980" TYPE="hidden"></INPUT> <INPUT NAME="pager.offset" VALUE="4" TYPE="hidden"></INPUT> <INPUT NAME="cId" VALUE="3154980" TYPE="hidden"></INPUT>
<INPUT NAME="Dispatch" VALUE="Save" TYPE="hidden"></INPUT> <INPUT NAME="mt" VALUE="0" TYPE="hidden"></INPUT> <INPUT NAME="tr" VALUE="y" TYPE="hidden"></INPUT> Rate It: <INPUT NAME="option" VALUE="1" TYPE="radio"></INPUT>1 <INPUT NAME="option" VALUE="2" TYPE="radio"></INPUT>2 <INPUT NAME="option" VALUE="3" TYPE="radio"></INPUT>3 <INPUT NAME="option" VALUE="4" TYPE="radio"></INPUT>4 <INPUT NAME="option" VALUE="5" TYPE="radio"></INPUT>5 <INPUT NAME="option" VALUE="6" TYPE="radio"></INPUT>6 <INPUT NAME="option" VALUE="7" TYPE="radio"></INPUT>7 <INPUT NAME="option" VALUE="8" TYPE="radio"></INPUT>8 <INPUT NAME="option" VALUE="9" TYPE="radio"></INPUT>9 <INPUT NAME="option" VALUE="10" TYPE="radio"></INPUT>10</TD>
</TR>
<TR>
<TD><SPAN CLASS="bold">Average Rating:</SPAN> 8.1</TD>
<TD CLASS="bold" STYLE="text-align: right;"><A HREF="http://www.1up.com/do/slideshow?pager.offset=2&amp;p=&amp;g=&amp;tr=&amp;mt=0&amp;cId=3154980" STYLE="text-decoration: none; cursor: default;"><SPAN STYLE="color: rgb(204, 0, 0);">Page:</SPAN></A> <A HREF="http://www.1up.com/do/slideshow?pager.offset=0&amp;p=&amp;g=&amp;tr=&amp;mt=0&amp;cId=3154980">
1</A> <A HREF="http://www.1up.com/do/slideshow?pager.offset=1&amp;p=&amp;g=&amp;tr=&amp;mt=0&amp;cId=3154980">
2</A> <A HREF="http://www.1up.com/do/slideshow?pager.offset=2&amp;p=&amp;g=&amp;tr=&amp;mt=0&amp;cId=3154980">
3</A> <SPAN STYLE="padding: 1px; background: rgb(204, 0, 0) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; color: rgb(255, 255, 255); margin-right: 3px;">
&nbsp;4</SPAN> <A HREF="http://www.1up.com/do/slideshow?pager.offset=4&amp;p=&amp;g=&amp;tr=&amp;mt=0&amp;cId=3154980">
5</A> <A HREF="http://www.1up.com/do/slideshow?pager.offset=2&amp;p=&amp;g=&amp;tr=&amp;mt=0&amp;cId=3154980">
&lt;</A> <A HREF="http://www.1up.com/do/slideshow?pager.offset=4&amp;p=&amp;g=&amp;tr=&amp;mt=0&amp;cId=3154980">
&gt;</A></TD>
</TR>
<TR>
<TD COLSPAN="2" CLASS="bold" STYLE="text-align: center;">
<IMG STYLE="width: 520px; height: 292px;" SRC="http://media.1up.com/media?id=3212093&amp;type=lg" ALT="" BORDER="0" WIDTH="800"></TD>
</TR>
</TBODY>
</TABLE>
<br/>
<IMG STYLE="width: 520px; height: 292px;" SRC="http://media.1up.com/media?id=3212092&amp;type=lg" ALT="" BORDER="0" WIDTH="800"><br/>
<br/>
]]></description>
            <author>aear</author>
            <comments>http://blog.sina.com.cn/s/blog_4b3173c5010007w2.html#comment</comments>
            <pubDate>Mon, 12 Mar 2007 17:35:54 GMT+8</pubDate>
            <guid>http://blog.sina.com.cn/s/blog_4b3173c5010007w2.html</guid>
        </item>
        <item>
            <title>我们新游戏的介绍，大家有空看看哦！</title>
            <link>http://blog.sina.com.cn/s/blog_4b3173c5010007qy.html</link>
            <description><![CDATA[<FONT FACE="Arial" SIZE="2"><SPAN STYLE="font-size: 10pt; font-family: Arial;">下面的文章转自：<br/>
<A TITLE="http://xbox360.ign.com/articles/767/767699p1.html" HREF="http://xbox360.ign.com/articles/767/767699p1.html">http://xbox360.ign.com/articles/767/767699p1.html</A><br/>

<br/>
<br/></SPAN></FONT>
<DIV ID="articleHeader">
<DIV CLASS="headline">NYCC 07: Fantastic Four: Rise of the Silver
Surfer First Look</DIV>
<DIV CLASS="subheadline">You get to battle Super Skrull? Say no
more.</DIV>
<DIV CLASS="byline">by <A HREF="http://xbox360.ign.com/email.html">Chris Carle</A></DIV>
</DIV>
<DIV ID="MediumRectangleAd">




<OBJECT CLASSID="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" CODEBASE="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab" HEIGHT="250" WIDTH="300"><PARAM NAME="movie" VALUE="http://spe.atdmt.com/ds/UFUFTTMNTTMT/tmnt_nycomiccon_300x250.swf?ver=1&amp;clickTag1=http://clk.atdmt.com/go/gnxxxtmt0010000003uft/direct;ai.22305488;ct.1/01&amp;clickTag=http://clk.atdmt.com/go/gnxxxtmt0010000003uft/direct;ai.22305488;ct.1/01"></PARAM>
<PARAM NAME="base" VALUE="http://spe.atdmt.com/ds/UFUFTTMNTTMT/"></PARAM>
<PARAM NAME="quality" VALUE="high"></PARAM>
<PARAM NAME="salign" VALUE="lt"></PARAM>
<PARAM NAME="loop" VALUE="true"></PARAM>
<PARAM NAME="wmode" VALUE="opaque"></PARAM>
<EMBED QUALITY="high" SALIGN="LT" LOOP="true" TYPE="application/x-shockwave-flash" PLUGINSPACE="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" BASE="http://spe.atdmt.com/ds/UFUFTTMNTTMT/" WMODE="opaque" SRC="http://spe.atdmt.com/ds/UFUFTTMNTTMT/tmnt_nycomiccon_300x250.swf?ver=1&amp;clickTag1=http://clk.atdmt.com/go/gnxxxtmt0010000003uft/direct;ai.22305488;ct.1/01&amp;clickTag=http://clk.atdmt.com/go/gnxxxtmt0010000003uft/direct;ai.22305488;ct.1/01" HEIGHT="250" WIDTH="300"></EMBED></OBJECT><NOSCRIPT><A HREF="http://clk.atdmt.com/UFT/go/gnxxxtmt0010000003uft/direct/01/bdbsixw,bcRllwibryqcR" TARGET="_blank"><IMG BORDER="0" SRC="http://view.atdmt.com/UFT/view/gnxxxtmt0010000003uft/direct/01/bdbsixw,bcRllwibryqcR"></A></NOSCRIPT><IMG SRC="http://de.ign.com/event.ng/Type=count&amp;ClientType=2&amp;AdID=53684&amp;FlightID=48130&amp;TargetID=6505&amp;EntityDefResetFlag=0&amp;Segments=1,255,264,348,1931,2092,2733,2747,2863,3494,3975,3982,4170,4178,4602,4603,4608,4611,4678,4682,4723,4834,4840,4917,4951,5015,5036,5091,5188,5194,5195,5650,5695,5718,5741,5971,6099,6101,6102,6382,6468,6486,6523,6573,6654,6657,6671,6701,7017,7054,7554,7681,7712,7790,7806,7807,7835,7849,7872,7887,7888,7898,7903,7911,7920,7940,7958,7965,7976,8009,8044,8060,8061,8078,8097,8116,8117,8118,8121,8143,8149&amp;Targets=7716,6556,9657,9234,7012,6781,8726,10064,9900,7995,9916,9827,6505,7413,9716,7938,8617,6507,9483,6619,5876,7085,7898,9635&amp;Values=25,30,46,50,60,72,83,90,100,110,150,155,225,227,236,268,469,653,703,806,1014,1187,1405,1481,1503,1591,1820,2522,2662,2682,2721,3152,3887,3932,4056,4295,4799,6612,6744&amp;RawValues=&amp;random=bdbsixw,bcRllwibryqcR" STYLE="position: absolute; visibility: hidden;" BORDER="0" HEIGHT="1" WIDTH="1"></DIV><P><STRONG>February 26, 2007</STRONG> - Today at New York
Comic-Con, we were treated to a special sneak peek of the newest
Marvel game, Fantastic Four: Rise of the Silver Surfer. Developed
by a brand new team at Visual Concepts and based on the upcoming
movie sequel, the game features realistic models patterned after
the actual actors and actresses from the film. If you have ever
dreamed of playing with Jessica Alba or Chris Evans, here is your
chance.<br/>
<br/>
Although versions of the game are being developed for the Wii, PS2
and DS, the Xbox 360 game is a much different experience. The game
is the same in that it is a team-based superhero brawler with an
emphasis on action and cooperative play.<br/>
<br/>
The game is set in the world of the upcoming film, but also draws
from the pages of the comics for some extra story elements. For
instance, the early stages of the game take the team to an alien
Skrull mine, which we were assured is definitely not a scene in the
film.<br/>
<br/>
Unfolding over six massive levels, the game features plenty of
large-scale combat and emphasizes interaction between characters.
Most intriguing are the fusion attacks, which take the normal
character abilities and mesh them into more powerful team moves
with the ability to deal massive damage.<br/>
<br/>
We saw a couple of these in action, and can't wait to check out
even more. In one, Sue Storm makes a ball of force energy which
Johnny pumps full of fireballs. The resulting ball of flame is a
powerful attack, indeed. In another, Mr. Fantastic stretches into
slingshot formation and pile-drives The Thing into the turf for an
extra-heavy slam attack.<br/>
<br/>
In addition to puzzle-solving elements and straight-up combat, a
couple of other wrinkles have been added to mix it up. In one of
the levels, Johnny Storm flames on and blazes forward, and the
action switches to an on-rails shooter as he careens forward
through the level.<br/>
<br/>
Who are the baddies? The Skrulls, longtime alien foes of the
Fantastic Four, are common fodder, and a jumbo-sized Super Skrull
is even a boss in the game. Super Skrull, for those unaware of the
comic, is an oversized alien badass who has developed the ability
to use some of the 4's powers…and his rocky, Thing-like arm is
perfect proof. As a boss, he looks large and menacing, and the
model is amazing. Other villains include old schooler Red Ghost,
and of course, Dr. Doom.<br/>
<br/>
Overall the game looks astounding, with great character models,
excellent lighting, and cool animations. This ain't your mama's
Fantastic Four game! We'll have more on all versions of <I>Rise</I>
in the coming months, so keep your browsers pointed to IGN for all
of the breaking developments.</P>
<br/>
]]></description>
            <author>aear</author>
            <category>游戏业界咨询</category>
            <comments>http://blog.sina.com.cn/s/blog_4b3173c5010007qy.html#comment</comments>
            <pubDate>Wed, 28 Feb 2007 16:32:36 GMT+8</pubDate>
            <guid>http://blog.sina.com.cn/s/blog_4b3173c5010007qy.html</guid>
        </item>
        <item>
            <title>Aear的参与制作的新游戏哦！</title>
            <link>http://blog.sina.com.cn/s/blog_4b3173c5010007od.html</link>
            <description><![CDATA[Aear参与制作的新游戏，
大约6月份就发布哦！不过这个Trailer做得很次啦，时间赶的太紧。相信Aear，
游戏要比这个好100倍。因为公司的封口令，Aear不能发布任何未经许可的信息。请大家谅解。<br/>

<br/>
更高分辨率的视频到这里看：<br/>
<br/>
http://www.gametrailers.com/gamepage.php?id=4444<br/>
<br/>
<OBJECT HEIGHT="461" WIDTH="474"><EMBED TYPE="application/x-shockwave-flash" SRC="http://v.blog.sina.com.cn/b/vblog_player.swf?vid=1329779&amp;uid=1261532101" ID="articlevblog" NAME="articlevblog" QUALITY="high" ALLOWSCRIPTACCESS="always" WMODE="transparent" FLASHVARS="url=http://v.blog.sina.com.cn/b/vblog_player.swf?vid=1329779&amp;uid=1261532101" HEIGHT="461" WIDTH="474"></EMBED></OBJECT><br/>
<br/>
（上面的视频转自www.gametrailers.com）<br/>
]]></description>
            <author>aear</author>
            <comments>http://blog.sina.com.cn/s/blog_4b3173c5010007od.html#comment</comments>
            <pubDate>Fri, 23 Feb 2007 22:24:53 GMT+8</pubDate>
            <guid>http://blog.sina.com.cn/s/blog_4b3173c5010007od.html</guid>
        </item>
        <item>
            <title>匿名namespace的一种应用</title>
            <link>http://blog.sina.com.cn/s/blog_4b3173c5010007dl.html</link>
            <description><![CDATA[<P>在库里有class A和class B，Class A有个Static Member
functions用来对Class A进行初始化。在 Class B中掉用Class
A，所以要保证在使用Class B的时候 Class
A已经正确初始化了。那么可以在写程序的时候显式的对A进行初始化，但是这种方式太累赘，容易犯错误，另一种方式如下：</P>
<P>&nbsp;&nbsp;&nbsp; // class
A header file</P>
<P>&nbsp;&nbsp;&nbsp; class
A<br/>
&nbsp;&nbsp;&nbsp; {<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.... // Class A member and interface</P>
<P>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// Helper class<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
class AInitHelper<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
{<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
static int _initRefCount;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
AInitHelper() {<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if( _initRefCount++ == 0 ) ... // Class A init here<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
};</P>
<P>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;~AInitHelper()
{ ... // Deinit here };</P>
<P>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
};</P>
<P>&nbsp;&nbsp;&nbsp; };</P>
<P>namespace {</P>
<P>A::AInitHelper __init;</P>
<P>};</P>
<P>在class B 的cpp 文件中 #include "a header" 这个时候由于是unnamed
namespace，所以会单独建立一个AInitHelper __init的拷贝。</P>
<P>然后 int AInitHelper::_initRefCount = 0;</P>
<P>这个时候由于__init是全局，那么必然先于class
B进行初始化。由于在unnamed namespace里，所以即使其他 file include
A的header,也会有不同的__init，所以可以保证每个include
A的module，都会进行_init的初始化，从而检查class
A是不是已经初始化了。保证正确的初始化顺序。这是STL中解决模块之间初试化依赖关系的标准方案.</P>
]]></description>
            <author>aear</author>
            <category>程序设计随笔</category>
            <comments>http://blog.sina.com.cn/s/blog_4b3173c5010007dl.html#comment</comments>
            <pubDate>Mon, 29 Jan 2007 20:37:24 GMT+8</pubDate>
            <guid>http://blog.sina.com.cn/s/blog_4b3173c5010007dl.html</guid>
        </item>
        <item>
            <title>浅谈网络游戏的数据传输处理和防火墙穿透</title>
            <link>http://blog.sina.com.cn/s/blog_4b3173c5010007dj.html</link>
            <description><![CDATA[<P>
一般来说，client和server之间的数据交换，分为几个优先级，大部分情况下是下面3种：<br/>

1.&nbsp;不可以丢失，但是不要求速度。<br/>
2.&nbsp;不可以丢失，但是要求速度,确并不是非常严格。<br/>

3.&nbsp;可以丢失，但是要求速度</P>
<P>对
于1来说，最直接的例子就是聊天信息，动态的地图信息。这些数据不是time-critical的，所以应该使用TCP连接。&nbsp;在大多数情况下，有专门的
&nbsp;voice/chat&nbsp;server和map&nbsp;server,client到每个server有个TCP连接。一个client有多少个连接根据需要决
定。同时有2-3个连接并没有多大开销。当然，如果开销很大，就是程序设计的问题了。其实你想想开BT的时候同时有4,50个连接，你用其他程序的速度并
没有慢多少。</P>
<P>
对于2来说，比较显著的例子是战斗信息，动作序列。&nbsp;比如一个人玩游戏，用鼠标点了下地图上的一个坐标，那么人物向这个坐标
前进。这个信息从server转发到其他的client,当然越快越好，如果client没收到，就要重发，否则client就看不到这个动作。如果你玩
过wow的盗贼，就会发现在网络卡的时候，经常先偷袭，按下键盘以后要等一会才看到攻击动作，就是这个原理。当然这里数据需要经过server的处理，每
次打包多个client的动作，和顺序，然后发送。需要复杂的server端逻辑处理。这种应该使用UDP，同时对所有的UDP包编号（用来防止2次处
理），使用slide&nbsp;window类似的协议进行重传。</P>
<P>
对于3来说，就是位置信息。&nbsp;位置信息可以丢失，但是由于这种信息更新的最频繁，
所以即使丢失其中一个，也可以根据&nbsp;dead&nbsp;reckoning&nbsp;算法进行位置预测和修正。&nbsp;dead&nbsp;reckoning算法有很多变种，适合多类情
况。&nbsp;比如你见过wow里，如果一个人掉线，但是一直往前不停的跑，那多半就是算法进行的预测。偶尔你会发现网络卡的时候，刚刚走到一个地方就退回到原来
的位置，就是因为你的动作数据包(2里的)没发送出去，导致update&nbsp;world&nbsp;position的时候，算法进行位置修正的结果。这类数据应该使
用UDP.</P>
<P>
需要说明的是&nbsp;UDP和TCP无明显分界。&nbsp;TCP相比UDP，有3个主要缺点，1是slow&nbsp;start,&nbsp;2是
throughput&nbsp;jitter,&nbsp;3是insistence&nbsp;on&nbsp;reliability(相对的，不时绝对缺点).&nbsp;在数据传送量比较小,网络
状况比较稳定的情况下，使用TCP和UDP无大分别。</P>
<P><br/>
对于防火墙穿透，如果你是做client的，不需要关心这个问题，因为你往Server发数据，建立连接，都不会受到防火墙的影响。不过server端对于放火墙可以有几种实现方式：</P>
<P>
1.&nbsp;最差的方式是client发送SYN包给服务器，在防火墙或网关上建立NAT地址，然后&nbsp;Server之需要取得这个NAT地址，把所有的数据包都封装成SYN-ACK包，发给client就行拉。这样做比较省事。但是无法穿透&nbsp;stateful&nbsp;firewall</P>
<P>
2.&nbsp;是比较好的方式。&nbsp;不过需要先建立TCP连接，然后对server发送正常的UDP包。大部分的NAT网关会为UDP专门建立个NAT地址，那么通过这个地址，server就可以发UDP包了。但是并不是所有的firewall都会为UDP建立单独的NAT地址。</P>
<P>3.&nbsp;
是最好的方式，由于防火墙不会阻止内部网发起的TCP连接，所以TCP进行数据传输没有任何问题。对于Server/Client来说，只要使用
Raw&nbsp;Socket模拟TCP协议，但是这个模拟的TCP协议使用UDP的本质，没有slide&nbsp;window,&nbsp;没有
congestion&nbsp;control,&nbsp;没有flow&nbsp;control等等，这种实现最麻烦，但是几乎能处理所有的防火墙。</P>
<P>4.&nbsp;其实没
有4，不过实在想提下这种最强技术.&nbsp;就是所有的Server到Client的数据包都可以是ICMP&nbsp;echo&nbsp;reply&nbsp;message.&nbsp;由于种
种原因，firewall不太可能禁止ICMP&nbsp;echo,所以这类消息也是很容易传送到client,但是。。。。。。。。Client如果有
IDS&nbsp;system,很容易把你的sever归类到入侵扫描的范围。所以不用最好。</P>
如果你们不是采用第3种方式，并且你只写client,那么防火墙跟你就没有什么关系。都是server的事。
]]></description>
            <author>aear</author>
            <category>程序设计随笔</category>
            <comments>http://blog.sina.com.cn/s/blog_4b3173c5010007dj.html#comment</comments>
            <pubDate>Mon, 29 Jan 2007 20:29:02 GMT+8</pubDate>
            <guid>http://blog.sina.com.cn/s/blog_4b3173c5010007dj.html</guid>
        </item>
        <item>
            <title>最近忙呀！</title>
            <link>http://blog.sina.com.cn/s/blog_4b3173c501000717.html</link>
            <description><![CDATA[每星期工作60小时。。。。。。。不过游戏马上就Alpha了。<br/>
<br/>
Aear估计最近没时间写什么东西了，不过还是欢迎大家来这里玩。<br/>
<br/>
祝大家过的开心！<br/>
]]></description>
            <author>aear</author>
            <category>胡砍乱砍</category>
            <comments>http://blog.sina.com.cn/s/blog_4b3173c501000717.html#comment</comments>
            <pubDate>Mon, 08 Jan 2007 18:28:40 GMT+8</pubDate>
            <guid>http://blog.sina.com.cn/s/blog_4b3173c501000717.html</guid>
        </item>
        <item>
            <title>C++基本功和 Design Pattern系列(11) Exception</title>
            <link>http://blog.sina.com.cn/s/blog_4b3173c5010006nt.html</link>
            <description><![CDATA[<SPAN><SPAN>======================================================<br/>

大家请把我的文章当参考，详细内容 还请参照 权威书<br/>
籍如果文中有错误和遗漏， 请指出，Aear会尽力更正,<br/>
谢谢！<br/>
Aear Blog: <A HREF="../../../u/1261532101">http://blog.sina.com.cn/u/1261532101</A><br/>

======================================================<br/>
<br/>
说到Exception就要说下相关的Error Handling. 比较常用的Error
Handling一般有如下几种类方式：<br/>
&nbsp;&nbsp;&nbsp; 1. Return
Value<br/>
&nbsp;&nbsp;&nbsp; 2.
Assert<br/>
&nbsp;&nbsp;&nbsp; 3. Debug
Output<br/>
&nbsp;&nbsp;&nbsp; 4.
Exception<br/>
<br/>
相对于其他三种错误处理方式，
Exception更加容易使用，而且使得错误代码相对集中，同时使得独立函数库的开发更加方便。
同样，对于C++来说， Exception提供了Class的Constructor 和 Operator =
错误处理机制，因为这两者都不是能够通过return
value进行报错的。<br/>
<br/>
但是就游戏开发来说，
Exception最大的缺点是内存和CPU的开销。当然，不是说游戏的代码中不应该使用Exception。
Aear见过用Exception的游戏代码，也有完全不用Exception的代码。因为对游戏来说，应该在运行过程中保持自身状态的正确性，不应该产生任何的无法处理的Exception。
而所有能够自己处理的错误情况，都是能够通过Return Value 来解决的。
唯一可能产生Exception的地方，就是系统资源，比如磁盘文件，网络等。不过大部分系统掉用都提供非Exception的错误处理。不过程序开发各不相同，用不用Exception可能还是需要大家自行决定。<br/>

<br/>
<SPAN STYLE="font-weight: bold;">Aear个人观点</SPAN>是能不用Exception，就不用Exception,</SPAN></SPAN>但是应该用Exception的时候，一定不要省。比如constructor里。<br/>

<SPAN><SPAN><br/></SPAN></SPAN> <SPAN><SPAN>============
Exception的用法</SPAN></SPAN> <SPAN><SPAN>============<br/>
<br/>
要使用Exception, 要么用系统的Exception的类，要么定义自己的类。
在定义自己类的时候，可以继承STD里边的Exception类，也可以创建自己新的类。比如：<br/>

<br/>
class ExceptionBase{<br/>
&nbsp;&nbsp;&nbsp; ...<br/>
};<br/>
<br/></SPAN></SPAN><SPAN><SPAN>class ExceptionDerived : public
ExceptionBase{<br/>
&nbsp;&nbsp;&nbsp; ...<br/>
};<br/>
<br/>
需要注意的是，通常定义自己的Exception类的时候，都要有一个公共的Base
Exception Class,
这样能够保证写代码的时候catch所有的你自定义的Exception,比如：<br/>
<br/>
try {<br/>
&nbsp;&nbsp;&nbsp; ...<br/>
}catch( ExceptionDerived &amp; e ) {<br/>
&nbsp;&nbsp;&nbsp; ...<br/>
}catch( ExceptionBase &amp; e ) {<br/>
<br/>
&nbsp;&nbsp;&nbsp; // Catch
其他的Exception， 这样的设计即使今后添加新的Exception,只要<br/>
&nbsp;&nbsp;&nbsp; //
是从ExceptionBase继承来的，都会被catch到。<br/>
<br/>
}catch( ... ) {<br/>
<br/>
&nbsp;&nbsp;&nbsp; //
这里最好再加上
catch(...)来catch所有的exception，防止有未catch的&nbsp;&nbsp;&nbsp;
// exception. 因为如果有unexpected exception,
C++的缺省动作是直接<br/>
&nbsp;&nbsp;&nbsp; //
终止程序的运行。<br/>
<br/>
};<br/>
<br/></SPAN></SPAN> <SPAN><SPAN>============ Exception in
Constructor</SPAN></SPAN>
<SPAN><SPAN>============</SPAN></SPAN><br/>
<SPAN><SPAN><br/>
</SPAN></SPAN><SPAN><SPAN>如果一个Constructor产生exception而且没有被程序catch到的话，那么这个object的创建就会失败,
比如：<br/>
<br/>
class MemoryBlock {<br/>
private:<br/>
&nbsp;&nbsp;&nbsp; void *
_pMem;<br/>
public:<br/>
&nbsp;&nbsp;&nbsp; MemoryBlock
( UINT32 size )<br/>
&nbsp;&nbsp;&nbsp; {<br/>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; _pMem = new char[size];<br/>
&nbsp;&nbsp;&nbsp; };<br/>
&nbsp;&nbsp;&nbsp; ....<br/>
};<br/>
<br/>
MemoryBlock myMemory(100000000000000000000000000);<br/>
<br/>
如果new在分配内存的过程中throw一个Exception ,通常是 bad_alloc，
那么myMemory的创建就会失败，以后任何对
myMemory的成员访问，都是非法的，会导致程序的崩溃。<br/>
<br/>
让我们看看另一中写法：<br/>
<br/></SPAN></SPAN><SPAN><SPAN>class MemoryBlock {<br/>
private:<br/>
&nbsp;&nbsp;&nbsp; void *
_pMem;<br/>
public:<br/>
&nbsp;&nbsp;&nbsp; MemoryBlock
( UINT32 size ) :<br/>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; _pMem(new char[size])<br/>
&nbsp;&nbsp;&nbsp; { };<br/>
&nbsp;&nbsp;&nbsp; ....<br/>
};<br/>
上面也是合法的，不过会产生同样的问题。但是区别在于如果在代码中catch到exception，那么第一种写法，能够保证object被创建，而第二种写法不能。比如：<br/>

<br/>
&nbsp;&nbsp;&nbsp; //
MemoryBlock
能够被创建<br/></SPAN></SPAN><SPAN><SPAN>&nbsp;&nbsp;&nbsp;
MemoryBlock ( UINT32 size )<br/>
&nbsp;&nbsp;&nbsp; {<br/>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; try {<br/>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; _pMem = new char[size];<br/>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; } catch(...) {}<br/>
&nbsp;&nbsp;&nbsp;
};</SPAN></SPAN><br/>
<br/>
&nbsp;&nbsp;&nbsp; //
MemoryBlock 创建失败<br/>
<SPAN><SPAN>&nbsp;&nbsp;&nbsp;
MemoryBlock ( UINT32 size )<br/>
&nbsp;&nbsp;&nbsp; try<br/>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;</SPAN></SPAN>
<SPAN><SPAN>:</SPAN></SPAN> <SPAN><SPAN>_pMem(new char[size])<br/>
&nbsp;&nbsp;&nbsp; { }
catch(...) {};</SPAN></SPAN><br/>
<SPAN><SPAN><br/>
<br/></SPAN></SPAN><SPAN><SPAN>============ Exception in
Destructor</SPAN></SPAN> <SPAN><SPAN>============<br/>
<br/>
其实对于Destructor来说就一句话，不能在Destructor中Throw Exception。
原因很简单，因为通常Destructor要么在Delete
Object中掉用，要么在已经Throw了Exception的时候，由系统掉用。如果在Throw
Exception的情况下再Throw
Exception的话，那么程序就会强制终止。<br/>
<br/></SPAN></SPAN><SPAN><SPAN>============ Exception in
Operator</SPAN></SPAN> <SPAN><SPAN>============<br/>
<br/>
这个是比较麻烦的，通常的Exception的处理有好几个级别， Basic,
Strong, Nofail.我们这里只说下Strong Exception Safety。
下面是个例子:<br/>
<br/></SPAN></SPAN><SPAN><SPAN>class X {<br/>
&nbsp;&nbsp;&nbsp; ...<br/>
private:<br/>
&nbsp;&nbsp;&nbsp; void *
_pMem1;<br/>
&nbsp;&nbsp;&nbsp; UINT32
_pMemSize1;<br/></SPAN></SPAN><SPAN><SPAN>&nbsp;&nbsp;&nbsp;
void *
_pMem2;<br/></SPAN></SPAN><SPAN><SPAN>&nbsp;&nbsp;&nbsp;
UINT32 _pMemSize2;<br/>
<br/></SPAN></SPAN><SPAN><SPAN>public:<br/>
&nbsp;&nbsp;&nbsp; X&amp;
operator = ( const X &amp; xo )<br/>
&nbsp;&nbsp;&nbsp; {<br/>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; if( _pMem1 )
delete
_pMem1;<br/></SPAN></SPAN><SPAN><SPAN>&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; if( _pMem2 )
delete _pMem2;<br/>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;
&nbsp;<br/></SPAN></SPAN>
<SPAN><SPAN>&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; _pMem1 = new
char[xo._pMemSize1];<br/></SPAN></SPAN>
<SPAN><SPAN>&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; _pMem2 = new
char[xo._pMemSize1];<br/>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;
...<br/></SPAN></SPAN><SPAN><SPAN>&nbsp;&nbsp;&nbsp;
};<br/></SPAN></SPAN><SPAN><SPAN>};<br/>
<br/>
这里如果</SPAN></SPAN> <SPAN><SPAN>_pMem2 = new
char[xo._pMemSize1]; Throw一个Exception，那么X只是被Copy了一半。
状态是不完整的。但是原来在pMem1&amp;2中的数据已经消失了。如果是Strong
Exception Safety,那么要求如果throw
excpetion，那么class的数据应该恢复在之前的状态，比如经典的exception
safe operator =
如下：<br/></SPAN></SPAN><SPAN><SPAN><br/></SPAN></SPAN><SPAN><SPAN>&nbsp;&nbsp;&nbsp;
X&amp; operator = ( const X &amp; xo )<br/>
&nbsp;&nbsp;&nbsp; {<br/>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; X
temp(xo);<br/>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; swap( *this,
temp );<br/>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; return
*this;<br/></SPAN></SPAN><SPAN><SPAN>&nbsp;&nbsp;&nbsp;
};<br/>
<br/>
swap是交换*this 和
Temp的所有数据。通常我们能够保证这个过程没有任何exception的产生。因此即使
temp(xo) throw一个exception，
也不会影响当前类的任何状态变化。<br/></SPAN></SPAN><SPAN><SPAN><br/>
</SPAN></SPAN><SPAN><SPAN><br/></SPAN></SPAN><SPAN><SPAN>============
RAII</SPAN></SPAN> <SPAN><SPAN>============<br/>
<br/>
最后说一种不使用Exception而能保证没有Resource Leakage的技术。那就是
Resource Aquisition Is Initialization ( RAII ).
其原理很简单，就是C++标准保证一个被成功创建的 Object，
无论任何情况下（即使是在Throw exception ）， 它的
Destructor都会被掉用。 因此，我们可以用一个object 的constructor
来获取资源，用Destructor来释放资源。下面举个最简单的应用，thread 的
asynchronization:<br/>
<br/>
class CriticalSection {<br/>
public:<br/>
&nbsp;&nbsp;&nbsp;
CriticalSection( CRTICIAL_SECTION *pCs ) :<br/>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; _pCs(pCS)<br/>
&nbsp;&nbsp;&nbsp; {
EnterCriticalSection( _pCS ) };<br/>
<br/>
</SPAN></SPAN><SPAN><SPAN>&nbsp;&nbsp;&nbsp;
~CriticalSection( )<br/>
&nbsp;&nbsp;&nbsp; {
LeaveCriticalSection( _pCS ) };</SPAN></SPAN><br/>
<SPAN><SPAN>private:<br/>
&nbsp;&nbsp;&nbsp;</SPAN></SPAN>
<SPAN><SPAN>CRTICIAL_SECTION * _pCs;</SPAN></SPAN><br/>
<SPAN><SPAN>};<br/></SPAN></SPAN><SPAN><SPAN><br/>
通常我们使用Critical Section的时候，用下列方式：<br/>
<br/>
void threadXX(</SPAN></SPAN> <SPAN><SPAN>CRTICIAL_SECTION *
pCs</SPAN></SPAN><SPAN><SPAN>)<br/>
{<br/>
&nbsp;&nbsp;&nbsp;</SPAN></SPAN>
<SPAN><SPAN>EnterCriticalSection( pCS );<br/>
<br/>
&nbsp;&nbsp;&nbsp; void * pTemp
= new char[100000000];<br/>
<br/>
</SPAN></SPAN><SPAN><SPAN>&nbsp;&nbsp;&nbsp;</SPAN></SPAN>
<SPAN><SPAN>LeaveCriticalSection( pCS );</SPAN></SPAN><br/>
<SPAN><SPAN>}<br/>
<br/>
问题是如果</SPAN></SPAN>
<SPAN><SPAN>&nbsp;&nbsp;&nbsp;
void * pTemp = new char[100000000]; Throw一个
bad_alloc,那么</SPAN></SPAN> <SPAN><SPAN>LeaveCriticalSection( pCS
);就不会被掉用而直接返回，很容易导致死锁。类似的代码在游戏服务器端的设计是很常见的，正确的做法是使用上面定义的类：<br/>

<br/></SPAN></SPAN> <SPAN><SPAN>void threadXX(</SPAN></SPAN>
<SPAN><SPAN>CRTICIAL_SECTION * pCs</SPAN></SPAN><SPAN><SPAN>)<br/>
{<br/>
&nbsp;&nbsp;&nbsp;</SPAN></SPAN>
<SPAN><SPAN>CriticalSection</SPAN></SPAN> <SPAN><SPAN>temp( pCS
);<br/>
<br/>
&nbsp;&nbsp;&nbsp; void * pTemp
= new char[100000000];<br/></SPAN></SPAN><SPAN><SPAN>}<br/>
<br/>
由于即使throw exception，
C++保证temp的destructor一定会被调用。因此不会产生死锁的情况。<br/>
<br/></SPAN></SPAN><SPAN><SPAN>============ 其他</SPAN></SPAN>
<SPAN><SPAN>============</SPAN></SPAN><br/>
<SPAN><SPAN><br/>
比如下面的代码是很容易产生问题的：<br/>
&nbsp;&nbsp;&nbsp; function(
new char[100], new char[300] );<br/>
如果new char[300]throw exception，那么 new
char[100]很有可能就不会被释放。<br/>
<br/>
推荐使用auto_ptr或者boost中的Shared_ptr，特别是在class
的initialization list 中， 比如下列做法不使用catch
exception也不会产生内存泄露：<br/>
<br/>
class X{<br/>
&nbsp;&nbsp;&nbsp; X() :<br/>
&nbsp;&nbsp;&nbsp; _ptr1(new
XXX()),<br/></SPAN></SPAN><SPAN><SPAN>&nbsp;&nbsp;&nbsp;
_ptr2(new XXX())<br/>
&nbsp;&nbsp;&nbsp; {};<br/>
<br/>
private:<br/></SPAN></SPAN><SPAN><SPAN>&nbsp;&nbsp;&nbsp;
auto_ptr&lt;void *&gt;
_ptr1;<br/></SPAN></SPAN><SPAN><SPAN>&nbsp;&nbsp;&nbsp;
auto_ptr&lt;void *&gt; _ptr2;</SPAN></SPAN><br/>
<SPAN><SPAN>}<br/>
<br/>
Destructor中不需要catch
exception，因为destructor主要是调用其他的destructor，没有任何的destructor会throw
exception的，所以没必要catch.<br/>
<br/>
这次就说这么多，大家过的开心，下次见！<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/></SPAN></SPAN>
]]></description>
            <author>aear</author>
            <category>程序设计随笔</category>
            <comments>http://blog.sina.com.cn/s/blog_4b3173c5010006nt.html#comment</comments>
            <pubDate>Sun, 24 Dec 2006 17:28:20 GMT+8</pubDate>
            <guid>http://blog.sina.com.cn/s/blog_4b3173c5010006nt.html</guid>
        </item>
        <item>
            <title>C++基本功和 Design Pattern系列(10) Base Class Design</title>
            <link>http://blog.sina.com.cn/s/blog_4b3173c5010006jz.html</link>
            <description><![CDATA[<SPAN>======================================================<br/>
大家请把我的文章当参考，详细内容 还请参照 权威书<br/>
籍如果文中有错误和遗漏， 请指出，Aear会尽力更正,<br/>
谢谢！<br/>
Aear Blog: <A HREF="../../../u/1261532101">http://blog.sina.com.cn/u/1261532101</A><br/>

======================================================<br/>
<br/>
在OO中Base
Class最多的应用有2种方式，第一种是interface,也就是基类是个abstract
class, 最典型的例子是Factory Design Pattern. 第二种方式是Base Class
提供一种机制，然后提供几个Virtual
Function,允许使用者对这个类进行重载，从而达到“配置”
(customization)的目的。 其典型的代表是
MFC，通过继承提供消息传递机制的CWin类的OnPaint等函数，实现更多更强大的功能。<br/>

<br/>
这次就主要讲讲这两种类的设计。<br/>
<br/></SPAN><SPAN>============== Abstract Interface</SPAN>
<SPAN>==============<br/>
<br/>
对于Interface Class来说，基类一定是个Abstract Class.
其含义是一类物体的抽象概念。比如下面一个例子：<br/>
<br/>
class Gun {<br/>
public:<br/></SPAN><SPAN>&nbsp;&nbsp;&nbsp;
void Shoot &nbsp;&nbsp; (void) =
0;<br/></SPAN><SPAN>&nbsp;&nbsp;&nbsp;
...<br/></SPAN><SPAN>};<br/>
<br/>
Gun是所有人的抽象概念，具体的实现起来可以为Eagle, AK47, MD5
等等。所有的枪都有射击的功能，但是他们具体射击的方式不同，
因此只要提供一个Shoot的Interface,内容由派生类来实现。<br/>
<br/>
在具体设计 Interface Class的时候，有几个需要注意的内容：<br/>
<br/>
1. 最好只提供 pure virtual function。 这样做能够使Interface
Class更加单一，更加纯净，更加漂亮，更容易维护。Interface就只能是Interface，不应该提供其他任何东西。因为Interface仅仅是一个描述。<br/>

<br/>
2. 最好没有data member。Data Member往往会限制 Interface
Class的灵活性。而且有Data Member，一般就要有Accessor
Function,使得Interface Class不再纯洁。。。。。。<br/>
<br/>
3. 如果不得不用Data
Member,那么一定要提供带参数的Constructor,并且把确省的Constructor设成private.例如：<br/>

<br/>
class</SPAN> <SPAN>InterfaceClass</SPAN> <SPAN>{<br/>
private:<br/>
&nbsp;&nbsp;&nbsp;
UINT32&nbsp;&nbsp; _dataMember;<br/>
public:<br/>
&nbsp;&nbsp;&nbsp;
Base()&nbsp;&nbsp;
&nbsp;&nbsp; {};<br/>
&nbsp;&nbsp;&nbsp; ...// other
interface &nbsp;&nbsp;
&nbsp;&nbsp;<br/>
};<br/>
<br/>
class Derived : public</SPAN> <SPAN>InterfaceClass
{<br/></SPAN><SPAN>public:<br/>
&nbsp;&nbsp;&nbsp;
Derived()&nbsp;&nbsp;&nbsp; {};
&nbsp;<br/>
};<br/></SPAN><SPAN><br/>
上面代码中的Derived
Constructor是合法的，但是由于写代码的人粗心大意，忘记给_dataMember附初值，很容易造成程序的崩溃。所以，对于有data
member的Base Class 正确的写法是：<br/>
<br/>
class</SPAN> <SPAN>InterfaceClass</SPAN> <SPAN>{<br/>
private:<br/>
&nbsp;&nbsp;&nbsp;
UINT32&nbsp;&nbsp; _dataMember;<br/>
public:<br/>
&nbsp;&nbsp;&nbsp; Base( UINT32
data ) : _dataMember(data) {};<br/>
&nbsp;&nbsp;&nbsp; ...//other
interface<br/>
};<br/>
<br/>
4. 在大部分情况下，Base Class的Destructor 一般要放到public
里边，并且要有实现，也就是说至少是空的实现，"{ }"，即使是pure
virtual destructor，这个
{}也是不能少的。因为还很多情况下，都需要通过Interface
调用Destructor来释放object. 如：<br/>
<br/>
class InterfaceClass {<br/>
public:<br/>
&nbsp;&nbsp;&nbsp;
~InterfaceClass() {}; &nbsp;<br/>
};<br/>
<br/></SPAN><SPAN>======= Derived Class的管理</SPAN>
<SPAN>=======<br/>
对于Interface Class来说，如果Derived
Class太多，是很难管理的，不过我们可以通过统一的ClassManager来实现。下面是个小例子：<br/>

<br/>
// Interface<br/></SPAN> <SPAN>class InterfaceClass {<br/>
public:<br/>
&nbsp;&nbsp;&nbsp; virtual void
SomeInterface( void ) = 0;<br/>
<br/>
private:<br/>
friend class ClassManager; &nbsp;<br/>
&nbsp;&nbsp;&nbsp;
~InterfaceClass()
&nbsp;&nbsp;&nbsp; = 0
&nbsp;&nbsp;&nbsp; {};
&nbsp;<br/>
};<br/></SPAN><br/>
// First Concrete Derived Class<br/>
<SPAN>class Derived1 : public InterfaceClass {<br/>
public:<br/>
&nbsp;&nbsp;&nbsp; virtual void
SomeInterface( void
)&nbsp;&nbsp;&nbsp; { ...
};<br/>
<br/>
private:<br/>
friend class ClassManager; &nbsp;<br/>
&nbsp;&nbsp;&nbsp;</SPAN>
<SPAN>Derived1()&nbsp;&nbsp;
{...};<br/></SPAN><SPAN>&nbsp;&nbsp;&nbsp;
~</SPAN><SPAN>Derived1()&nbsp;&nbsp;
{...};</SPAN><br/>
<SPAN>};<br/>
<br/></SPAN>// Second Concrete Derived Class<br/>
<SPAN>class Derived2 : public InterfaceClass {<br/>
public:<br/>
&nbsp;&nbsp;&nbsp; virtual void
SomeInterface( void
)&nbsp;&nbsp;&nbsp; { ...
};<br/>
<br/>
private:<br/>
friend class ClassManager; &nbsp;<br/>
&nbsp;&nbsp;&nbsp;</SPAN>
<SPAN>Derived2()&nbsp;&nbsp;
{...};<br/></SPAN><SPAN>&nbsp;&nbsp;&nbsp;
~</SPAN><SPAN>Derived2()&nbsp;&nbsp;
{...};</SPAN><br/>
<SPAN>};<br/></SPAN><br/>
<SPAN>// Class Manager<br/>
// Singleton<br/>
class ClassManager<br/>
{<br/>
public:<br/>
&nbsp;&nbsp;&nbsp; static
ClassManager* GetInstance( void )<br/>
&nbsp;&nbsp;&nbsp; {<br/>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; static ClassManager
instance;<br/>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; return &amp;instance;<br/>
&nbsp;&nbsp;&nbsp; }<br/>
&nbsp;&nbsp;&nbsp;<br/>
&nbsp;&nbsp;&nbsp;</SPAN>
<SPAN>InterfaceClass * GetDerived1(void) { return new Derived1()
};<br/></SPAN><SPAN>&nbsp;&nbsp;&nbsp;</SPAN>
<SPAN>InterfaceClass * GetDerived2(void) { return new Derived2()
};</SPAN><SPAN>&nbsp;&nbsp;<br/>
<br/>
private:<br/>
&nbsp;&nbsp;&nbsp;
ClassManager(); &nbsp;<br/></SPAN>
<SPAN>&nbsp;&nbsp;&nbsp;
~ClassManager();</SPAN><br/>
<SPAN>};<br/>
<br/></SPAN><SPAN>============== Concrete Base Class</SPAN>
<SPAN>==============</SPAN><br/>
<SPAN><br/>
Concrete Base
Class是使用的比较多的。游戏中经常有的object之间，差别非常的小，这些都可以通过Concrete
Base Class来抽象，提高代码重用的效率。比如 Design
Pattern中比较著名的 Strategy Pattern. 下面是 Strategy
Pattern的小例子：<br/>
<br/>
class StringArray {<br/>
public:<br/>
&nbsp;&nbsp;&nbsp; void
AddString() {...};<br/>
&nbsp;&nbsp;&nbsp; void
SearchString() {....};<br/>
&nbsp;&nbsp;&nbsp; void
SortString( void ) { StrategySortString(); };<br/>
&nbsp;&nbsp;&nbsp; ...<br/>
private:<br/>
&nbsp;&nbsp;&nbsp; virtual
StrategySortString ( void )<br/>
&nbsp;&nbsp;&nbsp; { ...
};&nbsp;&nbsp; // bubble sort<br/>
}; &nbsp;<br/>
<br/></SPAN> <SPAN>class StringArray2 : public StringArray {<br/>
&nbsp;&nbsp;&nbsp; ...<br/>
private:<br/>
&nbsp;&nbsp;&nbsp; virtual
StrategySortString ( void )<br/>
&nbsp;&nbsp;&nbsp; { ...
};&nbsp;&nbsp; // quick sort<br/>
}; &nbsp;<br/>
<br/>
假设我们有StringArray, 已经提供了所有基本的String
Array操作，不过对于不同的Array输入方式，删除方式等，对应的排序方式的效率也不大相同。因此我们可以把sort设置成为
virtual,然后对于不同的StringArray的使用方式，再相对选择正确的Derived
Class就可以了。<br/>
<br/>
对于Concrete Base Class 有几点需要注意的：<br/>
<br/>
1. Destructor。 相信这个不用多说了，一定要 virtual,
而且要保证资源释放的干净。<br/>
<br/>
2. 使用non-virtual interface. 这个是C++大师们的结论。
其原因是因为Derived
class在重载Virtual的时候，在很多情况下会影响到基类里提供的机制的正常运作。如果使用non-public
virtual，可以使得程序更加灵活，并且进程pre/post
condition的检查。比如：<br/>
<br/>
class StringArray {<br/>
public:<br/>
&nbsp;&nbsp;&nbsp; void
SortArray ( )<br/>
&nbsp;&nbsp;&nbsp; {<br/>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; // Pre-condition Check<br/>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; StrategySoryArray();<br/>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; // Post-condition Check<br/>
&nbsp;&nbsp;&nbsp;
};&nbsp;&nbsp;<br/>
private:<br/>
&nbsp;&nbsp;&nbsp; virtual void
StrategySoryArray( void ) { ... };<br/>
};<br/>
<br/>
这样通过 pre/post condition check,
可以最大程度的保证基类的使用者不会犯错误。从而避免程序bug.<br/>
<br/>
3. 尽量使用 private virtual. Protected virtual
只有在继承类需要调用基类实现的时候，才应该放在protected里。比较著名的是clone函数：<br/>

<br/>
&nbsp;&nbsp;&nbsp; class Base
{<br/>
&nbsp;&nbsp;&nbsp;
protected:<br/>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; Base * clone ( void )
{};<br/>
&nbsp;&nbsp;&nbsp; };<br/>
<br/>
</SPAN><SPAN>&nbsp;&nbsp;&nbsp;
class Derived : Base{<br/>
&nbsp;&nbsp;&nbsp;
protected:<br/>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; Base * clone ( void ) {
Base::Clone(); ... };<br/>
&nbsp;&nbsp;&nbsp;
};</SPAN><br/>
<SPAN><br/>
还有其他的一些方面，那就和基本的class设计大同小异了。
不过还有一个重要的方面，就是Operator 和 Copy Constructor.<br/>
<br/></SPAN> <SPAN>============== Operator</SPAN>
<SPAN>==============<br/>
<br/>
在Base Class里边，所有的 operator中最重要的就是operator =了。对于
Abstract Class 来说，最好是禁止使用 Operator =。 为什么呢？
让我们来看看代码：<br/>
<br/>
class Base {<br/>
public:<br/>
&nbsp;&nbsp;&nbsp; virtual void
Interface( void ) = 0;<br/>
&nbsp;&nbsp;&nbsp; ...
&nbsp;<br/>
};<br/>
<br/>
class Derived1</SPAN> : public Base<SPAN>{<br/>
private:<br/>
&nbsp;&nbsp;&nbsp; _x;<br/>
};<br/>
<br/></SPAN><SPAN>class Derived2</SPAN> : public Base<SPAN>{<br/>
private:<br/>
&nbsp;&nbsp;&nbsp; _x;<br/>
&nbsp;&nbsp;&nbsp; _y;<br/>
};</SPAN><br/>
<SPAN><br/>
Base *pD1 = new Derived1();<br/></SPAN><SPAN>Base *pD2 = new
Derived2();<br/>
<br/>
*pD1 = *pD2;<br/>
<br/>
也许 *pD1 =
*pD2并不常见，但是确实是合法的代码，可以通过编译器的检查。但是*pD1
= *pD2 调用的是 Base 的 operator = , 在Base 并没有提供operator
=的情况下，使用的是缺省的位拷贝操作。这个缺省的拷贝操作只拷贝Base
Class的内存，而忽略了Derived Class的内存。也就是说 _x
_y都没有被拷贝。<br/>
<br/>
如果我们在 Base Class 里提供一个 virtual operator =,
在一定程度上能够解决问题，但是 overload 的operator
必须进行类型转换，例如:<br/>
<br/></SPAN><SPAN>Base &amp; Derived1::Operator = (Base &amp; x)
{<br/>
&nbsp;&nbsp;&nbsp; ....<br/>
&nbsp;&nbsp;&nbsp;
static_cast&lt;</SPAN><SPAN>Derived1 *&gt;(x)<br/>
&nbsp;&nbsp;&nbsp;
....<br/></SPAN><SPAN>};<br/>
<br/>
但是下面的代码仍然可以编译通过，产生错误的结果：<br/>
<br/></SPAN><SPAN>*pD1 = *pD2;</SPAN><br/>
<br/>
因此，对与 abstract class 来说，最方便的就是禁止 operator = ,
把它设成 private.<br/>
<br/>
对于Concrete Base Class来说，要么提供 operator = ,要么放在private
里，但是要在Derived Class里调用 Base Class 的 operator =
在例如：<br/>
<br/>
class Base {<br/>
&nbsp;&nbsp;&nbsp; ...<br/>
public:<br/>
&nbsp;&nbsp;&nbsp; Base &amp;
operator = ( Base &amp; );<br/>
};<br/>
<br/>
class Derived : public Base{<br/>
&nbsp;&nbsp;&nbsp; ...<br/>
public:<br/>
&nbsp;&nbsp;&nbsp; Derived
&amp; operator = ( Derived &amp; X )<br/>
&nbsp;&nbsp;&nbsp; {<br/>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; Base::operator = ( X );<br/>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; ...<br/>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; // own assignment
operations<br/>
&nbsp;&nbsp;&nbsp; }<br/>
};<br/>
<br/>
这种方法不支持cast up,也就是:<br/>
&nbsp;&nbsp;&nbsp; Base *
pBase1 = new Derived();<br/>
&nbsp;&nbsp;&nbsp; Base *
pBase2 = new Derived();<br/>
&nbsp;&nbsp;&nbsp; *pBase1 =
*pBase2;<br/>
&nbsp;&nbsp;&nbsp;<br/>
稍微好点的方式是把 Base 的 operator = 放在
protected里边，但是也不是解决根本的问题。最好的解决方案是使用前面讲到的virtual
clone 和 construct实现。如：<br/>
<br/>
class Base {<br/>
&nbsp;&nbsp;&nbsp; virtual Base
* construct (void) { return new Base(); };<br/>
&nbsp;&nbsp;&nbsp; virtual Base
* clone(void) { return new Base(*this); };<br/>
};<br/>
<br/>
class Derived : public Base {<br/>
&nbsp;&nbsp;&nbsp; virtual Base
* construct (void)<br/>
&nbsp;&nbsp;&nbsp; { return new
Derived(); };<br/>
&nbsp;&nbsp;&nbsp;<br/>
&nbsp;&nbsp;&nbsp; virtual Base
* clone(void)<br/>
&nbsp;&nbsp;&nbsp; { return new
Derived(*this); };<br/>
};<br/>
<br/>
同时禁止Base的 opeartor =。
但是这样的效率会有所降低。总之，最好的方法是使用 abstract
interface,同时禁止base使用 private operator =.<br/>
<br/>
<br/>
好了。这次就说这么多，希望对大家有帮助，下次见！还有，虽然不是我们的节日，但是大家圣诞快乐！<br/>

<br/>
]]></description>
            <author>aear</author>
            <category>程序设计随笔</category>
            <comments>http://blog.sina.com.cn/s/blog_4b3173c5010006jz.html#comment</comments>
            <pubDate>Sat, 16 Dec 2006 19:28:29 GMT+8</pubDate>
            <guid>http://blog.sina.com.cn/s/blog_4b3173c5010006jz.html</guid>
        </item>
        <item>
            <title>C++基本功和 Design Pattern系列(9) virtual</title>
            <link>http://blog.sina.com.cn/s/blog_4b3173c5010006iz.html</link>
            <description><![CDATA[======================================================<br/>
大家请把我的文章当参考，详细内容 还请参照 权威书<br/>
籍如果文中有错误和遗漏， 请指出，Aear会尽力更正,<br/>
谢谢！<br/>
Aear Blog: <A HREF="../../../u/1261532101">http://blog.sina.com.cn/u/1261532101</A><br/>

======================================================<br/>
<br/>
关于virtual 一般有3种用法: virtual function, pure virtual function,
和 virtual inheritance. 今天就分别来讲讲这几种virtual.<br/>
<br/>
================ virtual function ================<br/>
virtual函数是在类里边的一种特殊的函数，至于具体的含义，相信大家都知道，我就不多说了。而virtual最基本的思想，就是OO语言中多态的体现。把函数从编译时的棒定，转移到运行时的动态绑定。<br/>

<br/>
virtual的好处很多，比如能使程序结构更加清晰，代码的重复利用率更高,
但是也是有代价的。让我们来看下代码：<br/>
<br/>
class Test {<br/>
&nbsp;&nbsp;&nbsp; ...<br/>
&nbsp;&nbsp;&nbsp; virtual void
VirtualFunc(void) { cout&lt;&lt;"Test1"&lt;&lt;endl; };<br/>
};<br/>
<br/>
class Test2 : public Test {<br/>
&nbsp;&nbsp;&nbsp; ...<br/>
&nbsp;&nbsp;&nbsp; virtual void
VirtualFunc(void) { cout&lt;&lt;"Test2"&lt;&lt;endl; };<br/>
};<br/>
<br/>
Test * pTest = new Test2();<br/>
pTest-&gt;VirtualFunc();<br/>
<br/>
上面代码的输出结果是"Test2"。也就是说，虽然你是通过Test *
进行的调用，但真正执行的代码是你创建的Test2的VirtualFunc.
这样的效果是通过在编译的时候创建virtual pointer: _vptr 和 virtual
table: _vtbl 来实现的（大部分编译器的实现是通过_vptr &amp;
_vtbl）。对于每个有virtual
function的class，compiler创建一个_vtbl，用来记录所有的virtual
function的地址。同时在所有这个class的instance(实例)里，都有一个_vptr，指向_vtbl。因此，
pTest-&gt;VirtualFunc() 这段代码等同于：<br/>
<br/>
&nbsp;&nbsp;&nbsp;
(*pTest-&gt;_vptr[X])()<br/>
<br/>
其中X是VirtualFunc在_vtbl中对应的位置。（其实对于不同的compiler，都有不同的实现，不同的类层次结构，_vptr和_vtbl的数目也不一定相同。）<br/>

<br/>
从上面的代码考虑，virtual 和
non-virtual的class对比，在性能上有3个方面受到影响：<br/>
&nbsp;&nbsp;&nbsp; 1.
_vptr是在constructor中由compiler生成的代码隐性的初始化，占用了一定的时间。<br/>

&nbsp;&nbsp;&nbsp; 2. virtual
function是通过指针间接调用的，比直接调用需要更多的时间，而且在有的情况下会导致CPU的指令缓存失效，从而浪费更多的时间。<br/>

&nbsp;&nbsp;&nbsp; 3.
由于virtual
function是在运行时进行动态绑定的，所以无法进行inline.<br/>
<br/>
对于第一条，如果是使用 virtual
function，那是无可避免的，对于第2条，有通过显式的调用virtual
function来提高速度,代码如下：<br/>
<br/>
class Test2 : public Test {<br/>
&nbsp;&nbsp;&nbsp; ...<br/>
&nbsp;&nbsp;&nbsp; virtual void
VirtualFunc(void) { cout&lt;&lt;"Test2"&lt;&lt;endl; };<br/>
&nbsp;&nbsp;&nbsp; void
VirtualFuncFast(void) { Test2::VirtualFunc(); };<br/>
};<br/>
<br/>
由于Test2::VirtualFunc指定了调用函数的版本，所以是在编译时候就绑定了，免去了指针的间接调用过程，而且VirtualFuncFast本身也是可以inline的。当然了，这样做也是有坏处的，就是VirtualFuncFast本身是Test2的函数，而不是Test的，所以不能通过Test的指针掉用。因此只有在确定是Test2的情况下，通过static_cast才能掉用VirtualFuncFast.<br/>

<br/>
同理，在一个virtual function里调用另外一个virtual
function的时候，使用显试的调用也能提高一定的速度，比如：<br/>
<br/>
class Test2 : public Test {<br/>
&nbsp;&nbsp;&nbsp; ...<br/>
&nbsp;&nbsp;&nbsp; virtual void
VirtualFunc(void) { cout&lt;&lt;"Test2"&lt;&lt;endl; };<br/>
&nbsp;&nbsp;&nbsp; virtual void
VirtualFunc2(void) { Test2::VirtualFunc(); };<br/>
};<br/>
<br/>
<br/>
对于第3种情况，我们可以通过用Template代替Virtual
Function来获得性能上的提高，举个简单的例子：<br/>
<br/>
========== virtual 实现 ==========<br/>
class Base{<br/>
public:<br/>
&nbsp;&nbsp;&nbsp; virtual void
VirtualFunc(void);<br/>
};<br/>
<br/>
class Derive1 : public Base{<br/>
public:<br/>
&nbsp;&nbsp;&nbsp; virtual void
VirtualFunc(void);<br/>
};<br/>
<br/>
class Derive2 : public Base{<br/>
public:<br/>
&nbsp;&nbsp;&nbsp; virtual void
VirtualFunc(void);<br/>
};<br/>
<br/>
class SomeClass {<br/>
public:<br/>
&nbsp;&nbsp;&nbsp; void
test(Base * pBase) { pBase-&gt;VirtualFunc(); };<br/>
};<br/>
<br/>
// 用法<br/>
Test * pTest1 = new Derive1();<br/>
Test * pTest2 = new Derive2();<br/>
SomeClass Temp1.test(pTest1);<br/>
SomeClass Temp2.test(pTest2);<br/>
<br/>
========== 对应的 Template 实现 ==========<br/>
<br/>
class D1{<br/>
public:<br/>
&nbsp;&nbsp;&nbsp; // inline
here<br/>
&nbsp;&nbsp;&nbsp; void
VirtualFunc(void) {};<br/>
};<br/>
<br/>
class D2{<br/>
public:<br/>
&nbsp;&nbsp;&nbsp; // inline
here<br/>
&nbsp;&nbsp;&nbsp; void
VirtualFunc(void) {};<br/>
};<br/>
<br/>
template &lt;class DCLASS&gt;<br/>
class SomeClass {<br/>
public:<br/>
&nbsp;&nbsp;&nbsp; // inline
here<br/>
&nbsp;&nbsp;&nbsp; void test(
void ) { Temp.TestVirtualFunc(); };<br/>
private:<br/>
&nbsp;&nbsp;&nbsp; DCLASS
Temp;<br/>
};<br/>
<br/>
// 用法<br/>
SomeClass &lt;D1&gt; Temp1;<br/>
SomeClass &lt;D2&gt; Temp2;<br/>
Temp1.test();<br/>
Temp2.test();<br/>
<br/>
<br/>
========== 如何选择 ==========<br/>
<br/>
对于到底是使用 Virtual ，还是使用Template或者Virtual的优化形式,
在大多数情况下不难做出决定。具体选择的过程，只需要问问自己到底是程序的速度重要，还是其他重要，也就是，要在：
速度，程序结构，灵活性，易用易维护性，代码的复杂度，代码大小
这些中间做出选择。<br/>
<br/>
如果速度排第一位，那么就使用template或者优化，如果其他排在速度的前面，应该尽量的使用virtual。<br/>

<br/>
<br/>
================ pure virtual function ================<br/>
<br/>
pure virtual function主要是用在abstract class里。有pure virtual
function的class,就是abstract class,是不能被实例化的。因此，pure
virtual function的代码只有在指定的情况下才能被调用。 例如：<br/>
<br/>
class Test {<br/>
&nbsp;&nbsp;&nbsp; virtual void
VirtualFunc(void) = 0 { cout&lt;&lt;"Test"&lt;&lt;endl; };<br/>
};<br/>
<br/>
<br/>
class Test2 : public Test {<br/>
&nbsp;&nbsp;&nbsp; virtual void
VirtualFunc(void) { Test::VirtualFunc(); };<br/>
};<br/>
<br/>
================ virtual inheritance ================<br/>
<br/>
其实Virtual Inheritance只有可能在Multiple
Inheritance中使用。对于Muliple Inheritance,
Aear是坚决反对反对再反对的。Aear个人认为，single
inheritance是足够用的，Java就是最好的例子。
MI实在是太让人头疼了，所以Aear不会在这个系列中讲MI，这里只说说
Virtual Inheritance和普通的Inheritance的区别。<br/>
<br/>
class Base {<br/>
&nbsp;&nbsp;&nbsp; virtual
~Base();<br/>
};<br/>
<br/>
class Derived1 : public Base {<br/>
};<br/>
<br/>
class Derived2 : virtual public Base {<br/>
};<br/>
<br/>
这里:<br/>
<br/>
sizeof(Derived1) == 4<br/>
sizeof(Derived2) == 8<br/>
<br/>
sizeof(Derived1) == 4 是因为 Derived1继承 Base以后，使用Derived1的
_vptr<br/>
<br/>
sizeof(Derived1) == 8 是因为由于在所有的vritual
inheritance里，Base作为基类在内存中只能出现一次。所以必须把Base和Derived2的附加部分单独对待。因此有2个_vptr,一个是Base的，一个是Derived2的。<br/>

<br/>
virtual
inheritance的直接结果就是大大增加了指令缓存失效的可能性，同时降低了类内部数据的访问速度。因为Base
和 Derived2的内部数据不再是放在连续的内存中了。如果virtual
inheritance的层次越多，对运行速度的影响就越大。<br/>
<br/>
所以Aear在这里极度不推荐MI和Virtual Inheritance.<br/>
<br/>
================ virtual 的一些用法 ================<br/>
下面是virtual的一些用法。<br/>
<br/>
========== virtual destructor ==========<br/>
<br/>
这个比较简单，就是所有的Base Class，都应该是 public virtual
destructor 或者是protected non-virtual destructor，例如：<br/>
<br/>
class Base {<br/>
public:<br/>
&nbsp;&nbsp;&nbsp; virtual
~Base();<br/>
};<br/>
<br/>
或者<br/>
<br/>
class Base {<br/>
protected:<br/>
&nbsp;&nbsp;&nbsp;
~Base();<br/>
};<br/>
<br/>
========== virtual constructor ==========<br/>
<br/>
其实本没有virtual
constructor，不过C++中有特殊的实现，实现类似virtual constructor 和
virtual copy constructor的。代码如下：<br/>
<br/>
class Base {<br/>
&nbsp;&nbsp;&nbsp; virtual Base
* construct (void) { return new Base(); };<br/>
&nbsp;&nbsp;&nbsp; virtual Base
* clone(void) { return new Base(*this); };<br/>
};<br/>
<br/>
class Derived : public Base {<br/>
&nbsp;&nbsp;&nbsp; virtual Base
* construct (void) { return new Derived(); };<br/>
&nbsp;&nbsp;&nbsp; virtual Base
* clone(void) { return new Derived(*this); };<br/>
};<br/>
<br/>
========== pure virtual destructor ==========<br/>
<br/>
如果我们想设置base class 为abstract
class,而又只有一个destructor作为唯一的成员函数，可以把它设成为pure
virtual<br/>
<br/>
class Base {<br/>
public:<br/>
&nbsp;&nbsp;&nbsp; virtual
~Base() = 0;<br/>
};<br/>
<br/>
========== protected &amp; private virtual ==========<br/>
<br/>
对于virtual
function是不是应该放在public里边，学术结论和现实中的代码往往不能统一。虽然很多人认为virtual
function
不应该放在public里边，但是这样的设计经常会造成编码中的不方便，<br/>

<br/>
实际上对与Java来说，protected 或 private 所有 virtual
function，几乎是不太可能的。因此，Aear个人观点，是不是要protected
&amp; private virtual function,要根据情况而定。下面是个private
virtual的例子：<br/>
<br/>
class Base {<br/>
public:<br/>
&nbsp;&nbsp;&nbsp; // this is
interface<br/>
&nbsp;&nbsp;&nbsp; void
print(void) { output() };<br/>
private:<br/>
&nbsp;&nbsp;&nbsp; virtual void
output (void) { cout&lt;&lt;"Base"&lt;&lt;endl; };
&nbsp;<br/>
};<br/>
<br/>
实际上这样的处理，要比public virtual速度上慢点。<br/>
<br/>
========== 一些要点 ==========<br/>
<br/>
1. 不建议使用MI (Mission Impossible?),
在大多数情况下，它引入的问题，要比它解决的问题多的多的多。<br/>
2. 类层次结构越多，类成员和函数的访问效率越低。<br/>
3. Virtual Inheritance的类成员访问效率要低于 Non-virtual
Inheritance.<br/>
<br/>
今天说了好多东西，下次见！祝大家过的愉快。<br/>
<br/>
]]></description>
            <author>aear</author>
            <category>程序设计随笔</category>
            <comments>http://blog.sina.com.cn/s/blog_4b3173c5010006iz.html#comment</comments>
            <pubDate>Fri, 15 Dec 2006 05:03:31 GMT+8</pubDate>
            <guid>http://blog.sina.com.cn/s/blog_4b3173c5010006iz.html</guid>
        </item>
        <item>
            <title>C++基本功和 Design Pattern系列(8) inline</title>
            <link>http://blog.sina.com.cn/s/blog_4b3173c5010006ec.html</link>
            <description><![CDATA[======================================================<br/>
大家请把我的文章当参考，详细内容 还请参照 权威书<br/>
籍如果文中有错误和遗漏， 请指出，Aear会尽力更正,<br/>
谢谢！<br/>
Aear Blog: <A HREF="../../../u/1261532101">http://blog.sina.com.cn/u/1261532101</A><br/>

======================================================<br/>
<br/>
今天讲的是inline.
其实大家都知道，inline并不是c++独有的特性。其实Aear的个人观点，inline根本就不应该是语言标准的一部分。因为inline的具体实现，跟compiler有很大的关系，把inline说成compiler的一个开关更合适一些。今天我们就说下在什么情况下可以使用inline,
使用inline的好处和坏处。<br/>
<br/>
================= Inline能做什么 =================<br/>
<br/>
关于inline能做什么，什么原理，相信很多人都知道。Aear再在这里重复一下：<br/>

<br/>
1. inline能够去掉function call的overhead<br/>
2. inline能够帮助函数调用时候常量参数进行优化<br/>
<br/>
举个例子来说明一：<br/>
<br/>
void function(void)<br/>
{<br/>
<br/>
}<br/>
<br/>
function();<br/>
<br/>
在调用function()前，一般会进行下面的操作（根据操作系统和compiler来决定，并不一定按照这个顺序）：<br/>

&nbsp;&nbsp;&nbsp; 保存IP FP
SP等寄存器的值(压栈)<br/>
&nbsp;&nbsp;&nbsp;
把参数压栈<br/>
&nbsp;&nbsp;&nbsp; 建立新的 IP
FP SP等以便进行函数调用<br/>
&nbsp;&nbsp;&nbsp;
函数有可能还需要保存一些寄存器数据到内存。<br/>
<br/>
在完成function()调用后，也会进行一系列的操作：<br/>
&nbsp;&nbsp;&nbsp;
如果有返回值，一般在一个寄存器中，需要进行一系列的处理工作<br/>
&nbsp;&nbsp;&nbsp; 恢复IP FP
SP等保存的寄存器值。<br/>
<br/>
整个过程大约需要花费20-150个CPU clock
cycle.具体要根据参数的多少，还有函数的具体实现来决定。使用inline
function,可以去掉这些函数调用前和调用后的工作，从而节省CPU clock
cycle,提高程序的运行效率。<br/>
<br/>
关于2的情况，例子如下：<br/>
&nbsp;&nbsp;&nbsp; float test =
cos(0);<br/>
<br/>
如果cos不是inline,compiler有可能会生成cos()的调用代码，计算cos(0)，然后返回给test.如果cos被inline了，由于cos(0)
== 1，所以经过优化的代码可是直接生成test = 1.<br/>
<br/>
================= Inline 坏处 =================<br/>
<br/>
Aear个人认为，inline只在特定的情况下起到正面的作用，在大部分情况下，起到负面的作用，也就是说，坏处多过好处。使用inline的缺点包括：<br/>

<br/>
1. 不容易debug，并不是所有的debugger都支持在inline
function中设置断点，不过幸运的是，VS .net支持。<br/>
<br/>
2.
很容易增加代码的长度，在很多情况下，代码长度的增加直接导致了代码执行速度的减慢，特别是在循环中，因为整个循环的长度超过了cache的容量，从而使得cache
miss的几率增大<br/>
<br/>
3. 使得编译的时间过长。如果一个inline
function被更改，所有调用这个程序的代码都要重新编译。对于一般的游戏代码,整个编译时间可能会有1，2个小时。<br/>

<br/>
4. 暴露了代码实现细节。由于inline
function在大多数情况下必须在header
file中定义（不过目前由于compiler越来越好，也可以在.cpp中定义inline了），所以导致使用者能够看到你的代码实现细节。<br/>

<br/>
Inline并不是一个好东西，也不是一个万能药，在很多时候，它会给你带来无穷无尽的麻烦。所以在inline的时候，最好慎重慎重。<br/>

<br/>
================= 如何使用 Inline =================<br/>
<br/>
下面给出几种inline的用法。由于个人的代码结构，平台，实现细节的不同，请参考相关资料自行决定.<br/>

<br/>
========= Platform Inline =========<br/>
首先要指出的是，inline并不是一条命令，而是对compiler的建议。compiler会具体分析你的代码，如果合适inline,才会进行inline的工作。在VS
.net下，一共有3个关于inline的定义：<br/>
<br/>
inline<br/>
__inline (__inline__ for GCC)<br/>
__forceinline<br/>
<br/>
inline和__inline相同，
只有compiler认为inline合适，才会进行。__forceinline是强制compiler进行inline.
比如：<br/>
<br/>
__forceinline void f(void);<br/>
<br/>
如果你使用了inline或者__inline, 并且打开了编译器的
/Ob开关，那么compiler就会告诉你一个function是不是被真正的inline了。<br/>

<br/>
========= Macro Inline =========<br/>
<br/>
使用一个macro来控制inline，我们可以做如下定义：<br/>
<br/>
#ifdef _DEBUG<br/>
#define COND_INLINE<br/>
#else<br/>
#define COND_INLINE inline<br/>
#endif<br/>
<br/>
// inline function declaration<br/>
COND_INLINE function();<br/>
<br/>
这样我们在debug模式下，就不会有inline带来的烦恼了。只有在release
version，编译器才会进行真正的inline.<br/>
<br/>
<br/>
========= Inline Condition =========<br/>
<br/>
一般来讲，根据程序员主观感觉inline得到的很有可能就是负面的效果。下面的一些情况，能够帮大家决定是否inline一个函数：<br/>

<br/>
1. 使用profiler分析的结果告诉你需要inline一个function。
这个是最有把握的。windows下比较流行的profiler是vTune<br/>
<br/>
2. class的属性访问函数（Accessor
Methods）。一般来讲，这些是可以inline的，而且很多compiler都会帮你自动inline这些函数。<br/>

<br/>
3. 小函数。这个需要举个例子说明，代码如下：<br/>
<br/>
int Cal(int x, int y, int z)<br/>
{<br/>
&nbsp;&nbsp;&nbsp; return
x+y-z;<br/>
}<br/>
<br/>
我们可以看到 Cal的代码很少，就是计算
x+y-Z，最多也就3，4条汇编代码。但是如果不inline,
Cal函数的调用和返回过程所产生的代码，都比cal实际运行的代码多。因此Cal最好inline,通过消除Cal的调用和返回的代码，可以减少可执行程序的大小，同时加快运行的速度。<br/>

<br/>
因此，一般来讲，5行内逻辑结构简单，没有if
else的代码，可以比较放心的inline,大过5行的代码，就需要仔细的斟酌了。<br/>

<br/>
================= 不能Inline的情况 =================<br/>
<br/>
1. 包含Static Member的function. 很多compiler不能inline有static
member的function.或者即使inline了，也会生成错误的代码（把static当成local处理）。所以最好先测试下compiler支持不支持static
inline.测试代码可以这么写：<br/>
<br/>
inline void f(void)<br/>
{<br/>
&nbsp;&nbsp;&nbsp; static int k
= 1;<br/>
&nbsp;&nbsp;&nbsp; k++;<br/>
&nbsp;&nbsp;&nbsp;
std::cout&lt;&lt;k&lt;&lt;endl;<br/>
}<br/>
<br/>
f();<br/>
f();<br/>
<br/>
2. virtual member function.&nbsp; Virtual Member
Function在很多情况下是不能被inline的（根据compiler而定），因为具体virtual的哪个版本被调用，要在运行时候才能决定。不过我们可以通过创建一个新的可以inline的non-virtual
member function，来提高运行速度。<br/>
<br/>
<br/>
================= 结论 =================<br/>
<br/>
总的来说，inline的坏处多过好处，请大家inline的时候，慎重慎重再慎重，并不是所有的函数都适合inline的。<br/>

<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
]]></description>
            <author>aear</author>
            <category>程序设计随笔</category>
            <comments>http://blog.sina.com.cn/s/blog_4b3173c5010006ec.html#comment</comments>
            <pubDate>Tue, 05 Dec 2006 02:35:37 GMT+8</pubDate>
            <guid>http://blog.sina.com.cn/s/blog_4b3173c5010006ec.html</guid>
        </item>
    </channel>
</rss>
