﻿<?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++博客-前进的路上-随笔分类-DX</title><link>http://www.cppblog.com/wc250en007/category/14563.html</link><description>前进的路上</description><language>zh-cn</language><lastBuildDate>Sat, 17 Mar 2012 04:31:19 GMT</lastBuildDate><pubDate>Sat, 17 Mar 2012 04:31:19 GMT</pubDate><ttl>60</ttl><item><title>技能吟唱之Client/Server消息流程</title><link>http://www.cppblog.com/wc250en007/archive/2012/03/16/168078.html</link><dc:creator>Let me see see</dc:creator><author>Let me see see</author><pubDate>Fri, 16 Mar 2012 07:23:00 GMT</pubDate><guid>http://www.cppblog.com/wc250en007/archive/2012/03/16/168078.html</guid><wfw:comment>http://www.cppblog.com/wc250en007/comments/168078.html</wfw:comment><comments>http://www.cppblog.com/wc250en007/archive/2012/03/16/168078.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wc250en007/comments/commentRss/168078.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wc250en007/services/trackbacks/168078.html</trackback:ping><description><![CDATA[<p>Client<br />1.技能快捷键<br />2.判断技能CD，范围，根据技能类型设置技能目标，eg.以自身为中心的AOE技能，目标是自身<br />3.向Server发送TryUseSkill消息</p>
<p>Server<br />1.收到Client消息,使用的技能压入到&#8216;技能处理列表&#8216;中<br />&nbsp;m_skillTaskMgr.Push( TaskType_Skill, target, position, skillID, skillLvl )<br />2.在玩家每一帧中调用 m_skillTaskMgr.GetTask() 处理所有类型的任务，包括技能</p>
<p>3.判断使用技能的一些条件，eg.技能目标，技能范围...<br />&nbsp; 都满足向Client发送MsgIntonateStart开始吟唱消息<br />&nbsp; <br />&nbsp; <br />Server:<br />1.目标进入视野，如果目标正在吟唱或维持魔法，将此状态消息MsgSkillStatus发给自己<br />&nbsp; EnterMySight(pTarget)<br />&nbsp; if ( pTarget-&gt;IsIntonate() || pTarget-&gt;IsHoldSkill() )<br />&nbsp;pTarget-&gt;SendSkillStatusTo( pMe )</p>
<p><br />Client<br />1.接受到Server技能吟唱消息 MsgIntonateStart MsgSkillStatus<br />&nbsp; 参数:iSkillID, iSkillLvl, srcPlayerID, tagPlayerID, iPercent<br />&nbsp; 1). 若是自己吟唱，显示吟唱进度条 UIProgressBar::Show(...)<br />&nbsp; 2). 加入到动作队列中等待处理 GetActionQueue()-&gt;Push_Intonate(...)<br />&nbsp; <br />2. 每帧 HandleActionQueue 中处理 &#8216;技能吟唱&#8217;Intonate<br />&nbsp;1）保存吟唱的技能 skillID, skillLvl<br />&nbsp;2）播放并记录吟唱的特效 iSkillEffectID = PlayEffect(...)<br />&nbsp;3）切换到吟唱动作 SwitchActionStatus( Intonate, ...)</p>
<p>3. 吟唱结束 条件诸如：EndIntonate IntonateInterrupt HoldSkillEnd HoldSkillCancel Dead <br />&nbsp;&nbsp; 1).切换动作到idle状态<br />&nbsp;&nbsp; 2).清除播放中的吟唱特效 GetEffectMgr()-&gt;ReleaseEffect( iSkillEffectID )</p>
<p><br />&nbsp;</p><img src ="http://www.cppblog.com/wc250en007/aggbug/168078.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wc250en007/" target="_blank">Let me see see</a> 2012-03-16 15:23 <a href="http://www.cppblog.com/wc250en007/archive/2012/03/16/168078.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>世界坐标系到屏幕坐标系的转换</title><link>http://www.cppblog.com/wc250en007/archive/2012/03/03/167050.html</link><dc:creator>Let me see see</dc:creator><author>Let me see see</author><pubDate>Sat, 03 Mar 2012 06:41:00 GMT</pubDate><guid>http://www.cppblog.com/wc250en007/archive/2012/03/03/167050.html</guid><wfw:comment>http://www.cppblog.com/wc250en007/comments/167050.html</wfw:comment><comments>http://www.cppblog.com/wc250en007/archive/2012/03/03/167050.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wc250en007/comments/commentRss/167050.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wc250en007/services/trackbacks/167050.html</trackback:ping><description><![CDATA[<span class="Apple-style-span" style="word-spacing: 0px; font: medium Simsun; text-transform: none; color: rgb(0,0,0); text-indent: 0px; white-space: normal; letter-spacing: normal; border-collapse: separate; orphans: 2; widows: 2; webkit-border-horizontal-spacing: 0px; webkit-border-vertical-spacing: 0px; webkit-text-decorations-in-effect: none; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px"><span class="Apple-style-span" style="font-size: 14px; line-height: 20px; font-family: Arial; webkit-border-horizontal-spacing: 2px; webkit-border-vertical-spacing: 2px"> 
<p style="line-height: normal"><strong style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体">本人想手动实现从世界坐标系中的一点到屏幕坐标系的转换<span style="line-height: normal"><span class="Apple-converted-space">&nbsp;</span>,&nbsp;</span>网上的资料都是在讲解<span style="line-height: normal"></span>固定管线的渲染过程<span style="line-height: normal"><span class="Apple-converted-space">&nbsp;</span>,&nbsp;</span>本人的需求并不需要做 背面拣选裁剪等操作<span style="line-height: normal"><span class="Apple-converted-space">&nbsp;</span>,&nbsp;</span>所以自己来写一个<span style="line-height: normal"><span class="Apple-converted-space">&nbsp;</span>,</span>总体流程是<span style="line-height: normal"></span></span></strong></p>
<p style="line-height: normal"><strong style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体">&nbsp;</span></strong></p>
<p style="line-height: normal"><strong style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体">世界坐标系<span style="line-height: normal">-&gt;</span>视图坐标系<span style="line-height: normal">-&gt;</span>投影平面坐标系<span style="line-height: normal">-&gt;</span>屏幕坐标系<span style="line-height: normal"></span></span></strong></p>
<p style="line-height: normal"><strong style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体">&nbsp;</span></strong></p>
<p style="line-height: normal"><strong style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体"><span style="font-size: 24px; line-height: normal; font-family: 宋体">世界坐标系</span><span style="font-size: 24px; line-height: normal; font-family: 宋体">-&gt;</span><span style="font-size: 24px; line-height: normal; font-family: 宋体">视图坐标系</span></span></strong></p>
<p style="line-height: normal"><strong style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体">见本人的另外一篇<br style="line-height: normal" /></span></strong></p>
<p style="line-height: normal"><strong style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体">&nbsp;</span></strong><span style="line-height: normal"><a style="line-height: normal" href="http://hi.baidu.com/mayany/blog/item/c4e1234c067941efd72afcc2.html" target="_blank">详述世界坐标系到视图坐标系(摄像机坐标系)的矩阵变换</a></span></p>
<p style="line-height: normal"><strong style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体"><span style="font-size: 24px; line-height: normal; font-family: 宋体">视图坐标系</span><span style="font-size: 24px; line-height: normal; font-family: 宋体">-&gt;</span><span style="font-size: 24px; line-height: normal; font-family: 宋体">投影平面坐标系</span><span style="font-size: 24px; line-height: normal; font-family: 宋体">(</span><span style="font-size: 24px; line-height: normal; font-family: 宋体">透视投影</span><span style="font-size: 24px; line-height: normal; font-family: 宋体">)</span></span></strong></p>
<p style="line-height: normal"><strong style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体"><span style="line-height: normal"><img class="blogimg" style="line-height: normal" height="259" alt="" src="http://www.cppblog.com/images/cppblog_com/wc250en007/D3D/proj1.jpg" width="459" border="0" longdesc="" /></span></span></strong></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体">投影平面<span style="line-height: normal">,&nbsp;</span>在<span style="line-height: normal">D3D</span>中<span style="line-height: normal">Z = 1&nbsp;</span>且与<span style="line-height: normal">X, Y</span>轴平行的平面<span style="line-height: normal"><span class="Apple-converted-space">&nbsp;</span>,&nbsp;</span>由于透视投影<span style="line-height: normal">,&nbsp;</span>灭点在视图坐标系的原点<span style="line-height: normal">,&nbsp;</span>任意一点在该平面的投影为<span style="line-height: normal"><span class="Apple-converted-space">&nbsp;</span>.</span></span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体"></span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体">&nbsp;</span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体"><span style="line-height: normal">&nbsp;</span></span><span style="font-size: 15pt; line-height: normal; font-family: 宋体">已知视图坐标系的一点<span style="line-height: normal">P(Y , Z) ,&nbsp;</span>求 在投影平面的点<span style="line-height: normal">P(Y&#8217; , Z&#8217;) ,&nbsp;</span>角<span style="line-height: normal">a</span>未知<span style="line-height: normal"><span class="Apple-converted-space">&nbsp;</span>,</span>则<span style="line-height: normal"></span></span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体"><span style="line-height: normal">&nbsp;</span></span><span style="font-size: 15pt; line-height: normal; font-family: 宋体">由三角形相似可得<span style="line-height: normal"><span class="Apple-converted-space">&nbsp;</span>, (X Z</span>的坐标轴与上图相同<span style="line-height: normal"><span class="Apple-converted-space">&nbsp;</span>,&nbsp;</span>只是把<span style="line-height: normal">Y</span>换成<span style="line-height: normal">X</span>而已<span style="line-height: normal">)</span></span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体">Y&#8217;=<span style="line-height: normal">&nbsp;&nbsp;</span>Y * Z&#8217; / Z</span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体">X&#8217;=<span style="line-height: normal">&nbsp;&nbsp;</span>X * Z&#8217; / Z</span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体">D3D</span><span style="font-size: 15pt; line-height: normal; font-family: 宋体">中投影平面<span style="line-height: normal">Z&#8217; =1,&nbsp;</span>所以<span style="line-height: normal"></span></span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体">Y&#8217;=<span style="line-height: normal">&nbsp;&nbsp;</span>Y / Z</span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体">X&#8217;=<span style="line-height: normal">&nbsp;&nbsp;</span>X / Z</span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体">Z&#8217;=<span style="line-height: normal">&nbsp;&nbsp;</span>1</span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体">&nbsp;</span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体">由上可得变换矩阵为<span style="line-height: normal"></span></span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal">1 0 0 0</span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal">0 1 0 0</span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal">0 0 1 1</span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal">0 0 0 0</span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal">&nbsp;</span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal">&nbsp;</span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal">&nbsp;</span></p>
<p style="line-height: normal"><strong style="line-height: normal"><span style="font-size: 15pt; line-height: normal"><span style="font-size: 24px; line-height: normal">投影平面坐标系</span><span style="font-size: 24px; line-height: normal">-&gt;</span><span style="font-size: 24px; line-height: normal">屏幕坐标系</span></span></strong></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal">设投投影平面最大高宽为<span style="line-height: normal">Ph ,Pw ,</span>通过<span style="line-height: normal">Y</span>轴的最大可视角度<span style="line-height: normal">a ,&nbsp;</span>视截体的最远<span style="line-height: normal">Z</span>值<span style="line-height: normal"><span class="Apple-converted-space">&nbsp;</span>Zf&nbsp;</span>则可得出<span style="line-height: normal"><span class="Apple-converted-space">&nbsp;</span>,&nbsp;</span>投影平面的最大高度<span style="line-height: normal">Ph(Y</span>轴方向<span style="line-height: normal">)</span></span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal">&nbsp;<span style="line-height: normal"><img class="blogimg" style="line-height: normal" height="259" alt="" src="http://www.cppblog.com/images/cppblog_com/wc250en007/D3D/proj2.jpg" width="459" border="0" longdesc="" small="0" /></span><br style="line-height: normal" /></span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal"></span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体">Ph= tan( a/2 ) * Zf</span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体">通过屏幕高宽比<span style="line-height: normal">Aspect,&nbsp;</span>求出最大宽度<span style="line-height: normal">Pw</span></span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体">Pw= Ph * Aspect</span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体">&nbsp;</span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体">求得<span style="line-height: normal">Ph , Pw ,&nbsp;</span>我们可以得到投影平面到屏幕平面的转换比例<span style="line-height: normal">(</span>由于<span style="line-height: normal">Ph , Pw</span>仅是整个最大高宽的一半<span style="line-height: normal"><span class="Apple-converted-space">&nbsp;</span>,&nbsp;</span>所以屏幕最大高宽也除二<span style="line-height: normal">)</span></span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体">Yscale= (Sh/2)/Ph</span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体">Xscale= (Sw/2)/Pw</span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体">&nbsp;</span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体">则投影面上任意一点<span style="line-height: normal">P(X, Y)&nbsp;</span>到屏幕平面<span style="line-height: normal">P&#8217;(X&#8217; , Y&#8217;)</span>的转换为<span style="line-height: normal"></span></span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体">X&#8217;= Sw/2 + X * Xscale</span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体">Y&#8217;= Sh/2 - Y * Yscale</span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体">PS.</span><span style="font-size: 15pt; line-height: normal; font-family: 宋体">屏幕坐标原点在左上角<span style="line-height: normal"></span></span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体">&nbsp;</span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体">由上可得变换矩阵为<span style="line-height: normal"></span></span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal">Xscale<span class="Apple-converted-space">&nbsp;</span><span style="line-height: normal">&nbsp;</span>0<span class="Apple-converted-space">&nbsp;</span><span style="line-height: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>00</span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal">0<span class="Apple-converted-space">&nbsp;</span><span style="line-height: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>-Yscale<span class="Apple-converted-space">&nbsp;</span><span style="line-height: normal">&nbsp;</span>0 0</span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal">0<span class="Apple-converted-space">&nbsp;</span><span style="line-height: normal">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="line-height: normal">&nbsp;&nbsp;</span>0<span class="Apple-converted-space">&nbsp;</span><span style="line-height: normal">&nbsp;&nbsp;</span><span style="line-height: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>1 0</span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal">Sw/2<span class="Apple-converted-space">&nbsp;</span><span style="line-height: normal">&nbsp;&nbsp;&nbsp;</span>Sh/2<span class="Apple-converted-space">&nbsp;</span><span style="line-height: normal">&nbsp;&nbsp;&nbsp;</span>0 1</span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal; font-family: 宋体">视口默认位置为<span style="line-height: normal">(0 , 0) ,&nbsp;</span>不排除你会修改<span style="line-height: normal"><span class="Apple-converted-space">&nbsp;</span>,&nbsp;</span>所以还要加上视口在<span style="line-height: normal">windows</span>窗口的起始位置<span style="line-height: normal"><span class="Apple-converted-space">&nbsp;</span>,&nbsp;</span>可以通过<span style="line-height: normal">getviewport</span>获得 所以矩阵应为<span style="line-height: normal"></span></span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal">Xscale<span class="Apple-converted-space">&nbsp;</span><span style="line-height: normal">&nbsp;</span>0<span class="Apple-converted-space">&nbsp;</span><span style="line-height: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>0 0</span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal">0<span class="Apple-converted-space">&nbsp;</span><span style="line-height: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>-Yscale<span class="Apple-converted-space">&nbsp;</span><span style="line-height: normal">&nbsp;</span>0 0</span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal">0<span class="Apple-converted-space">&nbsp;</span><span style="line-height: normal">&nbsp;</span><span style="line-height: normal">&nbsp;&nbsp;&nbsp;</span><span style="line-height: normal">&nbsp;&nbsp;</span>0<span class="Apple-converted-space">&nbsp;</span><span style="line-height: normal">&nbsp;&nbsp;</span><span style="line-height: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Apple-converted-space">&nbsp;</span></span>1 0</span></p>
<p style="line-height: normal"><span style="font-size: 15pt; line-height: normal">Port.x +Sw/2<span style="line-height: normal">&nbsp;&nbsp;&nbsp;&nbsp;</span>Port.y +Sh/2<span class="Apple-converted-space">&nbsp;</span><span style="line-height: normal">&nbsp;&nbsp;&nbsp;</span>0 1</span></p></span></span><img src ="http://www.cppblog.com/wc250en007/aggbug/167050.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wc250en007/" target="_blank">Let me see see</a> 2012-03-03 14:41 <a href="http://www.cppblog.com/wc250en007/archive/2012/03/03/167050.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>3D编程文章（顶点坐标转换）</title><link>http://www.cppblog.com/wc250en007/archive/2011/08/19/153834.html</link><dc:creator>Let me see see</dc:creator><author>Let me see see</author><pubDate>Fri, 19 Aug 2011 01:59:00 GMT</pubDate><guid>http://www.cppblog.com/wc250en007/archive/2011/08/19/153834.html</guid><wfw:comment>http://www.cppblog.com/wc250en007/comments/153834.html</wfw:comment><comments>http://www.cppblog.com/wc250en007/archive/2011/08/19/153834.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wc250en007/comments/commentRss/153834.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wc250en007/services/trackbacks/153834.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 原文：http://ziouchen.blog.163.com/blog/static/179759234201117101223852/&nbsp; 空间中的物体需要使用三维坐标来描述，而显示器是一个二维的表面，所以在屏幕上渲染一个三维场景时，首先需要将描述空间物体的三维坐标变换为二维坐标（世界坐标到屏幕坐标），这在Direct3D中称为顶点坐标变换。顶点坐标变换通常通过矩阵来完成。可以把顶...&nbsp;&nbsp;<a href='http://www.cppblog.com/wc250en007/archive/2011/08/19/153834.html'>阅读全文</a><img src ="http://www.cppblog.com/wc250en007/aggbug/153834.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wc250en007/" target="_blank">Let me see see</a> 2011-08-19 09:59 <a href="http://www.cppblog.com/wc250en007/archive/2011/08/19/153834.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DirectX中的投影变换</title><link>http://www.cppblog.com/wc250en007/archive/2011/08/18/153722.html</link><dc:creator>Let me see see</dc:creator><author>Let me see see</author><pubDate>Thu, 18 Aug 2011 06:58:00 GMT</pubDate><guid>http://www.cppblog.com/wc250en007/archive/2011/08/18/153722.html</guid><wfw:comment>http://www.cppblog.com/wc250en007/comments/153722.html</wfw:comment><comments>http://www.cppblog.com/wc250en007/archive/2011/08/18/153722.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wc250en007/comments/commentRss/153722.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wc250en007/services/trackbacks/153722.html</trackback:ping><description><![CDATA[<span class="Apple-style-span" style="word-spacing: 0px; font: medium Simsun; text-transform: none; color: rgb(0,0,0); text-indent: 0px; white-space: normal; letter-spacing: normal; border-collapse: separate; orphans: 2; widows: 2; webkit-border-horizontal-spacing: 0px; webkit-border-vertical-spacing: 0px; webkit-text-decorations-in-effect: none; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px"><span class="Apple-style-span" style="font-size: 14px; color: rgb(51,51,51); line-height: 26px; font-family: Arial; text-align: left"> 
<p>DirectX中投影变换D3DXMatrixPerspectiveFovLH（）其实产生的变换矩阵不是将3D物体转换为2D平面画面的变换。实际上是把3D世界的物体变换到(1,1,0) (-1,1,0) (-1,-1,0) (1,-1,0) (1,1,1) (-1,1,1) (-1,-1,1) (1,-1,1)这个小盒子中。在Jim Adams 的著作&lt;Role playing games with DriectX 8.0&gt;和Frank Luna 的著作中&lt;Introduction to 3D Game Programming with DirectX9.0&gt;都把这个变换矩阵讲成从3D到2D的变换。实际上在DirectX中3D到2D的变换是由SDK自己完成的。而我们要做的是把3D世界变换到上面那个小盒子中。</p>
<p><span style="font-size: 11pt; color: rgb(1,0,1); font-family: 新宋体"><span style="font-family: 'Times New Roman'">这个变换矩阵是投影变换的预变换。</span></span></p>
<p><span style="font-size: 11pt; color: rgb(1,0,1); font-family: 新宋体"><span style="font-family: 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在DirectX中，把视口的高作为3D世界里面的长度：2.0f来使用的，一个视点观察世界的视野范围在Y轴上无论什么情况下都是 -1.0f到1.0f（这一点在后面来证明）。把视口的高作为y轴，顶端坐标为（x，1），底端坐标为（x，-1）。</span></span></p>
<p>&nbsp;</p>
<p><span style="font-size: 11pt; color: rgb(1,0,1); font-family: 新宋体"><span style="font-family: 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;视口：在窗体中显示3D的矩形范围，可以通过D3DDevice的SetViewPort（）来设置大小，默认的大小为窗体的大小。</span></span></p>
<p>&nbsp;</p>
<p><span style="font-size: 11pt; color: rgb(1,0,1); font-family: 新宋体"><span style="font-family: 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;变换的过程就是把点的向量乘以变换矩阵，可以得到这个点在新坐标系的对应向量，在投影变换矩阵中Z轴的值落在0~1之内，也就是说3D世界里所有的点都会被投影到以上描述的小盒子中。</span></span></p>
<p><span style="font-size: 11pt; color: rgb(1,0,1); font-family: 新宋体"><span style="font-family: 'Times New Roman'">我们用函数D3DXMatrixPerspectiveFovLH来获得该&#8220;投影变换&#8221;矩阵。</span></span></p>
<p><span style="font-size: 11pt; color: rgb(1,0,1); font-family: 新宋体"><span style="font-family: 'Times New Roman'">D3DXMATRIX * D3DXMatrixPerspectiveFovLH(</span></span></p>
<p><span style="font-size: 11pt; color: rgb(1,0,1); font-family: 新宋体"><span style="font-family: 'Times New Roman'">&nbsp;D3DXMATRIX *<em>pOut</em>,</span></span></p>
<p><span style="font-size: 11pt; color: rgb(1,0,1); font-family: 新宋体"><span style="font-family: 'Times New Roman'">&nbsp;FLOAT<span class="Apple-converted-space">&nbsp;</span><em>fovy</em>,</span></span></p>
<p><span style="font-size: 11pt; color: rgb(1,0,1); font-family: 新宋体"><span style="font-family: 'Times New Roman'">&nbsp;FLOAT<span class="Apple-converted-space">&nbsp;</span><em>Aspect</em>,</span></span></p>
<p><span style="font-size: 11pt; color: rgb(1,0,1); font-family: 新宋体"><span style="font-family: 'Times New Roman'">&nbsp;FLOAT<span class="Apple-converted-space">&nbsp;</span><em>zn</em>,</span></span></p>
<p><span style="font-size: 11pt; color: rgb(1,0,1); font-family: 新宋体"><span style="font-family: 'Times New Roman'">&nbsp;FLOAT<span class="Apple-converted-space">&nbsp;</span><em>zf</em></span></span></p>
<p><span style="font-size: 11pt; color: rgb(1,0,1); font-family: 新宋体"><span style="font-family: 'Times New Roman'">);</span></span></p>
<p><span style="font-size: 11pt; color: rgb(1,0,1); font-family: 新宋体"><span style="font-family: 'Times New Roman'">其中参数fovy为y轴上的视角，Aspect为高宽比，zn为近裁面，zf为远裁面。</span></span></p>
<p>&nbsp;</p>
<p>Y轴的视角：在DirectX的帮助文档中描述fovy为filed of view in y direction。</p>
<p>&nbsp;</p>
<p>高宽比：一般用于全屏显示，如果我们要让3D世界充满整个窗口，就必须让高宽比等于窗口的高宽比，例如让我们的窗口正常显示&#8221;标准视野&#8221;[2X2 的一个面,顶点坐标为（1，1），（-1，1），（-1，-1），（1，-1）]，我们必须把窗口的高宽比设置成1：1，这样，标准视野就可以充满整个窗口，否则 会在左右留出空白，这个空白是无法用VIEW，WORLD变换所能填充的，相当于word文档采用&#8220;文档&#8221;视图里面的两边的灰色区域，是无法编辑的，在一般的3D程序里面是不允许出现这种情况的，但是我们的显示器的高宽比不是1：1，而且大部分的用户也不习惯用1：1的窗口来使用程序，我们需要调整这个标准视野，来适应我们的窗口大小，Aspect就是这个作用，有一点需要说明的Aspect不等于1，不代表标准视野就不是（1，1），（-1，1），（-1，-1），（1，-1），如果Aspect = 0.5 标准视野也还是（1，1），（-1，1），（-1，-1），（1，-1），只不过x轴上的单位长度的像素值 是 y轴上单位长度的像素值的2倍。</p>
<p>&nbsp;</p>
<p><span style="font-size: 11pt; color: rgb(1,0,1); font-family: 新宋体"><span style="font-family: 'Times New Roman'">裁面的作用: 在Z轴方向上，不显示z坐标小于zn的或者大于 zf的点。</span></span></p>
<p><span style="font-size: 11pt; color: rgb(1,0,1); font-family: 新宋体"><span style="font-family: 'Times New Roman'"><img style="border-top-style: none; border-right-style: none; border-left-style: none; border-bottom-style: none" height="203" alt="" src="http://images.cnblogs.com/cnblogs_com/baker_lee/projection2.JPG" width="297" border="0" /></span></span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在上图中，紫红色的线为我们要显示的面，红色的弧就是上面函数fovy<span style="font-family: 'Times New Roman'"><span style="font-family: 宋体">的夹角，当这个夹角为</span>90<span style="font-family: 宋体">&#176;的时候，我们窗口的视野为标准视野，当夹角缩小时，可视范围就变小，如图，从</span>90<span style="font-family: 宋体">&#176;变为</span>60<span style="font-family: 宋体">&#176;的时候，可视范围变小了，要显示的面，相对于可以范围变大了，由于我们的窗口是不变的，也就是说实际显示的像素值不变，要显示的面就相对于变大，</span>fovy<span style="font-family: 宋体">的值变小的结果就是把要显示的面变大。</span></span></p>
<p><span style="font-family: 'Times New Roman'"><span style="font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;当</span>fovy<span style="font-family: 宋体">为</span>0<span style="font-family: 宋体">的时候呢，视野就为</span>0<span style="font-family: 宋体">，就是说什么都看不到，窗口中显示的就是底色。</span></span></p>
<p><span style="font-family: 'Times New Roman'"><span style="font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;当</span>fovy<span style="font-family: 宋体">变大至</span>180<span style="font-family: 宋体">&#176;的时候呢？</span><span style="font-family: 宋体">视野的范围为视线夹角上的垂直于</span>Z<span style="font-family: 宋体">轴的且过点（</span>0<span style="font-family: 宋体">，</span>0<span style="font-family: 宋体">，</span>1<span style="font-family: 宋体">）的连线。当视线夹角变大视野范围也变大，夹角趋近于</span>180<span style="font-family: 宋体">&#176;的时候视野范围趋近于无穷大，要显示的面相对于视野范围就是</span>0<span style="font-family: 宋体">，也就是说缩小到最小就是</span>0.<span style="font-family: 宋体">所以我们在设定</span>fovy<span style="font-family: 宋体">的值为</span>180<span style="font-family: 宋体">&#176;的时候也是什么都看不见，为底色。</span></span></p>
<p><span style="font-family: 'Times New Roman'"><span style="font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;那大于</span>180<span style="font-family: 宋体">&#176;的情况呢？在我们的视野理论上是不存在这种情况的，当视角大于</span>180<span style="font-family: 宋体">&#176;时，视角于</span>Z<span style="font-family: 宋体">轴垂直的连线是不会过点（</span>0<span style="font-family: 宋体">，</span>0<span style="font-family: 宋体">，</span>1<span style="font-family: 宋体">）的。但是函数放在我们面前，我们是可以输入大于</span>180<span style="font-family: 宋体">&#176;的数值，结果会如何呢？</span></span></p>
<p><span style="font-family: 'Times New Roman'"><span style="font-family: 宋体">非常神奇的事情发生了，我们的图以原点为中心旋转了</span>180<span style="font-family: 宋体">&#176;！这是无法用我们的视野理论来解释的</span>,<span style="font-family: 宋体">因为</span>180<span style="font-family: 宋体">&#176;的视野范围就已经是个极限了，&#8220;超越极限&#8221;是只能在广告中出现的词汇（如果能超越，那就不叫极限了：</span>P<span style="font-family: 宋体">）。</span></span></p>
<p><span style="font-family: 'Times New Roman'"><span style="font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在</span>MSDN<span style="font-family: 宋体">的文档中有这样一个数学公式：</span>y-scale = cot<span style="font-family: 宋体">（</span>fovy/2<span style="font-family: 宋体">）</span></span></p>
<p><span style="font-family: 'Times New Roman'"><span style="font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这下就明白了，当我们输入大于</span>180<span style="font-family: 宋体">&#176;的时候</span>cot<span style="font-family: 宋体">的值为负数。而</span>x-scale = y-scale/ Aspect<span style="font-family: 宋体">。</span>.</span></p>
<p><span style="font-family: 'Times New Roman'"><span style="font-family: 宋体">也就是说，一个</span>3D<span style="font-family: 宋体">世界的点，在视野大于</span>180<span style="font-family: 宋体">&#176;的作用下，它的放大</span>/<span style="font-family: 宋体">缩小倍数不变，但是需要对</span>X<span style="font-family: 宋体">轴做一次对称变换，还要对</span>Y<span style="font-family: 宋体">轴做一次对称变换。相当于对原点做一次对称变换。</span></span></p>
<p><span style="font-family: 宋体"><span style="font-family: 'Times New Roman'">拿到这个公式，我们就可以对前面的标准做一个证明：</span></span></p>
<p><span style="font-family: 'Times New Roman'"><span style="font-family: 宋体">当</span>fovy<span style="font-family: 宋体">为</span>90<span style="font-family: 宋体">&#176;</span><span class="Apple-converted-space">&nbsp;</span>Aspect = 1<span style="font-family: 宋体">的时候，就是说</span>y-scale = cot<span style="font-family: 宋体">（</span>45<span style="font-family: 宋体">&#176;）</span><span class="Apple-converted-space">&nbsp;</span>= 1</span></p>
<p>x-scale = 1<span style="font-family: 'Times New Roman'"><span style="font-family: 宋体">，这时</span>y<span style="font-family: 宋体">和</span>x<span style="font-family: 宋体">的缩放比都为</span>1<span style="font-family: 宋体">，没有缩放。我们显示这样一个面</span></span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {-1.0f, -1.0f, 0.0f},</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {-1.0f, 1.0f, 0.0f},</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { 1.0f, 1.0f, 0.0f},</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {-1.0f, -1.0f, 0.0f},</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { 1.0f, 1.0f, 0.0f},</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { 1.0f,-1.0f, 0.0f}</p>
<p><span style="font-family: 'Times New Roman'"><span style="font-family: 宋体">我们会发现无论怎么改变窗口的高度，这个画面的</span>Y<span style="font-family: 宋体">轴方向上都会充满整个视口。（如果我们把视口的高度和宽度设置成一样的，在</span>X<span style="font-family: 宋体">轴上也会充满整个视口）所以</span>DirectX<span style="font-family: 宋体">会以视口的高度的二分之一作为</span>Y<span style="font-family: 宋体">轴的单位长度。</span></span></p></span></span><img src ="http://www.cppblog.com/wc250en007/aggbug/153722.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wc250en007/" target="_blank">Let me see see</a> 2011-08-18 14:58 <a href="http://www.cppblog.com/wc250en007/archive/2011/08/18/153722.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MipMap</title><link>http://www.cppblog.com/wc250en007/archive/2011/08/06/152653.html</link><dc:creator>Let me see see</dc:creator><author>Let me see see</author><pubDate>Sat, 06 Aug 2011 09:51:00 GMT</pubDate><guid>http://www.cppblog.com/wc250en007/archive/2011/08/06/152653.html</guid><wfw:comment>http://www.cppblog.com/wc250en007/comments/152653.html</wfw:comment><comments>http://www.cppblog.com/wc250en007/archive/2011/08/06/152653.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wc250en007/comments/commentRss/152653.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wc250en007/services/trackbacks/152653.html</trackback:ping><description><![CDATA[<span class="Apple-style-span" style="word-spacing: 0px; font: 16px Arial, Helvetica; text-transform: none; color: rgb(102,102,102); text-indent: 0px; white-space: normal; letter-spacing: normal; border-collapse: separate; orphans: 2; widows: 2; webkit-border-horizontal-spacing: 0px; webkit-border-vertical-spacing: 0px; webkit-text-decorations-in-effect: none; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px"><span class="Apple-style-span" style="font-size: 12px; line-height: 30px">首先从MIPMAP的原理说起，它是把一张贴图按照2的倍数进行缩小。直到1X1。把缩小的图都存储起来。在渲染时，根据一个像素离眼睛为之的距离，来判断从一个合适的图层中取出texel颜色赋值给像素。在D3D和OGL都有相对应的API控制接<br />口<img height="208" alt="" src="http://www.cppblog.com/images/cppblog_com/wc250en007/D3D/MipMap.jpg" width="428" border="0" longdesc="" /><br /><br /><span class="Apple-style-span" style="word-spacing: 0px; font: 16px Arial, Helvetica; text-transform: none; color: rgb(102,102,102); text-indent: 0px; white-space: normal; letter-spacing: normal; border-collapse: separate; orphans: 2; widows: 2; webkit-border-horizontal-spacing: 0px; webkit-border-vertical-spacing: 0px; webkit-text-decorations-in-effect: none; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px"><span class="Apple-style-span" style="font-size: 12px; line-height: 30px">透过它的工作原理我们可以发现，硬件总是根据眼睛到目标的距离，来玄奇最适合当前屏幕像素分辨率的图层。假设一张32768x32768的mipmap贴图，当前屏幕分辨率为1024*1024。眼睛距离物体比较近时，mipmap最大也只可能从1024*1024的Mipmap图层选取texel。再次，当使用三线性过滤（trilinear）时，最大也只能访问2048*2048的图层选取texel，来和1024*1024图层中的像素进行线性插值。<img height="144" alt="" src="http://www.cppblog.com/images/cppblog_com/wc250en007/D3D/MipMap1.jpg" width="514" border="0" /><br /><br /><span class="Apple-style-span" style="word-spacing: 0px; font: 16px sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; white-space: normal; letter-spacing: normal; border-collapse: separate; orphans: 2; widows: 2; webkit-border-horizontal-spacing: 0px; webkit-border-vertical-spacing: 0px; webkit-text-decorations-in-effect: none; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px"><span class="Apple-style-span" style="font-size: 15px; line-height: 22px">为了加快渲染速度和减少图像锯齿，贴图被处理成由一系列被预先计算和优化过的图片组成的文件,这样的贴图被称为 MIP map 或者 mipmap</span></span><br /><br /><span class="Apple-style-span" style="word-spacing: 0px; font: medium Simsun; text-transform: none; color: rgb(0,0,0); text-indent: 0px; white-space: normal; letter-spacing: normal; border-collapse: separate; orphans: 2; widows: 2; webkit-border-horizontal-spacing: 0px; webkit-border-vertical-spacing: 0px; webkit-text-decorations-in-effect: none; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px"><span class="Apple-style-span" style="font-size: 13px; color: rgb(32,32,32); line-height: 19px; font-family: Monaco, Consolas, 'Microsoft YaHei', 'Segoe UI', Tahoma">&nbsp; 
<p style="margin: 10px 0px">多级渐进纹理由一组分辨率逐渐降低的纹理序列组成，每一级纹理宽度和高度都是上一级纹理宽度和高度的一半。宽和高不一定相等，也就是说，这些纹理不一定都是正方形。</p>
<p style="margin: 10px 0px">Direct3D在纹理映射时，自动选择一幅与物体大小最接近的纹理进行渲染。当物体离投影平面较远时，Direct3D会选择一张尺寸较小、分辨率较低的纹理进行渲染；当物体离投影平面较近时，Direct3D会选择一张尺寸较大、分辨率较高的纹理进行渲染。Direct3D将纹理序列看成一条多级渐进纹理链。链头处纹理的分辨率最高，下一级往后依次递减，链尾处纹理的分辨率最低。</p>
<p style="margin: 10px 0px">Direct3D能估计出多级渐进纹理链中哪幅纹理的分辨率最接近想要的输出结果，然后它将像素映射到纹理空间。当最终显示的图形<span style="color: red">大小介于任意两级纹理图形之间</span><span style="color: red">时，Direct3D将两级纹理的相应元素进行混合后显示。</span></p>
<p style="margin: 10px 0px">多级渐进纹理过滤能够有效地<span style="color: red">提高图形渲染速度</span>，<span style="color: red">当物体离投影平面较远时，Direct3D会选择一张尺寸较小的纹理进行渲染，而无需经过复杂的诸如各项异性纹理过滤</span>，并且由于这时纹理需要的显存比不使用多级渐进纹理时小，因此能有效地<span style="color: red">减少纹理载入显存的时间。</span></span></span>缺点是对内存的要求比较高<br /><img alt="" src="http://www.cppblog.com/images/cppblog_com/wc250en007/D3D/MipMap_Example_STS101.jpg" border="0" /><br /><br /><span class="Apple-style-span" style="word-spacing: 0px; font: medium Simsun; text-transform: none; color: rgb(0,0,0); text-indent: 0px; white-space: normal; letter-spacing: normal; border-collapse: separate; orphans: 2; widows: 2; webkit-border-horizontal-spacing: 0px; webkit-border-vertical-spacing: 0px; webkit-text-decorations-in-effect: none; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px"><span class="Apple-style-span" style="font-size: 13px; color: rgb(32,32,32); line-height: 19px; font-family: Monaco, Consolas, 'Microsoft YaHei', 'Segoe UI', Tahoma"></p>
<p style="margin: 10px 0px"><strong>设置多级渐进纹理过滤方式</strong></p>
<p style="margin: 10px 0px">当最终显示的纹理贴图大小介于任意两级纹理之间时，Direct3D能够取得两级纹理元素进行混合后显示，具体的混合方式由指定的多级渐进纹理过滤方式决定。可以调用函数IDirect3DDevice9::SetSamplerState()设置多级渐进纹理过滤方式，将第一个参数设为纹理层序号，第二个参数设为D3DSAMP_MIPFILTER表示多级渐进纹理过滤，第三个参数设为在相邻纹理级之间的过滤方式，可取枚举类型D3DTEXTUREFILTERTYPE的任意值。下面的示例代码设置相邻纹理级之间的过滤方式为线性过滤。</p>
<p style="margin: 10px 0px"><font color="#004080">g_device-&gt;SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);</font></p>
<p style="margin: 10px 0px"><font color="#800000">如果将第三个参数设为D3DTEXF_NONE，那么就会一直使用最高一级的纹理，即禁用多级渐进纹理过滤。如果将其设为D3DTEXF_POINT，就会只使用与图元大小最匹配的一级纹理。如果将其设为D3DTEXF_LINEAR，Direct3D就将与图元大小最匹配的两级纹理以线性方式混合。</font></p>
<p style="margin: 10px 0px"><font color="#800000">需要注意的是，多级纹理过滤是缩小和放大过滤器的结合。例如，如果将缩小和方法过滤器设为线性过滤，但是多级纹理过滤方式设为最近点采样，Direct3D就会选择与要显示的纹理贴图大小最接近的纹理级别，在该级纹理上完成双线性纹理过滤，并将结果作为像素的值。如果将缩小、放大过滤器和多级渐进纹理都设置为线性过滤，则Direct3D就会在两个最接近的纹理级别上都进行双线性纹理过滤，然后再对相邻两级纹理图形上对应的两个纹理颜色进行加权平均，最后的结果作为单个像素值。这种为了图元中的一个像素，而结合了两幅纹理，共8个像素的技术，称为&#8220;三线性过滤&#8221;，因为它在纹理的三个方向----u、 v和纹理级别上都进行了线性过滤。</font></p>
<p style="margin: 10px 0px">可以通过IDirect3DDevice9::SetSamplerState()函数设置实际渲染时纹理过滤的最大级数，其中需要将第二个参数设为D3DSAMP_MAXMIPLEVEL，第三个参数设为实际渲染时纹理过滤的最大级数。下面的示例代码设置纹理层0的最大多级纹理过滤级数为16。</p>
<p style="margin: 10px 0px"><font color="#004080">g_device-&gt;SetSamplerState(0, D3DSAMP_MAXMIPLEVEL, 16);</font></p>
<p style="margin: 10px 0px">还可以通过将IDirect3DDevice9::SetSamplerState()的第二个参数设为D3DSAMP_MIPMAPLODBIAS，设置多级纹理映射级数偏移值。如果对某个纹理映射设置正偏移值，得到的图形结果就会比原来的更清晰，但锯齿更多；反之设为负偏移值，得到的图形结果就会更模糊。</p>
<p style="margin: 10px 0px">代码：<a title="实例下载" href="/Files/wc250en007/D3D/TextQuad纹理映射.rar">实例下载</a></span></span></span></span></span></span></p><img src ="http://www.cppblog.com/wc250en007/aggbug/152653.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wc250en007/" target="_blank">Let me see see</a> 2011-08-06 17:51 <a href="http://www.cppblog.com/wc250en007/archive/2011/08/06/152653.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>推导相机变换矩阵(转)</title><link>http://www.cppblog.com/wc250en007/archive/2011/07/31/152124.html</link><dc:creator>Let me see see</dc:creator><author>Let me see see</author><pubDate>Sun, 31 Jul 2011 02:02:00 GMT</pubDate><guid>http://www.cppblog.com/wc250en007/archive/2011/07/31/152124.html</guid><wfw:comment>http://www.cppblog.com/wc250en007/comments/152124.html</wfw:comment><comments>http://www.cppblog.com/wc250en007/archive/2011/07/31/152124.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/wc250en007/comments/commentRss/152124.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wc250en007/services/trackbacks/152124.html</trackback:ping><description><![CDATA[<span style="word-spacing: 0px; font: medium Simsun; text-transform: none; color: rgb(0,0,0); text-indent: 0px; white-space: normal; letter-spacing: normal; border-collapse: separate; orphans: 2; widows: 2; webkit-border-horizontal-spacing: 0px; webkit-border-vertical-spacing: 0px; webkit-text-decorations-in-effect: none; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px"><span style="font-size: 14px; color: rgb(51,51,51); line-height: 26px; font-family: Arial">
<p style="word-break: break-all; background-color: white; text-align: left; background-origin: initial; background-clip: initial" align="left"><span style="color: black; font-family: 宋体"><span style="font-size: small">-</span></span><span style="color: black; font-family: 宋体"><span style="font-size: small">潘宏</span><br /></span><span style="font-size: small"><span style="color: black; font-family: 宋体">-2009.12.31</span></span></p>
<p style="word-break: break-all; background-color: white; text-align: left; background-origin: initial; background-clip: initial" align="left"><span style="font-size: small"><span style="color: black; font-family: 宋体">-</span><span style="color: black; font-family: 宋体">本人水平有限，疏忽错误在所难免，还请各位数学高手、编程高手不吝赐教</span></span></p>
<p style="word-break: break-all; background-color: white; text-align: left; background-origin: initial; background-clip: initial" align="left"><span style="font-size: small"><span style="color: black; font-family: 宋体">-email:&nbsp;</span><span style="color: black; font-family: 宋体"><a style="color: rgb(51,102,153); text-decoration: none" href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#112;&#111;&#112;&#121;&#121;&#64;&#110;&#101;&#116;&#101;&#97;&#115;&#101;&#46;&#99;&#111;&#109;"><span style="text-decoration: none">popyy@netease.com</span></a><br /><br />原文地址：<a href="http://blog.csdn.net/popy007/article/details/5120158">http://blog.csdn.net/popy007/article/details/5120158</a><br /></span></span></p>
<p>&nbsp;</p>
<p style="text-indent: 21pt"><span style="font-size: small"><span style="font-family: 宋体">一些网友写信给我希望能够了解固定流水线中世界空间到相机空间变换矩阵的具体推导过程。其实之前我在《向量几何在游戏编程中的使用</span><span style="font-family: Calibri">6</span><span style="font-family: 宋体">》中已经简单的把相机变换作为一个使用基理论的例子进行了说明，但可能仍然不够具体。这篇文章中，我会尽力阐述相机变换的整个来龙去脉。希望能够对正在学习固定流水线的朋友们有所帮助。这里我们仍然会在推导相机变换之前介绍几个理论知识，目的是为了更好的理解推导过程。我们马上开始！</span></span></p>
<h1><span style="font-family: 宋体"><span style="font-size: x-large">什么是相机变换？</span></span></h1>
<p style="text-indent: 21pt"><span style="font-family: 宋体"><span style="font-size: small">在流水线中，当物体从模型坐标通过世界矩阵变换到世界空间之后，它将通过相机变换从世界空间变换到相机空间。下图的固定流水线中，蓝色框中的部分就是这个过程。</span></span></p>
<p style="text-indent: 21pt">&nbsp;</p>
<p style="text-indent: 21pt">&nbsp;</p>
<p style="text-indent: 21pt">&nbsp;</p>
<p style="text-indent: 21pt"><span style="font-family: 宋体"><img style="border-top-style: none; border-right-style: none; border-left-style: none; border-bottom-style: none" height="479" alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/popy007/EntryImages/20100102/pipeline.jpg" width="505" /></span></p>
<p style="text-indent: 21pt">&nbsp;</p>
<p style="text-indent: 21pt">&nbsp;</p>
<p>&nbsp;</p>
<p style="text-indent: 21pt"><span style="font-family: 宋体"><span style="font-size: small">其实，所谓的相机空间，就是以相机作为坐标原点的一个参考系，所以，从世界空间变换到相机空间，就是把物体从世界坐标系，变换到相机为原点的相机坐标系，如下图所示。</span></span></p>
<p style="text-indent: 21pt">&nbsp;</p>
<p style="text-indent: 21pt">&nbsp;</p>
<p>&nbsp;</p>
<p style="text-indent: 21pt"><span style="font-family: 宋体"><img style="border-top-style: none; border-right-style: none; border-left-style: none; border-bottom-style: none" height="439" alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/popy007/EntryImages/20100102/view_space.jpg" width="546" /></span></p>
<p>&nbsp;</p>
<p><span style="font-size: small"><span style="font-family: 宋体">左半部分是小人在世界空间中的位置，右半部分是小人变换到相机空间后的位置。这样的一个变换可以有很多种方式来实现：欧拉相机系统、</span><span style="font-family: Calibri">UVN</span><span style="font-family: 宋体">系统、</span><span style="font-family: Calibri">Two Points &amp; A Twist</span><span style="font-family: 宋体">等等。这里我们讨论最为广泛的</span><span style="font-family: Calibri">UVN</span><span style="font-family: 宋体">系统构建相机矩阵，如果读者对其他方法感兴趣，可以查找相关的资料。我们仍然讨论</span><span style="font-family: Calibri">OpenGL</span><span style="font-family: 宋体">的相机矩阵的推导，其他</span><span style="font-family: Calibri">API</span><span style="font-family: 宋体">可以类似的推导。</span></span></p>
<h1><span style="font-family: 宋体"><span style="font-size: x-large">坐标转换公式</span></span></h1>
<p style="text-indent: 20.25pt"><span style="font-size: small"><span style="font-family: 宋体">我们在《向量几何在游戏编程中的使用</span><span style="font-family: Calibri">6</span><span style="font-family: 宋体">》中提到了正交矩阵，这是在基理论基础上的一个概念（如果对基理论不是很熟悉，请参考《向量几何在游戏编程中的使用</span><span style="font-family: Calibri">6</span><span style="font-family: 宋体">》）。正交矩阵所有列（行）向量构成了一个<strong>标准正交基</strong>（它的列向量都是互相正交，并且长度为</span><span style="font-family: Calibri">1</span><span style="font-family: 宋体">），因此，可以把正交矩阵看成是对一个坐标系的描述。同时，我们知道：<strong>同一个向量，在不同的基下面的坐标是不同的</strong>。因此，可以用正交矩阵来代表坐标系（也可以看作基）从而写出在统一的参考系（全局坐标系）下同一个向量在不同基中的坐标。</span></span></p>
<p style="text-indent: 20.25pt">&nbsp;</p>
<p>&nbsp;</p>
<p><span style="font-size: small"><span style="font-family: 宋体"><img style="border-top-style: none; border-right-style: none; border-left-style: none; border-bottom-style: none" height="114" alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/popy007/EntryImages/20100102/qvrv1.jpg" width="352" /></span></span></p>
<p>&nbsp;</p>
<p><span style="font-size: small"></span></p>
<p><span style="font-family: 宋体">上面的式子表示，参考系中向量</span>v<span style="font-family: 宋体">在基</span>Q<span style="font-family: 宋体">中的坐标是</span>v&#8217;<span style="font-family: 宋体">，在基</span>R<span style="font-family: 宋体">中的坐标是</span>v&#8217;&#8217;<span style="font-family: 宋体">（注意这里的环境下基矩阵是用列向量表示的，这样相乘之后的结果表示的是基向量的线性组合）。如下图，黑色基表示的是参考系，红色是基</span>Q<span style="font-family: 宋体">，蓝色是基</span>R<span style="font-family: 宋体">，</span>v<span style="font-family: 宋体">是参考系中的一个向量。</span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体"><img style="border-top-style: none; border-right-style: none; border-left-style: none; border-bottom-style: none" height="193" alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/popy007/EntryImages/20100102/ref_qr.jpg" width="245" /></span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体"><span style="font-size: small">为了让大家更清楚，我举一个例子：</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体"><span style="font-size: small"><img style="border-top-style: none; border-right-style: none; border-left-style: none; border-bottom-style: none" height="89" alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/popy007/EntryImages/20100102/exp1.jpg" width="276" /></span></span></p>
<p>&nbsp;</p>
<p><span style="font-size: small"><span style="font-family: 宋体">上式的意思是：参考系中的向量</span><span style="font-family: Calibri">v</span><span style="font-family: 宋体">，在基</span><span style="font-family: Calibri">Q( 1 0 0 ), ( 0 1 0 ), ( 0 0 1)</span><span style="font-family: 宋体">下的坐标是</span><span style="font-family: Calibri">( 1 2 6 )</span><span style="font-family: 宋体">，在基</span><span style="font-family: Calibri">R( 0 1 0 ), ( 0 0 1 ), ( 1 0 0 )</span><span style="font-family: 宋体">下的坐标是</span><span style="font-family: Calibri">( 2 6 1 )</span><span style="font-family: 宋体">。注意，我们所讨论的所有基和向量的关系都只是线性表示的关系，没有位移关系，因此我们用</span><span style="font-family: Calibri">3D</span><span style="font-family: 宋体">向量表示，而不是</span><span style="font-family: Calibri">4D</span><span style="font-family: 宋体">的齐次表示（如果对齐次坐标不是很熟悉，请参考《深入探索透视投影变换》中的齐次坐标部分）。</span></span></p>
<p><span style="font-size: small"><span style="font-family: 宋体">这样，已知一个基</span><span style="font-family: Calibri">Q</span><span style="font-family: 宋体">和向量</span><span style="font-family: Calibri">v</span><span style="font-family: 宋体">在它之中的坐标</span><span style="font-family: Calibri">v&#8217;</span><span style="font-family: 宋体">，以及另外一个基</span><span style="font-family: Calibri">R</span><span style="font-family: 宋体">，我们可以通过</span><span style="font-family: Calibri">v=Qv&#8217;=Rv&#8217;&#8217;</span><span style="font-family: 宋体">公式来计算</span><span style="font-family: Calibri">v&#8217;&#8217;</span><span style="font-family: 宋体">。</span></span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><img style="border-top-style: none; border-right-style: none; border-left-style: none; border-bottom-style: none" height="60" alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/popy007/EntryImages/20100102/qvrv2.jpg" width="130" /></p>
<p><span style="font-size: small"><span style="font-family: 宋体">上面就是求</span><span style="font-family: Calibri">v&#8217;&#8217;</span><span style="font-family: 宋体">的公式，注意到右边需要计算基</span><span style="font-family: Calibri">R</span><span style="font-family: 宋体">的逆矩阵</span><span style="font-family: Calibri">R^-1</span><span style="font-family: 宋体">，因为基</span><span style="font-family: Calibri">R</span><span style="font-family: 宋体">是正交矩阵，而正交矩阵的一个重要性质就是逆等于转置。因此，我们可以把它写成</span></span></p>
<p><span style="font-size: small"><span style="font-family: 宋体"><img style="border-top-style: none; border-right-style: none; border-left-style: none; border-bottom-style: none" height="33" alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/popy007/EntryImages/20100102/qvrv3.jpg" width="88" /></span></span></p>
<p>&nbsp;</p>
<p><span style="font-size: small"><span style="font-family: 宋体">这个公式就是坐标转换公式。特别地，如果</span><span style="font-family: Calibri">Q</span><span style="font-family: 宋体">是和参考系相同的坐标系（</span><span style="font-family: Calibri">3D</span><span style="font-family: 宋体">编程中大多数情况下如此），比如世界坐标系，则</span><span style="font-family: Calibri">Q</span><span style="font-family: 宋体">是一个单位矩阵</span><span style="font-family: Calibri">I</span><span style="font-family: 宋体">，则我们可以把它写成</span></span></p>
<p>&nbsp;</p>
<p><span style="font-size: small"><span style="font-family: 宋体"><img style="border-top-style: none; border-right-style: none; border-left-style: none; border-bottom-style: none" height="25" alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/popy007/EntryImages/20100102/qvrv4.jpg" width="75" /></span></span></p>
<p>&nbsp;</p>
<p><span style="font-size: small"><span style="font-family: 宋体">这个坐标转换公式可以解释为：对于世界坐标系中的向量</span><span style="font-family: Calibri">v&#8217;</span><span style="font-family: 宋体">，它在坐标系</span><span style="font-family: Calibri">R</span><span style="font-family: 宋体">中的坐标是</span><span style="font-family: Calibri">v&#8217;&#8217;</span><span style="font-family: 宋体">。我们在后面会用到这个公式。</span></span></p>
<p><span style="font-size: small"><span style="font-family: Calibri">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-family: 宋体">除了用正交矩阵来阐述坐标转换，我们还可以使用点积所代表的<strong>共线程度</strong>（</span><span style="font-family: Calibri">colinear amount</span><span style="font-family: 宋体">）来描述坐标转换（</span><span style="font-family: Calibri">Andr</span><span style="font-family: 'Trebuchet MS'">&#233;</span><span style="font-family: Calibri">LaMothe</span><span style="font-family: 宋体">的《</span><span style="font-family: Calibri">Tricks Of The 3D Game Programming Gurus</span><span style="font-family: 宋体">》）。这个理论基于点积的几何意义：一个向量在另一个向量上的共线程度。比如两个向量</span><span style="font-family: Calibri">v</span><span style="font-family: 宋体">和</span><span style="font-family: Calibri">s</span><span style="font-family: 宋体">点积</span></span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><img style="border-top-style: none; border-right-style: none; border-left-style: none; border-bottom-style: none" height="89" alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/popy007/EntryImages/20100102/colinear.jpg" width="379" /></p>
<p><span style="font-size: small"><span style="font-family: 宋体">几何意义就是</span><span style="font-family: Calibri">v</span><span style="font-family: 宋体">在</span><span style="font-family: Calibri">s</span><span style="font-family: 宋体">方向上的投影长和</span><span style="font-family: Calibri">s</span><span style="font-family: 宋体">的长的乘积，或者是</span><span style="font-family: Calibri">s</span><span style="font-family: 宋体">在</span><span style="font-family: Calibri">v</span><span style="font-family: 宋体">方向上的投影长和</span><span style="font-family: Calibri">v</span><span style="font-family: 宋体">的长的乘积（积的符号为：若</span><span style="font-family: Calibri">v</span><span style="font-family: 宋体">和</span><span style="font-family: Calibri">s</span><span style="font-family: 宋体">的角度小于</span><span style="font-family: Calibri">90</span><span style="font-family: 宋体">度，积为正，如果是直角，积为零，否则为负）。</span></span></p>
<p><span style="font-size: small"><span style="font-family: 宋体"><img style="border-top-style: none; border-right-style: none; border-left-style: none; border-bottom-style: none" height="163" alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/popy007/EntryImages/20100102/dot.jpg" width="427" /></span></span></p>
<p>&nbsp;</p>
<p style="text-indent: 21pt"><span style="font-size: small"><span style="font-family: 宋体">进一步地，如果</span><span style="font-family: Calibri">v</span><span style="font-family: 宋体">是一个单位向量，则这个点积可以解释为</span><span style="font-family: Calibri">s</span><span style="font-family: 宋体">在</span><span style="font-family: Calibri">v</span><span style="font-family: 宋体">方向上的投影长；如果</span><span style="font-family: Calibri">s</span><span style="font-family: 宋体">是一个单位向量，则可以解释为</span><span style="font-family: Calibri">v</span><span style="font-family: 宋体">在</span><span style="font-family: Calibri">s</span><span style="font-family: 宋体">方向上的投影长。现在，我们把点积推广到基的层次上，把一个向量</span><span style="font-family: Calibri">v&#8217;</span><span style="font-family: 宋体">和一个基</span><span style="font-family: Calibri">R</span><span style="font-family: 宋体">的三个单位轴向量进行点积，点积得到的三个值则表示这个向量在这个基下的坐标</span><span style="font-family: Calibri">v&#8217;&#8217;</span></span></p>
<p>&nbsp;</p>
<p style="text-indent: 21pt"><span style="font-size: small"><img style="border-top-style: none; border-right-style: none; border-left-style: none; border-bottom-style: none" height="125" alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/popy007/EntryImages/20100102/colinear2.jpg" width="266" /></span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体"><span style="font-size: small">数学表达为</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体"><img style="border-top-style: none; border-right-style: none; border-left-style: none; border-bottom-style: none" height="89" alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/popy007/EntryImages/20100102/qvrv5.jpg" width="172" /></span></p>
<p>&nbsp;</p>
<p><span style="font-size: small"><span style="font-family: 宋体">请注意，为了让</span><span style="font-family: Calibri">v&#8217;</span><span style="font-family: 宋体">能够和基的每一个轴向量进行点积，我们必须把基写成转置形式，即行向量乘法，否则就变成了线性组合的形式。这个公式的意义就是世界空间中的向量</span><span style="font-family: Calibri">v&#8217;</span><span style="font-family: 宋体">和基</span><span style="font-family: Calibri">R</span><span style="font-family: 宋体">的轴向量进行点积从而得到</span><span style="font-family: Calibri">v&#8217;</span><span style="font-family: 宋体">在</span><span style="font-family: Calibri">R</span><span style="font-family: 宋体">下的共线程度&#8212;&#8212;坐标</span><span style="font-family: Calibri">v&#8217;&#8217;</span><span style="font-family: 宋体">。这个公式和上面我们得到的坐标转换公式一模一样。实际上我们是从两个不同的方向解释同一个公式，希望你能够把两个方向都理解。</span></span></p>
<h1><span style="font-size: x-large"><span style="font-family: Calibri">UVN</span><span style="font-family: 宋体">系统</span></span></h1>
<p><span style="font-size: small"><span style="font-family: Calibri">UVN</span><span style="font-family: 宋体">系统本身是一个基。如下图所示，三个基向量</span><span style="font-family: Calibri">U</span><span style="font-family: 宋体">，</span><span style="font-family: Calibri">V</span><span style="font-family: 宋体">，</span><span style="font-family: Calibri">N</span><span style="font-family: 宋体">分别指向相机的右方、上方和后方从而构成右手坐标系，相机则处于坐标原点。</span></span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><img style="border-top-style: none; border-right-style: none; border-left-style: none; border-bottom-style: none" height="105" alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/popy007/EntryImages/20100102/uvn.jpg" width="130" /></p>
<p><span style="font-size: small"><span style="font-family: 宋体">使用</span><span style="font-family: Calibri">UVN</span><span style="font-family: 宋体">系统可以非常方便的设置相机朝向。它的构建过程如下如所示</span></span></p>
<p><span style="font-size: small"><span style="font-family: 宋体"><img style="border-top-style: none; border-right-style: none; border-left-style: none; border-bottom-style: none" height="297" alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/popy007/EntryImages/20100102/uvn_gen.jpg" width="413" /></span></span></p>
<p>&nbsp;</p>
<p><span style="font-size: small"><span style="font-family: 宋体">在参考系下（这里是世界坐标系），我们给定相机的位置&#8212;&#8212;</span><span style="font-family: Calibri">eye</span><span style="font-family: 宋体">，被观察的小人的位置&#8212;&#8212;</span><span style="font-family: Calibri">lookat</span><span style="font-family: 宋体">，以及一个辅助向量&#8212;&#8212;参考系中表示&#8220;上方&#8221;的向量</span><span style="font-family: Calibri">up</span><span style="font-family: 宋体">，这个向量会影响</span><span style="font-family: Calibri">U</span><span style="font-family: 宋体">和</span><span style="font-family: Calibri">V</span><span style="font-family: 宋体">的生成，因为以后求出的</span><span style="font-family: Calibri">V</span><span style="font-family: 宋体">向量会在</span><span style="font-family: Calibri">up</span><span style="font-family: 宋体">和</span><span style="font-family: Calibri">N</span><span style="font-family: 宋体">向量所决定的平面上（有兴趣可以自己证明一下），所以可以通过这个向量让相机产生不同的偏转。</span></span></p>
<p>&nbsp;</p>
<p><span style="font-size: small"><span style="font-family: 宋体"><img style="border-top-style: none; border-right-style: none; border-left-style: none; border-bottom-style: none" height="71" alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/popy007/EntryImages/20100102/cam_roll.jpg" width="276" /></span></span></p>
<p>&nbsp;</p>
<p><span style="font-size: small"><span style="font-family: 宋体">首先我们求出向量</span><span style="font-family: Calibri">N</span></span></p>
<p>&nbsp;</p>
<p><span style="font-size: small"><img style="border-top-style: none; border-right-style: none; border-left-style: none; border-bottom-style: none" height="25" alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/popy007/EntryImages/20100102/n_gen.jpg" width="135" /></span></p>
<p>&nbsp;</p>
<p><span style="font-size: small"><span style="font-family: 宋体">很简单，用目标位置减去相机的位置，就是图中的步骤</span><span style="font-family: Calibri">2</span><span style="font-family: 宋体">。第</span><span style="font-family: Calibri">3</span><span style="font-family: 宋体">步，我们求出向量</span><span style="font-family: Calibri">U</span><span style="font-family: 宋体">。这一步需要使用辅助向量</span><span style="font-family: Calibri">up</span><span style="font-family: 宋体">，如果不希望相机产生偏转，一般取</span><span style="font-family: Calibri">(0, 1, 0)</span></span></p>
<p>&nbsp;</p>
<p><span style="font-size: small"><span style="font-family: Calibri"><img style="border-top-style: none; border-right-style: none; border-left-style: none; border-bottom-style: none" height="22" alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/popy007/EntryImages/20100102/u_gen.jpg" width="98" /></span></span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="font-size: small">U<span style="font-family: 宋体">使用向量的叉乘实现，就是图中的步骤</span>3<span style="font-family: 宋体">。最后，使用</span>N<span style="font-family: 宋体">和</span>U<span style="font-family: 宋体">计算出向量</span>V</span></p>
<p>&nbsp;</p>
<p><span style="font-size: small"><img style="border-top-style: none; border-right-style: none; border-left-style: none; border-bottom-style: none" height="22" alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/popy007/EntryImages/20100102/v_gen.jpg" width="87" /></span></p>
<p>&nbsp;</p>
<p><span style="font-size: small"></span></p>
<p><span style="font-family: 宋体">最后将计算出的</span>U<span style="font-family: 宋体">，</span>V<span style="font-family: 宋体">和</span>N<span style="font-family: 宋体">进行单位化，就得到了相机的</span>UVN<span style="font-family: 宋体">系统。结合上面我们谈到的坐标转换理论，我们可以把</span>UVN<span style="font-family: 宋体">系统看作是相机的基，从而可以方便的把一个向量在世界坐标和相机坐标进行转换。</span></p>
<p style="text-indent: 21pt">OpenGL<span style="font-family: 宋体">的</span>gluLookAt(eyex, eyey, eyez, lookatx, lookaty, lookatz, upx, upy, upz)<span style="font-family: 宋体">方法就是使用的上面的步骤进行相机矩阵的设置。它的前三个参数就是相机的位置向量，中间三个参数是所观察的目标位置向量，最后三个参数就是辅助向量</span>up<span style="font-family: 宋体">。</span></p>
<h1><span style="font-family: 宋体">相机矩阵的推导</span></h1>
<p style="text-indent: 20.25pt"><span style="font-family: 宋体">上面我们已经说明了</span>UVN<span style="font-family: 宋体">系统，标准流水线中就是使用了</span>UVN<span style="font-family: 宋体">系统来描述相机。</span>U, V, N<span style="font-family: 宋体">分别对应相机坐标系的三个基向量。</span></p>
<p style="text-indent: 20.25pt"><span style="font-family: 宋体">此外，对于一个相机来说，它在开始的时候和世界坐标系是重合的，用户控制相机在世界空间中移动之后，相机的状态可以用两个属性来描述&#8212;&#8212;朝向和位置。也就是说，有了这两个属性，一个相机模型在世界中的状态就确定了。而这两个属性，我们用变换的理论来描述，就是旋转和平移。可以想象，对于世界中的任何一个相机状态，我们都可以把它看成是：相机先围绕自身基原点旋转一定的角度，然后平移到世界空间的某个地方。下图展示了这个过程</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><img style="border-top-style: none; border-right-style: none; border-left-style: none; border-bottom-style: none" height="283" alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/popy007/EntryImages/20100102/cam_xform.jpg" width="554" /></p>
<p><span style="font-size: small"><span style="font-family: 宋体">图中，红色是相机的基，而黑色是世界的基，也就是参考系。小人是世界中的一个物体。相机在移动之前，两个基是重合的。当相机在屏幕中定位时，它首先会进行朝向的确定&#8212;&#8212;旋转，然后进行位置的确定&#8212;&#8212;平移。图中的</span><span style="font-family: Calibri">Rotation</span><span style="font-family: 宋体">和</span><span style="font-family: Calibri">Translation</span><span style="font-family: 宋体">两步就是相机定位时所发生的变换。可以看到相机相对于小人的运动。而当进行相机变换的时候，小人应该从世界基变换到相机的基里面。这样，他应该进行一个相机定位的逆定位，先逆平移小人和相机，然后再逆旋转小人和相机，最后相机归位，小人随相机变到了相机空间。这是由</span><span style="font-family: Calibri">Inverse Translation</span><span style="font-family: 宋体">和</span><span style="font-family: Calibri">Inverse Rotation</span><span style="font-family: 宋体">两个步骤完成的，这两个步骤就是相机变换。现在我们推导这个变换。我们把关系写出来，相机本身的变换</span><span style="font-family: Calibri">C</span><span style="font-family: 宋体">包括两个元素</span></span></p>
<p><span style="font-family: 宋体"><span style="font-size: small"><img style="border-top-style: none; border-right-style: none; border-left-style: none; border-bottom-style: none" height="22" alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/popy007/EntryImages/20100102/ctr.jpg" width="63" /></span></span></p>
<p>&nbsp;</p>
<p><span style="font-size: small"><span style="font-family: 宋体">其中</span><span style="font-family: Calibri">T</span><span style="font-family: 宋体">是平移变换，</span><span style="font-family: Calibri">R</span><span style="font-family: 宋体">是旋转变换。而相机变换是相机本身变换的逆变换</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体"><span style="font-size: small"><img style="border-top-style: none; border-right-style: none; border-left-style: none; border-bottom-style: none" height="29" alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/popy007/EntryImages/20100102/ctr_inv.jpg" width="173" /></span></span></p>
<p>&nbsp;</p>
<p><span style="font-size: small"><span style="font-family: 宋体">这个</span><span style="font-family: Calibri">C^-1</span><span style="font-family: 宋体">就是我们要求出的相机变换。其中</span><span style="font-family: Calibri">T^-1</span><span style="font-family: 宋体">很容易求出，即</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体"><img style="border-top-style: none; border-right-style: none; border-left-style: none; border-bottom-style: none" height="96" alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/popy007/EntryImages/20100102/t_inv.jpg" width="155" /></span></p>
<p>&nbsp;</p>
<p><span style="font-size: small"><span style="font-family: 宋体">而</span><span style="font-family: Calibri">R^-1</span><span style="font-family: 宋体">就没有这么容易求出来了。所以，我们不求它，我们用</span><span style="font-family: Calibri">UVN</span><span style="font-family: 宋体">系统。什么意思？请看上面的那张相机变换的图，当相机变换进行完</span><span style="font-family: Calibri">Inverse Translation</span><span style="font-family: 宋体">这一步之后，相机的原点和世界原点就重合了，也就是处理完了关于平移的变换。接下来我们要做的是逆旋转，而其实<strong>逆旋转的目的，就是要得到目前世界坐标中经过逆平移</strong><strong>的小人在相机坐标系中的坐标</strong>。是不是似曾相识？我们的坐标变换理论就派上用场了。我们回忆上面坐标变换的公式</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体"><span style="font-size: small"><img style="border-top-style: none; border-right-style: none; border-left-style: none; border-bottom-style: none" height="25" alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/popy007/EntryImages/20100102/vrv.jpg" width="75" /></span></span></p>
<p>&nbsp;</p>
<p><span style="font-size: small"><span style="font-family: 宋体">这个坐标转换公式可以解释为：对于世界坐标系中的向量</span><span style="font-family: Calibri">v&#8217;</span><span style="font-family: 宋体">，它在坐标系</span><span style="font-family: Calibri">R</span><span style="font-family: 宋体">中的坐标是</span><span style="font-family: Calibri">v&#8217;&#8217;</span><span style="font-family: 宋体">。那么，我们可以套用在这里：对于世界坐标中的已经经过逆平移的坐标</span><span style="font-family: Calibri">v&#8217;</span><span style="font-family: 宋体">，它在相机坐标系</span><span style="font-family: Calibri">R</span><span style="font-family: 宋体">中的坐标是</span><span style="font-family: Calibri">v&#8217;&#8217;</span><span style="font-family: 宋体">。什么是相机坐标系</span><span style="font-family: Calibri">R</span><span style="font-family: 宋体">？就是我们的相机</span><span style="font-family: Calibri">UVN</span><span style="font-family: 宋体">系统！就是</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体"><span style="font-size: small"><img style="border-top-style: none; border-right-style: none; border-left-style: none; border-bottom-style: none" height="96" alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/popy007/EntryImages/20100102/r.jpg" width="152" /></span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体"><span style="font-size: small">则相机变换的完整公式就是</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体"><span style="font-size: small"><img style="border-top-style: none; border-right-style: none; border-left-style: none; border-bottom-style: none" height="25" alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/popy007/EntryImages/20100102/vrv2.jpg" width="98" /></span></span></p>
<p>&nbsp;</p>
<p><span style="font-size: small"><span style="font-family: 宋体">这里，</span><span style="font-family: Calibri">v</span><span style="font-family: 宋体">是小人在世界空间中的坐标，</span><span style="font-family: Calibri">v&#8217;&#8217;</span><span style="font-family: 宋体">是小人在相机空间中的坐标。则相机变换矩阵就是</span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体"><img style="border-top-style: none; border-right-style: none; border-left-style: none; border-bottom-style: none" height="146" alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/popy007/EntryImages/20100102/c_inv.jpg" width="557" /></span></p>
<p><span style="font-family: 宋体"><span style="font-size: small"><span style="font-family: 宋体">至此，我们就完成了相机矩阵的推导。物体经过这个矩阵就从世界空间变换到了相机空间，等待流水线对它进行投影变换。</span><span style="font-family: Calibri">OpenGL</span><span style="font-family: 宋体">就使用了上面推导出的最后的那个矩阵。希望你能够理解这个推导过程，如果你有什么问题或者不同的看法，请一定给我发信</span><span style="font-family: Wingdings">J</span><span style="font-family: 宋体">下次见！</span></span></span></p></span></span><img src ="http://www.cppblog.com/wc250en007/aggbug/152124.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wc250en007/" target="_blank">Let me see see</a> 2011-07-31 10:02 <a href="http://www.cppblog.com/wc250en007/archive/2011/07/31/152124.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[翻译]DirectX 状态( 转)</title><link>http://www.cppblog.com/wc250en007/archive/2011/06/05/148113.html</link><dc:creator>Let me see see</dc:creator><author>Let me see see</author><pubDate>Sun, 05 Jun 2011 07:32:00 GMT</pubDate><guid>http://www.cppblog.com/wc250en007/archive/2011/06/05/148113.html</guid><wfw:comment>http://www.cppblog.com/wc250en007/comments/148113.html</wfw:comment><comments>http://www.cppblog.com/wc250en007/archive/2011/06/05/148113.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wc250en007/comments/commentRss/148113.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wc250en007/services/trackbacks/148113.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: [翻译]DirectX 状态状态&nbsp;&nbsp;&nbsp;&nbsp;Direct3D设备使用状态来配置所有的管道处理。采样器状态通过例如定义纹理寻址方式(texture addressing)和过滤模式控制纹理采样器设置。纹理状态设置用于控制纹理如何被组合以及相互之间如何混合的多重纹理混合器。渲染状态控制大多数管道状态。&nbsp;&nbsp;&nbsp;&nbsp;状...&nbsp;&nbsp;<a href='http://www.cppblog.com/wc250en007/archive/2011/06/05/148113.html'>阅读全文</a><img src ="http://www.cppblog.com/wc250en007/aggbug/148113.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wc250en007/" target="_blank">Let me see see</a> 2011-06-05 15:32 <a href="http://www.cppblog.com/wc250en007/archive/2011/06/05/148113.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>射线与三角形相交判断函数  (备忘)</title><link>http://www.cppblog.com/wc250en007/archive/2010/08/18/123826.html</link><dc:creator>Let me see see</dc:creator><author>Let me see see</author><pubDate>Wed, 18 Aug 2010 06:23:00 GMT</pubDate><guid>http://www.cppblog.com/wc250en007/archive/2010/08/18/123826.html</guid><wfw:comment>http://www.cppblog.com/wc250en007/comments/123826.html</wfw:comment><comments>http://www.cppblog.com/wc250en007/archive/2010/08/18/123826.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wc250en007/comments/commentRss/123826.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wc250en007/services/trackbacks/123826.html</trackback:ping><description><![CDATA[<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">BOOL&nbsp;D3DXIntersectTri(<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CONST&nbsp;D3DXVECTOR3</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;p0,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//顶点1<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CONST&nbsp;D3DXVECTOR3</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;p1,<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CONST&nbsp;D3DXVECTOR3</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;p2,<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CONST&nbsp;D3DXVECTOR3</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;pRayPos,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//射线起始位置<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CONST&nbsp;D3DXVECTOR3</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;pRayDir,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//射线方向<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FLOAT</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pU,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//三个点比重<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FLOAT</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pV,<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FLOAT</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pDist&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//射线起点到交点位置<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);</span></div>
<p><font color=#0000ff size=3><strong><font face=黑体>para ：</font></strong></font>其中p0, p1, p2分别指向三角形的三个顶点，position为射线起点，direction为射线方向向量，u,v,为交点重心坐标，因为不可能只点到顶点上，可能点在三角形范围内，distance为起点到交点距离，成功返回TRUE，失败返回FALSE。<br><br>vPickPos = v0 * ( 1-u-v) + v1*u + v2*v = v0 + u * (v1 - v0) + v * (v3 - v0);&nbsp;<br><br><span style="COLOR: red">特别注意：方向向量必须为单位向量，即<em>pRayDir - </em><em>pRayPos</em>&nbsp; 为单位向量否则，<em>pDist</em>的值和向量长度成正比关系</span></p>
<br>eg:<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;D3DXVECTOR3&nbsp;&nbsp;&nbsp;&nbsp;rayDir;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;D3DXVECTOR3&nbsp;vDest(&nbsp;</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">200</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">.f);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;D3DXVECTOR3&nbsp;vSour(&nbsp;</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">200</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">.f&nbsp;);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;rayDir&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;vDest&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">&nbsp;vSour;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;D3DXVec3Normalize(&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">rayDir,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">rayDir&nbsp;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//将方向向量化<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;BOOL&nbsp;bHit&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;D3DXIntersectTri(&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">D3DXVECTOR3(</span><span style="COLOR: #000000">0.0f</span><span style="COLOR: #000000">,&nbsp;&nbsp;</span><span style="COLOR: #000000">0.0f</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">0.5f</span><span style="COLOR: #000000">),<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">D3DXVECTOR3(</span><span style="COLOR: #000000">250.0f</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">250.0f</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">0.5f</span><span style="COLOR: #000000">),<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">D3DXVECTOR3(</span><span style="COLOR: #000000">0.0f</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">250.0f</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">0.5f</span><span style="COLOR: #000000">),&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">pos</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">D3DXVECTOR3(</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">200</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">.f&nbsp;),&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">dir</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">rayDir,&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">fu,&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">fv,&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">t&nbsp;);</span></div>
<br>游戏中应用<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000">&nbsp;CTerrain::GetZByXY(&nbsp;</span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000">&nbsp;fx,</span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000">&nbsp;fy&nbsp;&nbsp;)<br><img id=Codehighlighter1_49_1017_Open_Image onclick="this.style.display='none'; Codehighlighter1_49_1017_Open_Text.style.display='none'; Codehighlighter1_49_1017_Closed_Image.style.display='inline'; Codehighlighter1_49_1017_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_49_1017_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_49_1017_Closed_Text.style.display='none'; Codehighlighter1_49_1017_Open_Image.style.display='inline'; Codehighlighter1_49_1017_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_49_1017_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_49_1017_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">求出第几个方格</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;x,y;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;fx&nbsp;</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">&nbsp;MAPTILESIZE;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;fy&nbsp;</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">&nbsp;MAPTILESIZE;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(&nbsp;x&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">||</span><span style="COLOR: #000000">&nbsp;x&nbsp;</span><span style="COLOR: #000000">&gt;=</span><span style="COLOR: #000000">&nbsp;m_iMapWidth</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;&nbsp;)<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(&nbsp;y&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">||</span><span style="COLOR: #000000">&nbsp;y&nbsp;</span><span style="COLOR: #000000">&gt;=</span><span style="COLOR: #000000">&nbsp;m_iMapHeight</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;)<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">方格四顶点</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;D3DXVECTOR3&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">pos[</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">];<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pos[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">m_ppPointPos[&nbsp;y&nbsp;][&nbsp;x&nbsp;];<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pos[</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">m_ppPointPos[&nbsp;y&nbsp;][&nbsp;x&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">];<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pos[</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">m_ppPointPos[&nbsp;y&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">][&nbsp;x&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">];<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pos[</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">m_ppPointPos[&nbsp;y&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">][&nbsp;x&nbsp;];<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000">&nbsp;fMaxZ;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fMaxZ&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;pos[&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">&nbsp;]</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">z&nbsp;;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;iLoop;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">(&nbsp;iLoop&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;;&nbsp;iLoop&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">&nbsp;;&nbsp;iLoop&nbsp;</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">&nbsp;)<br><img id=Codehighlighter1_512_578_Open_Image onclick="this.style.display='none'; Codehighlighter1_512_578_Open_Text.style.display='none'; Codehighlighter1_512_578_Closed_Image.style.display='inline'; Codehighlighter1_512_578_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_512_578_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_512_578_Closed_Text.style.display='none'; Codehighlighter1_512_578_Open_Image.style.display='inline'; Codehighlighter1_512_578_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_512_578_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_512_578_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(&nbsp;fMaxZ&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;pos[&nbsp;iLoop&nbsp;]</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">z&nbsp;)<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fMaxZ&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;pos[&nbsp;iLoop&nbsp;]</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">z;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;求眼睛和地形相交位置，注意单位化方向向量</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;D3DXVECTOR3&nbsp;vEye,vDir(</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vEye.x&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;fx;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vEye.y&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;fy;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vEye.z&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;fMaxZ&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000">&nbsp;fU,fV,fDis;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(&nbsp;</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">D3DXIntersectTri(&nbsp;pos[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">],pos[</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">]&nbsp;,pos[</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">],</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">vEye,</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">vDir,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">三角形1</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">fU,</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">fV,</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">fDis&nbsp;)&nbsp;)<br><img id=Codehighlighter1_808_974_Open_Image onclick="this.style.display='none'; Codehighlighter1_808_974_Open_Text.style.display='none'; Codehighlighter1_808_974_Closed_Image.style.display='inline'; Codehighlighter1_808_974_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_808_974_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_808_974_Closed_Text.style.display='none'; Codehighlighter1_808_974_Open_Image.style.display='inline'; Codehighlighter1_808_974_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_808_974_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_808_974_Open_Text><span style="COLOR: #000000">{&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(&nbsp;</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">D3DXIntersectTri(&nbsp;pos[</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">],pos[</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">],pos[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">],</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">vEye,</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">vDir,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">三角形2</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">fU,</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">fV,</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">fDis&nbsp;)&nbsp;)<br><img id=Codehighlighter1_904_926_Open_Image onclick="this.style.display='none'; Codehighlighter1_904_926_Open_Text.style.display='none'; Codehighlighter1_904_926_Closed_Image.style.display='inline'; Codehighlighter1_904_926_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_904_926_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_904_926_Closed_Text.style.display='none'; Codehighlighter1_904_926_Open_Image.style.display='inline'; Codehighlighter1_904_926_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_904_926_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_904_926_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0.0f</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br><img id=Codehighlighter1_939_970_Open_Image onclick="this.style.display='none'; Codehighlighter1_939_970_Open_Text.style.display='none'; Codehighlighter1_939_970_Closed_Image.style.display='inline'; Codehighlighter1_939_970_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_939_970_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_939_970_Closed_Text.style.display='none'; Codehighlighter1_939_970_Open_Image.style.display='inline'; Codehighlighter1_939_970_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_939_970_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_939_970_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;vEye.z&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">&nbsp;fDis;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br><img id=Codehighlighter1_985_1014_Open_Image onclick="this.style.display='none'; Codehighlighter1_985_1014_Open_Text.style.display='none'; Codehighlighter1_985_1014_Closed_Image.style.display='inline'; Codehighlighter1_985_1014_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_985_1014_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_985_1014_Closed_Text.style.display='none'; Codehighlighter1_985_1014_Open_Image.style.display='inline'; Codehighlighter1_985_1014_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_985_1014_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_985_1014_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;vEye.z&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">&nbsp;fDis;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span></div>
<br><br>&nbsp;参考:<br>地形碰撞计算:<br>一.如果是鼠标点击地面,<br>可将射线固定长度并分段,然后用射线与每一个分段上的点所落在的地面tile(两个三角形)进行求交,<br>相交则返回对应位置,否则继续与下一个段上的点所落在的地面tile求交<br>/*<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ----&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | \&nbsp; |<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp; \ |<br>&nbsp;&nbsp;&nbsp; 2 V ---&nbsp; 3&nbsp;&nbsp;&nbsp; <br>*/<br>这里不讨论点击屏幕求射线方法与射线分段处理,只算求交<br>如下d3d求交得出uv,再求位置:<br>&nbsp;VECTOR3 vPickPos;<br>&nbsp;// 右边:<br>&nbsp;if( D3DXIntersectTri(&amp;v0, &amp;v1, &amp;v3, &amp;vOrig, &amp;vDir, &amp;u, &amp;v, NULL) == TRUE)<br>&nbsp;{<br>&nbsp;&nbsp;vPickPos = v0 + u * (v1 - v0) + v * (v3 - v0);&nbsp;<br>&nbsp;&nbsp;return vPickPos.z;<br>&nbsp;}<br>&nbsp;// 左边:<br>&nbsp;if( D3DXIntersectTri(&amp;v0, &amp;v3, &amp;v2, &amp;vOrig, &amp;vDir, &amp;u, &amp;v, NULL) == TRUE)<br>&nbsp;{<br>&nbsp;&nbsp;vPickPos = v0 + u * (v3 - v0) + v * (v2 - v0);&nbsp;&nbsp;<br>&nbsp;&nbsp;return vPickPos.z;<br>&nbsp;}
<p>二.如果是仅是求地表某点高度<br>则可用uv重心求法(注意上述第一点的d3d的那个uv重心求法不太一样,他的uv跟他的向量走?)<br>&nbsp;float u = (fX-(int)fX);<br>&nbsp;float v = (fY-(int)fY);
<p>&nbsp;float p0 = fHeight[0];<br>&nbsp;float p1 = fHeight[1];<br>&nbsp;float p2 = fHeight[2];<br>&nbsp;float p3 = fHeight[3];
<p>&nbsp;if(u&gt;v){ // 右边<br>&nbsp;&nbsp;return p0 + u * (p1 - p0) + v * (p3 - p1);;&nbsp;<br>&nbsp;}<br>&nbsp;else{&nbsp; // 左边<br>&nbsp;&nbsp;return&nbsp; p0 + u * (p3 - p2) + v * (p2 - p0);<br>&nbsp;} </p>
<br><a href="http://flipcode.spaces.live.com/blog/cns!8E578E7901A88369!1052.entry">http://flipcode.spaces.live.com/blog/cns!8E578E7901A88369!1052.entry</a>
<img src ="http://www.cppblog.com/wc250en007/aggbug/123826.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wc250en007/" target="_blank">Let me see see</a> 2010-08-18 14:23 <a href="http://www.cppblog.com/wc250en007/archive/2010/08/18/123826.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>高级纹理混合</title><link>http://www.cppblog.com/wc250en007/archive/2010/08/12/123253.html</link><dc:creator>Let me see see</dc:creator><author>Let me see see</author><pubDate>Thu, 12 Aug 2010 14:51:00 GMT</pubDate><guid>http://www.cppblog.com/wc250en007/archive/2010/08/12/123253.html</guid><wfw:comment>http://www.cppblog.com/wc250en007/comments/123253.html</wfw:comment><comments>http://www.cppblog.com/wc250en007/archive/2010/08/12/123253.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wc250en007/comments/commentRss/123253.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wc250en007/services/trackbacks/123253.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 使用纹理的时候，你需要告诉DX如何将纹理贴到几何体上，可以通过为每个顶点指定一个纹理坐标来实现：下面的顶点结构使用了2套纹理坐标：#define&nbsp;D3DFVF_CUSTOMVERTEX&nbsp;(D3DFVF_XYZ|&nbsp;D3DFVF_DIFFUSE|&nbsp;D3DFVF_TEX2)struct&nbsp;CUSTOMVERTEX{&nbsp;&nbsp;&nbsp;F...&nbsp;&nbsp;<a href='http://www.cppblog.com/wc250en007/archive/2010/08/12/123253.html'>阅读全文</a><img src ="http://www.cppblog.com/wc250en007/aggbug/123253.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wc250en007/" target="_blank">Let me see see</a> 2010-08-12 22:51 <a href="http://www.cppblog.com/wc250en007/archive/2010/08/12/123253.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>