﻿<?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++博客-Code Knight-随笔分类-图形学</title><link>http://www.cppblog.com/winmain/category/9275.html</link><description>Programming is so cool</description><language>zh-cn</language><lastBuildDate>Wed, 19 May 2010 03:56:22 GMT</lastBuildDate><pubDate>Wed, 19 May 2010 03:56:22 GMT</pubDate><ttl>60</ttl><item><title>CryEngine</title><link>http://www.cppblog.com/winmain/archive/2010/03/07/109136.html</link><dc:creator>Code Knight</dc:creator><author>Code Knight</author><pubDate>Sun, 07 Mar 2010 11:50:00 GMT</pubDate><guid>http://www.cppblog.com/winmain/archive/2010/03/07/109136.html</guid><wfw:comment>http://www.cppblog.com/winmain/comments/109136.html</wfw:comment><comments>http://www.cppblog.com/winmain/archive/2010/03/07/109136.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/winmain/comments/commentRss/109136.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/winmain/services/trackbacks/109136.html</trackback:ping><description><![CDATA[<p>CryEngine系列引擎玩家们并不陌生，从最初的单机游戏《孤岛惊魂》、《孤岛危机》到目前火热的网游《永恒之塔》等一系列大作都是由该系列1到2代引擎打造，目前，Crytek已经发布了该系列的第三代引擎&#8220;CryEngine 3&#8221;。</p>
<p>　　如下是最新公布的一段&#8220;CryEngine 3&#8221;引擎制作FPS游戏地图视频，从制作到演示仅长8分钟，看了让人瞠目结舌，唏嘘不已。</p>
<embed height=370 type=application/x-shockwave-flash pluginspage=http://www.macromedia.com/go/getflashplayer width=480 src=http://vhead.blog.sina.com.cn/player/outer_player.swf?auto=0&amp;vid=25220063&amp;uid=1503278774 allowscriptaccess="never" allowNetworking="internal" invokeurls="false" allownetworking="internal" allowfullscreen="true"></embed></object> 
<img src ="http://www.cppblog.com/winmain/aggbug/109136.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/winmain/" target="_blank">Code Knight</a> 2010-03-07 19:50 <a href="http://www.cppblog.com/winmain/archive/2010/03/07/109136.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Introduction To Octrees</title><link>http://www.cppblog.com/winmain/archive/2010/02/23/108306.html</link><dc:creator>Code Knight</dc:creator><author>Code Knight</author><pubDate>Tue, 23 Feb 2010 13:18:00 GMT</pubDate><guid>http://www.cppblog.com/winmain/archive/2010/02/23/108306.html</guid><wfw:comment>http://www.cppblog.com/winmain/comments/108306.html</wfw:comment><comments>http://www.cppblog.com/winmain/archive/2010/02/23/108306.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/winmain/comments/commentRss/108306.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/winmain/services/trackbacks/108306.html</trackback:ping><description><![CDATA[<center>
<table style="TABLE-LAYOUT: fixed" border=0 cellSpacing=0 cellPadding=0 width="80%">
    <tbody>
        <tr>
            <td style="BACKGROUND-COLOR: #000000; COLOR: #000000" width="100%"><font color=#ffffff size=3 face="Verdana, Helvetica, Arial, Times New Roman"><strong>Introduction <font size=1><br><img src="http://www.flipcode.com/archives/line_grey.png"><br><br></font></strong></font></td>
        </tr>
    </tbody>
</table>
</center>
<center>
<table style="TABLE-LAYOUT: fixed" border=0 cellSpacing=0 cellPadding=0 width="80%">
    <tbody>
        <tr>
            <td style="BACKGROUND-COLOR: #000000; COLOR: #000000" width="100%"><font color=#ffe291 size=2 face="Verdana, Helvetica, Arial, Times New Roman">Hidden surface removal is among the biggest problems when writing a 3D engine.<br><br>I struggled with it since the very beginning of writing 3D engines and still have no satisfactory solution to it. The ideal visibility detection scheme would allow unlimited data, extremely dynamic worlds and would have zero overdraw. The first 3d engine which implements these three demands still has to be written. <br><br>The Z buffer for example allows dynamical worlds and even crossing faces, but it suffers from immense overdraw. The BSP-tree on the other hand, if well implemented, has no overdraw at all but needs that much pre-processing that dynamical worlds are a definite nono. <br><br>It wasn't until recently i first heard of the octree, and I must admit i was struck by it's simplicity. I never actually implemented this structure and therefore I will present no pseudo code at all. This explanation is merely an attempt to make it more clear to people who have never heard of it. Besides, if you really understand the structure, then implementation is a piece of cake.</font></td>
        </tr>
    </tbody>
</table>
</center><br><br>
<center>
<table style="TABLE-LAYOUT: fixed" border=0 cellSpacing=0 cellPadding=0 width="80%">
    <tbody>
        <tr>
            <td style="BACKGROUND-COLOR: #000000; COLOR: #000000" width="100%"><font color=#ffffff size=3 face="Verdana, Helvetica, Arial, Times New Roman"><strong>The Octree Structure <font size=1><br><img src="http://www.flipcode.com/archives/line_grey.png"><br><br></font></strong></font></td>
        </tr>
    </tbody>
</table>
</center>
<center>
<table style="TABLE-LAYOUT: fixed" border=0 cellSpacing=0 cellPadding=0 width="80%">
    <tbody>
        <tr>
            <td style="BACKGROUND-COLOR: #000000; COLOR: #000000" width="100%"><font color=#ffe291 size=2 face="Verdana, Helvetica, Arial, Times New Roman">Our virtual world or level is actually nothing more then a soup of polygons. Some of you people might have thrown in a couple of curves and voxels but most of it will be polygons. Here it is:<br><br>
            <center><img src="http://www.flipcode.com/archives/article_introtooctrees01.jpg" width=340 height=314><br><br>Fig 1. Our little level.</center><br><br>In the picture I just built a simple level containing no more than 250 polys. Now imagine a cube surrounding the world like in the next image:<br><br>
            <center><img src="http://www.flipcode.com/archives/article_introtooctrees02.jpg" width=429 height=434><br><br>Fig. 2. Our little level surrounded by a cube.</center><br><br>Now it isn't hard to see that this cube can be divided into eight smaller cubes, hence the name octree. Take a look at this picture:<br><br>
            <center><img src="http://www.flipcode.com/archives/article_introtooctrees03.jpg" width=429 height=434><br><br>Fig 3. Our little level with the surrounding cube subdivided.</center><br><br>Call the larger cube the parent and the smaller cubes the children. On their turn subdivide each children into eight smaller cubes, and you will notice we are creating a tree where each node has eight children. <br><br>There is still one little problem left. When should we stop dividing cubes into smaller ones? There are two possible solutions. The first one is to stop when a cube has some size smaller then a fixed number. The second one is more common. You might have noticed that every child has less polygons then it's parent. The trick is to stop subdividing when the number of polygons in a cube is smaller then some fixed number. </font></td>
        </tr>
    </tbody>
</table>
</center><br><br>
<center>
<table style="TABLE-LAYOUT: fixed" border=0 cellSpacing=0 cellPadding=0 width="80%">
    <tbody>
        <tr>
            <td style="BACKGROUND-COLOR: #000000; COLOR: #000000" width="100%"><font color=#ffffff size=3 face="Verdana, Helvetica, Arial, Times New Roman"><strong>Creating The Octree <font size=1><br><img src="http://www.flipcode.com/archives/line_grey.png"><br><br></font></strong></font></td>
        </tr>
    </tbody>
</table>
</center>
<center>
<table style="TABLE-LAYOUT: fixed" border=0 cellSpacing=0 cellPadding=0 width="80%">
    <tbody>
        <tr>
            <td style="BACKGROUND-COLOR: #000000; COLOR: #000000" width="100%"><font color=#ffe291 size=2 face="Verdana, Helvetica, Arial, Times New Roman">Trees are recursion, recursion is trees. It is as simple as that. If you have a correct definition of you cubeNode it is very easy to create an octree recursively. First of all you check all polygons against the boundarys of the cube. This is very simple cause these boundaries are all axis aligned. This means that the cube has six plane equations, which are:<br><br>
            <li>1. X = Q.X </li>
            <li>2. Y = Q.Y </li>
            <li>3. Z = Q.Z<br><br></li>
            <li>4. X = Q.X + cubeSize </li>
            <li>5. Y = Q.Y + cubeSize </li>
            <li>6. Z = Q.Z + cubeSize<br><br>Where Q is the position of one corner of the cube. This are very easy equations and the all parent polygons can very easily be checked against them.<br><br>It could occur that a polygon crosses a cube boundary. Again two possible solution are at hand. First of all we could clip the polygon against the cube, which is simple, because of the axis aligned boundarys. On the other hand we could put the polygon in all cubes it is in. This means that some cubes can contain the same polygons. In order to prevent us from drawing one poly more than one time we should have a flag on each polygon which will be set if the poly is drawn for the first time.<br><br>The implementation of an octree is very straight forward. I haven't done it myself yet, but I will soon. It is all matter of recursion. In order to construct a tree, the first thing you should think of is recursion. Whether we are talking about binary trees, quad trees or octrees, it doesnt matter, just build the darn thing recursively. So have a class definition of one cubeNode and put the creation of the tree in it's constructor. In this constructor you will call the constructor itself for smaller cubes.</li>
            </font></td>
        </tr>
    </tbody>
</table>
</center><br><br>
<center>
<table style="TABLE-LAYOUT: fixed" border=0 cellSpacing=0 cellPadding=0 width="80%">
    <tbody>
        <tr>
            <td style="BACKGROUND-COLOR: #000000; COLOR: #000000" width="100%"><font color=#ffffff size=3 face="Verdana, Helvetica, Arial, Times New Roman"><strong>The Purpose Of The Octree <font size=1><br><img src="http://www.flipcode.com/archives/line_grey.png"><br><br></font></strong></font></td>
        </tr>
    </tbody>
</table>
</center>
<center>
<table style="TABLE-LAYOUT: fixed" border=0 cellSpacing=0 cellPadding=0 width="80%">
    <tbody>
        <tr>
            <td style="BACKGROUND-COLOR: #000000; COLOR: #000000" width="100%"><font color=#ffe291 size=2 face="Verdana, Helvetica, Arial, Times New Roman">An octree is actually nothing more then a data structure. It can be used for very different things. It is not only handy for visibility detection but also for collision detection, realtime shadows and many more things. The most important thing to understand about octrees is that if a parent is not important then it's children aren't either. Let's makes this a little bit more clear with an example.<br><br>We will do this in 2d, which therefore resembles a quadtree, but with some imagination it can very easily be extended to 3d. Here we test the cubes (squares) against the viewing frustrum. Take a look at the next picture: <br><br>
            <center><img src="http://www.flipcode.com/archives/article_introtooctrees04.jpg" width=342 height=331><br><br>Fig 4. An octree from the top and a viewing frustrum.</center><br><br>In this picture a colored square that has one color was dumped without checking it�s children. As you can see some squares had to be checked all the way to the final node, but some large squares could be dumped at once. The colored squares are the ones that are outside the viewing frustrum and the greyscale ones are the one inside the viewing frustrum. As you can see this is actually a worst case scenario because the viewing frustrum crosses the middle of the surrounding square and therefore all the four children have to be checked.<br><br>You could also apply the octree to many other things. Collision detection for example. Just check in which cube your bounding sphere or box is and you will only have to check against those faces. There are many more examples.</font></td>
        </tr>
    </tbody>
</table>
</center><br><br>
<center>
<table style="TABLE-LAYOUT: fixed" border=0 cellSpacing=0 cellPadding=0 width="80%">
    <tbody>
        <tr>
            <td style="BACKGROUND-COLOR: #000000; COLOR: #000000" width="100%"><font color=#ffffff size=3 face="Verdana, Helvetica, Arial, Times New Roman"><strong>Conclusion <font size=1><br><img src="http://www.flipcode.com/archives/line_grey.png"><br><br></font></strong></font></td>
        </tr>
    </tbody>
</table>
</center>
<center>
<table style="TABLE-LAYOUT: fixed" border=0 cellSpacing=0 cellPadding=0 width="80%">
    <tbody>
        <tr>
            <td style="BACKGROUND-COLOR: #000000; COLOR: #000000" width="100%"><font color=#ffe291 size=2 face="Verdana, Helvetica, Arial, Times New Roman">There is already a lot written about octrees. I tried to give my view on them in the hope somebody might read this. As you can see octrees are way easier to implement than BSP-trees (although some disagree) while offering a better structure. The main point about an octrees is that when a parent is discarded so are it's children. Actually that is all there is to it.<br><br>Code clean, play Goldeneye and go vegetarian.<br><br>Jaap Suter a.k.a .........</font></td>
        </tr>
    </tbody>
</table>
<br>译文：<br><strong>1、引言</strong>（<span class=English>Introduction</span>）<br>　　隐面移除是写3D引擎时候最大的问题之一。<br>　　<span class=English>Hidden surface removal is among the biggest problems when writing a 3D engine.</span><br><br>　　在我写3D引擎的开始阶段就开始和它斗争并且一直没有满意的解决方法。理想的可见检测方案应当做到允许（使用）无限的数据、大动态的世界和零重画。第一流的3D引擎一直在追求实现这3个要求。<br>　　<span class=English>I struggled with it since the very beginning of writing 3D engines and still have no satisfactory solution to it. The ideal visibility detection scheme would allow unlimited data, extremely dynamic worlds and would have zero overdraw. The first 3d engine which implements these three demands still has to be written.</span><br><br>　　Z buffer允许动态世界以及即使是交叉的面，但是得忍受大量的重画。另一方面，BSP树如果能够被很好的实现，可以避免重画，但是它需要大量的预处理计算而且不适合动态世界。<br>　　<span class=English>The Z buffer for example allows dynamical worlds and even crossing faces, but it suffers from immense overdraw. The BSP-tree on the other hand, if well implemented, has no overdraw at all but needs that much pre-processing that dynamical worlds are a definite nono.</span><br><br>　　直到最近我第一次听说了八叉树（<span class=English>Octree</span>），我必须承认我被它的简易性&#8220;狠狠地打了一下儿&#8221;。我从来没有真正地去实现这个结构，因此我不会去实现一些代码。这个解释只是想让从没有听说过八叉树的人感到更清晰易懂。如果你真的了解了这个结构（<span class=English>Octree</span>），实现它只是一个小意思。<br>　　<span class=English>It wasn't until recently i first heard of the octree, and I must admit i was struck by it's simplicity. I never actually implemented this structure and therefore I will present no pseudo code at all. This explanation is merely an attempt to make it more clear to people who have never heard of it. Besides, if you really understand the structure, then implementation is a piece of cake.</span><br><a name=2.0></a><br><strong>2、八叉树的结构</strong>（<span class=English>The Octree Structure</span>）<br>　　我们的实际&#8216;世界&#8217;或者说是关卡只不过是一些多边形。你们或许在其中加入了一些曲面（<span class=English>Curves</span>）和Voxels（地形实现方法的一种），但是大多数也都是多边形。<br>　　<span class=English>Our virtual world or level is actually nothing more then a soup of polygons. Some of you people might have thrown in a couple of curves and voxels but most of it will be polygons. Here it is:</span><br><br>
<table class=BGRed border=0 cellSpacing=0 cellPadding=2 align=center>
    <tbody>
        <tr align=middle>
            <td height=303 colSpan=3><img src="mhtml:file://G:%5CDocuments%5CMyDocument%5C%E6%8A%80%E6%9C%AF%E6%96%87%E7%AB%A0%5C%E6%94%B6%E8%97%8F%5C%E5%85%AB%E5%8F%89%E6%A0%91%E5%85%A5%E9%97%A8.mht%21http://www.chinagamedev.net/cgd/develop/3D/200306/image/IntroToOct/IntroToOct-1.jpg" width=340 height=314></td>
        </tr>
        <tr align=middle>
            <td colSpan=3><font color=#cccccc><strong>图1</strong></font></td>
        </tr>
    </tbody>
</table>
<br>　　图1：我们设计的小型关卡。<br>　　<span class=English>Fig 1. Our little level.</span><br><br>　　在这张图片中我建立了一个不超过250个多边形的&#8216;关卡&#8217;。现在想象有一个包围了这个世界的立方体，像下一张图片那样。<br>　　<span class=English>In the picture I just built a simple level containing no more than 250 polys. Now imagine a cube surrounding the world like in the next image:</span><br><br>
<table class=BGRed border=0 cellSpacing=0 cellPadding=2 align=center>
    <tbody>
        <tr align=middle>
            <td height=303 colSpan=3><img src="mhtml:file://G:%5CDocuments%5CMyDocument%5C%E6%8A%80%E6%9C%AF%E6%96%87%E7%AB%A0%5C%E6%94%B6%E8%97%8F%5C%E5%85%AB%E5%8F%89%E6%A0%91%E5%85%A5%E9%97%A8.mht%21http://www.chinagamedev.net/cgd/develop/3D/200306/image/IntroToOct/IntroToOct-2.jpg" width=429 height=434></td>
        </tr>
        <tr align=middle>
            <td colSpan=3><font color=#cccccc><strong>图2</strong></font></td>
        </tr>
    </tbody>
</table>
<br>　　图2：我们设计的关卡被一个立方体所包围着。<br>　　<span class=English>Fig. 2. Our little level surrounded by a cube.</span><br><br>　　现在不难看出这个立方体可以被八等分为八个小些的立方体，所以才叫八叉树。看看这张图：<br>　　<span class=English>Now it isn't hard to see that this cube can be divided into eight smaller cubes, hence the name octree. Take a look at this picture:</span><br><br>
<table class=BGRed border=0 cellSpacing=0 cellPadding=2 align=center>
    <tbody>
        <tr align=middle>
            <td height=303 colSpan=3><img src="mhtml:file://G:%5CDocuments%5CMyDocument%5C%E6%8A%80%E6%9C%AF%E6%96%87%E7%AB%A0%5C%E6%94%B6%E8%97%8F%5C%E5%85%AB%E5%8F%89%E6%A0%91%E5%85%A5%E9%97%A8.mht%21http://www.chinagamedev.net/cgd/develop/3D/200306/image/IntroToOct/IntroToOct-3.jpg" width=429 height=434></td>
        </tr>
        <tr align=middle>
            <td colSpan=3><font color=#cccccc><strong>图3</strong></font></td>
        </tr>
    </tbody>
</table>
<br>　　图3：对围绕着关卡的立方体进行细分。<br>　　<span class=English>Fig 3. Our little level with the surrounding cube subdivided.</span><br><br>　　大点儿的这个立方体被叫做&#8216;父亲&#8217;小些的立方体叫做&#8216;孩子&#8217;。处理每个&#8216;孩子&#8217;的时候，再为更小的八个立方体，你会发现我们在创建一个每个节点有八个子节点（孩子）的树。<br>　　<span class=English>Call the larger cube the parent and the smaller cubes the children. On their turn subdivide each children into eight smaller cubes, and you will notice we are creating a tree where each node has eight children.</span><br><br>　　还有一个小问题。什么时候我们该结束细分的过程呢？有两个可行的解决方法。第一个是当一个立方体的尺寸已经比一个预定的固定值小的时候。第二个更普通。你可以注意到每个&#8216;孩子&#8217;都比他的&#8216;父亲&#8217;有更少的多边形。这就是说：当一个立方体包含的多边形数量比一个预定的固定值少的时候停止细分。<br>　　<span class=English>There is still one little problem left. When should we stop dividing cubes into smaller ones? There are two possible solutions. The first one is to stop when a cube has some size smaller then a fixed number. The second one is more common. You might have noticed that every child has less polygons then it's parent. The trick is to stop subdividing when the number of polygons in a cube is smaller then some fixed number.</span><br><a name=3.0></a><br><strong>3、创建八叉树</strong>（<span class=English>Creating The Octree</span>）<br>　　树是递归的，递归的是树。就那么简单。如果你正确的定义了你的立方体节点，那么递归地创建一个八叉树是很容易的。首先，检查所有的多边形（多边形上位置最外面的点作为）立方体的边界。这很简单因为所有边界都是和坐标轴对其的。这意味着立方体有六个平面方程，分别是：<br>　　<span class=English>Trees are recursion, recursion is trees. It is as simple as that. If you have a correct definition of you cubeNode it is very easy to create an octree recursively. First of all you check all polygons against the boundarys of the cube. This is very simple cause these boundaries are all axis aligned. This means that the cube has six plane equations, which are:</span> <br>
<ul><font id=zoom class=f14>
    <li><span class=ColorCode>1. X = Q.X</span> </li>
    <li><span class=ColorCode>2. Y = Q.Y</span> </li>
    <li><span class=ColorCode>3. Z = Q.Z<br><br></span></li>
    <li><span class=ColorCode>4. X = Q.X + cubeSize<br></span></li>
    <li><span class=ColorCode>5. Y = Q.Y + cubeSize<br></span></li>
    <li><span class=ColorCode>6. Z = Q.Z + cubeSize</span> </li>
    </font></ul>
    <font id=zoom class=f14>　　在这里Q是立方体一个顶角的位置。这是个很简单的方程，而且所有的父亲多边形可以容易地用这些方程来检测。<br>　　<span class=English>WhereQ is the position of one corner of the cube. This are very easy equations and the all parent polygons can very easily be checked against them.</span><br><br>　　一个多边形穿过了一个立方体边界这样的事情是会发生的。再一次，有两个解决方案可用。首先我们可以沿着立方体剪切这个多边形，这也是很简单的，因为（立方体的）边界是与坐标轴对齐的。还有，我们可以把一个多边形放在所有它所在的立方体里面。这就意味着一些立方体可能包含着同一个多边形。为了防止重画一个多边形，我们应当在每一个多边形上做一个标记，当多边形第一次被画的时候，设置这个标记（当然画之前也要检查这个标记啦，不过肯定影响效率。<br>　　<span class=English>It could occur that a polygon crosses a cube boundary. Again two possible solution are at hand. First of all we could clip the polygon against the cube, which is simple, because of the axis aligned boundarys. On the other hand we could put the polygon in all cubes it is in. This means that some cubes can contain the same polygons. In order to prevent us from drawing one poly more than one time we should have a flag on each polygon which will be set if the poly is drawn for the first time.</span><br><br>　　实现一个八叉树是很简单明了的事情，我还没有自己做过，但是我不久会做的。只不过是递归而已。为了构造一个树，第一件你该想的事情就是递归。不管我们讨论的是二叉、四叉还是八叉树，都没有区别，都是递归的方法。所以定义一个立方体节点的类，在构造函数里面写上创建树的代码。在这个构造函数里面，你会调用到更小立方体的构造函数。<br>　　<span class=English>The implementation of an octree is very straight forward. I haven't done it myself yet, but I will soon. It is all matter of recursion. In order to construct a tree, the first thing you should think of is recursion. Whether we are talking about binary trees, quad trees or octrees, it doesnt matter, just build the darn thing recursively. So have a class definition of one cubeNode and put the creation of the tree in it's constructor. In this constructor you will call the constructor itself for smaller cubes.</span><br><a name=4.0></a><br><strong>4、八叉树的用途</strong>（<span class=English>The Purpose Of The Octree</span>）<br>　　一个八叉树实际上就是一个数据结构。它可以用做不同的事情。不仅仅对于&#8216;可见检测&#8217;来说很方便，还有实时阴影以及其它方面。理解八叉树过程中最重要的事情是：如果一个&#8216;父亲&#8217;节点是&#8216;没用&#8217;的，那么他的&#8216;孩子&#8217;节点也同样。让我们举个例子让它更清楚。<br>　　<span class=English>An octree is actually nothing more then a data structure. It can be used for very different things. It is not only handy for visibility detection but also for collision detection, realtime shadows and many more things. The most important thing to understand about octrees is that if a parent is not important then it's children aren't either. Let's makes this a little bit more clear with an example.</span><br><br>　　我们用2D来表示它，这样就很像一个四叉树，但是想象一下它也可以很容易的扩展到3D上。在这里我们沿着视锥（<span class=English>viewing frustrum</span>）检测立方体（正方形）。<br>　　<span class=English>We will do this in 2d, which therefore resembles a quadtree, but with some imagination it can very easily be extended to 3d. Here we test the cubes (squares) against the viewing frustrum. Take a look at the next picture:</span><br><br>
    <table class=BGRed border=0 cellSpacing=0 cellPadding=2 align=center>
        <tbody>
            <tr align=middle>
                <td height=303 colSpan=3><img src="mhtml:file://G:%5CDocuments%5CMyDocument%5C%E6%8A%80%E6%9C%AF%E6%96%87%E7%AB%A0%5C%E6%94%B6%E8%97%8F%5C%E5%85%AB%E5%8F%89%E6%A0%91%E5%85%A5%E9%97%A8.mht%21http://www.chinagamedev.net/cgd/develop/3D/200306/image/IntroToOct/IntroToOct-4.jpg" width=342 height=331></td>
            </tr>
            <tr align=middle>
                <td colSpan=3><font color=#cccccc><strong>图4</strong></font></td>
            </tr>
        </tbody>
    </table>
    <br>　　图4：顶部视锥内的八叉树。<br>　　<span class=English>Fig 4. An octree from the top and a viewing frustrum.</span><br><br>　　在这个图片中，彩色的正方形是没有（没必要）检测它的&#8216;孩子&#8217;的。就像你看到的那样一些正方形（灰色的一些）被检测直到最终节点，但是一些大的正方形只被涂了一种颜色。那些彩色的正方形就是超出了视锥范围的，灰色的是在视锥范围内的。就像你看到的那样，这确实是最糟糕的一种情况，因为视锥穿过了包围正方形的中央，所以所有的四个&#8216;孩子&#8217;都得被检测。<br>　　<span class=English>In this picture a colored square that has one color was dumped without checking it抯 children. As you can see some squares had to be checked all the way to the final node, but some large squares could be dumped at once. The colored squares are the ones that are outside the viewing frustrum and the greyscale ones are the one inside the viewing frustrum. As you can see this is actually a worst case scenario because the viewing frustrum crosses the middle of the surrounding square and therefore all the four children have to be checked.</span><br><br>　　你可以应用八叉树到很多别的地方。例如碰撞检测。只检查你的碰撞球或者碰撞盒子所在的立方体，而且只需要检测那些面。还有更多的例子。<br>　　<span class=English>You could also apply the octree to many other things. Collision detection for example. Just check in which cube your bounding sphere or box is and you will only have to check against those faces. There are many more examples.</span><br><a name=5.0></a><br><strong>5、结论</strong>（<span class=English>Conclusion</span>）<br>　　关于八叉树已经写了很多了。我设法表述自己对它的看法，并且希望有人会读到它。就像你看到的那样，当提供好的结构的时候，八叉树比BSP树更容易实现（有人持异议）。主要的一点是：当一个&#8216;父亲&#8217;节点被丢弃的时候，他的&#8216;孩子&#8217;节点也同样被丢弃。实际上这就是全部。<br>　　<span class=English>There is already a lot written about octrees. I tried to give my view on them in the hope somebody might read this. As you can see octrees are way easier to implement than BSP-trees (although some disagree) while offering a better structure. The main point about an octrees is that when a parent is discarded so are it's children. Actually that is all there is to it.<br>　　Code clean, play Goldeneye and go vegetarian. Jaap Suter a.k.a .........</span></font><br></center>
<img src ="http://www.cppblog.com/winmain/aggbug/108306.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/winmain/" target="_blank">Code Knight</a> 2010-02-23 21:18 <a href="http://www.cppblog.com/winmain/archive/2010/02/23/108306.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>图形学学习笔记2(cel-shading分析) </title><link>http://www.cppblog.com/winmain/archive/2010/02/23/108304.html</link><dc:creator>Code Knight</dc:creator><author>Code Knight</author><pubDate>Tue, 23 Feb 2010 13:14:00 GMT</pubDate><guid>http://www.cppblog.com/winmain/archive/2010/02/23/108304.html</guid><wfw:comment>http://www.cppblog.com/winmain/comments/108304.html</wfw:comment><comments>http://www.cppblog.com/winmain/archive/2010/02/23/108304.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/winmain/comments/commentRss/108304.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/winmain/services/trackbacks/108304.html</trackback:ping><description><![CDATA[&nbsp;
<p>参看word文档<span><br>// -------------------------------</span></p>
<p><span>// Cel Shading Section</span></p>
<p><span>// -------------------------------</span></p>
<p><span>vertex_program Ogre/CelShadingVP cg</span></p>
<p><span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>source Example_CelShading.cg</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>entry_point main_vp</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>profiles vs_1_1 arbvp1</span></p>
<p>&nbsp;</p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>default_params</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>param_named_auto lightPosition light_position_object_space 0<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>param_named_auto eyePosition camera_position_object_space</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>param_named_auto worldViewProj worldviewproj_matrix</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>param_named shininess float 10 </span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span>}</span></p>
<p>&nbsp;</p>
<p><span>fragment_program Ogre/CelShadingFP cg</span></p>
<p><span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>source Example_CelShading.cg</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>entry_point main_fp</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>profiles ps_1_1 arbfp1 fp20</span></p>
<p><span>}</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span>material Examples/CelShading</span></p>
<p><span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>technique</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pass</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>vertex_program_ref Ogre/CelShadingVP</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>// map shininess from custom renderable param 1</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>param_named_auto shininess custom 1</span></p>
<p><span>// </span><span>终于知道<span>param_named_auto</span>第三个参数的作用了，用于给程序中赋值的索引</span></p>
<p><span>sub</span><span>-&gt;<span>setCustomParameter</span>(<span>CUSTOM_SHININESS</span>, <span>Vector4</span>(<st1:chmetcnv w:st="on" UnitName="F" SourceValue="10" HasSpace="False" Negative="False" NumberType="1" TCSC="0">10.0f</st1:chmetcnv>, <st1:chmetcnv w:st="on" UnitName="F" SourceValue="0" HasSpace="False" Negative="False" NumberType="1" TCSC="0">0.0f</st1:chmetcnv>, <st1:chmetcnv w:st="on" UnitName="F" SourceValue="0" HasSpace="False" Negative="False" NumberType="1" TCSC="0">0.0f</st1:chmetcnv>, <st1:chmetcnv w:st="on" UnitName="F" SourceValue="0" HasSpace="False" Negative="False" NumberType="1" TCSC="0">0.0f</st1:chmetcnv>));<span> </span></span><span>CUSTOM_SHININESS == 1</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>fragment_program_ref Ogre/CelShadingFP</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>// map diffuse from custom renderable param 2</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>param_named_auto diffuse custom 2</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>// map specular from custom renderable param 2</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>param_named_auto specular custom 3</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>texture_unit</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>texture cel_shading_diffuse.png 1d</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>tex_address_mode clamp</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>filtering none</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>texture_unit</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>texture cel_shading_specular.png 1d</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>tex_address_mode clamp</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>filtering none</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>texture_unit</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>texture cel_shading_edge.png 1d</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>tex_address_mode clamp</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>filtering none</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span></span></p>
<p><span>}</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span>////////////////////////////////////////////////////////////////////////////////////</span><span>下面是<span>cg</span>文件</span></p>
<p><span>////////////////////////////////////////////////////////////////////////////////</span></p>
<p>&nbsp;</p>
<p><span>/* Cel shading vertex program for single-pass rendering</span></p>
<p><span><span>&nbsp;&nbsp; </span>In this program, we want to calculate the diffuse and specular</span></p>
<p><span><span>&nbsp;&nbsp; </span>ramp components, and the edge factor (for doing simple outlining)</span></p>
<p><span><span>&nbsp;&nbsp; </span>For the outlining to look good, we need a pretty well curved model.</span></p>
<p><span>*/</span></p>
<p><a><span>void main_vp(float4 position<span>&nbsp;&nbsp;&nbsp; </span>: POSITION,</span></a></p>
<p><span><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;float3 normal<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>: NORMAL,</span></span><span><span><a id=_anchor_1 language=JavaScript onmouseover="msoCommentShow('_anchor_1','_com_1')" onmouseout="msoCommentHide('_com_1')" href="#_msocom_1" name=_msoanchor_1>[U1]</a>&nbsp;</span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;// outputs</span></p>
<p><a><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;<span>out</span> float4 oPosition <span>&nbsp;&nbsp;&nbsp;</span>: POSITION,</span></a></p>
<p><span><span><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;<span>out</span> float&nbsp;diffuse<span>&nbsp;&nbsp;&nbsp;&nbsp; </span>: TEXCOORD0,</span></span></p>
<p><span><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;<span>out</span> float&nbsp;specular<span>&nbsp;&nbsp;&nbsp; </span>: TEXCOORD1,</span></span></p>
<p><span><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;<span>out</span> float&nbsp;edge<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>: TEXCOORD2,</span></span><span><span><a id=_anchor_2 language=JavaScript onmouseover="msoCommentShow('_anchor_2','_com_2')" onmouseout="msoCommentHide('_com_2')" href="#_msocom_2" name=_msoanchor_2>[U2]</a>&nbsp;</span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;// parameters</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;uniform float3 lightPosition, // object space</span><span>：世界坐标系</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;uniform float3 eyePosition,<span>&nbsp;&nbsp; </span>// object space</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;uniform float4&nbsp;shininess,</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;uniform float4x4 worldViewProj)</span></p>
<p><span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>// calculate output position</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>oPosition = mul(worldViewProj, position);</span></p>
<p>&nbsp;</p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>// calculate light vector</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>float3 N = normalize(normal);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>float<st1:chmetcnv w:st="on" UnitName="l" SourceValue="3" HasSpace="True" Negative="False" NumberType="1" TCSC="0">3 L</st1:chmetcnv> = normalize(lightPosition - position.xyz);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>// Calculate diffuse component</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>diffuse = max(dot(N, L) , 0);</span></p>
<p>&nbsp;</p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>// Calculate specular component</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>float3 E = normalize(eyePosition - position.xyz);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>float3 H = normalize(L + E);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>specular = pow(max(dot(N, H), 0), <a>shininess</a></span><span><span><a id=_anchor_3 language=JavaScript onmouseover="msoCommentShow('_anchor_3','_com_3')" onmouseout="msoCommentHide('_com_3')" href="#_msocom_3" name=_msoanchor_3>[U3]</a>&nbsp;</span></span><span>);</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>// Mask off specular if diffuse is 0</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>if (diffuse == 0) specular = 0;</span></p>
<p>&nbsp;</p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>// Edge detection, dot eye and normal vectors</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>edge = max(dot(N, E), 0);&nbsp;// </span><span>法线与视线平行的点认为是标远，给予黑色沟边</span></p>
<p><span>}</span></p>
<p>&nbsp;</p>
<p><span>void main_fp(<a>float diffuseIn <span>&nbsp;&nbsp; </span>: TEXCOORD0,</a></span></p>
<p><span><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;float specularIn<span>&nbsp;&nbsp; </span>: TEXCOORD1,</span></span></p>
<p><span><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;float edge<span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp; </span>: TEXCOORD2,</span></span></p>
<p><span><span><a id=_anchor_4 language=JavaScript onmouseover="msoCommentShow('_anchor_4','_com_4')" onmouseout="msoCommentHide('_com_4')" href="#_msocom_4" name=_msoanchor_4>[U4]</a>&nbsp;</span></span><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;out float4 colour&nbsp;: COLOR,</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;uniform float4 diffuse,</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;uniform float4 specular,</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><a>&nbsp;uniform sampler1D diffuseRamp,</a></span></p>
<p><span><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;uniform sampler1D specularRamp,</span></span></p>
<p><span><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;uniform sampler1D edgeRamp</span></span><span><span><a id=_anchor_5 language=JavaScript onmouseover="msoCommentShow('_anchor_5','_com_5')" onmouseout="msoCommentHide('_com_5')" href="#_msocom_5" name=_msoanchor_5>[U5]</a>&nbsp;</span></span><span>)</span></p>
<p><span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>// Step functions from textures</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>diffuseIn = tex1D(diffuseRamp, diffuseIn).x;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>specularIn = tex1D(specularRamp, specularIn).x;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>edge = tex1D(edgeRamp, edge).x;</span></p>
<p>&nbsp;</p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>colour = edge * ((diffuse * diffuseIn) + </span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>(specular * specularIn));</span></p>
<p><span>}</span></p>
<div>
<hr align=left SIZE=1 width="33%">
<div>
<div id=_com_1 language=JavaScript onmouseover="msoCommentShow('_anchor_1','_com_1')" onmouseout="msoCommentHide('_com_1')"><span><a name=_msocom_1></a></span>
<p><span><span><span>&nbsp;<a href="#_msoanchor_1">[U1]</a></span></span></span><span>这里是</span><span>GPU</span><span>传进来的，</span><span>POSITION</span><span>：顶点坐标，</span><span>NORMAL</span><span>法线，去看看</span><span>hlsl</span><span>的语意定义</span></p>
</div>
</div>
<div>
<div id=_com_2 language=JavaScript onmouseover="msoCommentShow('_anchor_2','_com_2')" onmouseout="msoCommentHide('_com_2')"><span><a name=_msocom_2></a></span>
<p><span><span><span>&nbsp;<a href="#_msoanchor_2">[U2]</a></span></span></span><span>out</span><span>都是输出参数，改变他们的值输出之后被</span><span>ps</span><span>获取</span></p>
</div>
</div>
<div>
<div id=_com_3 language=JavaScript onmouseover="msoCommentShow('_anchor_3','_com_3')" onmouseout="msoCommentHide('_com_3')"><span><a name=_msocom_3></a></span>
<p><span><span><span>&nbsp;<a href="#_msoanchor_3">[U3]</a></span></span></span><span>即</span><span>m</span><span>下标</span><span>gls</span><span>，为材料的光泽度</span></p>
</div>
</div>
<div>
<div id=_com_4 language=JavaScript onmouseover="msoCommentShow('_anchor_4','_com_4')" onmouseout="msoCommentHide('_com_4')"><span><a name=_msocom_4></a></span>
<p><span><span><span>&nbsp;<a href="#_msoanchor_4">[U4]</a></span></span></span><span>得到的是</span><span>vs</span><span>中</span><span>out</span><span>出来的值</span></p>
</div>
</div>
<div>
<div id=_com_5 language=JavaScript onmouseover="msoCommentShow('_anchor_5','_com_5')" onmouseout="msoCommentHide('_com_5')"><span><a name=_msocom_5></a></span>
<p><span><span><span>&nbsp;<a href="#_msoanchor_5">[U5]</a></span></span></span><span>从</span><span>texture_unit</span><span>中得到，顺序根据定义的顺序</span><span>texture_unit</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&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>texture cel_shading_diffuse.png 1d</span></p>
<p><span><span>&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>tex_address_mode clamp</span></p>
<p><span><span>&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>filtering none</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>texture_unit</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&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>texture cel_shading_specular.png 1d</span></p>
<p><span><span>&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>tex_address_mode clamp</span></p>
<p><span><span>&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>filtering none</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>texture_unit</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p><span><span>&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>texture cel_shading_edge.png 1d</span></p>
<p><span><span>&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>tex_address_mode clamp</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>filtering none</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
</div>
</div>
</div>
<img src ="http://www.cppblog.com/winmain/aggbug/108304.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/winmain/" target="_blank">Code Knight</a> 2010-02-23 21:14 <a href="http://www.cppblog.com/winmain/archive/2010/02/23/108304.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[原]图形学学习笔记1(光照着色模型)</title><link>http://www.cppblog.com/winmain/archive/2010/02/23/108303.html</link><dc:creator>Code Knight</dc:creator><author>Code Knight</author><pubDate>Tue, 23 Feb 2010 13:13:00 GMT</pubDate><guid>http://www.cppblog.com/winmain/archive/2010/02/23/108303.html</guid><wfw:comment>http://www.cppblog.com/winmain/comments/108303.html</wfw:comment><comments>http://www.cppblog.com/winmain/archive/2010/02/23/108303.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/winmain/comments/commentRss/108303.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/winmain/services/trackbacks/108303.html</trackback:ping><description><![CDATA[&nbsp;
<p><span>一，四种光照着色模型</span></p>
<p><span>1</span><span>，固定着色<span>(constant shading)</span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span></span><span>固定着色根本不考虑光照模型，只是根据多边形颜色的索引或<span>RGB</span>值绘制它。</span></p>
<p><span>PS:</span><span>基本已经被游戏淘汰，太简单的着色模型</span></p>
<p><span>2</span><span>，恒定着色（<span>flat shding</span>）</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span></span><span>对于每个多边形只需要根据一个顶点执行光照计算，然后根据计算结果对整个多边形进行着色，这就是恒定着色，也称为面片着色<span>(faceted shading)</span>，对于由平面组成的多边形这种方法是可行的（立方体），但对于由曲面组成的多边形这种着色方式会出现非你想要的结果<span>. </span></span></p>
<p><span>3</span><span>，<span>Gougraud</span>着色</span></p>
<p><span>　　对于顶点之间的像素值采用两个顶点之间的插值计算来确定，顶点之间的颜色过渡自然，渲染效果也比较平滑<span>,</span>没有恒定着色那样突兀。</span></p>
<p><span>4</span><span>，<span>Phong</span>着色</span></p>
<p><span>　　与<span>Gougraud</span>着色类似，不过优点在于还对每个像素进行了法线的插值，对于镜面反射效果比较好。</span></p>
<img src ="http://www.cppblog.com/winmain/aggbug/108303.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/winmain/" target="_blank">Code Knight</a> 2010-02-23 21:13 <a href="http://www.cppblog.com/winmain/archive/2010/02/23/108303.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【转贴】了解凹凸映射Bump Map技术的内幕 </title><link>http://www.cppblog.com/winmain/archive/2010/02/23/108301.html</link><dc:creator>Code Knight</dc:creator><author>Code Knight</author><pubDate>Tue, 23 Feb 2010 13:09:00 GMT</pubDate><guid>http://www.cppblog.com/winmain/archive/2010/02/23/108301.html</guid><wfw:comment>http://www.cppblog.com/winmain/comments/108301.html</wfw:comment><comments>http://www.cppblog.com/winmain/archive/2010/02/23/108301.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/winmain/comments/commentRss/108301.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/winmain/services/trackbacks/108301.html</trackback:ping><description><![CDATA[我翻译这篇教程的目的是为了帮助那些对图形渲染技术有兴趣却又苦于找不到免费中文学习资料的人。在我的身边没有任何一位从事计算机专业的前辈，从刚学会WINDOWS的基本操作到现在，我的计算机技术完全都是一步步自学过来的，算算学编程的历史也近5年时间了。我往往要花一半以上的学习时间用来查学习资料（记得我学GIF图像压缩解压算法时，用了近2个星期时间才编出了显示GIF图片的程序，主要原因就是资料不够，只看一两篇短篇幅的教程来写程序，其中多数时间花在调试代码和猜格式上）。所以我对那些不是从事计算机专业，身边又没有计算机高手的学习者深有同感——查一堆堆资料是自学中最痛苦的过程。这几天我也正在学BUMP MAPPING算法，在看完一篇简单的E文教程后，我觉得自己也确实应该为中国的教程事业做出一点我微薄的贡献。我并不是个3D高手，也只是个初学OpenGL的新手，所以只能先做翻译了。我也希望我的翻译小样能够抛砖引玉，看到中国越来越多的高手能够真正写点自己的东西，拿出来与大家分享。由于本人水平有限，翻译难免有错误和不妥之处，请多加指正。<br><br>为了尊重原作者，同时也是为了读者能够对照原文，在此贴出原文地址：<br><a href="http://freespace.virgin.net/hugo.elias/graphics/x_polybm.htm"><font color=#444444 size=3>http://freespace.virgin.net/hugo.elias/graphics/x_polybm.htm</font></a><font size=3>　<br>　 </font>
<div align=center>
<table id=table4 border=0 cellSpacing=0 cellPadding=0>
    <tbody>
        <tr>
            <td width="50%"><font face=Arial><font class=NewsContent2 size=3><strong>凹凸映射Bump Mapping</strong></font></font></td>
            <td width="50%"><img border=0 alt="" src="http://dev.gameres.com/Program/Visual/3D/BumpMap1.gif" width=119 height=113></td>
        </tr>
    </tbody>
</table>
</div>
<p>　　凹凸映射和纹理映射非常相似。然而，纹理映射是把颜色加到多边形上，而凹凸映射是把粗糙信息加到多边形上。这在多边形的视觉上会产生很吸引人的效果。我们只需要添加一点信息到本来需要使用大量多边形的物体上。需要注意的是这个物体是平的，但是它看起来却是粗糙不平的。让我们来看看左边的那个立方体。如果你很近地观察它时，你会发现它上面的很多细节。它看起来好像是由成千上万个多边形构成的，其实它只是由6个矩形构成。你或许会问：&#8220;这和纹理映射有什么不同？&#8221;它们的不同之处在于——凹凸映射是一种负责光方向的纹理映射。<br><br><strong>（1）凹凸映射背后的原理</strong><br><br>　　让我们来看看一个粗糙的表面。<br>　　　　<img border=0 alt="" src="http://dev.gameres.com/Program/Visual/3D/BumpMap2.gif" width=194 height=172><br><br>　　从远处看，你判断这个物体是粗糙的的唯一证据是在它表面上下的亮度有改变。你的大脑能够获得这些亮暗不一的图案信息，然后判断出它们是表面中有凹凸的部位。</p>
<p>　　那么你也许会问：我是怎么知道哪些点要亮，哪些点要暗呢？这不难。绝大多数人生活在这样一种环境下——这个环境的大多数光源来自上方（译者注：比如白天主要的光来自太阳，夜晚主要的光来自天花板上的日光灯）。所以向上倾的地方就会更亮，而向下倾的地方就会更暗。所以这种现象使你的眼睛看到一个物体上亮暗区域时，可以判断出它的凹凸情况。相对亮的块被判断是面向上的，相对暗的块被判断是面向下的。所以我只需要给物体上的线条简单得上色。<br><br>　　如果你想要更多的证据，这里还有一幅几乎相同的图，不同于前的是它旋转了180度。所以它是前一幅图倒转的图像。那些先前看起来是凹进去的区域，现在看起来是凸出来的了。<br>　　　　<img border=0 alt="" src="http://dev.gameres.com/Program/Visual/3D/BumpMap3.gif" width=194 height=172><br><br>　　这个时候你的大脑并没有被完全欺骗，你脑中存留的视觉印象使你仍然有能力判断出这是前一幅图，只是它的光源变了，是从小往上照的你的大脑可能强迫性地判断出它是第一幅图。事实上，你只要始终盯着它，并且努力地想像着光是从右下方向照射的，你就会理解它是凹的（译者注：因为日常生活的习惯，你会很容易把这些图形判断成凸出的图形，但是因为有了上一幅对照图的印象，你可能才会特别注意到这些图块其实还是凹入的，只是判断方法不符合我们日常生活习惯，因为这时大多数光不是从上方照射，而是从下往上照射）。<br><br><strong>（2）什么是凹凸图（Bump Map）</strong><br><br>　　凹凸图和纹理图很相似。但是不同的是，凹凸图包含的不是颜色信息，而是凹凸信息。最通常的方法是通过存储高度值实现。我们要用到一个灰色的纹理图，灰色的亮度体现出每个点分别凸出多少（见右图）。这就是一个非常方便的保存凹凸图的方法，而且这种图很容易制作。这副图具体又是怎样被渲染器使用的呢？你接着往下看就会明白了。<br><br>　　当然，你并不一定要把自己局限于这些简单的图形，你可以扩展，用它来做木材，做石头，做脱了漆的墙面，做任何你想做的物体。<br>　　　　<img border=0 alt="" src="http://dev.gameres.com/Program/Visual/3D/BumpMap4.gif" width=194 height=172><br><br><strong>（3）那么它是怎么工作的</strong><br><br>　　凹凸映射是补色渲染技术（Phong Shading Technique）的一项扩展，只是在补色渲染里，多边形表面上的法线将被改变，这个向量用来计算该点的亮度。当你加入了凹凸映射，法线向量会略微地改变，怎么改变则基于凹凸图。改变法线向量就会改变多边形的点的颜色值。就这么简单。<br><br>　　现在，有几种方法来达到这个目的（译者注：这个目的指改变法线向量）。我并没有实际编写补色渲染和凹凸映射的程序，但是我在这里将介绍一种我喜欢的方法来实现！<br><br>　　现在我们需要将凹凸图中的高度信息转换成补色渲染用到的法线的调节信息。这个做起来不难，但是解释起来比较费劲。<br><br>　　　　<img border=0 alt="" src="http://dev.gameres.com/Program/Visual/3D/BumpMap5.gif" width=145 height=145><br>　　好的，我们现在将凹凸位图的信息转换成一些小向量——一个向量对应于一个点。请看左边一副放大的凹凸图。相对亮的点比相对暗的点更为凸出。看清楚了吗？现在计算每个点的向量，这些向量表征了每个点的倾斜情况，请看下图的描绘。图中红色小圆点表示向量是向下的：<br>　　　　<img border=0 alt="" src="http://dev.gameres.com/Program/Visual/3D/BumpMap6.gif" width=145 height=145><br><br>　　有很多计算向量的方法，不同的方法精确度不同，但是选择什么方法要取决于你所要求的精确度是个什么层次。最通常的方法是分别计算每个点上X和Y的倾斜度：<br><font color=#ff0000><br>　　x_gradient = pixel(x-1, y) - pixel(x+1, y)<br>　　y_gradient = pixel(x, y-1) - pixel(x, y+1)</font><br><br>在得出了这两个倾斜度后，你就可以计算多边形点的法线了。<br><br><img border=0 alt="" src="http://dev.gameres.com/Program/Visual/3D/BumpMap7.gif" width=120 height=130>　　　　<img border=0 alt="" src="http://dev.gameres.com/Program/Visual/3D/BumpMap8.gif" width=120 height=130><br><br>　　这里有一个多边形，图上绘出了它的一条法线向量——n。除此，还有两条向量，它们将用来调节该点法线向量。这两条向量必须与当前被渲染的多边形的凹凸图对齐，换句话说，它们要与凹凸图使用同一种坐标轴。下边的图分别是凹凸图和多边形，两副图都显示了U、V两条向量（译者注：也就是平面2D坐标的两条轴）：<br><br><img border=0 alt="" src="http://dev.gameres.com/Program/Visual/3D/BumpMap9.gif" width=154 height=117>　　　　<img border=0 alt="" src="http://dev.gameres.com/Program/Visual/3D/BumpMap10.gif" width=99 height=116><br><br>　　现在你可以看到被调节后的新法线向量了。这个调节公式很简单：<br><br>　　<font color=#ff0000>New_Normal = Normal + (U * x_gradient) + (V * y_gradient)</font><br><br>有了新法线向量后，你就可以通过补色渲染技术计算出多边形每个点的亮度了</p>
<img src ="http://www.cppblog.com/winmain/aggbug/108301.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/winmain/" target="_blank">Code Knight</a> 2010-02-23 21:09 <a href="http://www.cppblog.com/winmain/archive/2010/02/23/108301.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OCTREE 教程</title><link>http://www.cppblog.com/winmain/archive/2010/02/23/108300.html</link><dc:creator>Code Knight</dc:creator><author>Code Knight</author><pubDate>Tue, 23 Feb 2010 13:08:00 GMT</pubDate><guid>http://www.cppblog.com/winmain/archive/2010/02/23/108300.html</guid><wfw:comment>http://www.cppblog.com/winmain/comments/108300.html</wfw:comment><comments>http://www.cppblog.com/winmain/archive/2010/02/23/108300.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/winmain/comments/commentRss/108300.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/winmain/services/trackbacks/108300.html</trackback:ping><description><![CDATA[&nbsp;
<td bgcolor="#f7ebde"><font class=NewsContent2><br><strong>对OCTREE的描述</strong><br><br>　　OCTREE 是对3D空间进行划分，也可以叫空间分割。他允许你只对你的3D世界中摄象机照射的区域进行作画。他也能用于冲突检测。下面讲一下为什么要进行空间分割。假设你建立了一个游戏世界，这个世界有超过100，000个多边形要画。如果你建立一个循环并传递这些多边形，那速度是很慢的。即使你有一块很好的显示卡，他也会有很大的麻烦。但是玩你游戏的玩家的显示卡不会超过300$。有没有一种方法只渲染摄象机看见的多边形？那就是美丽的OCTREE。他允许你快速的找到你要渲染的多边形。<br><br><br><strong>OCTREE是怎样工作的</strong><br><br>　　OCTREE工作在立方体中。最初，OCTREE从根接点开始，这个根接点对齐于立方体中整个世界，水平或场景的axis中心线。因此，把我们的整个世界想象成一个不可见的立方体。<br>　</font>
<div align=center><font class=NewsContent2>
<table id=table4 border=0 cellSpacing=0 cellPadding=0 width="100%">
    <tbody>
        <tr>
            <td>
            <p align=center><img border=0 src="http://dev.gameres.com/Program/Visual/3D/OCTREETutorial1.jpg" width=320 height=200></p>
            </td>
        </tr>
    </tbody>
</table>
</font></div>
<font class=NewsContent2></font>
<p><font class=NewsContent2><br>　　现在根接点存储了世界中的全部顶点。这是，他还是不能给我们任何好处，因为他还会画所有的东西。我们想把这个接点分成8个部分。一次，我们划分时，有8个立方体包含那最初的根接点的立方体。那意味着有4个立方体在上面，4个立方体在下面。请看下图：</font></p>
<font class=NewsContent2></font>
<div align=center><font class=NewsContent2>
<table id=table5 border=0 cellSpacing=0 cellPadding=0 width="100%">
    <tbody>
        <tr>
            <td>
            <p align=center><img border=0 src="http://dev.gameres.com/Program/Visual/3D/OCTREETutorial2.jpg" width=320 height=200></p>
            </td>
        </tr>
    </tbody>
</table>
</font></div>
<font class=NewsContent2></font>
<p><font class=NewsContent2><br>　　记住图中黄色轮廓线没有。<br>　　我们刚刚把这个世界分成8个部分。想象一下如果我们有2，3，4个部分，我们的世界将是怎样？我们的摄象机在世界的中间，向着后面靠右的角落。如果你看这些线，你将注意到在OCTREE中8个结点中的第4个。这些结点包含2个后面的顶和底结点。这意味着我们只用画存储在这些结点中的顶点。</font></p>
<font class=NewsContent2></font>
<div align=center><font class=NewsContent2>
<table id=table6 border=0 cellSpacing=0 cellPadding=0 width="100%">
    <tbody>
        <tr>
            <td>
            <p align=center><img border=0 src="http://dev.gameres.com/Program/Visual/3D/OCTREETutorial3.jpg" width=320 height=200></p>
            </td>
        </tr>
    </tbody>
</table>
</font></div>
<font class=NewsContent2></font>
<p><font class=NewsContent2><br>　　我们如何检测出我们要画的结点？如果你学过破片拣选（frustum culling),这将是很简单的。你能得到这些破片的大小并检测每个结点，看他是否被截断或在你的视觉破片中。有一个关于破片拣选的教程在<a href="http://www.gametutorials.com/"><u><font color=#0066cc>http://www.gametutorials.com</font></u></a>. 如果一个立方体截断破片，我们就将画这些结点。在这个例子中，我们切的数量是我们需要画的50%。记住，这只是我们世界中的一个部分。部分越多，我们就将越精确。当然，我们不会需要太多的点。下面，我们来看一下下面的图：</font></p>
<font class=NewsContent2></font>
<div align=center><font class=NewsContent2>
<table id=table7 border=0 cellSpacing=0 cellPadding=0 width="100%">
    <tbody>
        <tr>
            <td>
            <p align=center><img border=0 src="http://dev.gameres.com/Program/Visual/3D/OCTREETutorial4.jpg" width=320 height=200></p>
            </td>
        </tr>
    </tbody>
</table>
</font></div>
<font class=NewsContent2></font>
<p><font class=NewsContent2><br>　　在上面这幅图中，你将发现许多的不同。这个例子中，不是在原始的8个立方体的每一个结点中建立8个新的立方体。原始的8个结点的顶和底面没有细分。你总是把一个结点分成8个或更多的结点，但是，如果在这个面没有三角形可以存储，我们将忽视这个结点并不给他分配内存。如果我们进一步的细分，更多的结点将形成原始的世界。如果我们变换到另一个部分，那立方体将相似的变换。为了说明这一点，请看图： </font></p>
<font class=NewsContent2></font>
<div align=center><font class=NewsContent2>
<table id=table8 border=0 cellSpacing=0 cellPadding=0 width="100%">
    <tbody>
        <tr>
            <td align=middle><img border=0 src="http://dev.gameres.com/Program/Visual/3D/OCTREETutorial5.jpg" width=304 height=304></td>
            <td align=middle><img border=0 src="http://dev.gameres.com/Program/Visual/3D/OCTREETutorial6.jpg" width=304 height=304></td>
        </tr>
    </tbody>
</table>
</font></div>
<font class=NewsContent2></font>
<p><font class=NewsContent2><br>　　在图中，有两个球，但是方向相反。注意左边的部分，他将那世界分成2个结点，不是8个。这是因为球只要2个结点。请看右边的球是不是和左边的很相似。这幅图告诉我们：只显示需要的部分结点。如果没有三角形占用空间，结点将不会建立。<br><br><br><strong>何时停止细分</strong><br><br>　　现在，我们明白了如何细分，但是我们也需要知道怎样停止细分。有许多的方法：<br>　　1。如果当时的三角形数量少于我们定义的最大的三角形数量，我们可以停止细分当前的结点。举个例子，我们定义三角形的最大数量为100。这意味着我们在细分结点之前，要检测一下当前三角形的总数量是否小于或等于我们定义的最大数量，然后再做决定。如果数量少于或等于，我们将停止细分并指定这些三角形到那个结点。请注意我们从不指定任何三角形到任何结点，除非他是末结点。如果我们划分一个结点，我们不能存储三角形到那个结点，但是可以存储在他的子结点或他们的子结点中，甚至到他们的子中，等等。当我们复习了怎样画0C树后，将会有更多的了解。<br><br>　　2。另一个方法是在停止细分时，看我们是否细分的数目是否超过了细分的标准。例如，我们可以先建立细分的标准为10，如果细分的数量大于这个标准，我们将停止并指定这些在立方体中这个面的顶点到那个结点。当我们说&#8220;大于这个标准&#8221;就意味着细分的数量有11个。<br><br>　　3。最后的方法是看结点数是否超过结点变量定义时的值。例如，我们设置结点变量的值为500。每次，我们建立一个结点，相应的结点数增加1。然后在我们每次建立另一个结点时，检测一下我们当前的结点数是否超过结点变量。如果结点数为501，我们将不会细分这个结点，但是指定他的当前顶点给他。我自己用 1和3的方法，但是1和2也很好，因为你可以测试不同的细分的标准。<br><br>　<br><strong>怎样画OCTREE</strong><br><br>　　OCTREE建立后，我们就可以画我们需要的结点。那些立方体不是全部包含在我们的视觉中的，只有一部分。这就是我们为什么要计算每个结点的三角形的数量，如果我们只需要一个结点中的一部分，这样我们就不需要画成千上万个三角形。我们从根目录开始画OCTREE。对于每个结点都存储着一个中心点。这是非常好的，比如在下面这个函数中：<br><br>　　//这个函数取走立方体（X，Y，Z）的中心点和他的大小（width/2)<br>　　bool CubeInFrustum(float x,float y,float z,float size);<br><br>　　这个函数返回true or false,是由立方体是否在破片中决定的。如果立方体在破片中，我们将检测所有他的结点，看他们是否在破片中，否则我们将忽约树中的整个分枝。当我们得到了破片中的结点，但是没有任何结点在他下面。我们想画的顶点存储在末结点中。记住，只有末结点有顶点存储。看下面的图：</font></p>
<font class=NewsContent2></font>
<div align=center><font class=NewsContent2>
<table id=table9 border=0 cellSpacing=0 cellPadding=0 width="100%">
    <tbody>
        <tr>
            <td>
            <p align=center><img border=0 src="http://dev.gameres.com/Program/Visual/3D/OCTREETutorial7.jpg" width=320 height=200></p>
            </td>
        </tr>
    </tbody>
</table>
</font></div>
<font class=NewsContent2></font>
<p><font class=NewsContent2><br>　　有阴影的立方体是在破片中。白色的立方体不是在破片中。这里显示了细分的2层。<br><br><br><strong>OCTREE 中的冲突</strong><br><br>　　OCTREE 不是用于渲染，但是用于冲突检测很好。随着游戏的发展，冲突检测也在改变，你将不得不在游戏世界中运用自己的算式检测你的角色或目标是否冲突。下面是一些冲突检测的例子：<br>　　1。你将建立一个函数允许你转递3D空间中的点到你的OCTREE并返回在这个点周围的顶点。你将转递的那个点是你的角色和目标的中心点。这虽然可以工作一端时间，但如果这个点靠近一个立方体的边时呢？你的角色或目标可能和另一个立方体的顶点相冲突。为了解决这个问题，你将做一些事情。你可以转递角色/目标的半径或一定的空间，然后检测半径或一定的空间是否和周围的结点相冲突。这由你的角色/目标的形状决定。下面是一些典型的函数：<br><br>　　//这个函数取走角色/目标（X，Y，Z）的中心点并返回靠近他的顶点<br>　　CVector3 *GetVerticesFromPoint(float x,float y,float z);<br><br>　　//这个函数取走角色/目标（X，Y，Z）的中心点和半径，然后返回和他冲突的结点中的顶点<br>　　CVector3 *GetVerticesFromPointAndRadius(float x,float y,float z,float radius);<br><br>　　//这个函数取走角色/目标（X，Y，Z）的中心点和立方体的大小，然后返回和他冲突的结点中的顶点<br>　　CVector3 *GetVerticesFromPointAndCube(float x,float y,float z,float size);<br><br>　　我相信你有更好的方法快速的检测，在这里只是给你一点基础。<br><br><br><strong>总结</strong><br><br>　　这篇教程只是给你讲截如何建立自己的OCTREE。关于这篇文章中的代码在www.gametutorials.com，我希望这篇文章对你有用。<br><br><br>中文译者：antking<br><a href="http://akinggame.gameres.com/"><u><font color=#0066cc>http://akinggame.gameres.com</font></u></a> <br>这篇文章的英文版在<a href="http://www.gametutorials.com/Tutorials/OpenGL/Octree.htm"><u><font color=#0066cc>http://www.gametutorials.com/Tutorials/OpenGL/Octree.htm</font></u></a> <br><br>Ben Humphrey (DigiBen)<br>Game Programmer<br>DigiBen@GameTutorials.com<br>Co-Web Host of www.GameTutorials.com</font></p>
</td>
<img src ="http://www.cppblog.com/winmain/aggbug/108300.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/winmain/" target="_blank">Code Knight</a> 2010-02-23 21:08 <a href="http://www.cppblog.com/winmain/archive/2010/02/23/108300.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>贴</title><link>http://www.cppblog.com/winmain/archive/2009/12/29/104407.html</link><dc:creator>Code Knight</dc:creator><author>Code Knight</author><pubDate>Tue, 29 Dec 2009 13:54:00 GMT</pubDate><guid>http://www.cppblog.com/winmain/archive/2009/12/29/104407.html</guid><wfw:comment>http://www.cppblog.com/winmain/comments/104407.html</wfw:comment><comments>http://www.cppblog.com/winmain/archive/2009/12/29/104407.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/winmain/comments/commentRss/104407.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/winmain/services/trackbacks/104407.html</trackback:ping><description><![CDATA[<img  src="http://www.cppblog.com/images/cppblog_com/winmain/screenshot_2.png" border="0"><img src="http://www.cppblog.com/images/cppblog_com/winmain/screenshot_1.png" border="0"><br> <img src ="http://www.cppblog.com/winmain/aggbug/104407.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/winmain/" target="_blank">Code Knight</a> 2009-12-29 21:54 <a href="http://www.cppblog.com/winmain/archive/2009/12/29/104407.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>shader小综</title><link>http://www.cppblog.com/winmain/archive/2009/12/27/104232.html</link><dc:creator>Code Knight</dc:creator><author>Code Knight</author><pubDate>Sun, 27 Dec 2009 14:17:00 GMT</pubDate><guid>http://www.cppblog.com/winmain/archive/2009/12/27/104232.html</guid><wfw:comment>http://www.cppblog.com/winmain/comments/104232.html</wfw:comment><comments>http://www.cppblog.com/winmain/archive/2009/12/27/104232.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/winmain/comments/commentRss/104232.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/winmain/services/trackbacks/104232.html</trackback:ping><description><![CDATA[注明：摘自七星重剑的BLOG<br><strong>纹理（Texture）&amp;取样器（Sampler）</strong> <br><br>这
俩东西可以看作特殊类型变量。纹理就是Shader中用到的贴图资源，这我想没什么好说的。来解释一下取样器：实际上每张贴图在使用的时候都要用一个取样
器。取样器相当于这样一个结构，除了保存贴图本身数据之外，还包括过滤参数等取样信息。通常，读取贴图这样的指令接收的都是取样器类型的参数而并非直接接
收纹理贴图。声明及使用纹理或取样器跟使用普通变量一样。这里有一些初始化取样器的方法，还是等到后面的实例中讲述吧。<br><br><strong> Semantic &amp; Annotation<br></strong> <br>任
何类型的变量（包括纹理和取样器），我们都可以用Semantic或Annotation修饰来起到一些特殊作用。Semantic暂时翻译成语义；
Annotation暂时翻译成注解，这是HLSL中独特的东西。下面这两行中，第一个变量冒号后面的POSITION就是Semantic，第二个变量
后面用一对尖括号&lt;&gt;圈起来的表达式就是Annotation，一组&lt;&gt;中可以有很多个表达式。<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: #eeeeee;"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top">float3&nbsp;OmniPos&nbsp;:&nbsp;POSITION;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top">texture&nbsp;TexMap&nbsp;&lt;&nbsp;string&nbsp;name&nbsp;=&nbsp;"test.dds";&nbsp;&gt;;</div>
<br>一般来讲，<u>Semantic</u>是告诉应用程序或D3D这个被修饰的变量是做什么用的，<u>Annotation</u>是告诉程序这个变量怎么用。
很云山雾罩是吗，是这样，在应用程序代码中，是可以调用D3D的API认出Semantic和Annotation的。例如上面这两行，程序的逻辑就可能
是这样：首先写主程序的甲和写Shader的乙约定好POSITION标识该变量代表灯泡A的位置，甲在程序里写：{灯泡A.位置 = XXX;
找到Shader中带POSITION的变量; 给该变量赋值为灯泡A.位置; return;}
那么甲可以不知道乙在Shader中给这个要用灯泡A位置的变量起了什么名，而且乙可以在好几个Shader中给用这个数据的变量起不同的名。然后，甲和
乙再约定遇到Annotation中的&#8220;name&#8221;就将后面的字符串作为文件名建立贴图。于是甲的程序就从Shader中读出了一个文件名，建立了一个贴
图以供这个texture变量使用。Semantic和Annotation大概就这么用，首先要约定好各个Semantic和Annotation都是
什么意思，这是up to you的，然后就是通过它们的标识来给变量赋值或作其他辅助性工作了。<br><br>既然都是做辅助说明的为什么还要分成Semantic和Annotation，我的想法是Semantic简单方便而Annotation能干的事更多。不说这个了，无关大局。要说的是，D3D也跟我们约定了一套Semantic，它们大体上都能顾名思义,控制流<br><br>控
制流，就是if&#8230;else，for，while什么的。在CPU中，这些控制流造成的实际上是指令跳转。但在GPU中指令跳转并不被广泛的支持，以往的大
部分显卡只懂得按顺序一句一句执行指令。因此HLSL的编译器可能会做出诸如展开循环、遍历分支等等莽撞的事来适应显卡。所以使用时要特别小心，而且不是
所有情况的控制流语句都被支持。<br><br><strong> 函数</strong> <br><br>HLSL
中提供了很多函数可供调用，在Direct3D 文档 -&gt; DirectX Graphics -&gt; Reference -&gt;
HLSL Shader Reference -&gt; HLSL Intrinsic
Functions中有这些函数的详细列表。也可自己写函数用，但是在较早的Shader版本中，就像内联函数一样编译时最终要将函数展开插入到函数调用
处。还有一点我想你一定会想到的就是主函数会是什么。Vertex Shader和Pixel
Shader各自需要一个主函数，由程序员来指定！没错，程序员在Shader外部指定。
<br> <img src ="http://www.cppblog.com/winmain/aggbug/104232.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/winmain/" target="_blank">Code Knight</a> 2009-12-27 22:17 <a href="http://www.cppblog.com/winmain/archive/2009/12/27/104232.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>复习下最基本的数学知识</title><link>http://www.cppblog.com/winmain/archive/2009/12/08/102819.html</link><dc:creator>Code Knight</dc:creator><author>Code Knight</author><pubDate>Tue, 08 Dec 2009 14:28:00 GMT</pubDate><guid>http://www.cppblog.com/winmain/archive/2009/12/08/102819.html</guid><wfw:comment>http://www.cppblog.com/winmain/comments/102819.html</wfw:comment><comments>http://www.cppblog.com/winmain/archive/2009/12/08/102819.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/winmain/comments/commentRss/102819.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/winmain/services/trackbacks/102819.html</trackback:ping><description><![CDATA[<img alt="" src="http://www.cppblog.com/images/cppblog_com/winmain/dot.jpg"><br>
<img src ="http://www.cppblog.com/winmain/aggbug/102819.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/winmain/" target="_blank">Code Knight</a> 2009-12-08 22:28 <a href="http://www.cppblog.com/winmain/archive/2009/12/08/102819.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>昏头！被Intersect折腾了半天！</title><link>http://www.cppblog.com/winmain/archive/2009/02/11/73482.html</link><dc:creator>Code Knight</dc:creator><author>Code Knight</author><pubDate>Wed, 11 Feb 2009 09:41:00 GMT</pubDate><guid>http://www.cppblog.com/winmain/archive/2009/02/11/73482.html</guid><wfw:comment>http://www.cppblog.com/winmain/comments/73482.html</wfw:comment><comments>http://www.cppblog.com/winmain/archive/2009/02/11/73482.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/winmain/comments/commentRss/73482.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/winmain/services/trackbacks/73482.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; D3D中的PICK例程中有这样的一个检测函数，检测拾取，具体原理网上有很多，自己改了一下，却掉了两个重要的东西，不过还不是很明白是怎么一回事！修改我射线起始点的坐标有何用呢？<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080;">&nbsp;&nbsp;1</span>&nbsp;<span style="color: #000000;">BOOL&nbsp;IntersectTest(LPDIRECT3DVERTEXBUFFER9&nbsp;pVB,<br></span><span style="color: #008080;">&nbsp;&nbsp;2</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LPDIRECT3DINDEXBUFFER9&nbsp;pIB,<br></span><span style="color: #008080;">&nbsp;&nbsp;3</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;nStride,<br></span><span style="color: #008080;">&nbsp;&nbsp;4</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;dwNumFaces,<br></span><span style="color: #008080;">&nbsp;&nbsp;5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;D3DXVECTOR3</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;vPickRayOrig,<br></span><span style="color: #008080;">&nbsp;&nbsp;6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;D3DXVECTOR3</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;vPickRay,<br></span><span style="color: #008080;">&nbsp;&nbsp;7</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;D3DXVECTOR3&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">pVRet,<br></span><span style="color: #008080;">&nbsp;&nbsp;8</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;dwFlag</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">)&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;主要检测与地形相交&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;此函数相当耗费CPU</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;生成地形有13W个面，逐一检查是否相交</span><span style="color: #008000;"><br></span><span style="color: #008080;">&nbsp;&nbsp;9</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;">{<br></span><span style="color: #008080;">&nbsp;10</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;WORD</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pIndices;<br></span><span style="color: #008080;">&nbsp;11</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;BYTE</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pVertices;<br></span><span style="color: #008080;">&nbsp;12</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;D3DINDEXBUFFER_DESC&nbsp;IB_Desc;<br></span><span style="color: #008080;">&nbsp;13</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;14</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;FLOAT&nbsp;fBary1,&nbsp;fBary2,fDist</span><span style="color: #000000;">=</span><span style="color: #000000;">1e+32f</span><span style="color: #000000;">;<br></span><span style="color: #008080;">&nbsp;15</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;16</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;FLOAT&nbsp;t_fBary1,&nbsp;t_fBary2,t_fDist;<br></span><span style="color: #008080;">&nbsp;17</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;dwFace</span><span style="color: #000000;">=-</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br></span><span style="color: #008080;">&nbsp;18</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;dwUpperLower;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">&nbsp;19</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;20</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;D3DXVECTOR3</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pV[</span><span style="color: #000000;">3</span><span style="color: #000000;">];<br></span><span style="color: #008080;">&nbsp;21</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;ULONG&nbsp;&nbsp;n;<br></span><span style="color: #008080;">&nbsp;22</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;23</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;pIB</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">GetDesc(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">IB_Desc);&nbsp;<br></span><span style="color: #008080;">&nbsp;24</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;pIB</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">Lock(&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;(</span><span style="color: #0000ff;">void</span><span style="color: #000000;">**</span><span style="color: #000000;">)</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">pIndices,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;);<br></span><span style="color: #008080;">&nbsp;25</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;pVB</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">Lock(&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;(</span><span style="color: #0000ff;">void</span><span style="color: #000000;">**</span><span style="color: #000000;">)</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">pVertices,</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;);<br></span><span style="color: #008080;">&nbsp;26</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;27</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;28</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">(&nbsp;DWORD&nbsp;i</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">dwNumFaces;&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">&nbsp;)<br></span><span style="color: #008080;">&nbsp;29</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">&nbsp;30</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;j</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;j</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">3</span><span style="color: #000000;">;j</span><span style="color: #000000;">++</span><span style="color: #000000;">)<br></span><span style="color: #008080;">&nbsp;31</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">&nbsp;32</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(IB_Desc.Format</span><span style="color: #000000;">==</span><span style="color: #000000;">D3DFMT_INDEX16)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">&nbsp;33</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n</span><span style="color: #000000;">=</span><span style="color: #000000;">(WORD)pIndices[</span><span style="color: #000000;">3</span><span style="color: #000000;">*</span><span style="color: #000000;">i</span><span style="color: #000000;">+</span><span style="color: #000000;">j];<br></span><span style="color: #008080;">&nbsp;34</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(IB_Desc.Format</span><span style="color: #000000;">==</span><span style="color: #000000;">D3DFMT_INDEX32)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">&nbsp;35</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n</span><span style="color: #000000;">=*</span><span style="color: #000000;">(DWORD</span><span style="color: #000000;">*</span><span style="color: #000000;">)</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">pIndices[</span><span style="color: #000000;">2</span><span style="color: #000000;">*</span><span style="color: #000000;">(</span><span style="color: #000000;">3</span><span style="color: #000000;">*</span><span style="color: #000000;">i</span><span style="color: #000000;">+</span><span style="color: #000000;">j)];<br></span><span style="color: #008080;">&nbsp;36</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;<br></span><span style="color: #008080;">&nbsp;37</span>&nbsp;<span style="color: #000000;">&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;FALSE;<br></span><span style="color: #008080;">&nbsp;38</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pV[j]</span><span style="color: #000000;">=</span><span style="color: #000000;">(D3DXVECTOR3</span><span style="color: #000000;">*</span><span style="color: #000000;">)(pVertices</span><span style="color: #000000;">+</span><span style="color: #000000;">nStride</span><span style="color: #000000;">*</span><span style="color: #000000;">n);&nbsp;<br></span><span style="color: #008080;">&nbsp;39</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">&nbsp;40</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;41</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dwUpperLower</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br></span><span style="color: #008080;">&nbsp;42</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;43</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(dwFlag)&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;这段是必须要的，具体是怎么做到的？</span><span style="color: #008000;"><br></span><span style="color: #008080;">&nbsp;44</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">&nbsp;45</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(dwFlag&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;INTERSECT_NEGATIVEY)&nbsp;<br></span><span style="color: #008080;">&nbsp;46</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">&nbsp;47</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;j</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;j</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">3</span><span style="color: #000000;">;j</span><span style="color: #000000;">++</span><span style="color: #000000;">)<br></span><span style="color: #008080;">&nbsp;48</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">&nbsp;49</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dwUpperLower</span><span style="color: #000000;">|=</span><span style="color: #000000;">vPickRayOrig</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">x</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">pV[j]</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">x</span><span style="color: #000000;">?</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0x0010</span><span style="color: #000000;">:</span><span style="color: #000000;">0x0001</span><span style="color: #000000;">;&nbsp;<br></span><span style="color: #008080;">&nbsp;50</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dwUpperLower</span><span style="color: #000000;">|=</span><span style="color: #000000;">vPickRayOrig</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">z</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">pV[j]</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">z</span><span style="color: #000000;">?</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0x1000</span><span style="color: #000000;">:</span><span style="color: #000000;">0x0100</span><span style="color: #000000;">;&nbsp;<br></span><span style="color: #008080;">&nbsp;51</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;52</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">&nbsp;53</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(dwUpperLower</span><span style="color: #000000;">!=</span><span style="color: #000000;">0x1111</span><span style="color: #000000;">)&nbsp;</span><span style="color: #0000ff;">continue</span><span style="color: #000000;">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">&nbsp;54</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">&nbsp;55</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(dwFlag&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;INTERSECT_HORIZENTAL)&nbsp;<br></span><span style="color: #008080;">&nbsp;56</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">&nbsp;57</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;j</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;j</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">3</span><span style="color: #000000;">;j</span><span style="color: #000000;">++</span><span style="color: #000000;">)<br></span><span style="color: #008080;">&nbsp;58</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">&nbsp;59</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dwUpperLower</span><span style="color: #000000;">|=</span><span style="color: #000000;">(vPickRayOrig</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">y&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;pV[j]</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">y)</span><span style="color: #000000;">?</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0x0010</span><span style="color: #000000;">:</span><span style="color: #000000;">0x0001</span><span style="color: #000000;">;<br></span><span style="color: #008080;">&nbsp;60</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">&nbsp;61</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;62</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(dwUpperLower</span><span style="color: #000000;">!=</span><span style="color: #000000;">0x0011</span><span style="color: #000000;">)&nbsp;</span><span style="color: #0000ff;">continue</span><span style="color: #000000;">;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">&nbsp;63</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">&nbsp;64</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;65</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;66</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">&nbsp;67</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;68</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;69</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;70</span>&nbsp;<span style="color: #000000;">&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></span><span style="color: #008080;">&nbsp;71</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(&nbsp;IntersectTriangle(&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">vPickRayOrig,&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">vPickRay,&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">pV[</span><span style="color: #000000;">0</span><span style="color: #000000;">],&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">pV[</span><span style="color: #000000;">1</span><span style="color: #000000;">],&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">pV[</span><span style="color: #000000;">2</span><span style="color: #000000;">],<br></span><span style="color: #008080;">&nbsp;72</span>&nbsp;<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;">t_fDist,&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">t_fBary1,&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">t_fBary2&nbsp;)&nbsp;)<br></span><span style="color: #008080;">&nbsp;73</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">&nbsp;74</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(&nbsp;&nbsp;&nbsp;&nbsp;t_fDist&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;fDist&nbsp;)&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">是否返回最近的一个点</span><span style="color: #008000;"><br></span><span style="color: #008080;">&nbsp;75</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">&nbsp;76</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dwFace&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;i;<br></span><span style="color: #008080;">&nbsp;77</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fBary1&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;t_fBary1;<br></span><span style="color: #008080;">&nbsp;78</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fBary2&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;t_fBary2;<br></span><span style="color: #008080;">&nbsp;79</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fDist&nbsp;&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;t_fDist;<br></span><span style="color: #008080;">&nbsp;80</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">&nbsp;81</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">&nbsp;82</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">&nbsp;83</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">&nbsp;84</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;85</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(dwFace</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">dwNumFaces&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;dwFace</span><span style="color: #000000;">&gt;=</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;)<br></span><span style="color: #008080;">&nbsp;86</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">&nbsp;87</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;88</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;j</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;j</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">3</span><span style="color: #000000;">;j</span><span style="color: #000000;">++</span><span style="color: #000000;">)<br></span><span style="color: #008080;">&nbsp;89</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">&nbsp;90</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(IB_Desc.Format</span><span style="color: #000000;">==</span><span style="color: #000000;">D3DFMT_INDEX16)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">&nbsp;91</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n</span><span style="color: #000000;">=</span><span style="color: #000000;">(WORD)pIndices[</span><span style="color: #000000;">3</span><span style="color: #000000;">*</span><span style="color: #000000;">dwFace&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">j];<br></span><span style="color: #008080;">&nbsp;92</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(IB_Desc.Format</span><span style="color: #000000;">==</span><span style="color: #000000;">D3DFMT_INDEX32)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="color: #008080;">&nbsp;93</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n</span><span style="color: #000000;">=*</span><span style="color: #000000;">(DWORD</span><span style="color: #000000;">*</span><span style="color: #000000;">)</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">pIndices[</span><span style="color: #000000;">2</span><span style="color: #000000;">*</span><span style="color: #000000;">(</span><span style="color: #000000;">3</span><span style="color: #000000;">*</span><span style="color: #000000;">dwFace</span><span style="color: #000000;">+</span><span style="color: #000000;">j)];<br></span><span style="color: #008080;">&nbsp;94</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;<br></span><span style="color: #008080;">&nbsp;95</span>&nbsp;<span style="color: #000000;">&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;FALSE;<br></span><span style="color: #008080;">&nbsp;96</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pV[j]</span><span style="color: #000000;">=</span><span style="color: #000000;">(D3DXVECTOR3</span><span style="color: #000000;">*</span><span style="color: #000000;">)(pVertices</span><span style="color: #000000;">+</span><span style="color: #000000;">nStride</span><span style="color: #000000;">*</span><span style="color: #000000;">n);<br></span><span style="color: #008080;">&nbsp;97</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">&nbsp;98</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">pVRet</span><span style="color: #000000;">=*</span><span style="color: #000000;">pV[</span><span style="color: #000000;">0</span><span style="color: #000000;">]&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">fBary1</span><span style="color: #000000;">*</span><span style="color: #000000;">(</span><span style="color: #000000;">*</span><span style="color: #000000;">pV[</span><span style="color: #000000;">1</span><span style="color: #000000;">]</span><span style="color: #000000;">-*</span><span style="color: #000000;">pV[</span><span style="color: #000000;">0</span><span style="color: #000000;">])</span><span style="color: #000000;">+</span><span style="color: #000000;">fBary2</span><span style="color: #000000;">*</span><span style="color: #000000;">(</span><span style="color: #000000;">*</span><span style="color: #000000;">pV[</span><span style="color: #000000;">2</span><span style="color: #000000;">]</span><span style="color: #000000;">-*</span><span style="color: #000000;">pV[</span><span style="color: #000000;">0</span><span style="color: #000000;">]);&nbsp;&nbsp;<br></span><span style="color: #008080;">&nbsp;99</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">100</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">101</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pVB</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">Unlock();<br></span><span style="color: #008080;">102</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pIB</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">Unlock();<br></span><span style="color: #008080;">103</span>&nbsp;<span style="color: #000000;">&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;">1</span><span style="color: #000000;">;<br></span><span style="color: #008080;">104</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">105</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">106</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">107</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;pVB</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">Unlock();<br></span><span style="color: #008080;">108</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;pIB</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">Unlock();<br></span><span style="color: #008080;">109</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">110</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">111</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">112</span>&nbsp;<span style="color: #000000;">&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></span><span style="color: #008080;">113</span>&nbsp;<span style="color: #000000;">}</span></div>
另一个问题，大规模的地形一般如何最大程度的优化避免对所有的面进行检测？用LOD么？<br><br><img src ="http://www.cppblog.com/winmain/aggbug/73482.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/winmain/" target="_blank">Code Knight</a> 2009-02-11 17:41 <a href="http://www.cppblog.com/winmain/archive/2009/02/11/73482.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>