﻿<?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-随笔分类-OGRE</title><link>http://www.cppblog.com/winmain/category/12309.html</link><description>Programming is so cool</description><language>zh-cn</language><lastBuildDate>Thu, 25 Feb 2010 20:40:38 GMT</lastBuildDate><pubDate>Thu, 25 Feb 2010 20:40:38 GMT</pubDate><ttl>60</ttl><item><title>[转]OGRE新插件PagedGeometry(海量场景分页调度)</title><link>http://www.cppblog.com/winmain/archive/2010/02/24/108371.html</link><dc:creator>Code Knight</dc:creator><author>Code Knight</author><pubDate>Wed, 24 Feb 2010 13:31:00 GMT</pubDate><guid>http://www.cppblog.com/winmain/archive/2010/02/24/108371.html</guid><wfw:comment>http://www.cppblog.com/winmain/comments/108371.html</wfw:comment><comments>http://www.cppblog.com/winmain/archive/2010/02/24/108371.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/winmain/comments/commentRss/108371.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/winmain/services/trackbacks/108371.html</trackback:ping><description><![CDATA[<div class=postcontent>
<div><font size=3><strong><span>1,</span></strong><strong><span>介绍：</span></strong></font></div>
<div><span><strong><font size=3>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></strong>
<p><font size=3><font face="Times New Roman">&nbsp;<span>PagedGeometry</span></font><span>是</span><span><font face="Times New Roman">OGRE</font></span><span>引擎的一个插件，它对（无穷）大区域的海量网格的渲染提供优化策略。它非常适合于稠密的森林和室外场景，那里有海量的树，草，岩石，灌木丛等场景对象。</span></font></p>
<p><span><span><font size=3>&nbsp;</font> </span></span></p>
<p><font size=3><strong><span>2,</span><span> </span></strong><strong><span>PagedGeometry</span></strong><strong><span>管理</span></strong><strong></strong></font></p>
<p><span><font size=3>PagedGeometry class</font></span></p>
<p>&nbsp;</p>
<p><span><font size=3></font></span></p>
<font size=3><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>该类负责加载那些需要立即（或很快）可见的场景几何，而不加载其他的场景以节约内存空间。</span><span>PagedGeometry</span><span>引擎可以通过诸如静态几何，</span><span>imposters</span><span>等方法去显示实体对象（</span><span>Entities</span><span>）。这些方法是与实体和场景相机的距离，以及你的配置相关的。</span></font>
<p><font size=3><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>对页面的加载是通过用户定义的</span><span>PageLoader</span><span>来完成的。这样，用户可以编程实现加载页面，无论它是来自硬盘上的文件，程序产生的或是其他地方。</span></font></p>
<p><span><font size=3>&nbsp;</font></span></p>
<p><span><font size=3><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>GeometryPageManager</font></span></p>
<p><font size=3><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>在</span><span>PagedGeometry</span><span>类中使用，用于管理分页页面，在需要的时候做</span><span>cacheing, deleting</span><span>等工作。它通过分析摄像机距离去计算页面</span><span>cathe</span><span>的速度，并</span><span>delete</span><span>那些已经经过了设定时间的不可见页面。</span></font></p>
<p><font size=3><span>调用</span><span>PagedGeometry::addDetailLevel(), </span><span>创建</span><span> GeometryPageManager </span><span>。</span></font></p>
<p><span><font size=3>addDetailLevel() returns a pointer to this page manager, allowing you access to some useful functions, documented below.</font></span></p>
<p><font size=3><span>类成员函数中有些注释了</span><span>DO NOT USE</span><span>的，不能被用户使用，它们是在</span><span>PagedGeometry</span><span>中被使用的。</span></font></p>
<p><span><font size=3>addDetailLevel()</font></span></p>
<p><span><font size=3>Adds a detail level to the PagedGeometry object.</font></span></p>
<p><font size=3><span>PageType&nbsp;</span><span>对该</span><span>detail level</span><span>，用户想使用的页面类型。它不是一个函数参数，而是一个模板参数。</span></font></p>
<p><font size=3><span>&nbsp;maxRange&nbsp;</span><span>这个</span><span>detail level</span><span>使用的最大距离（摄像机的视距）</span></font></p>
<p><font size=3><span>transitionLength&nbsp;</span><span>期望的衰减转变长度</span><span> - </span><span>（可选）</span></font></p>
<p><span><font size=3>示例：</font></span></p>
<p><span><font size=3><span>&nbsp;&nbsp;&nbsp; </span>pagedTrees-&gt;addDetailLevel&lt;BatchPage&gt;(100); //Use batched geometry from 0-100</font></span></p>
<p><span><font size=3><span>&nbsp;&nbsp;&nbsp; </span>pagedTrees-&gt;addDetailLevel&lt;ImpostorPage&gt;(500); //Use impostors from 100-500</font></span></p>
<p><font size=3><span>名叫</span><span>pagedTrees</span><span>的</span><span>PagedGeometry </span><span>的对象会在</span><span>0</span><span>－</span><span>100</span><span>单位摄像机距离的范围内使用</span><span>batched</span><span>（分批几何，静态几何），</span><span>100</span><span>－</span><span>500</span><span>单位距离范围内使用</span><span>imposters</span></font></p>
<p><font size=3><span>如果已有的页面类型不合适，用户可以很轻松的添加自定义的</span><span>GeometryPage</span><span>子类</span></font></p>
<p><font size=3><span>transitionLength&nbsp;</span><span>参数在默认情况下是没有的，但是用户可以自己添加，它的作用是使细节层次转变更平滑。但是注意，使用参数可能会是渲染的效率下降</span><span>10</span><span>％－</span><span>30</span><span>％。</span></font></p>
<span>
<p><font size=3><strong><span><font face="Times New Roman"></font></span></strong></font></p>
<p><font size=3><strong><span><font face="Times New Roman">3,</font></span></strong><strong><span>页面类型</span></strong></font></p>
<span>
<p><span><font size=3 face="Times New Roman">Class GeometryPage</font></span></p>
<p><font size=3><span>如上所说，该类是一个虚基类，用户可以扩展继承该类去实现不同的替代被渲染实体的方式，如</span><span><font face="Times New Roman">batched</font></span><span>，</span><span><font face="Times New Roman">imposters</font></span><span>等。如果你需要其他的页面类型，你可以自己实现一些。</span></font></p>
<p><span><font size=3>以下是用户必须在子类中实现的虚函数：</font></span></p>
<p><span><font size=3 face="Times New Roman">virtual void init(SceneManager *mgr, Camera *cam) = 0;</font></span></p>
<p><span><font size=3 face="Times New Roman">virtual void setRegion(Real left, Real top, Real right, Real bottom) = 0;</font></span></p>
<p><span><font size=3 face="Times New Roman">virtual void addEntity(Entity *ent, const Vector3 &amp;position, const Quaternion &amp;rotation, const Vector3 &amp;scale, const Ogre::ColourValue &amp;color) = 0;</font></span></p>
<p><span><font size=3 face="Times New Roman">virtual void build() {}</font></span></p>
<p><span><font size=3 face="Times New Roman">virtual void removeEntities() = 0;</font></span></p>
<p><span><font size=3 face="Times New Roman">virtual void setVisible(bool visible) = 0;</font></span></p>
<p><span><font size=3 face="Times New Roman">virtual void setFade(bool enabled, Real visibleDist, Real invisibleDist) = 0;</font></span></p>
<p><span><font size=3 face="Times New Roman">virtual void update() {}</font></span></p>
<p><font size=3><span>以下是页面管理器（</span><span><font face="Times New Roman">page manager</font></span><span>）如何去使用上面的函数：</span></font></p>
<p><font size=3><span><font face="Times New Roman">1</font></span><span>，当</span><span><font face="Times New Roman">PagedGeometry</font></span><span>首先</span><span><font face="Times New Roman">create</font></span><span>一个</span><span><font face="Times New Roman">GeometryPage</font></span><span>，马上调用它的</span><span><font face="Times New Roman">init</font></span><span>（），该函数就好像构造函数一样。</span></font></p>
<p><font size=3><span><font face="Times New Roman">2</font></span><span>，准备一个几何页面给待渲染实体，设置页面区域。</span></font></p>
<p><font size=3><span><font face="Times New Roman">3</font></span><span>，添加实体对象到该页面，并初始化位置，方向等。</span></font></p>
<p><font size=3><span><font face="Times New Roman">4</font></span><span>，添加实体到场景中的最后一步。在添加完所有实体对象后自动调用。</span></font></p>
<p><font size=3><span><font face="Times New Roman">5</font></span><span>，从页面完全删除实体对象。</span></font></p>
<p><font size=3><span><font face="Times New Roman">6</font></span><span>，使整个页面变为可见。</span></font></p>
<p><font size=3><span><font face="Times New Roman">7</font></span><span>，设置页面的消减属性。</span></font></p>
<p><font size=3><span><font face="Times New Roman">8</font></span><span>，在帧循环中保证页面几何的更新。</span></font></p>
<p><span><font face="Times New Roman"><font size=3>class BatchPage</font></font></span></p>
<p><font size=3><span><font face="Times New Roman">The BatchPage class</font></span><span>把实体当作静态几何体来渲染。</span></font></p>
<p>&nbsp;</p>
<p><span><font size=3 face="Times New Roman"></font></span></p>
<font size=3><span>静态几何体（</span><span><font face="Times New Roman">StaticGeometry</font></span><span>）：在场景中有许多实体是从它们加入场景开始就不会移动的，如房屋，树等，</span><span><font face="Times New Roman">Ogre</font></span><span>为这种情况提供了</span><span><font face="Times New Roman">StaticGeometry</font></span><span>类</span><span><font face="Times New Roman">,</font></span><span>它允许你<strong>批渲染</strong>很多物体</span><span><font face="Times New Roman">.</font></span><span>这个通常要比手动在</span><span><font face="Times New Roman">SceneNodes</font></span><span>添加要快多了。</span></font>
<p><span><font size=3 face="Times New Roman">&nbsp;</font></span></p>
<p><span><font face="Times New Roman"><font size=3>class ImposterPage</font></font></span></p>
<p><font size=3><span><font face="Times New Roman">the ImpostorPage class.</font></span><span>把实体当作</span><span><font face="Times New Roman">impostors</font></span><span>（一种布告版图像，看起来像真实的实体）来渲染</span></font></p>
<p><font size=3><span>所有</span><span><font face="Times New Roman">page</font></span><span>类型中，这个是最快的，它使用</span><span><font face="Times New Roman">Impostors</font></span><span>去代替要渲染的</span><span><font face="Times New Roman">entities</font></span><span>，这样，显卡只要去渲染一系列的</span><span><font face="Times New Roman">2d image</font></span><span>，而不是</span><span><font face="Times New Roman">3d mesh</font></span></font></p>
<p>&nbsp;</p>
<p><span><font size=3 face="Times New Roman"></font></span></p>
<span><font size=3 face="Times New Roman">&nbsp;</font></span>
<p><span><font face="Times New Roman"><font size=3>class GrassPage</font></font></span></p>
<p><span><font face="Times New Roman"><font size=3>A custom page type designed specifically for use with GrassLoader.</font></font></span></p>
<p><font size=3><span><font face="Times New Roman">GrassPage</font></span><span>页面类型是被设计来配合</span><span><font face="Times New Roman">GrassLoader</font></span><span>使用的</span></font></p>
<p><font size=3><span>这种类型是没有做过优化的，它只是对所给的</span><span><font face="Times New Roman">entity</font></span><span>进行克隆，然后绑定到一个新的场景节点之上。这意味着性能很差。</span></font></p>
<p><font size=3><strong><span><font face="Times New Roman"></font></span></strong></font></p>
<p><font size=3><strong><span><font face="Times New Roman">4</font></span></strong><strong><span>，</span></strong><strong><span><font face="Times New Roman">BatchedGeometry</font></span></strong><strong><span>－一种静态几何的版本</span></strong></font></p>
<span>
<p><span><font face="Times New Roman"><font size=3>class BatchedGeometry</font></font></span></p>
<p><font size=3><span>它是</span><span><font face="Times New Roman">Ogre::StaticGeometry</font></span><span>的一个轻量级版本。</span></font></p>
<p><font size=3><span><font face="Times New Roman">staticGeometry</font></span><span>是</span><span><font face="Times New Roman">ogre</font></span><span>提供给用户的批渲染的类，它可以一次性渲染那些在场景中保持&#8220;静态的&#8221;实体（</span><span><font face="Times New Roman">entities</font></span><span>），如，房屋，树等。</span></font></p>
<p><font size=3><span>它给用户提供多一些的对</span><span><font face="Times New Roman">batch</font></span><span>材质等的控制。</span></font></p>
<p><span><font face="Times New Roman"><font size=3>class SubBatch: public Ogre::Renderable</font></font></span></p>
<p><font size=3><span><font face="Times New Roman">subBatch</font></span><span>继承于</span><span><font face="Times New Roman">Renderable</font></span><span>，是</span><span><font face="Times New Roman">BatchedGeometry</font></span><span>的内部类，它的构造函数中传入</span><span><font face="Times New Roman">BatchedGeometry</font></span><span>指针和</span><span><font face="Times New Roman">submesh</font></span><span>的指针，该类包含在</span><span><font face="Times New Roman">BatchedGeometry</font></span><span>中。</span></font></p>
<p><font size=3><strong><span><font face="Times New Roman"></font></span></strong></font></p>
<p><font size=3><strong><span><font face="Times New Roman">5</font></span></strong><strong><span>，</span></strong><strong><span><font face="Times New Roman">Loading Entities</font></span></strong></font></p>
<p><span><font face="Times New Roman"><font size=3>class PageLoader</font></font></span></p>
<p><font size=3><span>虚基类。用户可以扩展它去提供负责加载页面（</span><span><font face="Times New Roman">Page</font></span><span>）的回调函数。</span></font></p>
<p><font size=3><span><font face="Times New Roman">PagedGeometry</font></span><span>预装了几种不同的</span><span><font face="Times New Roman">Loader</font></span><span>，继承于</span><span><font face="Times New Roman">PageLoader</font></span><span>，跟很多实体管理器不同的是，</span><span><font face="Times New Roman">PagedGeometry</font></span><span>不允许用户一次性向</span><span><font face="Times New Roman">object</font></span><span>添加所有的</span><span><font face="Times New Roman">entities</font></span><span>，由于它是用于大规模的游戏场景，所以它会对世界几何进行分页，然后调度，只加载需要绘制的页面。</span></font></p>
<p><font size=3><span>只要引擎需要确定世界几何的那一块区域需要被加载，就要调用</span><span><font face="Times New Roman">PageLoader</font></span><span>的成员</span><span><font face="Times New Roman">loadPage()</font></span><span>。在函数中的</span><span><font face="Times New Roman">PageInfo</font></span><span>结构体，提供了页面的包围体信息。在函数中，用户通过</span></font></p>
<p><font size=3><span><font face="Times New Roman">addEntity</font></span><span>（）来添加实体到该页面中，还可以定义实体的尺度，位置，旋转等属性。</span></font></p>
<p><font size=3><span>当用户创建了自己的</span><span><font face="Times New Roman">loader</font></span><span>对象后，必须将其</span><span><font face="Times New Roman">attatch</font></span><span>到</span><span><font face="Times New Roman">PagedGeometry</font></span><span>对象上去。如下：</span></font></p>
<p><span><font face="Times New Roman"><font size=3>pagedGeometry-&gt;setPageLoader(yourPageLoader);</font></font></span></p>
<p><span><font size=3 face="Times New Roman">&nbsp;</font></span></p>
<p><font size=3><font face="Times New Roman"><span>PageInfo:</span><span> </span></font><span>结构体。提供给</span><span><font face="Times New Roman">PageLoader</font></span><span>的有用的页面信息。基本的信息是定义被加载的区域，还有一些该区域的其他信息。</span></font></p>
<p><font size=3><span>结构体内包含了一个</span><span><font face="Times New Roman">TBound</font></span><span>（</span><span><font face="Times New Roman">typedef Ogre::TRect&lt;Ogre::Real&gt; TBounds</font></span><span>），所有在该页面内的实体都必须放置在这个矩形包围体之中。</span></font></p>
<p><font size=3></font></p>
<p><font size=3><span>具体的</span><span><font face="Times New Roman">loaders</font></span><span>：</span></font></p>
<p><font size=3><span>（</span><span><font face="Times New Roman">1</font></span><span>）</span><span><font face="Times New Roman">GrassLoader </font></span><span>继承于</span><span><font face="Times New Roman">PageLoader</font></span><span>，用于和</span><span><font face="Times New Roman">PagedGeometry</font></span><span>一起产生真实的草地场景。所谓真实的草地模拟，使用</span><span><font face="Times New Roman">GrassLoader</font></span><span>成员函数</span><span><font face="Times New Roman">addLayer</font></span><span>（）来添加草，使用</span><span><font face="Times New Roman">updateAnimation()</font></span><span>来驱动动画。</span></font></p>
<p><font size=3><span><span><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span><span>当用户创建了</span><span><font face="Times New Roman">Grassloader</font></span><span>对象后，必须将其</span><span><font face="Times New Roman">attatch</font></span><span>到</span><span><font face="Times New Roman">PagedGeometry</font></span><span>对象上去。如下：</span></font></p>
<p><span><font face="Times New Roman"><font size=3>pagedGeometry-&gt;setPageLoader(GrassLoader);</font></font></span></p>
<p><font size=3><span><span><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span><span>草地</span><span><font face="Times New Roman">loader</font></span><span>在使用几何页面类型的时候，被推荐为使用</span><span><font face="Times New Roman">GrassPage</font></span><span>，这样的渲染效率较高，而采用其他类型则效率很低。</span></font></p>
<p><font size=3><span><span><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span><span>同时提供了一个数据结构来完全控制</span><span><font face="Times New Roman">Grass</font></span><span>的属性</span><span><font face="Times New Roman"> class GrassLayer</font></span><span>，它是通过</span><span><font face="Times New Roman">addLayer</font></span><span>（）来添加的，该类提供了一系列的&#8220;</span><span><font face="Times New Roman">set</font></span><span>&#8221;方法，用于用户配置草地的材质，密度，大小等属性信息。</span></font></p>
<p><span><font size=3 face="Times New Roman">&nbsp;</font></span></p>
<p><font size=3><span>（</span><span><font face="Times New Roman">2</font></span><span>）</span><span><font face="Times New Roman">TreeLoader2D</font></span><span>继承于</span><span><font face="Times New Roman">PageLoader</font></span><span>，用于和</span><span><font face="Times New Roman">PagedGeometry</font></span><span>一起轻易的实现在地形上放置树木的功能。</span></font></p>
<p><font size=3><span><span><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span><span>使用方法和前述一致，使用时，</span><span><font face="Times New Roman">addTrees</font></span><span>（）方法向场景中添加树木。需要注意的是，</span><span><font face="Times New Roman">loader</font></span><span>加载树木时并不知道该地形的高度，而是假设高度为</span><span><font face="Times New Roman">0</font></span><span>，这就需要设定获得当前（即给定</span><span><font face="Times New Roman">x</font></span><span>，</span><span><font face="Times New Roman">z</font></span><span>值时）的地形高度。</span><span><font face="Times New Roman">Loader</font></span><span>提供了这些方法。</span></font></p>
<p><span><font size=3 face="Times New Roman">&nbsp;</font></span></p>
<p><font size=3><span>（</span><span><font face="Times New Roman">3</font></span><span>）</span><span><font face="Times New Roman">TreeLoader3D</font></span><span>同</span><span><font face="Times New Roman">2D</font></span><span>的情况差不多，只是效率大概低</span><span><font face="Times New Roman">40</font></span><span>％左右。</span><span><font face="Times New Roman">TreeLoader3D</font></span><span>将树在内存中打包的效率很高，大约</span><span><font face="Times New Roman">10Bytes</font></span><span>一棵树，相当于</span><span><font face="Times New Roman">100</font></span><span>万棵树只要</span><st1:chmetcnv unitname="m" sourcevalue="9.53" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on"><span><font face="Times New Roman">9.53m</font></span></st1:chmetcnv><span>内存空间。这就很适用于大规模森林的渲染。</span></font></p>
<p><font size=3><span><span><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span><span>引擎为</span><span><font face="Times New Roman">2D</font></span><span>，</span><span><font face="Times New Roman">3Dloader</font></span><span>提供了一些公用的工具类，如</span><span><font face="Times New Roman">class TreeRef</font></span><span>，以内联函数的性质为</span><span><font face="Times New Roman">loader</font></span><span>提供了位置，旋转，尺寸，方向等的&#8220;</span><span><font face="Times New Roman">get</font></span><span>&#8221;数学运算。而</span><span>TreeIterator2D</span><span>，<span>TreeIterator3D</span>则为<span>loader</span>提供了树指针的操作。</span></font></p>
</span></span></span></span></div>
</div>
<img src ="http://www.cppblog.com/winmain/aggbug/108371.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-24 21:31 <a href="http://www.cppblog.com/winmain/archive/2010/02/24/108371.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转] OGRE地形配置文件解析</title><link>http://www.cppblog.com/winmain/archive/2010/02/24/108369.html</link><dc:creator>Code Knight</dc:creator><author>Code Knight</author><pubDate>Wed, 24 Feb 2010 13:30:00 GMT</pubDate><guid>http://www.cppblog.com/winmain/archive/2010/02/24/108369.html</guid><wfw:comment>http://www.cppblog.com/winmain/comments/108369.html</wfw:comment><comments>http://www.cppblog.com/winmain/archive/2010/02/24/108369.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/winmain/comments/commentRss/108369.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/winmain/services/trackbacks/108369.html</trackback:ping><description><![CDATA[<p>OGRE通过配置文件生成地形，极大提高了地形生成的灵活性。下面对地形配置文件(terrain.cfg)各配置项的意义进行简要分析。</p>
<p>WorldTexture=terrain_texture.jpg&nbsp; <span style="COLOR: rgb(0,128,0)">//地形纹理<br></span>DetailTexture=terrain_detail.jpg&nbsp; <span style="COLOR: rgb(0,128,0)">//地形细节纹理(相机距离地面很近时采用细节纹理)<br></span>DetailTile=3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: rgb(0,128,0)"> //细节纹理在一个地形小块中的平铺数<br></span>PageSource=Heightmap&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: rgb(0,128,0)"> //高度图数据源<br></span>Heightmap.image=terrain.png&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: rgb(0,128,0)"> //高度图名称(灰度图文件名),符合2^n+1<br></span>PageSize=513&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: rgb(0,128,0)"> //高度图大小<br></span>TileSize=65&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: rgb(0,128,0)"> //地形小块大小<br></span>MaxPixelError=3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: rgb(0,128,0)"> //决定使用层次细节时充许误差<br></span>PageWorldX=1500&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: rgb(0,128,0)">//地形在世界中的范围x方向<br></span>PageWorldZ=1500&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: rgb(0,128,0)">&nbsp; //z方向<br></span>MaxHeight=100&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: rgb(0,128,0)">&nbsp; //世界中地形最大映射高度<br></span>MaxMipMapLevel=5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: rgb(0,128,0)">&nbsp; //层次细节上限<br></span>#VertexNormals=yes&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: rgb(0,128,0)">//在缓冲中计算顶点法线，计算机光照或GPU程序用到时打开<br></span>#VertexColors=yes　　　　　　　　 <span style="COLOR: rgb(0,128,0)">//在缓冲中设置顶点颜色，假如有GPU程序需要时打开</span><br>#UseTriStrips=yes&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: rgb(0,128,0)"> //对于现在的硬件，建议关掉<br></span>VertexProgramMorph=yes　　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: rgb(0,128,0)"> //使用顶点程序进行LOD融合处理<br></span>LODMorphStart=0.2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: rgb(0,128,0)"> //LOD融合开始点：高，低LOD之间距离之比</span></p>
<p>下列参数用于提供自己的着色程序时使用，这会提供自己定义的material，那么先前定义的<br>WorldTexture 与 DetailTexture的设置不再用到。</p>
<p>MorphLODFactorParamName=morphFactor　<br><span style="COLOR: rgb(0,128,0)">//假设VertexProgramMorph被设为yes,定制的material中包括一个高级顶点程序。它指定了一个顶点<br>//程序的参数名，这个参数用于融合LOD,参数值从0－1，0表示不调整，1表示完全调整到下一级LOD</span><br>MorphLODFactorParamIndex&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: rgb(0,128,0)"> //用于materail中包含低级顶点程序的情况，意义同上<br></span>CustomMaterialName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: rgb(0,128,0)"> //指定的materail名字</span></p>
<p>上述配置文件定义了基于高度图的地形。</p>
<p>这些参数定义可概括为两类：Ogre使用第一类从高度图产生地形<br>mesh与材质。</p>
<p>第二类是定制材质与GPU顶点程序，这可以代替ogre自动产生的着色程序。<br><span style="COLOR: rgb(255,20,147)">另外的说明：</span><br>TerrainScenceManager会把高度图分为多个page,每个page由几个tile组成.它们都定义了在产生的mesh中一组构成正方形的顶点集。<br>WorldTexture定义的纹理不必与目标地形一样大。<br>PageWorldX，PageWorldZ可以缩放世界中的地形。<br>MaxHeight 在Y方向缩放地形。<br>DetailTexture 只使用一个纹理，如使用多层纹理，应该使用自定义materail。<br><br><span style="COLOR: rgb(0,0,255)">从程序加载地形</span><br>setWorldGeometry()有重载形式，一种用于加载配置文件，另一种我们可在程序中使用，以<br>达到手工加载的功能。这里，SceneData被 typedef 为std:map,它存储了如我们在terrain.cfg<br>中看到那些值对。假设我们已经从某个二进制文件读入我们想要的内容到SceneData中。我们要做<br>的就是把读入的内容转换成setWorldGeometry()需要的类型。</p>
<img src ="http://www.cppblog.com/winmain/aggbug/108369.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-24 21:30 <a href="http://www.cppblog.com/winmain/archive/2010/02/24/108369.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]OGRE根据高度图创建Terrain地形流程分析</title><link>http://www.cppblog.com/winmain/archive/2010/02/24/108370.html</link><dc:creator>Code Knight</dc:creator><author>Code Knight</author><pubDate>Wed, 24 Feb 2010 13:30:00 GMT</pubDate><guid>http://www.cppblog.com/winmain/archive/2010/02/24/108370.html</guid><wfw:comment>http://www.cppblog.com/winmain/comments/108370.html</wfw:comment><comments>http://www.cppblog.com/winmain/archive/2010/02/24/108370.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/winmain/comments/commentRss/108370.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/winmain/services/trackbacks/108370.html</trackback:ping><description><![CDATA[<p><span style="FONT-SIZE: small">OGRE可以通过两个接口来生成地形，分别是void TerrainSceneManager::setWorldGeometry( const String&amp; filename )以及void TerrainSceneManager::setWorldGeometry(DataStreamPtr&amp; stream, const String&amp; typeName )，两者的根本区别就是一个是传递地形信息文件名一个是传递地形信息数据流，设计两个接口的目的是可以让用户使用自己的地形信息配置文件，而不必局限于 OGRE定义的地形信息配置文件格式。在分析流程之前，先说明一点，为了提高渲染性能以及地形查找性能，OGRE把整个地形分成若干个地形页，每个地形页又分成了多个地形小块，到最后会把地形页及地形小块tile挂接到场景节点上。以下是生成地形的主要流程：</span></p>
<p><span style="FONT-SIZE: small">一：清除地形分级索引缓冲及地形分页，根据地形信息数据流加载地形信息配置文件，</span></p>
<p><span style="FONT-SIZE: small">void TerrainSceneManager::loadConfig(DataStreamPtr&amp; stream)，其先将地形配置信息从数据流中逐一读出到map中，然后通过void TerrainSceneManager::selectPageSource(const String&amp; typeName,&nbsp; TerrainPageSourceOptionList&amp; optionList)设置地形数据源(目前只有高度图数据源)。在地形信息配置文件中可以配置多个地形数据源，然后根据一种数据源类型生成地形，参数 typeName就用来指定数据源类型，目前就是HeightMap，找到指定的数据源后，对指定的数据源进行初始化，</span></p>
<p><span style="FONT-SIZE: small">&nbsp;void HeightmapTerrainPageSource::initialise(TerrainSceneManager* tsm,&nbsp; ushort tileSize, ushort pageSize, bool asyncLoading,&nbsp;TerrainPageSourceOptionList&amp; optionList)。初始化的过程主要是调用void HeightmapTerrainPageSource::loadHeightmap(void)将高度图灰度图像数据加载到内存中，如果是Raw数据，就加载到mRawData中，否则加载到mImage中。整个加载过程其实完成了两大工作，首先加载地形配置信息，然后加载高度图数据。 <br></span></p>
<p><span style="FONT-SIZE: small">二：初始化分级索引缓冲，void TerrainSceneManager::initLevelIndexes()； <br></span></p>
<p><span style="FONT-SIZE: small">三：void OctreeSceneManager::resize( const AxisAlignedBox &amp;box ) <br></span></p>
<p><span style="FONT-SIZE: small">四：设置地形材质，void TerrainSceneManager::setupTerrainMaterial(void)； <br></span></p>
<p><span style="FONT-SIZE: small">五：设置地形分页， void TerrainSceneManager::setupTerrainPages(void)</span></p>
<p><span style="FONT-SIZE: small">首先创建一个名为Terrain的场景根节点的子节点</span></p>
<p><span style="FONT-SIZE: small">mTerrainRoot = getRootSceneNode() -&gt; createChildSceneNode( "Terrain" );</span></p>
<p><span style="FONT-SIZE: small">然后初始化TerrainPage2D mTerrainPages；</span></p>
<p><span style="FONT-SIZE: small">最后调用 void HeightmapTerrainPageSource::requestPage(ushort x, ushort y)requestPage只支持一个Page，首先将图像数据进行缩放</span></p>
<p><span style="FONT-SIZE: small">然后调用 &#8220;TerrainPageSource::firePageConstructed（）&#8221;通知Listener；然后调用&#8220;TerrainPage* TerrainPageSource::buildPage(Real*heightData, const MaterialPtr&amp; pMaterial)&#8221;创建一个新的TerrainPage对象。</span></p>
<p><span style="FONT-SIZE: small">buildPage()是一个比较核心的函数。它首先构造一个 TerrainPage对象，然后创建一个用于容纳该TerrainPage对象的场景节点：&#8220;page-&gt;pageSceneNode = mSceneManager-&gt;createSceneNode(name);&#8221;，然后根据对地形的分割，循环创建子SceneNode，并且创建子场景节点对应的可渲染体TerrainRenderable，将该可渲染体attach到这个子节点上。通过 &#8220;TerrainRenderable::initialise（）&#8221;来创建顶点数据、渲染方式等。 <br></span></p>
<p><span style="FONT-SIZE: small">然后调用void TerrainSceneManager::attachPage(ushort pageX, ushort pageZ, TerrainPage* page)加入到mTerrainPages中；</span></p>
<p><span style="FONT-SIZE: small">然后在attachPage中调用&#8220;mTerrainRoot-&gt;addChild(page-&gt;pageSceneNode);&#8221;加入到SceneGraph中。 <br></span></p>
<p><span style="FONT-SIZE: small">注：当前只支持一个Page，该分页被挂接到一个称谓Terrain的场景节点上，该场景节点下面又创建了很多子场景节点，每一个子场景节点对应一个tile，也就是一个独立的可渲染体TerrainRenderable</span></p>
<img src ="http://www.cppblog.com/winmain/aggbug/108370.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-24 21:30 <a href="http://www.cppblog.com/winmain/archive/2010/02/24/108370.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>地形显示了</title><link>http://www.cppblog.com/winmain/archive/2010/02/05/107307.html</link><dc:creator>Code Knight</dc:creator><author>Code Knight</author><pubDate>Fri, 05 Feb 2010 13:27:00 GMT</pubDate><guid>http://www.cppblog.com/winmain/archive/2010/02/05/107307.html</guid><wfw:comment>http://www.cppblog.com/winmain/comments/107307.html</wfw:comment><comments>http://www.cppblog.com/winmain/archive/2010/02/05/107307.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/winmain/comments/commentRss/107307.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/winmain/services/trackbacks/107307.html</trackback:ping><description><![CDATA[&nbsp; <img border=0 src="http://www.cppblog.com/images/cppblog_com/winmain/tlscene.jpg">
<img src ="http://www.cppblog.com/winmain/aggbug/107307.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-05 21:27 <a href="http://www.cppblog.com/winmain/archive/2010/02/05/107307.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>第一个场景</title><link>http://www.cppblog.com/winmain/archive/2010/01/15/105785.html</link><dc:creator>Code Knight</dc:creator><author>Code Knight</author><pubDate>Fri, 15 Jan 2010 15:51:00 GMT</pubDate><guid>http://www.cppblog.com/winmain/archive/2010/01/15/105785.html</guid><wfw:comment>http://www.cppblog.com/winmain/comments/105785.html</wfw:comment><comments>http://www.cppblog.com/winmain/archive/2010/01/15/105785.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/winmain/comments/commentRss/105785.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/winmain/services/trackbacks/105785.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 干，整了半个月总算出了天龙的第一个场景：少林。天下武功出少林...&nbsp;<br></p>
<p><img src="http://www.cppblog.com/images/cppblog_com/winmain/tianlong1.JPG" border=0><br></p>
<p><img src="http://www.cppblog.com/images/cppblog_com/winmain/tianlong2.JPG" border=0><br></p>
<p><br>纹理好像还有些问题....<br><br></p>
<img src ="http://www.cppblog.com/winmain/aggbug/105785.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-01-15 23:51 <a href="http://www.cppblog.com/winmain/archive/2010/01/15/105785.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OGRE贴花分类</title><link>http://www.cppblog.com/winmain/archive/2010/01/14/105618.html</link><dc:creator>Code Knight</dc:creator><author>Code Knight</author><pubDate>Wed, 13 Jan 2010 16:03:00 GMT</pubDate><guid>http://www.cppblog.com/winmain/archive/2010/01/14/105618.html</guid><wfw:comment>http://www.cppblog.com/winmain/comments/105618.html</wfw:comment><comments>http://www.cppblog.com/winmain/archive/2010/01/14/105618.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/winmain/comments/commentRss/105618.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/winmain/services/trackbacks/105618.html</trackback:ping><description><![CDATA[<p>法线贴花，根据所在位置的法线自动调整贴花朝向（不要求紧贴）</p>
<p>模型贴花，根据贴花所在的网格自动生成模型（一般贴图）</p>
<p>投影贴花，利用投影纹理的方式实现的贴花（frustum）</p>
<p>网格贴花，创建指定大小的网格贴花，然后自动调整网格的位置（mesh，贴图）</p>
<br><img src ="http://www.cppblog.com/winmain/aggbug/105618.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-01-14 00:03 <a href="http://www.cppblog.com/winmain/archive/2010/01/14/105618.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>OGRE小记</title><link>http://www.cppblog.com/winmain/archive/2009/12/28/104319.html</link><dc:creator>Code Knight</dc:creator><author>Code Knight</author><pubDate>Mon, 28 Dec 2009 15:15:00 GMT</pubDate><guid>http://www.cppblog.com/winmain/archive/2009/12/28/104319.html</guid><wfw:comment>http://www.cppblog.com/winmain/comments/104319.html</wfw:comment><comments>http://www.cppblog.com/winmain/archive/2009/12/28/104319.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/winmain/comments/commentRss/104319.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/winmain/services/trackbacks/104319.html</trackback:ping><description><![CDATA[1,entity是没有getPosition的<br>2,node的默认position是原点<br>3,材质脚本中定义的程序段中的source文件名后缀必须与定义的shader文件类型匹配。<br>如：<br>vertex_program Ogre/CelShadingVP1 <span style="color: red;">hlsl</span><br>{<br>&nbsp;&nbsp; &nbsp;source Example_CelShading1.<span style="color: red;">hlsl</span><br>&nbsp;&nbsp; &nbsp;entry_point main_vp<br>&nbsp;&nbsp; &nbsp;<span style="color: red;">target</span> vs_2_0<br>}
<br>注意target是hlsl中独占,cg中是profile,且参数不同<br>4，Plugin_CgProgramManager_d.dll 插件一定要有cg.dll配合<br>5，OGRE不支持的中文路径用下面解决：<br>setlocale(LC_ALL, "chinese-simplified");
<br>记得读取完资源要还原<br>6，&nbsp;&nbsp;&nbsp; Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups()一定要在rendersystem初始化完毕才能调用。也就是在root的createRenderWindow 之后<br>7，想要你的OIS中的mouse何keboard响应你得记得在frameStarted
中每次去capture;<br>记得在&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; <br>mKeyboard = static_cast&lt;OIS::Keyboard*&gt;(mInputManager-&gt;createInputObject(OIS::OISKeyboard, true));<br>mMouse = static_cast&lt;OIS::Mouse*&gt;(mInputManager-&gt;createInputObject(OIS::OISMouse, true));<br>之后<br>mMouse-&gt;setEventCallback(this);<br>mKeyboard-&gt;setEventCallback(this);
<br>
<br><br><br>
<br>      <img src ="http://www.cppblog.com/winmain/aggbug/104319.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-28 23:15 <a href="http://www.cppblog.com/winmain/archive/2009/12/28/104319.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OGRE学习之地形跟踪</title><link>http://www.cppblog.com/winmain/archive/2009/12/16/103349.html</link><dc:creator>Code Knight</dc:creator><author>Code Knight</author><pubDate>Wed, 16 Dec 2009 13:15:00 GMT</pubDate><guid>http://www.cppblog.com/winmain/archive/2009/12/16/103349.html</guid><wfw:comment>http://www.cppblog.com/winmain/comments/103349.html</wfw:comment><comments>http://www.cppblog.com/winmain/archive/2009/12/16/103349.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/winmain/comments/commentRss/103349.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/winmain/services/trackbacks/103349.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hey,guys,又上来贴代码啦。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 继续OGRE的学习。废话少说看代码。Code highlighting produced by Actipro CodeHighlighter...&nbsp;&nbsp;<a href='http://www.cppblog.com/winmain/archive/2009/12/16/103349.html'>阅读全文</a><img src ="http://www.cppblog.com/winmain/aggbug/103349.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-16 21:15 <a href="http://www.cppblog.com/winmain/archive/2009/12/16/103349.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OGRE之输入系统笔记</title><link>http://www.cppblog.com/winmain/archive/2009/12/06/102659.html</link><dc:creator>Code Knight</dc:creator><author>Code Knight</author><pubDate>Sun, 06 Dec 2009 11:44:00 GMT</pubDate><guid>http://www.cppblog.com/winmain/archive/2009/12/06/102659.html</guid><wfw:comment>http://www.cppblog.com/winmain/comments/102659.html</wfw:comment><comments>http://www.cppblog.com/winmain/archive/2009/12/06/102659.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/winmain/comments/commentRss/102659.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/winmain/services/trackbacks/102659.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 一个基本的例子：<br>&nbsp;&nbsp;&nbsp;&nbsp; <br>
<pre>#include "ExampleApplication.h"<br><br>class TutorialFrameListener&nbsp;: public ExampleFrameListener, public OIS::MouseListener, public OIS::KeyListener<br>{<br>public:<br>    TutorialFrameListener(RenderWindow* win, Camera* cam, SceneManager *sceneMgr)<br>       &nbsp;: ExampleFrameListener(win, cam, true, true)<br>    {<br>        // Populate the camera and scene manager containers<br>        mCamNode = cam-&gt;getParentSceneNode();<br>        mSceneMgr = sceneMgr;<br><br>        // set the rotation and move speed<br>        mRotate = 0.13;<br>        mMove = 250;<br><br>        // continue rendering<br>        mContinue = true;<br><br>        mMouse-&gt;setEventCallback(this);<br>        mKeyboard-&gt;setEventCallback(this);<br><br>        mDirection = Vector3::ZERO;<br>    }<br><br>    bool frameStarted(const FrameEvent &amp;evt)<br>    {<br>        if(mMouse)<br>            mMouse-&gt;capture();<br>        if(mKeyboard) <br>            mKeyboard-&gt;capture();<br><br>        mCamNode-&gt;translate(mDirection * evt.timeSinceLastFrame, Node::TS_LOCAL);<br>        return mContinue;<br>    }<br><br>    // MouseListener<br>    bool mouseMoved(const OIS::MouseEvent &amp;e)<br>    {<br>        if (e.state.buttonDown(OIS::MB_Right))<br>        {<br>            mCamNode-&gt;yaw(Degree(-mRotate * e.state.X.rel), Node::TS_WORLD);<br>            mCamNode-&gt;pitch(Degree(-mRotate * e.state.Y.rel), Node::TS_LOCAL);<br>        }<br>        return true;<br>    }<br><br>    bool mousePressed(const OIS::MouseEvent &amp;e, OIS::MouseButtonID id)<br>    {<br>        Light *light = mSceneMgr-&gt;getLight("Light1");<br>        switch (id)<br>        {<br>        case OIS::MB_Left:<br>            light-&gt;setVisible(! light-&gt;isVisible());<br>            break;<br>        }<br>        return true;<br>    }<br><br>    bool mouseReleased(const OIS::MouseEvent &amp;e, OIS::MouseButtonID id) { return true; }<br><br>    // KeyListener<br>    bool keyPressed(const OIS::KeyEvent &amp;e)<br>    {<br>        switch (e.key)<br>        {<br>        case OIS::KC_ESCAPE: <br>            mContinue = false;<br>            break;<br><br>        case OIS::KC_1:<br>            mCamera-&gt;getParentSceneNode()-&gt;detachObject(mCamera);<br>            mCamNode = mSceneMgr-&gt;getSceneNode("CamNode1");<br>            mCamNode-&gt;attachObject(mCamera);<br>            break;<br><br>        case OIS::KC_2:<br>            mCamera-&gt;getParentSceneNode()-&gt;detachObject(mCamera);<br>            mCamNode = mSceneMgr-&gt;getSceneNode("CamNode2");<br>            mCamNode-&gt;attachObject(mCamera);<br>            break;<br><br>        case OIS::KC_UP:<br>        case OIS::KC_W:<br>            mDirection.z -= mMove;<br>            break;<br><br>        case OIS::KC_DOWN:<br>        case OIS::KC_S:<br>            mDirection.z += mMove;<br>            break;<br><br>        case OIS::KC_LEFT:<br>        case OIS::KC_A:<br>            mDirection.x -= mMove;<br>            break;<br><br>        case OIS::KC_RIGHT:<br>        case OIS::KC_D:<br>            mDirection.x += mMove;<br>            break;<br><br>        case OIS::KC_PGDOWN:<br>        case OIS::KC_E:<br>            mDirection.y -= mMove;<br>            break;<br><br>        case OIS::KC_PGUP:<br>        case OIS::KC_Q:<br>            mDirection.y += mMove;<br>            break;<br>        }<br>        return true;<br>    }<br><br>    bool keyReleased(const OIS::KeyEvent &amp;e)<br>    {<br>        switch (e.key)<br>        {<br>        case OIS::KC_UP:<br>        case OIS::KC_W:<br>            mDirection.z += mMove;<br>            break;<br><br>        case OIS::KC_DOWN:<br>        case OIS::KC_S:<br>            mDirection.z -= mMove;<br>            break;<br><br>        case OIS::KC_LEFT:<br>        case OIS::KC_A:<br>            mDirection.x += mMove;<br>            break;<br><br>        case OIS::KC_RIGHT:<br>        case OIS::KC_D:<br>            mDirection.x -= mMove;<br>            break;<br><br>        case OIS::KC_PGDOWN:<br>        case OIS::KC_E:<br>            mDirection.y += mMove;<br>            break;<br><br>        case OIS::KC_PGUP:<br>        case OIS::KC_Q:<br>            mDirection.y -= mMove;<br>            break;<br>        } // switch<br>        return true;<br>    }<br>protected:<br>    Real mRotate;          // The rotate constant<br>    Real mMove;            // The movement constant<br><br>    SceneManager *mSceneMgr;   // The current SceneManager<br>    SceneNode *mCamNode;   // The SceneNode the camera is currently attached to<br><br>    bool mContinue;        // Whether to continue rendering or not<br>    Vector3 mDirection;     // Value to move in the correct direction<br>};<br><br>class TutorialApplication&nbsp;: public ExampleApplication<br>{<br>public:<br>    void createCamera(void)<br>    {<br>        // create camera, but leave at default position<br>        mCamera = mSceneMgr-&gt;createCamera("PlayerCam"); <br>        mCamera-&gt;setNearClipDistance(5);<br>    }<br><br>    void createScene(void)<br>    {<br>        mSceneMgr-&gt;setAmbientLight(ColourValue(0.25, 0.25, 0.25));<br><br>        // add the ninja<br>        Entity *ent = mSceneMgr-&gt;createEntity("Ninja", "ninja.mesh");<br>        SceneNode *node = mSceneMgr-&gt;getRootSceneNode()-&gt;createChildSceneNode("NinjaNode");<br>        node-&gt;attachObject(ent);<br><br>        // create the light<br>        Light *light = mSceneMgr-&gt;createLight("Light1");<br>        light-&gt;setType(Light::LT_POINT);<br>        light-&gt;setPosition(Vector3(250, 150, 250));<br>        light-&gt;setDiffuseColour(ColourValue::White);<br>        light-&gt;setSpecularColour(ColourValue::White);<br><br>        // Create the scene node<br>        node = mSceneMgr-&gt;getRootSceneNode()-&gt;createChildSceneNode("CamNode1", Vector3(-400, 200, 400));<br>        node-&gt;yaw(Degree(-45));<br>        node-&gt;attachObject(mCamera);<br><br>        // create the second camera node/pitch node<br>        node = mSceneMgr-&gt;getRootSceneNode()-&gt;createChildSceneNode("CamNode2", Vector3(0, 200, 400));<br>    }<br><br>    void createFrameListener(void)<br>    {<br>        // Create the FrameListener<br>        mFrameListener = new TutorialFrameListener(mWindow, mCamera, mSceneMgr);<br>        mRoot-&gt;addFrameListener(mFrameListener);<br><br>        // Show the frame stats overlay<br>        mFrameListener-&gt;showDebugOverlay(true);<br>    }<br>};<br><br>#if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32<br>#define WIN32_LEAN_AND_MEAN<br>#include "windows.h"<br><br>INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT)<br>#else<br>int main(int argc, char **argv)<br>#endif<br>{<br>    // Create application object<br>    TutorialApplication app;<br><br>    try {<br>        app.go();<br>    } catch(Exception&amp; e) {<br>#if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32<br>        MessageBox(NULL, e.getFullDescription().c_str(), "An exception has occurred!", MB_OK | MB_ICONERROR | MB_TASKMODAL);<br>#else<br>        fprintf(stderr, "An exception has occurred:&nbsp;%s\n",<br>            e.getFullDescription().c_str());<br>#endif<br>    }<br><br>    return 0;<br>}<br><br>按照理论来说<br><font size="3">unbuffered：不断的响应按键信息，直到按键放开。例如，按下上下左右，使得角色持续移动。 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一般来讲适合于3D场景漫游过程，当在每帧渲染之前，系统捕获输入设备状态，并根据这些状态对场景中的物体和摄象机进行控制。 <br>buffered：在一个按键放开之前，只处理一次输入信息。 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 例如呼出主菜单。适合于GUI界面的情况（如设置菜单），输入设备状态可以被发送到各GUI元素进行处理（如按钮被按下）。<br><br></font>这个例子试图说明缓冲输入和非缓冲输入的区别，但是让我困惑的是为什么采用了缓冲输入系统还能响应持续按键呢？编译后运行按住WSAD照样移动摄像机。</pre>
<br>  <img src ="http://www.cppblog.com/winmain/aggbug/102659.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-06 19:44 <a href="http://www.cppblog.com/winmain/archive/2009/12/06/102659.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>