﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-Bill Hsu-随笔分类-Game Dev</title><link>http://www.cppblog.com/billhsu/category/7690.html</link><description /><language>zh-cn</language><lastBuildDate>Thu, 23 Jun 2011 13:22:17 GMT</lastBuildDate><pubDate>Thu, 23 Jun 2011 13:22:17 GMT</pubDate><ttl>60</ttl><item><title>Android游戏计时</title><link>http://www.cppblog.com/billhsu/archive/2011/01/30/139627.html</link><dc:creator>Bill Hsu</dc:creator><author>Bill Hsu</author><pubDate>Sun, 30 Jan 2011 15:16:00 GMT</pubDate><guid>http://www.cppblog.com/billhsu/archive/2011/01/30/139627.html</guid><wfw:comment>http://www.cppblog.com/billhsu/comments/139627.html</wfw:comment><comments>http://www.cppblog.com/billhsu/archive/2011/01/30/139627.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/billhsu/comments/commentRss/139627.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/billhsu/services/trackbacks/139627.html</trackback:ping><description><![CDATA[
Read this post in english:<a target="_blank" href="http://androgeek.info/?p=299">http://androgeek.info/?p=299<br></a><br>以前代码经验很多都是基于windows的，所以对android下面的计时函数不是太了解。<br><br>在写<a target="_blank" href="http://hi.baidu.com/probill/blog/item/16945fde1f86005b94ee37bb.html">Friut3D</a>时，我用的代码是用gettimeofday()来计时的。但是效果不好，游戏里有个场景跑起来十分卡，acepig兄和我都觉得这个问题很诡异。开始觉得这是模型的问题，现在看来是计时函数不精确惹得祸。<br><br>看看当时写的获取系统时间的代码：<br><br>
<div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">long</span><span style="color: #000000;">&nbsp;getTime(</span><span style="color: #0000ff;">void</span><span style="color: #000000;">)<br><br>{<br>gettimeofday(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">now,&nbsp;NULL);<br></span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">long</span><span style="color: #000000;">)(now.tv_sec</span><span style="color: #000000;">*</span><span style="color: #000000;">1000</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;now.tv_usec</span><span style="color: #000000;">/</span><span style="color: #000000;">1000</span><span style="color: #000000;">);<br>}</span></div>
<br><br>今天在一个google讨论组里得知gettimeofday()记得的tick是不准确的。而这个游戏逻辑依赖于time delta来计算各个物体运动，计时不精确，渲染自然会卡顿。<br><br>于是用纳秒级的准确度的clock_gettime()重写了getTime()函数：<br><br>
<div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">long</span><span style="color: #000000;">&nbsp;_getTime(</span><span style="color: #0000ff;">void</span><span style="color: #000000;">)<br><br>{<br></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;timespec&nbsp;now;<br>clock_gettime(CLOCK_MONOTONIC,&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">now);<br></span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;now.tv_sec</span><span style="color: #000000;">*</span><span style="color: #000000;">1000000</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;now.tv_nsec</span><span style="color: #000000;">/</span><span style="color: #000000;">1000</span><span style="color: #000000;">;<br><br>}</span></div>
<br><br>改了计时函数后，游戏各个场景都流畅了。<br>  <img src ="http://www.cppblog.com/billhsu/aggbug/139627.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/billhsu/" target="_blank">Bill Hsu</a> 2011-01-30 23:16 <a href="http://www.cppblog.com/billhsu/archive/2011/01/30/139627.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>骨骼动画中的反向动力学</title><link>http://www.cppblog.com/billhsu/archive/2010/08/26/124852.html</link><dc:creator>Bill Hsu</dc:creator><author>Bill Hsu</author><pubDate>Thu, 26 Aug 2010 09:29:00 GMT</pubDate><guid>http://www.cppblog.com/billhsu/archive/2010/08/26/124852.html</guid><wfw:comment>http://www.cppblog.com/billhsu/comments/124852.html</wfw:comment><comments>http://www.cppblog.com/billhsu/archive/2010/08/26/124852.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/billhsu/comments/commentRss/124852.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/billhsu/services/trackbacks/124852.html</trackback:ping><description><![CDATA[<span class="Apple-style-span" style="border-collapse: separate; color: #000000; font-family: Simsun; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;">IK在骨骼动画里常常能看到，作用就是根据子骨骼的方位推算出它的那些父骨骼方位。可是一直都是知道有那么回事，但是又不太知道具体是怎么实现的。<br />在multi-crash.com上看到一篇<a target="_blank" href="http://multi-crash.com/?p=45"><span style="font-style: italic;">骨骼动画反向动力学(IK)的实现&nbsp; </span></a>，内容写的很易懂。<br />这是基于CCD(</span>Cyclic Coordinate Descent<span class="Apple-style-span" style="border-collapse: separate; color: #000000; font-family: Simsun; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;">)算法的。还有种雅可比矩阵的算法，不过这种算法我还不太清楚，希望高手指教啊。<br />下面讲讲CCD，先看这张图。<br /><img style="width: 540px; height: 214px;" src="http://www.cppblog.com/images/cppblog_com/billhsu/ccd.gif" border="0"  alt="" /><br />注意图中的红线和绿线，红线是当前骨骼与目标骨骼的连线，绿线是目标骨骼与最终位置的连线。<br />从子骨骼到父骨骼的顺序迭代计算，旋转红线到绿线。这样多迭代几次就会得到较好的结果。<br /><br />要注意的是需要对骨骼的旋转范围加以限制，因为人体的关节不是以可以任意方式旋转的。<br /><img src="http://www.cppblog.com/images/cppblog_com/billhsu/ccd3.JPG" border="0"  alt="" /><br />[例如图中蓝色部分为可以旋转的范围]<br /><br /><span style="font-style: italic;"></span></span><img src ="http://www.cppblog.com/billhsu/aggbug/124852.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/billhsu/" target="_blank">Bill Hsu</a> 2010-08-26 17:29 <a href="http://www.cppblog.com/billhsu/archive/2010/08/26/124852.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Android NDK 开发OpenGL ES 2.0一些注意点</title><link>http://www.cppblog.com/billhsu/archive/2010/08/10/122914.html</link><dc:creator>Bill Hsu</dc:creator><author>Bill Hsu</author><pubDate>Tue, 10 Aug 2010 03:37:00 GMT</pubDate><guid>http://www.cppblog.com/billhsu/archive/2010/08/10/122914.html</guid><wfw:comment>http://www.cppblog.com/billhsu/comments/122914.html</wfw:comment><comments>http://www.cppblog.com/billhsu/archive/2010/08/10/122914.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/billhsu/comments/commentRss/122914.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/billhsu/services/trackbacks/122914.html</trackback:ping><description><![CDATA[Android是个好系统哇，特别是Android NDK r3出来以后，可以用OpenGL ES 2.0了。<br>自己也试了试用NDK编一个OpenGL ES 2.0的程序，可是，编译的时候出现了一大堆错。<br><img style="width: 592px; height: 392px;" src="http://www.cppblog.com/images/cppblog_com/billhsu/jni1.JPG" border="0"><br>如图，满屏幕都是 undefined reference to 那些OpenGL ES函数。<br>看来是库文件没有链接进来。<br><br>这是NDK例子里的Android.mk的写法：<br>
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">LOCAL_PATH:</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;$(call&nbsp;my</span><span style="color: #000000;">-</span><span style="color: #000000;">dir)<br><br>include&nbsp;$(CLEAR_VARS)<br><br>LOCAL_MODULE&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;libgl2jni<br>LOCAL_CFLAGS&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">Werror<br>LOCAL_SRC_FILES&nbsp;:</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;gl_code.cpp<br><span style="color: red;">LOCAL_LDLIBS&nbsp;&nbsp;&nbsp;&nbsp;:</span></span><span style="color: red;">=&nbsp;-llog&nbsp;-</span><span style="color: #000000;"><span style="color: red;">lGLESv2</span><br><br>include&nbsp;$(BUILD_SHARED_LIBRARY)</span></div>
<br>问题就出在用红色标出的那行。<br><br>把那句修改为：<br>
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">LOCAL_LDLIBS&nbsp;:</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">L$(SYSROOT)</span><span style="color: #000000;">/</span><span style="color: #000000;">usr</span><span style="color: #000000;">/</span><span style="color: #000000;">lib&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">llog<br>LOCAL_LDLIBS</span><span style="color: #000000;">+=-</span><span style="color: #000000;">L$(SYSROOT)</span><span style="color: #000000;">/</span><span style="color: #000000;">usr</span><span style="color: #000000;">/</span><span style="color: #000000;">lib&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">lGLESv2</span></div>
<br>就可以正常编译了。<br><br>还有一些注意点是：<br>编译程序前要clean，否则编译会出错；<br>每次更新了自己的.so文件后，在eclipse的那个java项目里要记着refresh一下。<br><br>  <img src ="http://www.cppblog.com/billhsu/aggbug/122914.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/billhsu/" target="_blank">Bill Hsu</a> 2010-08-10 11:37 <a href="http://www.cppblog.com/billhsu/archive/2010/08/10/122914.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>靠得住的休眠函数XSleep</title><link>http://www.cppblog.com/billhsu/archive/2010/07/30/121679.html</link><dc:creator>Bill Hsu</dc:creator><author>Bill Hsu</author><pubDate>Fri, 30 Jul 2010 02:55:00 GMT</pubDate><guid>http://www.cppblog.com/billhsu/archive/2010/07/30/121679.html</guid><wfw:comment>http://www.cppblog.com/billhsu/comments/121679.html</wfw:comment><comments>http://www.cppblog.com/billhsu/archive/2010/07/30/121679.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/billhsu/comments/commentRss/121679.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/billhsu/services/trackbacks/121679.html</trackback:ping><description><![CDATA[直接用timeGetTime()这个函数的误差是有目共睹的，在15ms左右，于是，如果游戏的消息循环用了timeGetTime()，那么3D游戏画面会因为两帧之间时间误差大而有些抖动。<br>今天在csdn上看到了一篇文章：<a href="http://blog.csdn.net/lanzhengpeng2/archive/2008/05/06/2401554.aspx">http://blog.csdn.net/lanzhengpeng2/archive/2008/05/06/2401554.aspx</a><br>讲的也正好是这个问题，记录一下。<br><br>在使用timeGetTime()的代码块的前后加上<span class="Apple-style-span" style="border-collapse: separate; color: #000000; font-family: Simsun; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;"><span class="Apple-style-span" style="font-family: verdana,sans-serif; font-size: 14px; line-height: 21px; text-align: left;">timeBeginPeriod(1)和</span></span><span class="Apple-style-span" style="border-collapse: separate; color: #000000; font-family: Simsun; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;"><span class="Apple-style-span" style="font-family: verdana,sans-serif; font-size: 14px; line-height: 21px; text-align: left;">timeEndPeriod(1)，就可以提高</span></span>timeGetTime()的精度。<br><br>同时，可以利用timeSetEvent写了一个靠得住的休眠函数[代码来自上述文章]：<br>
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;XSleep(DWORD&nbsp;dwDelay,HANDLE&nbsp;hEvent)<br>&nbsp;{<br>&nbsp;&nbsp;MMRESULT&nbsp;hTimer&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;timeSetEvent(dwDelay,</span><span style="color: #000000;">1</span><span style="color: #000000;">,(LPTIMECALLBACK)hEvent,</span><span style="color: #000000;">0</span><span style="color: #000000;">,TIME_ONESHOT&nbsp;</span><span style="color: #000000;">|</span><span style="color: #000000;">&nbsp;TIME_CALLBACK_EVENT_SET);<br>&nbsp;&nbsp;MsgWaitForMultipleObjectsEx(</span><span style="color: #000000;">1</span><span style="color: #000000;">,</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">hEvent,INFINITE,QS_ALLINPUT,</span><span style="color: #000000;">0</span><span style="color: #000000;">);&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">当有Windows消息时，还能继续处理Windows消息。故选择了这个函数。</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;timeKillEvent(hTimer);<br>&nbsp;}</span></div>
<br>消息循环[代码来自上述文章]：<br>
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">&nbsp;MSG&nbsp;msg;<br>&nbsp;DWORD&nbsp;dwLastTime;<br>&nbsp;HANDLE&nbsp;hSleepEvent&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;CreateEvent(NULL,FALSE,FALSE,NULL);<br><br>&nbsp;timeBeginPeriod(</span><span style="color: #000000;">1</span><span style="color: #000000;">);<br><br>&nbsp;dwLastTime&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;timeGetTime();<br>&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">(isActive())<br>&nbsp;{<br>&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">需要一直处理Windows消息到无消息处理为止</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">(;PeekMessage(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">msg,NULL,</span><span style="color: #000000;">0</span><span style="color: #000000;">,</span><span style="color: #000000;">0</span><span style="color: #000000;">,PM_REMOVE);)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(msg.message&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;WM_QUIT)<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle(hSleepEvent);<br>&nbsp;&nbsp;&nbsp;&nbsp;timeEndPeriod(</span><span style="color: #000000;">1</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;;<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(</span><span style="color: #000000;">!</span><span style="color: #000000;">TranslateAccelerator(msg.hwnd,hAccelTable,</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">msg))<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;TranslateMessage(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">msg);<br>&nbsp;&nbsp;&nbsp;&nbsp;DispatchMessage(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">msg);<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;DWORD&nbsp;FrameDelay&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;max(</span><span style="color: #000000;">1</span><span style="color: #000000;">,</span><span style="color: #000000;">1000</span><span style="color: #000000;">/</span><span style="color: #000000;">max(</span><span style="color: #000000;">1</span><span style="color: #000000;">,GetMaxFPS()));<br>&nbsp;&nbsp;DWORD&nbsp;dwTime&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;timeGetTime();<br>&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(dwLastTime&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;FrameDelay&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;dwTime)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;XSleep(dwLastTime&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;FrameDelay&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;dwTime,hSleepEvent);<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;update();<br>&nbsp;&nbsp;&nbsp;dwLastTime&nbsp;</span><span style="color: #000000;">+=</span><span style="color: #000000;">&nbsp;((dwTime&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;dwLastTime)&nbsp;</span><span style="color: #000000;">/</span><span style="color: #000000;">&nbsp;FrameDelay)&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;FrameDelay;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">当实际帧数严重低于预期帧数时，这段代码可以完成跳帧功能；当实际帧数大于等于预期帧数时，这段代码仍然可以使帧之间的时间间隔固定。之前谢Boss没有处理好的主要就是这个。</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;}<br>&nbsp;}<br><br>&nbsp;CloseHandle(hSleepEvent);<br>&nbsp;timeEndPeriod(</span><span style="color: #000000;">1</span><span style="color: #000000;">);</span></div>
这样，时间误差就会在1ms之内了，游戏也就不会抖动了。<br> <img src ="http://www.cppblog.com/billhsu/aggbug/121679.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/billhsu/" target="_blank">Bill Hsu</a> 2010-07-30 10:55 <a href="http://www.cppblog.com/billhsu/archive/2010/07/30/121679.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>基于shader的骨骼蒙皮计算</title><link>http://www.cppblog.com/billhsu/archive/2010/04/01/111326.html</link><dc:creator>Bill Hsu</dc:creator><author>Bill Hsu</author><pubDate>Thu, 01 Apr 2010 14:10:00 GMT</pubDate><guid>http://www.cppblog.com/billhsu/archive/2010/04/01/111326.html</guid><wfw:comment>http://www.cppblog.com/billhsu/comments/111326.html</wfw:comment><comments>http://www.cppblog.com/billhsu/archive/2010/04/01/111326.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/billhsu/comments/commentRss/111326.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/billhsu/services/trackbacks/111326.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 我的古董显卡很操蛋，好端端的shader，传骨骼矩阵进去，硬是没反应。。<br>寻寻觅觅，找到了 NVIDIA SDK 的example，终于解决了。<br>难道我的显卡不支持BLENDINDICES和BLENDWEIGHT?<br>把BLENDINDICES和BLENDWEIGHT用TEXCOORD[n]表示才正常。。<br>不说废话，直接上代码。&nbsp;&nbsp;<a href='http://www.cppblog.com/billhsu/archive/2010/04/01/111326.html'>阅读全文</a><img src ="http://www.cppblog.com/billhsu/aggbug/111326.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/billhsu/" target="_blank">Bill Hsu</a> 2010-04-01 22:10 <a href="http://www.cppblog.com/billhsu/archive/2010/04/01/111326.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>GPU水面模拟</title><link>http://www.cppblog.com/billhsu/archive/2010/03/23/110376.html</link><dc:creator>Bill Hsu</dc:creator><author>Bill Hsu</author><pubDate>Tue, 23 Mar 2010 12:59:00 GMT</pubDate><guid>http://www.cppblog.com/billhsu/archive/2010/03/23/110376.html</guid><wfw:comment>http://www.cppblog.com/billhsu/comments/110376.html</wfw:comment><comments>http://www.cppblog.com/billhsu/archive/2010/03/23/110376.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/billhsu/comments/commentRss/110376.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/billhsu/services/trackbacks/110376.html</trackback:ping><description><![CDATA[先上个自己实现的水面模拟图：<br /><img id="ViewPicture1_GalleryImage" src="http://www.cppblog.com/images/cppblog_com/billhsu/7643/r_water1.JPG" style="border: 2px solid Black;" height="206" width="274" /><br /><br />效果比较简单，只是模拟了下水面的反射效果。折射与Fresnel系数没有考虑。<br /><br />水面模拟大致需要分这么几步：<br />1.剪裁掉水面以下的顶点[gpu里的clipplane要注意转换到Clip Space]，<br />将摄像机放到同原摄像机关于水面对称的位置，比如原来摄像机在(x,y,z)，<br />此时就该把摄像机放在(x,-y,z)，up向量也要设置成向下的。<br />再把场景渲染到Render Target的纹理上(我用的纹理大小是256*256)，不知道为什么Render Target的纹理大小不能超过窗口大小，超过的话渲染会出错，知道的大大告诉我一下哈。<br /><br />于是，就得到了这样一个纹理：<br /><img id="ViewPicture1_GalleryImage" src="http://www.cppblog.com/images/cppblog_com/billhsu/7643/r_water3.JPG" style="border: 2px solid Black;" height="198" width="198" /><br /><br />2.将上面得到的纹理与水面的顶点对应.<br />把Vertex Shader中乘过变换矩阵后的坐标传到Pixel Shader,<br />在PS中计算<br /><div style="background-color: rgb(238, 238, 238); font-size: 13px; border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">        float2 clipspace = input.Coord.xy / input.Coord.w;<br />        clipspace.x=((clipspace.x * 0.5f) + 0.5f);<br />        clipspace.y = ((clipspace.y * -0.5f) + 0.5f);<br />        clipspace.x=1-clipspace.x;</span><span style="color: rgb(0, 0, 0);"></span></div>既可以让水面顶点与纹理对应，然后再想办法把纹理坐标扰乱来模拟水面波动。<br /><br />3.再渲染一次场景就可以了。<br /><br />大家也可以参考下Azure的水面渲染源代码：<a temp_href=" http://www.azure.com.cn/article.asp?id=186" href="%20http://www.azure.com.cn/article.asp?id=186"><br />http://www.azure.com.cn/article.asp?id=186</a><br /><img src ="http://www.cppblog.com/billhsu/aggbug/110376.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/billhsu/" target="_blank">Bill Hsu</a> 2010-03-23 20:59 <a href="http://www.cppblog.com/billhsu/archive/2010/03/23/110376.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>可编程管道下的剪裁平面</title><link>http://www.cppblog.com/billhsu/archive/2010/01/20/106088.html</link><dc:creator>Bill Hsu</dc:creator><author>Bill Hsu</author><pubDate>Wed, 20 Jan 2010 14:00:00 GMT</pubDate><guid>http://www.cppblog.com/billhsu/archive/2010/01/20/106088.html</guid><wfw:comment>http://www.cppblog.com/billhsu/comments/106088.html</wfw:comment><comments>http://www.cppblog.com/billhsu/archive/2010/01/20/106088.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/billhsu/comments/commentRss/106088.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/billhsu/services/trackbacks/106088.html</trackback:ping><description><![CDATA[
		<p class="MsoNormal">
				<span>剪裁平面</span>
				<span>(Clip Plane)</span>
				<span>在图形学领域有着重要的作用，比如水面模拟中，渲染折射纹理时，我们就必须将水面以上的顶点通过剪裁平面剪裁掉。</span>
		</p>
		<p class="MsoNormal">
				<span>在过去的固定渲染管道时代，剪裁平面的实现较为简单，比如在</span>
				<span>DirectX 9</span>
				<span>中，可以先设定剪裁平面在世界坐标系下的方程</span>
				<span>(ax+by+cz+d=0)</span>
				<span>，再调用</span>
				<span>SetClipPlane(DWORD Index,CONST float * pPlane)</span>
				<span>这个</span>
				<span>API</span>
				<span>函数就可以了。</span>
		</p>
		<p class="MsoNormal">
				<span> </span>
		</p>
		<p class="MsoNormal">
				<span>附上例子程序：</span>
		</p>
		<p class="MsoNormal" style="background: none repeat scroll 0% 0% rgb(238, 238, 238); text-align: left; -moz-background-inline-policy: continuous;" align="left">
				<span style="font-size: 10pt; color: black;">vPosition=D3DXVECTOR3(0,0,0);</span>
				<span style="font-size: 10pt; color: green;">//</span>
				<span style="font-size: 10pt; color: green;">平面上一个点<span><br /></span></span>
				<span style="font-size: 10pt; color: black;">vNormal=D3DXVECTOR3(0,1,0);</span>
				<span style="font-size: 10pt; color: green;">//</span>
				<span style="font-size: 10pt; color: green;">法向量<span><br /></span></span>
				<span style="font-size: 10pt; color: black;">D3DXPlaneFromPointNormal( &amp;clipplane, &amp;vPosition, &amp;vNormal );</span>
				<span style="font-size: 10pt; color: green;">//</span>
				<span style="font-size: 10pt; color: green;">生成剪裁平面<span><br /></span></span>
				<span style="font-size: 10pt; color: black;">
						<br />
m_pDevice()-&gt;SetClipPlane( 0, (</span>
				<span style="font-size: 10pt; color: blue;">float</span>
				<span style="font-size: 10pt; color: black;">*)clipplane); </span>
		</p>
		<p class="MsoNormal">
				<span> </span>
		</p>
		<p class="MsoNormal">
				<span>然而，在现在的可编程管道</span>
				<span>(programmable pipeline)</span>
				<span>下，设置的剪裁平面会被在剪裁坐标系下处理，而不是在世界坐标系下。</span>
		</p>
解决这个问题的方法有：<br /><br />
1）  给要剪裁的顶点做标记，在Pixel Shader中把它剪裁掉。<br /><br />
2）  使用近斜平面裁剪（Oblique Near-Plane Clipping），即修改投影矩阵，将要剪裁的顶点放在视截体之外，从而避免了该顶点的绘制。<br /><br />
3）  修改平面方程，使之从世界坐标系转换到剪裁坐标系。<span><br /><br /><br />
上述方法中，第一种和第二种效率并不高：在</span><span>Pixel Shader</span><span>中剪裁没有减少任何不必要的顶点处理，而计算近斜平面裁剪矩阵较为繁琐。所以，方法三是最佳选择。</span><p class="MsoNormal"><span> </span><span>要将一个平面从世界坐标系转换到剪裁坐标系，必须求出这个变换矩阵。</span></p><p class="MsoNormal"><span>设平面方程</span><span>ax+by+cz+d=0</span><span>，用一个</span><span>4</span><span>维向量来</span><span>n</span><span>表示</span><span>(a,b,c,d)</span><span>，设平面上有个点</span><span>p:(x,y,z,1)</span><span>。根据平面方程的定义，有：</span></p><p class="MsoNormal"><span><br /></span></p><p class="MsoNormal"><strong>n</strong><sup>T</sup><strong>p</strong> = ax + by + cz + d = 0</p><p class="MsoNormal"></p><p class="MsoNormal"><span>设矩阵</span><span>R</span><span>可以让点</span><span>P</span><span>从世界坐标系转换到剪裁坐标系，矩阵</span><span>Q</span><span>可以让平面</span><span>n</span><span>实现同样的变换。那么，有：</span></p><p class="MsoNormal" style="text-align: center;" align="center"></p><div align="left"><strong>p</strong>'= <strong>R</strong><strong>p</strong></div><div align="left"><strong>n'</strong>= <strong>Q</strong><strong>n</strong></div><p class="MsoNormal"><span>其中</span><span>p'</span><span>、</span><span>n'</span><span>分别是转换后的点与平面。</span></p><br /><div align="left"><strong>n</strong><span>'</span><sup>T</sup><strong>p'</strong>= 0</div><div align="left">(<strong>Q</strong><strong>n</strong>)<sup>T</sup> (<strong>R</strong><strong>p</strong>) = 0 <br /><strong>n</strong><sup>T</sup><strong>Q</strong><sup>T</sup><strong>R</strong><strong>p</strong> = 0<br /><br /><br /><span>如果：</span><strong>Q</strong><sup>T</sup><strong>R</strong> = <strong>I</strong></div><br /><p class="MsoNormal"><span>那么：</span></p><p class="MsoNormal"><strong>n</strong><sup>T</sup><strong>Q</strong><sup>T</sup><strong>R</strong><strong>p</strong> = <strong>n</strong><sup>T</sup><strong>I</strong><strong>p</strong> = <strong>n</strong><sup>T</sup><strong>p</strong> = 0</p><p class="MsoNormal"><span>于是：</span></p><div align="left"><strong>Q</strong><sup>T</sup> = <strong>R</strong><sup>-1</sup><strong><br />
Q</strong> = (<strong>R</strong><sup>-1</sup>)<sup>T</sup></div><br /><p class="MsoNormal"><span>在</span><span>DirectX 3D</span><span>中，将一个点从世界坐标系转换到剪裁坐标系，所用的矩阵为观察矩阵与投影矩阵的乘积，即：</span></p><p class="MsoNormal" style="background: none repeat scroll 0% 0% rgb(238, 238, 238); -moz-background-inline-policy: continuous;"><span style="font-size: 10pt; color: black;">D3DXMATRIX  TranMatrix = matView*matProj;</span></p><p class="MsoNormal"><span style="font-size: 9pt;">(TranMatrix</span><span style="font-size: 9pt;">为所求的变换矩阵，<span>matView</span>和<span>matProj</span>分别为</span><span>观察矩阵与投影矩阵</span><span>)</span></p><p class="MsoNormal"><span> </span></p><p class="MsoNormal"><span>附上在</span><span>D3D</span><span>中变换的完整代码：</span></p><p class="MsoNormal" style="background: none repeat scroll 0% 0% rgb(238, 238, 238); text-align: left; -moz-background-inline-policy: continuous;" align="left"><span style="font-size: 10pt; color: black;">D3DXPLANE tempPlane = clipplane;<br />
D3DXPlaneNormalize(&amp;tempPlane, &amp;tempPlane);<br /><br />
D3DXMATRIX  TranMatrix = matView*matProj;<br />
D3DXMatrixInverse(&amp;TranMatrix, NULL, &amp;TranMatrix);<br />
D3DXMatrixTranspose(&amp;TranMatrix, &amp;TranMatrix);<br />
D3DXPlaneTransform(&amp;tempPlane, &amp;tempPlane, &amp;TranMatrix);</span></p><p class="MsoNormal" style="background: none repeat scroll 0% 0% rgb(238, 238, 238); text-align: left; -moz-background-inline-policy: continuous;" align="left"></p><p class="MsoNormal"></p><p class="MsoNormal"><span>参考资料：</span></p><p class="MsoNormal"><span>1.Back Face Culling Notes ,Jordan Smith (University of California, Berkeley)<br /></span></p><p class="MsoNormal"><span>http://www.cs.berkeley.edu/~ug/slide/pipeline/assignments/backfacecull.shtml</span> </p><p class="MsoNormal">2.GameDev Forum</p><p class="MsoNormal">http://www.gamedev.net/community/forums/topic.asp?topic_id=402381</p><p class="MsoNormal">3.Oblique Near-Plane Clipping with Orthographic Camera ,Aras</p><p class="MsoNormal">http://aras-p.info/texts/obliqueortho.html</p><img src ="http://www.cppblog.com/billhsu/aggbug/106088.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/billhsu/" target="_blank">Bill Hsu</a> 2010-01-20 22:00 <a href="http://www.cppblog.com/billhsu/archive/2010/01/20/106088.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>发日志纪念~~第一次写导出插件</title><link>http://www.cppblog.com/billhsu/archive/2009/11/25/101921.html</link><dc:creator>Bill Hsu</dc:creator><author>Bill Hsu</author><pubDate>Wed, 25 Nov 2009 11:25:00 GMT</pubDate><guid>http://www.cppblog.com/billhsu/archive/2009/11/25/101921.html</guid><wfw:comment>http://www.cppblog.com/billhsu/comments/101921.html</wfw:comment><comments>http://www.cppblog.com/billhsu/archive/2009/11/25/101921.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/billhsu/comments/commentRss/101921.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/billhsu/services/trackbacks/101921.html</trackback:ping><description><![CDATA[
		<div id="blog_text" class="cnt">
				<p>今天终于把模型导出插件最基本的功能--导出网格给写好了。</p>
				<p>c++和max sdk一起用的感觉很怪，系统崩溃了N次，不过，总算能导出网格了~</p>
				<p> </p>
				<p>有图有真相，截图纪念</p>
				<p>(注意：模型是从value的csol中弄出来的)</p>
				<p>
						<span>
								<img src="http://www.cppblog.com/images/cppblog_com/billhsu/7643/o_2.JPG" small="0" class="blogimg" border="0" />
						</span>
				</p>
				<p>在d3d中渲染导出的模型­</p>
				<p>
						<span>
								<img src="http://www.cppblog.com/images/cppblog_com/billhsu/7643/o_1.JPG" small="0" class="blogimg" border="0" />
						</span>
				</p>
				<p>在d3d中渲染导出的模型­</p>
				<p>
						<span>
								<img src="http://www.cppblog.com/images/cppblog_com/billhsu/7643/o_3.JPG" small="0" class="blogimg" border="0" />
						</span>
						<br />
我的模型导出插件­</p>
				<p>
				</p>
				<p>导出数据样本：</p>
				<p>[这是一个带贴图的立方体的导出数据]</p>
				<p> </p>
				<p>8//　　8个顶点<br />
-6.70302 -21.2068 -5.46039<br />
17.1883 -6.46757  0.162097<br />
-22.4049 2.22378 -0.162097<br />
1.48644 16.963 5.46039<br />
-8.48039  -28.3257 20.7542<br />
15.411 -13.5865 26.3767<br />
-24.1823 -4.89514  26.0525<br />
-0.290929 9.84411 31.675</p>
				<p>12//　　12个纹理坐标<br />
0 1 0<br />
1 1 0<br />
0 0 0<br />
1 0 0<br />
0 1 0<br />
1 1 0<br />
0 0  0<br />
1 0 0<br />
0 1 0<br />
1 1 0<br />
0 0 0<br />
1 0 0</p>
				<p>12//　　12个面引索<br />
0 9 2 11 3 10<br />
3 10 1 8 0 9<br />
4 8 5 9 7 11<br />
7 11 6 10 4  8<br />
0 4 1 5 5 7<br />
5 7 4 6 0 4<br />
1 0 3 1 7 3<br />
7 3 5 2 1 0<br />
3 4 2 5 6  7<br />
6 7 7 6 3 4<br />
2 0 0 1 4 3<br />
4 3 6 2 2 0</p>
		</div>
<img src ="http://www.cppblog.com/billhsu/aggbug/101921.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/billhsu/" target="_blank">Bill Hsu</a> 2009-11-25 19:25 <a href="http://www.cppblog.com/billhsu/archive/2009/11/25/101921.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DirectX 3D 设备丢失(lost device)的处理</title><link>http://www.cppblog.com/billhsu/archive/2009/10/17/98823.html</link><dc:creator>Bill Hsu</dc:creator><author>Bill Hsu</author><pubDate>Sat, 17 Oct 2009 05:10:00 GMT</pubDate><guid>http://www.cppblog.com/billhsu/archive/2009/10/17/98823.html</guid><wfw:comment>http://www.cppblog.com/billhsu/comments/98823.html</wfw:comment><comments>http://www.cppblog.com/billhsu/archive/2009/10/17/98823.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/billhsu/comments/commentRss/98823.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/billhsu/services/trackbacks/98823.html</trackback:ping><description><![CDATA[
		<font color="#000000">
低手交流，高手勿入<br /><br />当初觉得DX中设备丢失很讨厌，差点就投奔OpenGL了。<br />
不过现在发现其实也没那么麻烦啦，写点东西，给不清楚</font>
		<font color="#000000">设备丢失怎么处理的同学参考下。<br /><br /></font>在创建时使用D3DPOOL_MANAGED标志的资源可以不需要重新载入，但D3DPOOL_DEFAULT加载的资源就需要先释放，后重建。<br /><br />通常需要这样处理的有ID3DXFont和ID3DXSprite，而.X模型什么的就不需要。<br />在发现设备丢失时，我们要调用 <span style="color: rgb(0, 0, 0);">OnLostDevice(</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">)</span>函数让D3DPOOL_DEFAULT加载的资源释放掉。<br />好在ID3DXFont和ID3DXSprite有设备丢失处理函数，直接调用就好了<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> OnLostDevice(</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">)<br />{<br /></span><span style="color: rgb(0, 0, 0);">    m_sprite</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">OnLostDevice();</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">    m_font</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">OnLostDevice();<br />}<br /></span></div><br />可是，怎么知道设备丢失了呢？<br />如果设备丢失，Present()函数就会“出问题”，返回值是D3DERR_DEVICELOST。<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 0);">m_pIDirect3DDevice</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">EndScene();<br /><br />HRESULT hr;<br />hr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> m_pIDirect3DDevice</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">Present(NULL, NULL, NULL, NULL);<br /></span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(hr </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> D3DERR_DEVICELOST)<br />{<br />    </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(m_pIDirect3DDevice</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">TestCooperativeLevel() </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> D3DERR_DEVICENOTRESET)<br />    {<br />        OnLostDevice();<br />        OnResetDevice();<br />    }<br />}</span></div><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 0);">TestCooperativeLevel()</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> D3DERR_DEVICENOTRESET时，就可以恢复设备了。<br />于是，我们调用</span><span style="color: rgb(0, 0, 0);">OnLostDevice(</span><span style="color: rgb(0, 0, 0);">)</span>让D3DPOOL_DEFAULT加载的资源释放掉，之后，调用<span style="color: rgb(0, 0, 0);">OnResetDevice()来恢复设备就可以了。<br /><br />怎么恢复设备呢？<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> OnResetDevice(</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">)<br />{<br />    </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(FAILED(m_pIDirect3DDevice</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">Reset(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">d3dpp)))<br />    {<br />        </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">;<br />    }<br /><br />    m_sprite</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">OnResetDevice();<br />    m_font</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">OnResetDevice();<br /><br />    InitDevice();<br />}</span></div>先让D3D设备reset，然后调用</span>ID3DXFont和ID3DXSprite的恢复函数，最后，需要把<span style="color: rgb(0, 0, 0);">D3D设备中的状态啊，矩阵变换啊这些重新设置下就完成了，也就是调用</span><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);">InitDevice()。<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> InitDevice()<br />{<br />m_pIDirect3DDevice</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">SetRenderState( D3DRS_ZENABLE, TRUE );<br /><br />m_pIDirect3DDevice</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">SetRenderState( D3DRS_AMBIENT, </span><span style="color: rgb(0, 0, 0);">0xffffffff</span><span style="color: rgb(0, 0, 0);"> );<br /><br />m_pIDirect3DDevice</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">SetSamplerState(</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);<br />m_pIDirect3DDevice</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">SetSamplerState(</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);<br />m_pIDirect3DDevice</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">SetSamplerState(</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">, D3DSAMP_MIPFILTER, D3DTEXF_POINT);<br /><br />D3DXMatrixPerspectiveFovLH( </span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">matProj, D3DX_PI</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">1.0f</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">1.0f</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">1000.0f</span><span style="color: rgb(0, 0, 0);"> );<br />m_pIDirect3DDevice</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">SetTransform( D3DTS_PROJECTION, </span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">matProj );<br /><br />vEyeVec</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">D3DXVECTOR3(</span><span style="color: rgb(0, 0, 0);">0.0f</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">0.0f</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">1.0f</span><span style="color: rgb(0, 0, 0);">);<br />vLookatVec</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">D3DXVECTOR3(</span><span style="color: rgb(0, 0, 0);">0.0f</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">0.0f</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">0.0f</span><span style="color: rgb(0, 0, 0);">);<br />vUpVec</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">D3DXVECTOR3(</span><span style="color: rgb(0, 0, 0);">0.0f</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">1.0f</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">0.0f</span><span style="color: rgb(0, 0, 0);">);<br />D3DXMatrixLookAtLH( </span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">matView, </span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">vEyeVec, </span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">vLookatVec, </span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">vUpVec );<br />m_pIDirect3DDevice</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">SetTransform( D3DTS_VIEW, </span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">matView );<br /><br />}</span></div><br /></span></span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 0);"><br /></span><font color="#000000">啊，这样设备丢失就处理好了<br /><br />//<br /></font><font color="#ffffff">tag:DirectX 3D  d3d lost device TestCooperativeLevel OnLostDevice</font><font color="#ffffff"> 恢复设备 设备丢失 DeviceLost</font><font color="#000000"><br /></font><br /><img src ="http://www.cppblog.com/billhsu/aggbug/98823.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/billhsu/" target="_blank">Bill Hsu</a> 2009-10-17 13:10 <a href="http://www.cppblog.com/billhsu/archive/2009/10/17/98823.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>游戏开发者年会2009</title><link>http://www.cppblog.com/billhsu/archive/2009/10/11/98318.html</link><dc:creator>Bill Hsu</dc:creator><author>Bill Hsu</author><pubDate>Sun, 11 Oct 2009 09:56:00 GMT</pubDate><guid>http://www.cppblog.com/billhsu/archive/2009/10/11/98318.html</guid><wfw:comment>http://www.cppblog.com/billhsu/comments/98318.html</wfw:comment><comments>http://www.cppblog.com/billhsu/archive/2009/10/11/98318.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/billhsu/comments/commentRss/98318.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/billhsu/services/trackbacks/98318.html</trackback:ping><description><![CDATA[
		<a target="_blank" href="/images/cppblog_com/billhsu/7643/o_GDCC3.JPG">
				<img class="blogimg" small="0" src="http://www.cppblog.com/images/cppblog_com/billhsu/7643/o_GDCC3.JPG" border="0" />
		</a>
		<br />
		<br />
看到了不少比较震撼的技术。<br />
感触最深的还是Cry Engine3的展台，<br />
他们的次世代效果太强大了，还有那个场景编辑器，感觉无敌了=_=<br /><br />
独立游戏展上的一些游戏创意还是很好的，可我玩不好===<br /><br /><br />
鄙视下腾讯游戏，占了好大一个台，就摆了2个显示器……<br /><br />

拍的照片<br /><br /><a target="_blank" href="/images/cppblog_com/billhsu/7643/o_GDCC1.JPG"><img class="blogimg" small="0" src="http://www.cppblog.com/images/cppblog_com/billhsu/7643/o_GDCC1.JPG" border="0" /></a><br /><br /><a target="_blank" href="/images/cppblog_com/billhsu/7643/o_GDCC2.JPG"><img class="blogimg" small="0" src="http://www.cppblog.com/images/cppblog_com/billhsu/7643/o_GDCC2.JPG" border="0" /></a><br /><br /><a target="_blank" href="/images/cppblog_com/billhsu/7643/o_GDCC4.JPG"><img class="blogimg" small="0" src="http://www.cppblog.com/images/cppblog_com/billhsu/7643/o_GDCC4.JPG" border="0" /></a><br /><br /><a target="_blank" href="/images/cppblog_com/billhsu/7643/o_GDCC5.JPG"><img class="blogimg" small="0" src="http://www.cppblog.com/images/cppblog_com/billhsu/7643/o_GDCC5.JPG" border="0" /></a><img src ="http://www.cppblog.com/billhsu/aggbug/98318.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/billhsu/" target="_blank">Bill Hsu</a> 2009-10-11 17:56 <a href="http://www.cppblog.com/billhsu/archive/2009/10/11/98318.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>3d编程的无敌组合</title><link>http://www.cppblog.com/billhsu/archive/2009/08/03/91991.html</link><dc:creator>Bill Hsu</dc:creator><author>Bill Hsu</author><pubDate>Mon, 03 Aug 2009 00:35:00 GMT</pubDate><guid>http://www.cppblog.com/billhsu/archive/2009/08/03/91991.html</guid><wfw:comment>http://www.cppblog.com/billhsu/comments/91991.html</wfw:comment><comments>http://www.cppblog.com/billhsu/archive/2009/08/03/91991.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/billhsu/comments/commentRss/91991.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/billhsu/services/trackbacks/91991.html</trackback:ping><description><![CDATA[发现有了Irrlicht+IrrNewt+IrrKlang ，3d编程就无敌了。。<br /><br />
简介一下<br /><br />
1.Irrlicht<br /><div forimg="1"><a href="http://irrlicht.sourceforge.net/images/general/irrlichtlogo.gif" target="_blank"><img src="http://irrlicht.sourceforge.net/images/general/irrlichtlogo.gif" small="0" class="blogimg" border="0" /></a></div>
Irrlicht在开源3d引擎里算很好的一个，<br />
而且它是LGPL( Lesser General Public License)协议的，你可以随意使用它。<br />
主页：<a href="http://irrlicht.sourceforge.net/" target="_blank">http://irrlicht.sourceforge.net/</a><br /><br />
2.IrrNewt<br /><div forimg="1"><a href="http://aresfps.sourceforge.net/irrnewt.gif" target="_blank"><img src="http://aresfps.sourceforge.net/irrnewt.gif" small="0" class="blogimg" border="0" height="64" width="219" /></a></div>
IrrNewt是把Newton dynamic(一个物理引擎)和Irrlicht(3d图形引擎)结合的一个库，<br />
用了它的确会让游戏效果很震撼。<br />
主页：<a href="http://aresfps.sourceforge.net/irrnewt.htm" target="_blank">http://aresfps.sourceforge.net/irrnewt.htm</a><br /><br />
3.IrrKlang<br /><div forimg="1"><a href="http://www.ambiera.com/irrklang/images/irrklang2_link_big.png" target="_blank"><img src="http://www.ambiera.com/irrklang/images/irrklang2_link_big.png" small="0" class="blogimg" border="0" height="63" width="218" /></a></div>
它是为Irrlicht设计的声音引擎，支持3d和2d声效。<br />
主页：<a href="http://www.ambiera.com/irrklang/" target="_blank">http://www.ambiera.com/irrklang/</a><img src ="http://www.cppblog.com/billhsu/aggbug/91991.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/billhsu/" target="_blank">Bill Hsu</a> 2009-08-03 08:35 <a href="http://www.cppblog.com/billhsu/archive/2009/08/03/91991.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>自己写的3D游戏</title><link>http://www.cppblog.com/billhsu/archive/2009/07/29/91578.html</link><dc:creator>Bill Hsu</dc:creator><author>Bill Hsu</author><pubDate>Wed, 29 Jul 2009 05:04:00 GMT</pubDate><guid>http://www.cppblog.com/billhsu/archive/2009/07/29/91578.html</guid><wfw:comment>http://www.cppblog.com/billhsu/comments/91578.html</wfw:comment><comments>http://www.cppblog.com/billhsu/archive/2009/07/29/91578.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cppblog.com/billhsu/comments/commentRss/91578.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/billhsu/services/trackbacks/91578.html</trackback:ping><description><![CDATA[名称：猛禽任务 Raptor Mission<br /><div forimg="1"><a target="_blank" href="/images/cppblog_com/billhsu/7643/o_RapMis1.JPG"><img class="blogimg" small="1" src="http://www.cppblog.com/images/cppblog_com/billhsu/7643/o_RapMis1.JPG" border="0" height="150" width="200" /></a></div><div forimg="1"><a target="_blank" href="/images/cppblog_com/billhsu/7643/o_RapMis2.JPG"><img class="blogimg" small="1" src="http://www.cppblog.com/images/cppblog_com/billhsu/7643/o_RapMis2.JPG" border="0" height="150" width="200" /></a></div><br />
这个游戏使用了我自己开发的开源3D引擎Rap3d。<br />
个人感觉Rap3d用起来很方便，<br />
如果您想使用，请访问Rap3d在sourceforge的项目主页。<br /><a target="_blank" href="http://rap3d.sf.net/">http://rap3d.sf.net</a><br /><br />

游戏介绍：<br />
地球被火星人占领，<br />
你驾驶人类最先进的飞船“猛禽”号，<br />
冲入了火星人基地，勇敢地战斗，<br />
地球命运，在你之手……<br /><div forimg="1"><a target="_blank" href="/images/cppblog_com/billhsu/7643/o_RapMis1.JPG"><br /></a></div><br /><div forimg="1"></div><br />
开发环境：<br />
Visual C++ 2003 &amp; Directx9.0c SDK<br />
在windows系统都可以运行<br /><br />
操作：<br />
用上下左右键控制您的飞船<br />
用控制键[Ctrl]射击,用[Esc]键退出游戏<br />
具体玩法见游戏Help.<br /><br /><br />
下载猛禽任务：<a href="http://rap3d.googlecode.com/files/Rap3d%20Demo--RaptorMission.rar"><br />http://rap3d.googlecode.com/files/Rap3d%20Demo--RaptorMission.rar</a><br />或<br /><a href="http://show.gameres.com/RaptorMission/RaptorMission.zip" target="_blank">
http://show.gameres.com/RaptorMission/RaptorMission.zip</a><br /><font color="#ff6600"><b><br />Win7/Vista使用前把包里的d3d9.dll删掉</b></font><br /><img src ="http://www.cppblog.com/billhsu/aggbug/91578.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/billhsu/" target="_blank">Bill Hsu</a> 2009-07-29 13:04 <a href="http://www.cppblog.com/billhsu/archive/2009/07/29/91578.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>自己写的Rap3d 引擎 开源发布啦</title><link>http://www.cppblog.com/billhsu/archive/2009/07/25/91123.html</link><dc:creator>Bill Hsu</dc:creator><author>Bill Hsu</author><pubDate>Sat, 25 Jul 2009 07:00:00 GMT</pubDate><guid>http://www.cppblog.com/billhsu/archive/2009/07/25/91123.html</guid><wfw:comment>http://www.cppblog.com/billhsu/comments/91123.html</wfw:comment><comments>http://www.cppblog.com/billhsu/archive/2009/07/25/91123.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/billhsu/comments/commentRss/91123.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/billhsu/services/trackbacks/91123.html</trackback:ping><description><![CDATA[Rap3d是自己写的一个轻量级3D引擎，自己觉得比较好用。<br />我在sourceforge上申请了开源项目，在那里可以下载到Rap3d SDK.<br /><a target="_blank" href="http://rap3d.sf.net/">http://rap3d.sf.net/</a><br /><br />
Rap3d SDK 中有引擎的使用说明和几个例子，上手很快的。<br /><div align="center"><p class="style1" align="left">What Rap3d can do?</p><p class="style1" align="left">1.Display 3d models</p><p class="style1" align="left">2.Bill Board,Sprite,Animation..</p><p class="style1" align="left">3.Music playing</p><p class="style1" align="left">4.Draw text on screen</p><h2 align="left"><img src="http://rap3d.sourceforge.net/images/Rap3d.jpg" /></h2><p align="left"><span class="style1"><a class="style1" target="_blank" href="http://rap3d.sourceforge.net/">http://rap3d.sf.net/</a></span></p><p align="left"><br /></p></div><img src ="http://www.cppblog.com/billhsu/aggbug/91123.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/billhsu/" target="_blank">Bill Hsu</a> 2009-07-25 15:00 <a href="http://www.cppblog.com/billhsu/archive/2009/07/25/91123.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Rap3d更新</title><link>http://www.cppblog.com/billhsu/archive/2009/06/23/88346.html</link><dc:creator>Bill Hsu</dc:creator><author>Bill Hsu</author><pubDate>Tue, 23 Jun 2009 02:12:00 GMT</pubDate><guid>http://www.cppblog.com/billhsu/archive/2009/06/23/88346.html</guid><wfw:comment>http://www.cppblog.com/billhsu/comments/88346.html</wfw:comment><comments>http://www.cppblog.com/billhsu/archive/2009/06/23/88346.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/billhsu/comments/commentRss/88346.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/billhsu/services/trackbacks/88346.html</trackback:ping><description><![CDATA[
		<img src="http://www.cppblog.com/images/cppblog_com/billhsu/7643/o_rap3d090623.JPG" width="314" height="235" />
		<br />增加了 TextureManager和 <br />BillBoard动画播放,方便渲染爆炸效果<br /><img src ="http://www.cppblog.com/billhsu/aggbug/88346.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/billhsu/" target="_blank">Bill Hsu</a> 2009-06-23 10:12 <a href="http://www.cppblog.com/billhsu/archive/2009/06/23/88346.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>游戏中CPU使用率的控制</title><link>http://www.cppblog.com/billhsu/archive/2009/06/12/87472.html</link><dc:creator>Bill Hsu</dc:creator><author>Bill Hsu</author><pubDate>Fri, 12 Jun 2009 04:00:00 GMT</pubDate><guid>http://www.cppblog.com/billhsu/archive/2009/06/12/87472.html</guid><wfw:comment>http://www.cppblog.com/billhsu/comments/87472.html</wfw:comment><comments>http://www.cppblog.com/billhsu/archive/2009/06/12/87472.html#Feedback</comments><slash:comments>18</slash:comments><wfw:commentRss>http://www.cppblog.com/billhsu/comments/commentRss/87472.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/billhsu/services/trackbacks/87472.html</trackback:ping><description><![CDATA[通常情况下，如果不处理下，再小的游戏也会让CPU使用率100%.<br />应该用Sleep(1)把多余的片段还给CPU,<br />像这样：<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">while</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">true</span><span style="color: rgb(0, 0, 0);">)<br />{<br />DWORD start_time </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> GetTickCount();<br /></span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(PeekMessage(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">msg,NULL,</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">,PM_REMOVE))<br />{<br /></span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (msg.message </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> WM_QUIT) </span><span style="color: rgb(0, 0, 255);">break</span><span style="color: rgb(0, 0, 0);">;<br />TranslateMessage(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">msg);<br />DispatchMessage(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">msg);<br />}</span><span style="color: rgb(0, 128, 0);"></span><span style="color: rgb(0, 128, 0);"></span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">update(</span><span style="color: rgb(0, 0, 255);">float</span><span style="color: rgb(0, 0, 0);">(GetTickCount() </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);"> start_time));<br /></span><span style="color: rgb(0, 0, 255);">while</span><span style="color: rgb(0, 0, 0);">((GetTickCount() </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);"> start_time) </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">30</span><span style="color: rgb(0, 0, 0);">) Sleep(</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">);<br />}</span></div><br />update(float timeDelta)是游戏逻辑与画面更新的函数。<br />效果图：<br /><img src="http://www.cppblog.com/images/cppblog_com/billhsu/7643/o_fps-ctrl.JPG" /><br /><img src ="http://www.cppblog.com/billhsu/aggbug/87472.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/billhsu/" target="_blank">Bill Hsu</a> 2009-06-12 12:00 <a href="http://www.cppblog.com/billhsu/archive/2009/06/12/87472.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>3D引擎计划</title><link>http://www.cppblog.com/billhsu/archive/2009/06/10/87356.html</link><dc:creator>Bill Hsu</dc:creator><author>Bill Hsu</author><pubDate>Wed, 10 Jun 2009 13:15:00 GMT</pubDate><guid>http://www.cppblog.com/billhsu/archive/2009/06/10/87356.html</guid><wfw:comment>http://www.cppblog.com/billhsu/comments/87356.html</wfw:comment><comments>http://www.cppblog.com/billhsu/archive/2009/06/10/87356.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/billhsu/comments/commentRss/87356.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/billhsu/services/trackbacks/87356.html</trackback:ping><description><![CDATA[暑假了，打算写一个3D游戏引擎。<br />
其实也就是把一些类封装一下，让开发更简结，以开源和实用为第一准则。<br /><br /><img src="http://www.cppblog.com/images/cppblog_com/billhsu/7643/o_rap3d.JPG" height="392" width="491" /><br /><img src ="http://www.cppblog.com/billhsu/aggbug/87356.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/billhsu/" target="_blank">Bill Hsu</a> 2009-06-10 21:15 <a href="http://www.cppblog.com/billhsu/archive/2009/06/10/87356.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>寻路算法整理</title><link>http://www.cppblog.com/billhsu/archive/2009/01/23/72513.html</link><dc:creator>Bill Hsu</dc:creator><author>Bill Hsu</author><pubDate>Fri, 23 Jan 2009 09:22:00 GMT</pubDate><guid>http://www.cppblog.com/billhsu/archive/2009/01/23/72513.html</guid><wfw:comment>http://www.cppblog.com/billhsu/comments/72513.html</wfw:comment><comments>http://www.cppblog.com/billhsu/archive/2009/01/23/72513.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/billhsu/comments/commentRss/72513.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/billhsu/services/trackbacks/72513.html</trackback:ping><description><![CDATA[整理自《Programming Game AI by example》<br /><br />1.DFS<br />优先深入每个图，直到找到目标节点<br />往往可以找到到达路线，可往往不是最优的。<br /><img src="http://www.cppblog.com/images/cppblog_com/billhsu/09-1-23-DFS.JPG" alt="09-1-23-DFS.JPG" border="0" width="503" height="551" /><br /><br /><br />2.BFS<br />广度优先地寻找目标节点。<br />往往可以找到最优路径，但耗时多。<br /><img src="http://www.cppblog.com/images/cppblog_com/billhsu/09-1-23-BFS.JPG" alt="09-1-23-BFS.JPG" border="0" width="503" height="551" /><br /><br /><br />3.Dijkstra<br />使用了动态规划（原文中称为“边放松”）//该为贪心，本人罪过<br />速度较快<br /><img src="http://www.cppblog.com/images/cppblog_com/billhsu/09-1-23-Dijkstra.JPG" alt="09-1-23-Dijkstra.JPG" border="0" width="503" height="551" /><br /><br /><br />4.A*<br />与Dijkstra相似，使用启发因子(F=G+H)，速度是以上算法里最快的。<br />可以看看：<br /><a temp_href="http://hi.baidu.com/probill/blog/item/80d71f1b19e2fe1e8718bfe5.html " href="http://hi.baidu.com/probill/blog/item/80d71f1b19e2fe1e8718bfe5.html%20">http://hi.baidu.com/probill/blog/item/80d71f1b19e2fe1e8718bfe5.html</a><br /><img src="http://www.cppblog.com/images/cppblog_com/billhsu/09-1-23-Astar.JPG" alt="09-1-23-Astar.JPG" border="0" width="503" height="551" /><br /><br />5.创建导航图<br /><img src="http://www.cppblog.com/images/cppblog_com/billhsu/09-1-23-Nav.JPG" alt="09-1-23-Nav.JPG" border="0" width="480" height="412" /><br /><img src ="http://www.cppblog.com/billhsu/aggbug/72513.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/billhsu/" target="_blank">Bill Hsu</a> 2009-01-23 17:22 <a href="http://www.cppblog.com/billhsu/archive/2009/01/23/72513.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用GDI实现3D</title><link>http://www.cppblog.com/billhsu/archive/2008/12/27/70517.html</link><dc:creator>Bill Hsu</dc:creator><author>Bill Hsu</author><pubDate>Sat, 27 Dec 2008 09:18:00 GMT</pubDate><guid>http://www.cppblog.com/billhsu/archive/2008/12/27/70517.html</guid><wfw:comment>http://www.cppblog.com/billhsu/comments/70517.html</wfw:comment><comments>http://www.cppblog.com/billhsu/archive/2008/12/27/70517.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/billhsu/comments/commentRss/70517.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/billhsu/services/trackbacks/70517.html</trackback:ping><description><![CDATA[在CSDN上看到了一个很强大的程序：用GDI实现3D,可以变换视角的查看.x文件。<br /><br />不过想想看，好像实现起来也并不难。。。<br />和所有基础的3D程序一样，先把视椎变换为单位立方体，<br /><img src="http://www.cppblog.com/images/cppblog_com/billhsu/3_thumb.jpg" alt="3_thumb.jpg" border="0" width="334" height="113" /><br />变换矩阵为：<br /><img src="http://www.cppblog.com/images/cppblog_com/billhsu/5.jpg" alt="5.jpg" border="0" width="435" height="124" /><br /><br />当然，DirectX和OpenGL里都有现成的函数：<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">OpenGL</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> gluPerspective(GLdouble fovy,<br />    GLdouble aspect,<br />    GLdouble zNear,<br />    GLdouble zFar);<br /><br /></span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">DirectX</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">D3DXMatrixPerspectiveFovLH( D3DXMATRIX </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">pOut,<br />    FLOAT fovY,<br />    FLOAT Aspect,<br />    FLOAT zn,<br />    FLOAT zf<br />); <br /></span></div><br />单位立方体中的点正交投影得到的(x,y,z)*视口变换矩阵 得到 (x',y',z')。<br />(x',y')对应屏幕点，z'为其深度，用于点的竞争。<br />把每个三角面匹配纹理用GDI基本函数画出来就可以了。<br /><br /><br />CSDN的那个程序<br /><img src="http://www.cppblog.com/images/cppblog_com/billhsu/rtwtsdgdg.JPG" alt="rtwtsdgdg.JPG" border="0" width="594" height="460" /><br /><br /><img src ="http://www.cppblog.com/billhsu/aggbug/70517.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/billhsu/" target="_blank">Bill Hsu</a> 2008-12-27 17:18 <a href="http://www.cppblog.com/billhsu/archive/2008/12/27/70517.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>A* (A-star A星)寻路算法</title><link>http://www.cppblog.com/billhsu/archive/2008/11/01/65700.html</link><dc:creator>Bill Hsu</dc:creator><author>Bill Hsu</author><pubDate>Sat, 01 Nov 2008 10:19:00 GMT</pubDate><guid>http://www.cppblog.com/billhsu/archive/2008/11/01/65700.html</guid><wfw:comment>http://www.cppblog.com/billhsu/comments/65700.html</wfw:comment><comments>http://www.cppblog.com/billhsu/archive/2008/11/01/65700.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/billhsu/comments/commentRss/65700.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/billhsu/services/trackbacks/65700.html</trackback:ping><description><![CDATA[A*在游戏寻路算法里使用很广，可是感觉很多介绍它的文章故意让人看不懂。<br />仔细看了看gamedev.net的一片文章(<span class="title">A* Pathfinding for Beginners</span>
http://www.gamedev.net/reference/articles/article2003.asp    
          )，对A*更了解了一点，写点东西记录一下。<br />A*是一种启发式的算法，所谓的"启发式"，就是对每一个搜索的位置进行评估，也就是把找的位置离目标的距离当成找点的一个依据，然后猜测这个点是否最佳("启发式"就是猜测)。<br /><br /><img src="http://www.cppblog.com/images/cppblog_com/billhsu/image001.jpg" alt="image001.jpg" border="0" width="362" height="256" /><br /><br />为了找到最佳的那个点<br />可以规定：<br />G = 从起点，沿着产生的路径，移动到网格上指定方格的距离。<br />H = 从网格上那个方格移动到终点B的预估移动距离。<br /><br />F = G + H<br />F最小的点可以认为是该选的点。<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">引用</span><span style="color: rgb(0, 0, 0);">一下原文的翻译：<br />我们令水平或者垂直移动的耗费为10，对角线方向耗费为14。我们取这些值是因为沿对角线的距离是沿水平或垂直移动耗费的的根号2（别怕），或者约1.414倍。为了简化，我们用10和14近似。比例基本正确，同时我们避免了求根运算和小数。<br /><br /><br />既然我们在计算沿特定路径通往某个方格的G值，求值的方法就是取它父节点的G值，然后依照它相对父节点是对角线方向或者直角方向(非对角线)，分别增加14和10。例子中这个方法的需求会变得更多，因为我们从起点方格以外获取了不止一个方格。<br /><br />H值可以用不同的方法估算。我们这里使用的方法被称为曼哈顿方法，它计算从当前格到目的格之间水平和垂直的方格的数量总和，忽略对角线方向。然后把结果乘以10。这被成为曼哈顿方法是因为它看起来像计算城市中从一个地方到另外一个地方的街区数，在那里你不能沿对角线方向穿过街区。很重要的一点，我们忽略了一切障碍物。这是对剩余距离的一个估算，而非实际值，这也是这一方法被称为启发式的原因。想知道更多？你可以在这里找到方程和额外的注解。<br /><br /></span></div><br /><br /><span style="color: rgb(0, 0, 0);">第一步搜索的结果可以在下面的图表中看到。F,G和H的评分被写在每个方格里。正如在紧挨起始格右侧的方格所表示的，F被打印在左上角，G在左下角，H则在右下角。</span><br /><br /><img src="http://www.cppblog.com/images/cppblog_com/billhsu/image003.jpg" alt="image003.jpg" border="0" width="362" height="255" /><br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">引用</span><span style="color: rgb(0, 0, 0);">一下原文的翻译：</span><br /><span style="color: rgb(0, 0, 0);"><br />我们做如下操作开始搜索：<br />   </span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">，从点A开始，并且把它作为待处理点存入一个“开启列表”。开启列表就像一张购物清单。尽管现在列表里只有一个元素，但以后就会多起来。你的路径可能会通过它包含的方格，也可能不会。基本上，这是一个待检查方格的列表。<br />   </span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">，寻找起点周围所有可到达或者可通过的方格，跳过有墙，水，或其他无法通过地形的方格。也把他们加入开启列表。为所有这些方格保存点A作为“父方格”。当我们想描述路径的时候，父方格的资料是十分重要的。后面会解释它的具体用途。<br />   </span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">，从开启列表中删除点A，把它加入到一个“关闭列表”，列表中保存所有不需要再次检查的方格。<br /><br />为了继续搜索，我们简单的从开启列表中选择F值最低的方格。然后，对选中的方格做如下处理：<br /><br />   </span><span style="color: rgb(0, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">，把它从开启列表中删除，然后添加到关闭列表中。<br />   </span><span style="color: rgb(0, 0, 0);">5</span><span style="color: rgb(0, 0, 0);">，检查所有相邻格子。跳过那些已经在关闭列表中的或者不可通过的(有墙，水的地形，或者其他无法通过的地形)，把他们添加进开启列表，如果他们还不在里面的话。把选中的方格作为新的方格的父节点。<br />   </span><span style="color: rgb(0, 0, 0);">6</span><span style="color: rgb(0, 0, 0);">，如果某个相邻格已经在开启列表里了，检查现在的这条路径是否更好。换句话说，检查如果我们用新的路径到达它的话，G值是否会更低一些。如果不是，那就什么都不做。<br />      另一方面，如果新的G值更低，那就把相邻方格的父节点改为目前选中的方格（在上面的图表中，把箭头的方向改为指向这个方格）。最后，重新计算F和G的值。如果这看起来不够清晰，你可以看下面的图示。</span></div><br /><br /><img src="http://www.cppblog.com/images/cppblog_com/billhsu/image004.jpg" alt="image004.jpg" border="0" width="357" height="256" /><br /><br /><img src="http://www.cppblog.com/images/cppblog_com/billhsu/image005.jpg" alt="image005.jpg" border="0" width="357" height="254" /><br /><br /><img src="http://www.cppblog.com/images/cppblog_com/billhsu/image006.jpg" alt="image006.jpg" border="0" width="404" height="307" /><br /><br /><img src="http://www.cppblog.com/images/cppblog_com/billhsu/image007.jpg" alt="image007.jpg" border="0" width="411" height="308" /><br /><br />这样就可以找到最佳路径了。<br /><br /><br /><img src ="http://www.cppblog.com/billhsu/aggbug/65700.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/billhsu/" target="_blank">Bill Hsu</a> 2008-11-01 18:19 <a href="http://www.cppblog.com/billhsu/archive/2008/11/01/65700.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>四元数入门</title><link>http://www.cppblog.com/billhsu/archive/2008/09/30/63099.html</link><dc:creator>Bill Hsu</dc:creator><author>Bill Hsu</author><pubDate>Tue, 30 Sep 2008 11:34:00 GMT</pubDate><guid>http://www.cppblog.com/billhsu/archive/2008/09/30/63099.html</guid><wfw:comment>http://www.cppblog.com/billhsu/comments/63099.html</wfw:comment><comments>http://www.cppblog.com/billhsu/archive/2008/09/30/63099.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/billhsu/comments/commentRss/63099.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/billhsu/services/trackbacks/63099.html</trackback:ping><description><![CDATA[四元数常常可以在3D的书上看到。<br />但我的那本3D图形学书上，在没讲四元数是干什么的之前，就列了几张纸的公式，<br />大概因为自己还在上高中，不知道的太多，看了半天没看懂。。。<br />终于，在gameres上看到了某强人翻译的一个“4元数宝典 ”（原文是日本人写的。。。），感觉很好，分享下。<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">★旋转篇：<br />　我将说明使用了四元数（si yuan shu, quaternion）的旋转的操作步骤<br />（</span><span style="color: rgb(0, 0, 0);">１</span><span style="color: rgb(0, 0, 0);">）四元数的虚部，实部和写法<br />所谓四元数，就是把4个实数组合起来的东西。<br />4个元素中，一个是实部，其余3个是虚部。<br />比如，叫做Q的四元数，实部t而虚部是x,y,z构成，则像下面这样写。<br />Q </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (t; x, y, z) <br />又，使用向量 V</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">(x,y,z)，<br />Q </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (t; V)  <br />也可以这么写。<br /><br />正规地用虚数单位i,j,k的写法的话，<br />Q </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> t </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> xi </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> yj </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> zk <br />也这样写，不过，我不大使用<br /><br />（</span><span style="color: rgb(0, 0, 0);">２</span><span style="color: rgb(0, 0, 0);">）四元数之间的乘法<br />虚数单位之间的乘法 <br />ii </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">, ij </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">ji </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> k (其他的组合也是循环地以下同文) <br />有这么一种规则。（我总觉得，这就像是向量积（外积），对吧） <br />用这个规则一点点地计算很麻烦，所以请用像下面这样的公式计算。<br /><br />A </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (a; U) <br />B </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (b; V) <br />AB </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (ab </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);"> U·V; aV </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> bU </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> U×V)<br />不过，“U·V”是内积，「U×V」是外积的意思。<br />注意：一般AB</span><span style="color: rgb(0, 0, 0);">&lt;&gt;</span><span style="color: rgb(0, 0, 0);">BA所以乘法的左右要注意！<br /><br />（</span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">）3次元的坐标的四元数表示<br />如要将某坐标(x,y,z)用四元数表示，<br />P </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">; x, y, z) <br />则要这么写。<br /> <br />另外，即使实部是零以外的值，下文的结果也一样。用零的话省事所以我推荐。<br /><br />（</span><span style="color: rgb(0, 0, 0);">４</span><span style="color: rgb(0, 0, 0);">）旋转的四元数表示<br />以原点为旋转中心，旋转的轴是(α, β, γ)<br />（但 α</span><span style="color: rgb(0, 0, 0);">^</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> β</span><span style="color: rgb(0, 0, 0);">^</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> γ</span><span style="color: rgb(0, 0, 0);">^</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">）， <br />（右手系的坐标定义的话，望向向量(α, β, γ)的前进方向反时针地） <br />转θ角的旋转，用四元数表示就是，<br />Q </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (cos(θ</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">); α sin(θ</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">), β sin(θ</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">), γ sin(θ</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">)) <br />R </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (cos(θ</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">); </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">α sin(θ</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">), </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">β sin(θ</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">), </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">γ sin(θ</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">)) <br />(另外R 叫 Q 的共轭四元数。） <br /><br />那么，如要实行旋转，<br /><b>则 <font color="#ff6600">R P Q<font color="#ffcc00"> </font></font></b></span><font color="#ffcc00"><b><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">0</span></b></font><span style="color: rgb(0, 0, 0);"><b><font color="#ff6600">; 答案)</font> </b><br /><br />请像这样三明治式地计算。这个值的虚部就是旋转之后的点的坐标值。<br /> （另外，实部应该为零。请验算看看） </span></div><br />例子代码<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(128, 128, 128);">///</span><span style="color: rgb(0, 128, 0);"> Quaternion.cpp <br /></span><span style="color: rgb(128, 128, 128);">///</span><span style="color: rgb(0, 128, 0);"> (C) Toru Nakata, toru-nakata@aist.go.jp <br /></span><span style="color: rgb(128, 128, 128);">///</span><span style="color: rgb(0, 128, 0);"> 2004 Dec 29 </span><span style="color: rgb(128, 128, 128);"><br /></span><span style="color: rgb(0, 0, 0);">  <br />#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">math.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"> <br />#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">iostream.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"> <br />  <br /></span><span style="color: rgb(128, 128, 128);">///</span><span style="color: rgb(0, 128, 0);"> Define Data type </span><span style="color: rgb(128, 128, 128);"><br /></span><span style="color: rgb(0, 0, 0);">typedef </span><span style="color: rgb(0, 0, 255);">struct</span><span style="color: rgb(0, 0, 0);"> <br />{ <br />              </span><span style="color: rgb(0, 0, 255);">double</span><span style="color: rgb(0, 0, 0);"> t; </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> real-component </span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">              </span><span style="color: rgb(0, 0, 255);">double</span><span style="color: rgb(0, 0, 0);"> x; </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> x-component </span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">              </span><span style="color: rgb(0, 0, 255);">double</span><span style="color: rgb(0, 0, 0);"> y; </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> y-component </span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">              </span><span style="color: rgb(0, 0, 255);">double</span><span style="color: rgb(0, 0, 0);"> z; </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> z-component </span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">} quaternion; <br />  <br /><br /></span><b><span style="color: rgb(128, 128, 128);">///</span><span style="color: rgb(0, 128, 0);">/ Bill 注：Kakezan </span></b><span style="color: rgb(128, 128, 128);"><font color="#669900"><b>在日语里是 “乘法”的意思</b></font><br /></span><span style="color: rgb(0, 0, 0);">quaternion Kakezan(quaternion left, quaternion right) <br />{ <br />              quaternion ans; <br />              </span><span style="color: rgb(0, 0, 255);">double</span><span style="color: rgb(0, 0, 0);"> d1, d2, d3, d4; <br />  <br />              d1 </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">  left.t </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> right.t; <br />              d2 </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">left.x </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> right.x; <br />              d3 </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">left.y </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> right.y; <br />              d4 </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">left.z </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> right.z; <br />              ans.t </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> d1</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> d2</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> d3</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> d4; <br />  <br />              d1 </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">  left.t </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> right.x; <br />              d2 </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">  right.t </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> left.x; <br />              d3 </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">  left.y </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> right.z; <br />              d4 </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">left.z </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> right.y; <br />              ans.x </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">  d1</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> d2</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> d3</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> d4; <br />  <br />              d1 </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">  left.t </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> right.y; <br />              d2 </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">  right.t </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> left.y; <br />              d3 </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">  left.z </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> right.x; <br />              d4 </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">left.x </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> right.z; <br />              ans.y </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">  d1</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> d2</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> d3</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> d4; <br />  <br />              d1 </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">  left.t </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> right.z; <br />              d2 </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">  right.t </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> left.z; <br />              d3 </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">  left.x </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> right.y; <br />              d4 </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">left.y </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> right.x; <br />              ans.z </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">  d1</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> d2</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> d3</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> d4; <br />              <br />              </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> ans; <br />} <br />  <br /></span><span style="color: rgb(128, 128, 128);">///</span><span style="color: rgb(0, 128, 0);">/ Make Rotational quaternion </span><span style="color: rgb(128, 128, 128);"><br /></span><span style="color: rgb(0, 0, 0);">quaternion MakeRotationalQuaternion(</span><span style="color: rgb(0, 0, 255);">double</span><span style="color: rgb(0, 0, 0);"> radian, </span><span style="color: rgb(0, 0, 255);">double</span><span style="color: rgb(0, 0, 0);"> AxisX, </span><span style="color: rgb(0, 0, 255);">double</span><span style="color: rgb(0, 0, 0);"> AxisY, </span><span style="color: rgb(0, 0, 255);">double</span><span style="color: rgb(0, 0, 0);"> AxisZ) <br />{ <br />              quaternion ans; <br />              </span><span style="color: rgb(0, 0, 255);">double</span><span style="color: rgb(0, 0, 0);"> norm; <br />              </span><span style="color: rgb(0, 0, 255);">double</span><span style="color: rgb(0, 0, 0);"> ccc, sss; <br />              <br />              ans.t </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> ans.x </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> ans.y </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> ans.z </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0.0</span><span style="color: rgb(0, 0, 0);">; <br />  <br />              norm </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> AxisX </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">  AxisX </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);">  AxisY </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">  AxisY </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);">  AxisZ </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">  AxisZ; <br />              </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(norm </span><span style="color: rgb(0, 0, 0);">&lt;=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0.0</span><span style="color: rgb(0, 0, 0);">) </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> ans; <br />  <br />              norm </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">1.0</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);"> sqrt(norm); <br />              AxisX </span><span style="color: rgb(0, 0, 0);">*=</span><span style="color: rgb(0, 0, 0);"> norm; <br />              AxisY </span><span style="color: rgb(0, 0, 0);">*=</span><span style="color: rgb(0, 0, 0);"> norm; <br />              AxisZ </span><span style="color: rgb(0, 0, 0);">*=</span><span style="color: rgb(0, 0, 0);"> norm; <br />  <br />              ccc </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> cos(</span><span style="color: rgb(0, 0, 0);">0.5</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> radian); <br />              sss </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> sin(</span><span style="color: rgb(0, 0, 0);">0.5</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> radian); <br />  <br />              ans.t </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> ccc; <br />              ans.x </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> sss </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> AxisX; <br />              ans.y </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> sss </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> AxisY; <br />              ans.z </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> sss </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> AxisZ; <br />  <br />              </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> ans; <br />} <br />  <br /></span><span style="color: rgb(128, 128, 128);">///</span><span style="color: rgb(0, 128, 0);">/ Put XYZ into  quaternion </span><span style="color: rgb(128, 128, 128);"><br /></span><span style="color: rgb(0, 0, 0);">quaternion PutXYZToQuaternion(</span><span style="color: rgb(0, 0, 255);">double</span><span style="color: rgb(0, 0, 0);"> PosX, </span><span style="color: rgb(0, 0, 255);">double</span><span style="color: rgb(0, 0, 0);"> PosY, </span><span style="color: rgb(0, 0, 255);">double</span><span style="color: rgb(0, 0, 0);"> PosZ) <br />{ <br />              quaternion ans; <br />  <br />              ans.t </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0.0</span><span style="color: rgb(0, 0, 0);">; <br />              ans.x </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> PosX; <br />              ans.y </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> PosY; <br />              ans.z </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> PosZ; <br />  <br />              </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> ans; <br />} <br />  <br /></span><span style="color: rgb(128, 128, 128);">///</span><span style="color: rgb(0, 128, 0);">// main </span><span style="color: rgb(128, 128, 128);"><br /></span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> main() <br />{ <br />              </span><span style="color: rgb(0, 0, 255);">double</span><span style="color: rgb(0, 0, 0);"> px, py, pz; <br />              </span><span style="color: rgb(0, 0, 255);">double</span><span style="color: rgb(0, 0, 0);"> ax, ay, az, th; <br />              quaternion ppp, qqq, rrr; <br />  <br />              cout </span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Point Position (x, y, z) </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);"> endl; <br />              cout </span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">  x = </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">; <br />              cin </span><span style="color: rgb(0, 0, 0);">&gt;&gt;</span><span style="color: rgb(0, 0, 0);"> px; <br />              cout </span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">  y = </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">; <br />              cin </span><span style="color: rgb(0, 0, 0);">&gt;&gt;</span><span style="color: rgb(0, 0, 0);"> py; <br />              cout </span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">  z = </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">; <br />              cin </span><span style="color: rgb(0, 0, 0);">&gt;&gt;</span><span style="color: rgb(0, 0, 0);"> pz; <br />              ppp </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> PutXYZToQuaternion(px, py, pz); <br />  <br />              </span><span style="color: rgb(0, 0, 255);">while</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">) { <br />                            cout </span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">\nRotation Degree ? (Enter 0 to Quit) </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);"> endl; <br />                            cout </span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">  angle = </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">; <br />                            cin </span><span style="color: rgb(0, 0, 0);">&gt;&gt;</span><span style="color: rgb(0, 0, 0);"> th; <br />                            </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(th </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0.0</span><span style="color: rgb(0, 0, 0);">) </span><span style="color: rgb(0, 0, 255);">break</span><span style="color: rgb(0, 0, 0);">; <br />  <br />                            cout </span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Rotation Axis Direction ? (x, y, z) </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);"> endl; <br />                            cout </span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">  x = </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">; <br />                            cin </span><span style="color: rgb(0, 0, 0);">&gt;&gt;</span><span style="color: rgb(0, 0, 0);"> ax; <br />                            cout </span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">  y = </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">; <br />                            cin </span><span style="color: rgb(0, 0, 0);">&gt;&gt;</span><span style="color: rgb(0, 0, 0);"> ay; <br />                            cout </span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">  z = </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">; <br />                            cin </span><span style="color: rgb(0, 0, 0);">&gt;&gt;</span><span style="color: rgb(0, 0, 0);"> az; <br />  <br />  <br />                            th </span><span style="color: rgb(0, 0, 0);">*=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">3.1415926535897932384626433832795</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">180.0</span><span style="color: rgb(0, 0, 0);">; </span><span style="color: rgb(128, 128, 128);">///</span><span style="color: rgb(0, 128, 0);"> Degree -&gt; radian; </span><span style="color: rgb(128, 128, 128);"><br /></span><span style="color: rgb(0, 0, 0);">  <br />                            qqq </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> MakeRotationalQuaternion(th, ax, ay, az); <br />                            rrr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> MakeRotationalQuaternion(</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">th, ax, ay, az); <br />  <br />                            ppp </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Kakezan(rrr, ppp); <br />                            ppp </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Kakezan(ppp, qqq); <br />  <br />                            cout </span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">\nAnser X = </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);"> ppp.x <br />                                          </span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">  </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">\n      Y = </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);"> ppp.y <br />                                          </span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">  </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">\n      Z = </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);"> ppp.z </span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);"> endl; <br />  <br />              } <br />  <br />              </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">; <br />}  <br /></span></div>http://staff.aist.go.jp/toru-nakata/quaternion.html<br />http://bbs.gameres.com/showthread.asp?threadid=73511<br /><br /><img src ="http://www.cppblog.com/billhsu/aggbug/63099.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/billhsu/" target="_blank">Bill Hsu</a> 2008-09-30 19:34 <a href="http://www.cppblog.com/billhsu/archive/2008/09/30/63099.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>超越3D，4D来了。。。</title><link>http://www.cppblog.com/billhsu/archive/2008/09/15/61846.html</link><dc:creator>Bill Hsu</dc:creator><author>Bill Hsu</author><pubDate>Mon, 15 Sep 2008 03:56:00 GMT</pubDate><guid>http://www.cppblog.com/billhsu/archive/2008/09/15/61846.html</guid><wfw:comment>http://www.cppblog.com/billhsu/comments/61846.html</wfw:comment><comments>http://www.cppblog.com/billhsu/archive/2008/09/15/61846.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cppblog.com/billhsu/comments/commentRss/61846.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/billhsu/services/trackbacks/61846.html</trackback:ping><description><![CDATA[在gameres上看到的，感觉很创意。。。<br>
<br>
实现方法<br>
准备两个摄像机，对准同一点，交替渲染红和绿的画面，带上红绿眼镜<img  src="http://www.cppblog.com/images/cppblog_com/slowhand/glass.jpg" class="blogimg" small="0" border="0" width="67" height="35">即可观察到4D的场景了！<br>
<br>
大家可以看看那这里，有源代码(C++&amp;D3d实现的)<br>
http://bbs.gameres.com/showthread.asp?threadid=73818<br>
<br>
<div forimg="1"><img  src="http://bbs.gameres.com/upload/sf_20089914631.jpg" class="blogimg" small="0" border="0" width="488" height="305"><br>
一个4D的例子</div><img src ="http://www.cppblog.com/billhsu/aggbug/61846.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/billhsu/" target="_blank">Bill Hsu</a> 2008-09-15 11:56 <a href="http://www.cppblog.com/billhsu/archive/2008/09/15/61846.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>irrlicht--这个引擎很强大。。。</title><link>http://www.cppblog.com/billhsu/archive/2008/08/23/59735.html</link><dc:creator>Bill Hsu</dc:creator><author>Bill Hsu</author><pubDate>Sat, 23 Aug 2008 09:53:00 GMT</pubDate><guid>http://www.cppblog.com/billhsu/archive/2008/08/23/59735.html</guid><wfw:comment>http://www.cppblog.com/billhsu/comments/59735.html</wfw:comment><comments>http://www.cppblog.com/billhsu/archive/2008/08/23/59735.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/billhsu/comments/commentRss/59735.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/billhsu/services/trackbacks/59735.html</trackback:ping><description><![CDATA[<img style="width: 472px; height: 373px;" alt="" src="http://www.cppblog.com/images/cppblog_com/billhsu/irr.JPG"><br><br>上次在sourceforge.net(大名鼎鼎的开源代码网站)上看到的，这个irrlicht真很了不起， 虽然是开源的，不过感觉已经达到那些几万美元的商业级的3D引擎上具有的特性。而且跨平台，写一次代码可以在多种操作系统上编译。<br>
<br>
支持<span><font face="Times New Roman">.3ds, .md2, .obj, .pk3, .ms3d, .bsp, .x, .bmp, .tga, .jpg, .psd, .pcx</font></span><span>等等文件，速度快的没得说，比我写的那些3D渲染库类快好几个级别。</span><span>那个UI库，也是无敌的。。。</span><br>开源的力量太强大了。<br>
<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;">百度百科：Irrlicht是一个德国神话故事中的一种动物的名字，它能够发光和飞翔，可以在大部分的沼泽地附近发现它。单词"Irrlicht"是两个德国单词（"irr"意思是疯狂的；而"Licht"意思是光）的组合。在英语中，它被译为"鬼火"。</div>
<br>
主页： <br>
http://irrlicht.sourceforge.net/  <img src ="http://www.cppblog.com/billhsu/aggbug/59735.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/billhsu/" target="_blank">Bill Hsu</a> 2008-08-23 17:53 <a href="http://www.cppblog.com/billhsu/archive/2008/08/23/59735.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>脚本引擎RapScript V0.0.0.1发布</title><link>http://www.cppblog.com/billhsu/archive/2008/08/10/58429.html</link><dc:creator>Bill Hsu</dc:creator><author>Bill Hsu</author><pubDate>Sun, 10 Aug 2008 03:05:00 GMT</pubDate><guid>http://www.cppblog.com/billhsu/archive/2008/08/10/58429.html</guid><wfw:comment>http://www.cppblog.com/billhsu/comments/58429.html</wfw:comment><comments>http://www.cppblog.com/billhsu/archive/2008/08/10/58429.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/billhsu/comments/commentRss/58429.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/billhsu/services/trackbacks/58429.html</trackback:ping><description><![CDATA[这是最近完成的RapScript的0.0.0.1版的源代码。<br>这份代码目前比较糟糕，有点乱，而且没有错误处理，但开源是一种习惯。。。<br><br>先介绍一下怎么用：<br>把RapScript.h RapScript.cpp RapStack.h加入工程，然后在自己的main.cpp里加入<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">RapScript.h</span><span style="color: #000000;">"</span><span style="color: #000000;"><br><br>RapScript&nbsp;XXX;</span></div>
<br>XXX是对象名，可以自己取。<br><br>关于函数互交：<br>比如说，你在C++中写了一个函数：<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;test(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;a,</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;b)<br>{<br>cout&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">"</span><span style="color: #000000;">In&nbsp;void&nbsp;test(int&nbsp;a,int&nbsp;b)&nbsp;a:</span><span style="color: #000000;">"</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">a</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;b:&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">b</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">endl;<br>}</span></div>
要调用它，要在写一个：<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;rap_test()<br>{<br></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;a</span><span style="color: #000000;">=</span><span style="color: #000000;">rapscript.para[</span><span style="color: #000000;">0</span><span style="color: #000000;">].v_int;</span><span style="color: #008000;">//</span><span style="color: #008000;">参数一</span><span style="color: #008000;"><br></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;b</span><span style="color: #000000;">=</span><span style="color: #000000;">rapscript.para[</span><span style="color: #000000;">1</span><span style="color: #000000;">].v_int;</span><span style="color: #008000;">//</span><span style="color: #008000;">参数二</span><span style="color: #008000;"><br></span><span style="color: #000000;">test(a,b);<br><br>}</span></div>
然后在合适的位置(比如int main()中)加入<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">rapscript.tmp_cmd.cmd_name</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">test</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br>rapscript.tmp_cmd.v_type</span><span style="color: #000000;">=</span><span style="color: #000000;">rapscript.CMD_VOID;<br>rapscript.tmp_cmd.fp_void</span><span style="color: #000000;">=</span><span style="color: #000000;">rap_test;<br>rapscript.cmd_list.push_back(rapscript.tmp_cmd);</span></div>
调用rapscript.run_rap();<br>脚本就会执行了。<br>说明一下：<br>1.在脚本中写命令时要这样：test(a;b;);//我偷懒了<br>2.所有变量用前必须声明（如int a;string b;）<br>目前只支持int 和 string<br>3.Bug超多。<br>4.if()和 for()等暂时不支持<br>5.如果你愿意修改源代码，只要合理，就会被采用，名字也会加入Author里。。。<br><br><a href="http://www.cppblog.com/Files/billhsu/RapScript.rar">下载RapScript V0.0.0.1源代码</a><br><font color="#000000">
┏━┓　　　┏━━┓　　　┏┓　　　　　<br>
┃┃┣━┳━┫━━╋━┳┳╋╋━┳━━┓<br>
┃　┫━┃┃┣━━┃┣┫┏┫┃┃┣┓┏┛<br>
┗┻┻┻┫┏┻━━┻━┻┛┗┫┏┛┗┛　<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp; ┗┛　　　　　　　　┗┛　　　　</font><br><br>  <img src ="http://www.cppblog.com/billhsu/aggbug/58429.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/billhsu/" target="_blank">Bill Hsu</a> 2008-08-10 11:05 <a href="http://www.cppblog.com/billhsu/archive/2008/08/10/58429.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>RapScript开发日志 2008.8.6</title><link>http://www.cppblog.com/billhsu/archive/2008/08/06/58176.html</link><dc:creator>Bill Hsu</dc:creator><author>Bill Hsu</author><pubDate>Wed, 06 Aug 2008 12:19:00 GMT</pubDate><guid>http://www.cppblog.com/billhsu/archive/2008/08/06/58176.html</guid><wfw:comment>http://www.cppblog.com/billhsu/comments/58176.html</wfw:comment><comments>http://www.cppblog.com/billhsu/archive/2008/08/06/58176.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/billhsu/comments/commentRss/58176.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/billhsu/services/trackbacks/58176.html</trackback:ping><description><![CDATA[今天把正则表达式引擎写好了，也就是说，可以运行这样的程序了。<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;a;<br></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;b;<br>a</span><span style="color: #000000;">=</span><span style="color: #000000;">(</span><span style="color: #000000;">1</span><span style="color: #000000;">+</span><span style="color: #000000;">2</span><span style="color: #000000;">)</span><span style="color: #000000;">*</span><span style="color: #000000;">3</span><span style="color: #000000;">*</span><span style="color: #000000;">3</span><span style="color: #000000;">;<br>b</span><span style="color: #000000;">=</span><span style="color: #000000;">a</span><span style="color: #000000;">/</span><span style="color: #000000;">3</span><span style="color: #000000;">;</span></div>
效果图：<br><img src="http://www.cppblog.com/images/cppblog_com/billhsu/7643/rap1.JPG" border="0"><br><br>估计在8月8日京奥开幕前会以源代码的形式放出第一个可用的版本，<br>支持与C++的命令互交(用RapScript调用你在C++程序中写的函数)。<br><br>很好使用的，只要把RapScript.h RapScript.cpp RapStack.h加入工程里就可以了。<br>兼容性很好，至少支持g++和VC(MFC和非MFC都支持)。<br>每行都有注释(用英文写的，为了将来国际化^_^)<br><img src="http://www.cppblog.com/images/cppblog_com/billhsu/7643/rap2.JPG" border="0"><br><br><br>  <img src ="http://www.cppblog.com/billhsu/aggbug/58176.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/billhsu/" target="_blank">Bill Hsu</a> 2008-08-06 20:19 <a href="http://www.cppblog.com/billhsu/archive/2008/08/06/58176.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>我的VC++ RPG游戏紫日2037源代码</title><link>http://www.cppblog.com/billhsu/archive/2008/07/23/56974.html</link><dc:creator>Bill Hsu</dc:creator><author>Bill Hsu</author><pubDate>Wed, 23 Jul 2008 11:04:00 GMT</pubDate><guid>http://www.cppblog.com/billhsu/archive/2008/07/23/56974.html</guid><wfw:comment>http://www.cppblog.com/billhsu/comments/56974.html</wfw:comment><comments>http://www.cppblog.com/billhsu/archive/2008/07/23/56974.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.cppblog.com/billhsu/comments/commentRss/56974.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/billhsu/services/trackbacks/56974.html</trackback:ping><description><![CDATA[<img alt="" src="http://www.cppblog.com/images/cppblog_com/billhsu/7643/o_2037.JPG"><br>
我<span>刚学游戏编程时写的程序，对初学者可能有用，希望大家喜欢 :-)<br><br>执行文件下载：<br><a target="_blank" href="http://www.cppblog.com/Files/billhsu/2037.rar">http://www.cppblog.com/Files/billhsu/2037.rar</a><br><br>源代码下载：<br><a target="_blank" href="http://www.cppblog.com/Files/billhsu/Source_2037.rar">http://www.cppblog.com/Files/billhsu/Source_2037.rar</a><br></span><br>  <img src ="http://www.cppblog.com/billhsu/aggbug/56974.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/billhsu/" target="_blank">Bill Hsu</a> 2008-07-23 19:04 <a href="http://www.cppblog.com/billhsu/archive/2008/07/23/56974.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>