主界面如上文设计完成后,场景刚开始添加了是Ogre例子里的,发现场景里实物太少,于是想到直接把天龙的场景拿下来,天龙网上有源码,参考了下,把天龙的地形用Ogre的地形组件完成了下,如下是效果图:  

  因为主要是加载地形,然后只是简单加载了静态模型,因此场景看着比较简陋,再者因为上传的图片限制,场景复杂后根本传不上来.

  天龙的地形还是比较简单的,如下是天龙的pingpan.terrain简化后的内容.

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Terrain name="_pingpan_1" tileSize="32" xsize="128" zsize="128">
<scale x="100" y="100" z="100"/>
<heightmap filename="_pingpan_1.Heightmap" type="standard"/>
<gridInfo filename="_pingpan_1.GridInfo" type="standard"/>
<lightmap filename="_pingpan_1.Lightmap" type="standard"/>
<textures>
<texture filename="08大理/大理方砖地.tga" type="image"/>
<texture filename="08大理/大理石台阶.tga" type="image"/>
<texture filename="08大理/台基座矮.tga" type="image"/>
<texture filename="08大理/台基座高.tga" type="image"/>
<texture filename="13镜湖/镜湖桃花瓣.tga" type="image"/>
<texture filename="江南/花2.tga" type="image"/>
<texture filename="江南/花3.tga" type="image"/>
<texture filename="江南/花4.tga" type="image"/>
<texture filename="西南/浅草地底层.jpg" type="image"/>
<texture filename="西南/浅草地上层.tga" type="image"/>
<texture filename="西南/山b01.jpg" type="image"/>
<texture filename="西南/山b02.jpg" type="image"/>
<texture filename="西南/山b03.jpg" type="image"/>
<texture filename="西南/深草地底层.jpg" type="image"/>
<texture filename="西南/深草地上层.tga" type="image"/>
<texture filename="西南/西南碎石地.tga" type="image"/>
<texture filename="西南/沼泽.jpg" type="image"/>
<texture filename="西南/砖地.tga" type="image"/>
</textures>
<pixmaps>
<pixmap bottom="0.2480469" left="0.00390625" right="0.4960938" textureId="0" top="0.001953125"/>
<pixmap bottom="0.4980469" left="0.00390625" right="0.4960938" textureId="0" top="0.2519531"/>
<pixmap bottom="0.7480469" left="0.00390625" right="0.4960938" textureId="0" top="0.5019531"/>
<pixmap bottom="0.9980469" left="0.00390625" right="0.4960938" textureId="0" top="0.7519531"/>
<pixmap bottom="0.748047" left="0.503906" right="0.996094" textureId="0" top="0.501953"/>
<pixmap bottom="0.2480469" left="0.5039063" right="0.9960938" textureId="0" top="0.001953125"/>
<pixmap bottom="0.4980469" left="0.5039063" right="0.9960938" textureId="0" top="0.2519531"/>
<pixmap bottom="0.7480469" left="0.5039063" right="0.9960938" textureId="0" top="0.5019531"/>
<pixmap bottom="0.9980469" left="0.5039063" right="0.9960938" textureId="0" top="0.7519531"/>
<pixmap bottom="0.4960938" left="0.00390625" right="0.4960938" textureId="1" top="0.00390625"/>
<pixmap bottom="0.9960938" left="0.00390625" right="0.4960938" textureId="1" top="0.5039063"/>
<pixmap bottom="0.4960938" left="0.5039063" right="0.9960938" textureId="1" top="0.00390625"/>
<pixmap bottom="0.9960938" left="0.5039063" right="0.9960938" textureId="1" top="0.5039063"/>
<pixmap bottom="0.9960938" left="0.00390625" right="0.4960938" textureId="2" top="0.00390625"/>
<pixmap bottom="0.996094" left="0.00390625" right="0.496094" textureId="2" top="0.00390625"/>
<pixmap bottom="0.996094" left="0.503906" right="0.996094" textureId="2" top="0.00390625"/>
<pixmap bottom="0.9960938" left="0.5039063" right="0.9960938" textureId="2" top="0.00390625"/>
<pixmap bottom="0.9980469" left="0.00390625" right="0.4960938" textureId="3" top="0.001953125"/>
<pixmap bottom="0.998047" left="0.00390625" right="0.496094" textureId="3" top="0.00195313"/>
<pixmap bottom="0.998047" left="0.503906" right="0.996094" textureId="3" top="0.00195313"/>
<pixmap bottom="0.9980469" left="0.5039063" right="0.9960938" textureId="3" top="0.001953125"/>
<pixmap bottom="0.2480469" left="0.00390625" right="0.4960938" textureId="4" top="0.001953125"/>
<pixmap bottom="0.4980469" left="0.00390625" right="0.4960938" textureId="4" top="0.2519531"/>
<pixmap bottom="0.7480469" left="0.00390625" right="0.4960938" textureId="4" top="0.5019531"/>
<pixmap bottom="0.9980469" left="0.00390625" right="0.4960938" textureId="4" top="0.7519531"/>
<pixmap bottom="0.2480469" left="0.5039063" right="0.9960938" textureId="4" top="0.001953125"/>
<pixmap bottom="0.4980469" left="0.5039063" right="0.9960938" textureId="4" top="0.2519531"/>
<pixmap bottom="0.7480469" left="0.5039063" right="0.9960938" textureId="4" top="0.5019531"/>
<pixmap bottom="0.9980469" left="0.5039063" right="0.9960938" textureId="4" top="0.7519531"/>
<pixmap bottom="0.4960938" left="0.00390625" right="0.4960938" textureId="5" top="0.00390625"/>
<pixmap bottom="0.9960938" left="0.00390625" right="0.4960938" textureId="5" top="0.5039063"/>
<pixmap bottom="0.4960938" left="0.5039063" right="0.9960938" textureId="5" top="0.00390625"/>
<pixmap bottom="0.9960938" left="0.5039063" right="0.9960938" textureId="5" top="0.5039063"/>
<pixmap bottom="0.2480469" left="0.00390625" right="0.4960938" textureId="6" top="0.001953125"/>
<pixmap bottom="0.7480469" left="0.00390625" right="0.4960938" textureId="6" top="0.5019531"/>
<pixmap bottom="0.9980469" left="0.00390625" right="0.4960938" textureId="6" top="0.7519531"/>
<pixmap bottom="0.2480469" left="0.00390625" right="0.4960938" textureId="7" top="0.001953125"/>
<pixmap bottom="0.4980469" left="0.00390625" right="0.4960938" textureId="7" top="0.2519531"/>
<pixmap bottom="0.7480469" left="0.00390625" right="0.4960938" textureId="7" top="0.5019531"/>
<pixmap bottom="0.2480469" left="0.5039063" right="0.9960938" textureId="7" top="0.001953125"/>
<pixmap bottom="0.4980469" left="0.5039063" right="0.9960938" textureId="7" top="0.2519531"/>
<pixmap bottom="0.7480469" left="0.5039063" right="0.9960938" textureId="7" top="0.5019531"/>
<pixmap bottom="0.9980469" left="0.5039063" right="0.9960938" textureId="7" top="0.7519531"/>
<pixmap bottom="0.2480469" left="0.2519531" right="0.4980469" textureId="8" top="0.001953125"/>
<pixmap bottom="0.2480469" left="0.001953125" right="0.2480469" textureId="9" top="0.001953125"/>
<pixmap bottom="0.9980469" left="0.4980469" right="0.2519531" textureId="9" top="0.7519531"/>
<pixmap bottom="0.4980469" left="0.7480469" right="0.5019531" textureId="9" top="0.2519531"/>
<pixmap bottom="0.250977" left="0.00195313" right="0.250977" textureId="10" top="0.00195313"/>
<pixmap bottom="0.5" left="0.00195313" right="0.250977" textureId="10" top="0.250977"/>
<pixmap bottom="0.749023" left="0.00195313" right="0.250977" textureId="10" top="0.5"/>
<pixmap bottom="0.998047" left="0.00195313" right="0.250977" textureId="10" top="0.749023"/>
<pixmap bottom="0.250977" left="0.250977" right="0.5" textureId="10" top="0.00195313"/>
<pixmap bottom="0.5" left="0.250977" right="0.5" textureId="10" top="0.250977"/>
<pixmap bottom="0.749023" left="0.250977" right="0.5" textureId="10" top="0.5"/>
<pixmap bottom="0.998047" left="0.250977" right="0.5" textureId="10" top="0.749023"/>
<pixmap bottom="0.250977" left="0.5" right="0.749023" textureId="10" top="0.00195313"/>
<pixmap bottom="0.5" left="0.5" right="0.749023" textureId="10" top="0.250977"/>
<pixmap bottom="0.749023" left="0.5" right="0.749023" textureId="10" top="0.5"/>
<pixmap bottom="0.998047" left="0.5" right="0.749023" textureId="10" top="0.749023"/>
<pixmap bottom="0.250977" left="0.749023" right="0.998047" textureId="10" top="0.00195313"/>
<pixmap bottom="0.5" left="0.749023" right="0.998047" textureId="10" top="0.250977"/>
<pixmap bottom="0.749023" left="0.749023" right="0.998047" textureId="10" top="0.5"/>
<pixmap bottom="0.998047" left="0.749023" right="0.998047" textureId="10" top="0.749023"/>
<pixmap bottom="0.25" left="0.00195313" right="0.25" textureId="11" top="0.00195313"/>
<pixmap bottom="0.498047" left="0.00195313" right="0.25" textureId="11" top="0.25"/>
<pixmap bottom="0.75" left="0.00195313" right="0.250977" textureId="11" top="0.501953"/>
<pixmap bottom="0.998047" left="0.00195313" right="0.250977" textureId="11" top="0.75"/>
<pixmap bottom="0.25" left="0.25" right="0.498047" textureId="11" top="0.00195313"/>
<pixmap bottom="0.498047" left="0.25" right="0.498047" textureId="11" top="0.25"/>
<pixmap bottom="0.75" left="0.250977" right="0.5" textureId="11" top="0.501953"/>
<pixmap bottom="0.998047" left="0.250977" right="0.5" textureId="11" top="0.75"/>
<pixmap bottom="0.75" left="0.5" right="0.749023" textureId="11" top="0.501953"/>
<pixmap bottom="0.998047" left="0.5" right="0.749023" textureId="11" top="0.75"/>
<pixmap bottom="0.25" left="0.501953" right="0.75" textureId="11" top="0.00195313"/>
<pixmap bottom="0.498047" left="0.501953" right="0.75" textureId="11" top="0.25"/>
<pixmap bottom="0.75" left="0.749023" right="0.998047" textureId="11" top="0.501953"/>
<pixmap bottom="0.998047" left="0.749023" right="0.998047" textureId="11" top="0.75"/>
<pixmap bottom="0.25" left="0.75" right="0.998047" textureId="11" top="0.00195313"/>
<pixmap bottom="0.498047" left="0.75" right="0.998047" textureId="11" top="0.25"/>
<pixmap bottom="0.5" left="0.00390625" right="0.5" textureId="12" top="0.00390625"/>
<pixmap bottom="0.996094" left="0.00390625" right="0.5" textureId="12" top="0.5"/>
<pixmap bottom="0.5" left="0.5" right="0.996094" textureId="12" top="0.00390625"/>
<pixmap bottom="0.996094" left="0.5" right="0.996094" textureId="12" top="0.5"/>
<pixmap bottom="0.25" left="0" right="0.5" textureId="13" top="0"/>
<pixmap bottom="0.5" left="0" right="0.5" textureId="13" top="0.25"/>
<pixmap bottom="0.75" left="0" right="0.5" textureId="13" top="0.5"/>
<pixmap bottom="1" left="0" right="0.5" textureId="13" top="0.75"/>
<pixmap bottom="0.2480469" left="0.00390625" right="0.4960938" textureId="13" top="0.001953125"/>
<pixmap bottom="0.248047" left="0.00390625" right="0.496094" textureId="13" top="0.00195313"/>
<pixmap bottom="0.498047" left="0.00390625" right="0.496094" textureId="13" top="0.251953"/>
<pixmap bottom="0.4980469" left="0.00390625" right="0.4960938" textureId="13" top="0.2519531"/>
<pixmap bottom="0.748047" left="0.00390625" right="0.496094" textureId="13" top="0.501953"/>
<pixmap bottom="0.7480469" left="0.00390625" right="0.4960938" textureId="13" top="0.5019531"/>
<pixmap bottom="0.998047" left="0.00390625" right="0.496094" textureId="13" top="0.751953"/>
<pixmap bottom="0.9980469" left="0.00390625" right="0.4960938" textureId="13" top="0.7519531"/>
<pixmap bottom="0.25" left="0.5" right="1" textureId="13" top="0"/>
<pixmap bottom="0.5" left="0.5" right="1" textureId="13" top="0.25"/>
<pixmap bottom="0.75" left="0.5" right="1" textureId="13" top="0.5"/>
<pixmap bottom="1" left="0.5" right="1" textureId="13" top="0.75"/>
<pixmap bottom="0.248047" left="0.503906" right="0.996094" textureId="13" top="0.00195313"/>
<pixmap bottom="0.498047" left="0.503906" right="0.996094" textureId="13" top="0.251953"/>
<pixmap bottom="0.748047" left="0.503906" right="0.996094" textureId="13" top="0.501953"/>
<pixmap bottom="0.998047" left="0.503906" right="0.996094" textureId="13" top="0.751953"/>
<pixmap bottom="0.2480469" left="0.5039063" right="0.9960938" textureId="13" top="0.001953125"/>
<pixmap bottom="0.4980469" left="0.5039063" right="0.9960938" textureId="13" top="0.2519531"/>
<pixmap bottom="0.7480469" left="0.5039063" right="0.9960938" textureId="13" top="0.5019531"/>
<pixmap bottom="0.9980469" left="0.5039063" right="0.9960938" textureId="13" top="0.7519531"/>
<pixmap bottom="0.2480469" left="0.001953125" right="0.2480469" textureId="14" top="0.001953125"/>
<pixmap bottom="0.4980469" left="0.001953125" right="0.2480469" textureId="14" top="0.2519531"/>
<pixmap bottom="0.7480469" left="0.001953125" right="0.2480469" textureId="14" top="0.5019531"/>
<pixmap bottom="0.9980469" left="0.001953125" right="0.2480469" textureId="14" top="0.7519531"/>
<pixmap bottom="0.248047" left="0.00195313" right="0.248047" textureId="14" top="0.00195313"/>
<pixmap bottom="0.498047" left="0.00195313" right="0.248047" textureId="14" top="0.251953"/>
<pixmap bottom="0.748047" left="0.00195313" right="0.248047" textureId="14" top="0.501953"/>
<pixmap bottom="0.998047" left="0.00195313" right="0.248047" textureId="14" top="0.751953"/>
<pixmap bottom="0.2480469" left="0.2519531" right="0.4980469" textureId="14" top="0.001953125"/>
<pixmap bottom="0.4980469" left="0.4980469" right="0.2519531" textureId="14" top="0.2519531"/>
<pixmap bottom="0.5019531" left="0.4980469" right="0.2519531" textureId="14" top="0.7480469"/>
<pixmap bottom="0.9980469" left="0.4980469" right="0.2519531" textureId="14" top="0.7519531"/>
<pixmap bottom="0.498047" left="0.498047" right="0.251953" textureId="14" top="0.251953"/>
<pixmap bottom="0.501953" left="0.498047" right="0.251953" textureId="14" top="0.748047"/>
<pixmap bottom="0.998047" left="0.498047" right="0.251953" textureId="14" top="0.751953"/>
<pixmap bottom="0.001953125" left="0.7480469" right="0.5019531" textureId="14" top="0.2480469"/>
<pixmap bottom="0.4980469" left="0.7480469" right="0.5019531" textureId="14" top="0.2519531"/>
<pixmap bottom="0.7480469" left="0.7480469" right="0.5019531" textureId="14" top="0.5019531"/>
<pixmap bottom="0.00195313" left="0.748047" right="0.501953" textureId="14" top="0.248047"/>
<pixmap bottom="0.498047" left="0.748047" right="0.501953" textureId="14" top="0.251953"/>
<pixmap bottom="0.248047" left="0.751953" right="0.998047" textureId="14" top="0.00195313"/>
<pixmap bottom="0.498047" left="0.751953" right="0.998047" textureId="14" top="0.251953"/>
<pixmap bottom="0.748047" left="0.751953" right="0.998047" textureId="14" top="0.501953"/>
<pixmap bottom="0.2480469" left="0.7519531" right="0.9980469" textureId="14" top="0.001953125"/>
<pixmap bottom="0.4980469" left="0.7519531" right="0.9980469" textureId="14" top="0.2519531"/>
<pixmap bottom="0.7480469" left="0.7519531" right="0.9980469" textureId="14" top="0.5019531"/>
<pixmap bottom="0.2480469" left="0.00390625" right="0.4960938" textureId="15" top="0.001953125"/>
<pixmap bottom="0.4980469" left="0.00390625" right="0.4960938" textureId="15" top="0.2519531"/>
<pixmap bottom="0.7480469" left="0.00390625" right="0.4960938" textureId="15" top="0.5019531"/>
<pixmap bottom="0.9980469" left="0.00390625" right="0.4960938" textureId="15" top="0.7519531"/>
<pixmap bottom="0.2480469" left="0.5039063" right="0.9960938" textureId="15" top="0.001953125"/>
<pixmap bottom="0.4980469" left="0.5039063" right="0.9960938" textureId="15" top="0.2519531"/>
<pixmap bottom="0.7480469" left="0.5039063" right="0.9960938" textureId="15" top="0.5019531"/>
<pixmap bottom="0.9980469" left="0.5039063" right="0.9960938" textureId="15" top="0.7519531"/>
<pixmap bottom="0.2480469" left="0.001953125" right="0.2480469" textureId="16" top="0.001953125"/>
<pixmap bottom="0.4980469" left="0.001953125" right="0.2480469" textureId="16" top="0.2519531"/>
<pixmap bottom="0.7480469" left="0.001953125" right="0.2480469" textureId="16" top="0.5019531"/>
<pixmap bottom="0.9980469" left="0.001953125" right="0.2480469" textureId="16" top="0.7519531"/>
<pixmap bottom="0.2480469" left="0.2519531" right="0.4980469" textureId="16" top="0.001953125"/>
<pixmap bottom="0.4980469" left="0.2519531" right="0.4980469" textureId="16" top="0.2519531"/>
<pixmap bottom="0.7480469" left="0.2519531" right="0.4980469" textureId="16" top="0.5019531"/>
<pixmap bottom="0.9980469" left="0.2519531" right="0.4980469" textureId="16" top="0.7519531"/>
<pixmap bottom="0.2480469" left="0.5019531" right="0.7480469" textureId="16" top="0.001953125"/>
<pixmap bottom="0.4980469" left="0.5019531" right="0.7480469" textureId="16" top="0.2519531"/>
<pixmap bottom="0.7480469" left="0.5019531" right="0.7480469" textureId="16" top="0.5019531"/>
<pixmap bottom="0.9980469" left="0.5019531" right="0.7480469" textureId="16" top="0.7519531"/>
<pixmap bottom="0.2480469" left="0.7519531" right="0.9980469" textureId="16" top="0.001953125"/>
<pixmap bottom="0.4980469" left="0.7519531" right="0.9980469" textureId="16" top="0.2519531"/>
<pixmap bottom="0.7480469" left="0.7519531" right="0.9980469" textureId="16" top="0.5019531"/>
<pixmap bottom="0.9980469" left="0.7519531" right="0.9980469" textureId="16" top="0.7519531"/>
<pixmap bottom="0.2480469" left="0.001953125" right="0.2480469" textureId="17" top="0.001953125"/>
<pixmap bottom="0.4980469" left="0.001953125" right="0.2480469" textureId="17" top="0.2519531"/>
<pixmap bottom="0.7480469" left="0.001953125" right="0.2480469" textureId="17" top="0.5019531"/>
<pixmap bottom="0.9980469" left="0.001953125" right="0.2480469" textureId="17" top="0.7519531"/>
<pixmap bottom="0.2480469" left="0.2519531" right="0.4980469" textureId="17" top="0.001953125"/>
<pixmap bottom="0.4980469" left="0.2519531" right="0.4980469" textureId="17" top="0.2519531"/>
<pixmap bottom="0.7480469" left="0.2519531" right="0.4980469" textureId="17" top="0.5019531"/>
<pixmap bottom="0.9980469" left="0.2519531" right="0.4980469" textureId="17" top="0.7519531"/>
<pixmap bottom="0.2480469" left="0.5019531" right="0.7480469" textureId="17" top="0.001953125"/>
<pixmap bottom="0.4980469" left="0.5019531" right="0.7480469" textureId="17" top="0.2519531"/>
<pixmap bottom="0.7480469" left="0.5019531" right="0.7480469" textureId="17" top="0.5019531"/>
<pixmap bottom="0.9980469" left="0.5019531" right="0.7480469" textureId="17" top="0.7519531"/>
<pixmap bottom="0.2480469" left="0.7519531" right="0.9980469" textureId="17" top="0.001953125"/>
<pixmap bottom="0.4980469" left="0.7519531" right="0.9980469" textureId="17" top="0.2519531"/>
<pixmap bottom="0.7480469" left="0.7519531" right="0.9980469" textureId="17" top="0.5019531"/>
<pixmap bottom="0.9980469" left="0.7519531" right="0.9980469" textureId="17" top="0.7519531"/>
</pixmaps> <materials>
<template material="Terrain/OneLayer" name="OneLayer"/>
<template material="Terrain/OneLayerLightmap" name="OneLayerLightmap"/>
<template material="Terrain/TwoLayer" name="TwoLayer"/>
<template material="Terrain/TwoLayerLightmap" name="TwoLayerLightmap"/>
<fog_replacement exp="Terrain/OneLayer_ps%fog_exp" exp2="Terrain/OneLayer_ps%fog_exp2" linear="Terrain/OneLayer_ps%fog_linear" none="Terrain/OneLayer_ps"/>
<fog_replacement exp="Terrain/TwoLayer_ps%fog_exp" exp2="Terrain/TwoLayer_ps%fog_exp2" linear="Terrain/TwoLayer_ps%fog_linear" none="Terrain/TwoLayer_ps"/>
<fog_replacement exp="Terrain/OneLayerLightmap_ps%fog_exp" exp2="Terrain/OneLayerLightmap_ps%fog_exp2" linear="Terrain/OneLayerLightmap_ps%fog_linear" none="Terrain/OneLayerLightmap_ps"/>
<fog_replacement exp="Terrain/TwoLayerLightmap_ps%fog_exp" exp2="Terrain/TwoLayerLightmap_ps%fog_exp2" linear="Terrain/TwoLayerLightmap_ps%fog_linear" none="Terrain/TwoLayerLightmap_ps"/>
</materials>
</Terrain>

地形文件

  天龙的地形代码我没仔细看,大致看了下,如下有不对的地方请指明,前面的titleSize与xsize与zsize主要是指明天龙是如何分块,xsize*zsize是所有的网格,而每titleSize指明多个网格合成一个MovableObject,如这个,一共有128*128块,然后每32*32块合成一个MovableObject(天龙中是TerrainTile),然后TerrainTile根据每个网格的纹理决定生成多少个Renderable,这样达到有限的合并网格渲染的目的.

  然后是scale,这个就是对应的在游戏中的实际位置,如xsize是128,那么x轴的实际长度应该是12800,其中y是地形高度的缩放,然后是高度图,网格信息文件,光照图.然后是所有网格要用的纹理,然后是网格要用的分块纹理pixmaps.简单来说,一个纹理分成几块pixmap,而pixmap才是每个网格用到的纹理部分.其中最重要的gridInfo文件是网格信息文件,存放的是每个网格用的二层pixmap id和显示方式.

  天龙的这种地形方式,一般来说会分成十几块(如上面是(128/32)^2=16),每块差不多用到所有纹理的一半左右,如果不设置雾与摄像机在远处全看到,综合下来,每次渲染要一百多个单元,不算多也不算少,不过没有LOD,也不会合成远处显示,故天龙的场景一般要开很大雾.

  Ogre地形组件比较复杂,实现的功能比较多,在这 Ogre 1.7的地形系统 简单说了下,其中和天龙不一样的是,天龙中的地形材质针对是每个网格,而Ogre中地形材质一般针对是整个地形,那么我们需要拿到天龙整个地形的纹理,这个纹理要拿到,我们只需想下这个地形是如何组成的就行,由zsize行xsize列个网格组成,每成对应的显示在对应gridInfo上的pixmaps上,这样我们只需要借助RTT把一块纹理分成zsize行xsize列,然后把每个pixmap渲染Rectangle2D与manualRender方法渲染到对应位置.请看如下代码:

        void createLayerTexture(int width, int height, string& textureName, bool firstLay)
{
auto layName = firstLay ? "firstLay" : "secondLay";
auto fullName = name + layName;
textureName = fullName;
auto texture = Ogre::TextureManager::getSingleton().getByName(fullName);
if (!texture.isNull())
{
return;
} auto scene = Ogre::Root::getSingleton().getSceneManager(DSceneName);
auto mRtTexture = Ogre::TextureManager::getSingleton().createManual(fullName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
Ogre::TEX_TYPE_2D, width, height, , Ogre::PF_A8R8G8B8, Ogre::TU_RENDERTARGET); Ogre::RenderTexture* renderTaget = mRtTexture->getBuffer()->getRenderTarget();
auto mRtCamera = scene->createCamera(fullName);
renderTaget->addViewport(mRtCamera);
renderTaget->getViewport()->setClearEveryFrame(false);
renderTaget->getViewport()->setBackgroundColour(ColourValue(1.0f, 1.0f, 1.0f, 1.0f));
renderTaget->getViewport()->setOverlaysEnabled(true);
renderTaget->setAutoUpdated(false);
renderTaget->setActive(true); MaterialPtr matPtr = MaterialManager::getSingleton().create
(fullName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
Ogre::Pass* pass = matPtr->getTechnique()->getPass();
pass->setLightingEnabled(false);
pass->createTextureUnitState();
pass->getTextureUnitState()->addFrameTextureName("");
auto tUnit = pass->getTextureUnitState(); Ogre::Rectangle2D* rect = new Ogre::Rectangle2D(true);
//opengl 不知是否是BUG,需要先update一下,才能用manualRender.
renderTaget->update(); auto getLocation = [&](int t, float &aleft, float &atop, float& aright, float& abottom){
int width = gridInfos->m_width;
int height = gridInfos->m_height;
int row = t / width;
int col = t % width;
aleft = (1.0f / width) * col * 2.0f - 1.0f;
atop = 1.0f - (1.0f / height) * row * 2.0f;
aright = aleft + 2.0f / width;
abottom = atop - 2.0f / height;
};
int i = ;
for (auto grid : gridInfos->m_data)
{
int gridIndex = i++;
int index = firstLay ? grid.nFirstLayer : grid.nSecondLayer;
if (index < && index >= pixmaps.size())
continue;
auto pixmap = pixmaps[index];
int textureIndex = pixmap->textureId;
auto left = pixmap->left;
auto top = pixmap->top;
auto right = pixmap->right;
auto bottom = pixmap->bottom;
//auto texture = Ogre::TextureManager::getSingletonPtr()->getByName(textures[textureIndex]);
tUnit->setFrameTextureName(textures[textureIndex], );
int op = firstLay ? grid.nFirstLayerOp : grid.nSecondLayerOp;
auto leftTop = Vector2(left, top);
auto leftBottom = Vector2(left, bottom);
auto rightTop = Vector2(right, top);
auto rightBottom = Vector2(right, bottom);
if (op > )
{
if (op & )
{
swap(leftTop, rightTop);
swap(leftBottom, rightBottom);
}
if (op & )
{
swap(leftTop, leftBottom);
swap(rightTop, rightBottom);
} if (op & )
{
swap(leftTop, rightTop);
swap(leftBottom, rightTop);
swap(rightBottom, rightTop);
} if (op & )
{
// 非正常索引
if (grid.IndexOrder == ) {
leftBottom.x = rightTop.x;
leftBottom.y = rightTop.y;
}
// 正常索引
else {
rightBottom.x = leftTop.x;
rightBottom.y = leftTop.y;
}
}
}
rect->setUVs(leftTop, leftBottom, rightTop, rightBottom);
//得到当前网格在整个屏幕上的位置(-1,1)
getLocation(gridIndex, left, top, right, bottom);
rect->setCorners(left, top, right, bottom);
Ogre::RenderOperation renderOp;
rect->getRenderOperation(renderOp);
scene->manualRender(&renderOp,
pass,
renderTaget->getViewport(),
Ogre::Matrix4::IDENTITY,
Ogre::Matrix4::IDENTITY,
Ogre::Matrix4::IDENTITY, false);
} //std::string saveFile = "d:\\" + fullName + ".png";
//renderTaget->writeContentsToFile(saveFile);
renderTaget->removeAllViewports();
scene->destroyCamera(mRtCamera);
MaterialManager::getSingleton().remove(fullName);
delete rect;
}

RTT 天龙地图

  如下是pingpan中对应的二张图:  

  这个方法过程就是生成一张Ogre::TU_RENDERTARGET纹理,调用scene->manualRender方法渲染到这张渲染上就行了,这个方法manualRender是我在看Ogre源码时,他的注释让我特别关注了下,发现用在这个地方完美,最开始我想到这个方法,但是发现生成的图片上啥都没,如果用正常的方法,生成多个Rectangle2D,多个Material,并挂在SceneNode下,然后调用rtt->pdate ,想想就变态,因为我只是暂时用下,生成这么多,我update后要清理多个,并且速度也不见的比这个快,网上找manualRender发现很多人也在说这个渲染不出来,也没人说为啥并给出解决方法,还好,我也是忽然想到了下,在调用manualRender 之前,我先让rtt->update一下,这样就能正常的输出到纹理了,不知这个地方算不算BUG.

  有了这二张纹理后,我们就让正常的流程加载高度图,然后生成TerrainGroup,在原来的地形组件中,Ogre会自动给我们生成对应的着色器代码,包含多层混合,灯光,雾设置,远景Technique等等.请看如下地形加载的代码. 

class TLTerrainManager :
public TerrainManager
{
protected:
bool autoMaterialGen = true;
SharedPtr<TLTerrainMaterial> tlMaterial;
public:
TLTerrainManager(SceneManager* scene, Ogre::Camera* camera)
:TerrainManager(scene, camera)
{
tlMaterial = SharedPtr<TLTerrainMaterial>(new TLTerrainMaterial());
//loadTerrainFile("_pingpan_1.Terrain");
} ~TLTerrainManager()
{ } void initBlendMaps(Terrain* terrain,string towTexture)
{
int blendMapSize = terrain->getLayerBlendMapSize();
auto texture2 = Ogre::TextureManager::getSingleton().getByName(towTexture);
Image image2;
tool::TextureToImage(texture2, image2);
int scale = image2.getWidth() / blendMapSize;
TerrainLayerBlendMap* blendMap1 = terrain->getLayerBlendMap();
float* pBlend1 = blendMap1->getBlendPointer();
for (Ogre::uint16 y = ; y < blendMapSize; ++y)
{
for (Ogre::uint16 x = ; x < blendMapSize; ++x)
{
auto color2 = image2.getColourAt(x * scale + scale / , y*scale + scale / , );
float blendA = color2.a;
*pBlend1++ = blendA;
}
}
blendMap1->dirty();
blendMap1->update();
} virtual void loadTerrainFile(const string& fileName)
{
TLTerrain tlTerrain;
tlTerrain.openTerrain(fileName);
TerrainInfo terrainInfo;
tlTerrain.grenate(, , terrainInfo);
loadInfo(terrainInfo);
} float getHeight(Vector3 pos)
{
return mTerrainGroup->getHeightAtWorldPosition(pos);
}
private:
void loadInfo(TerrainInfo& info)
{
mTerrainGroup = OGRE_NEW TerrainGroup(mScene, Terrain::ALIGN_X_Z, info.TerrainSize, info.WorldSize);
mTerrainGroup->setFilenameConvention(info.FileName, info.FileSuffix);
mTerrainGroup->setOrigin(info.Center);
mTerrainGroup->setResourceGroup(info.ResourceGroup); mTerrainGlobals->setMaxPixelError();
mTerrainGlobals->setCompositeMapDistance(); Vector3 lightdir(0.0, -, 0.0); Ogre::Light* l = mScene->createLight(info.FileName + "tstLight");
l->setType(Light::LT_DIRECTIONAL);
l->setDirection(lightdir);
l->setDiffuseColour(ColourValue::White);
l->setSpecularColour(ColourValue::White); mTerrainGlobals->setLightMapDirection(l->getDerivedDirection());
mTerrainGlobals->setCompositeMapAmbient(mScene->getAmbientLight());
mTerrainGlobals->setCompositeMapDiffuse(l->getDiffuseColour()); Terrain::ImportData& defaultimp = mTerrainGroup->getDefaultImportSettings();
defaultimp.terrainSize = info.TerrainSize;
defaultimp.worldSize = info.WorldSize;
defaultimp.inputScale = info.InputScale;
defaultimp.minBatchSize = info.MinBatchSize;
defaultimp.maxBatchSize = info.MaxBatchSize;
if (autoMaterialGen)
{
defaultimp.layerList = info.LayerList;
auto matProfile =
static_cast<TerrainMaterialGeneratorA::SM2Profile*>(mTerrainGlobals->getDefaultMaterialGenerator()->getActiveProfile());
matProfile->setLayerNormalMappingEnabled(false);
matProfile->setLayerParallaxMappingEnabled(false);
matProfile->setLayerSpecularMappingEnabled(false);
matProfile->setGlobalColourMapEnabled(false);
//matProfile->setCompositeMapEnabled(false);
//matProfile->setLightmapEnabled(false);
}
else
{
mTerrainGlobals->setDefaultMaterialGenerator(tlMaterial);
tlMaterial->setLight(l);
tlMaterial->setLayerName(info.LayerList[].textureNames[], info.LayerList[].textureNames[]);
} if (mPaging)
{
mPageManager = new PageManager();
mPageManager->setPageProvider(&mDummyPageProvider);
mPageManager->addCamera(mCamera);
mPageManager->setDebugDisplayLevel();
mTerrainPaging = new TerrainPaging(mPageManager);
mPagedWorld = mPageManager->createWorld();
mTerrainPagedWorldSection = mTerrainPaging->createWorldSection(mPagedWorld, mTerrainGroup, , ,
, ,
, );
mPageDefiner = new SimpleTerrainDefiner(info.HeightImage);
mTerrainPagedWorldSection->setDefiner(mPageDefiner);
}
else
{
mTerrainGroup->defineTerrain(, , info.HeightImage);
mTerrainGroup->loadTerrain(, , true);
if (autoMaterialGen)
initBlendMaps(mTerrainGroup->getTerrain(, ), info.LayerList[].textureNames[]);
} mTerrainGroup->freeTemporaryResources();
}
};

天龙地形加载设置

  这段代码Ogre例子中有差不多的,天龙的地图就用二层,并且每层只有一个散射光纹理,所以我们把每层的镜面光,法线,视差纹理全部关闭,如果我们使用光照图,需要设置terrainglobal的光照方向.

  代码参照Ogre地形例子里的就行,需要注意我们设置混合值.我们如果有超过一层的纹理,需要设置混合值,否则只有第一层的颜色,这个混合值在地形中有纹理专门来保存,如有1-5层纹理,那么对应一个混合纹理的argb四个通道,其中1-2层散射光纹理的混合值对应a,2-3对应g,如果超过5层,就生成第二个混合纹理.在这我们只有二层,那么只需要设置第一层的混合值就行,如果第二张图的Alpha为0,我们则全用第一层的.在天龙的地形中,第二层是专门用来混合的,在这,我们取对应第二层的Alpha就好.

  但是这样有个问题,我们发现颜色和天龙自己的编辑器加载还是有些区别,如下是地形组件自动生成的场景.

  通过分析,主要是二者的片断着色器代码有些区别.

#version
vec4 expand(vec4 v)
{
return v * 2.0 - 1.0;
} vec4 lit(float NdotL, float NdotH, float m) {
float ambient = 1.0;
float diffuse = max(0.0, NdotL);
float specular = step(0.0, NdotL) * max(NdotH, 0.0);
return vec4(ambient, diffuse, specular, 1.0);
} in vec4 oPosObj;
in vec4 oUVMisc;
out vec4 fragColour;
in vec4 layerUV0;
uniform vec4 lightPosObjSpace;
uniform vec3 lightDiffuseColour;
uniform vec3 lightSpecularColour;
uniform vec3 eyePosObjSpace;
uniform vec4 ambient;
uniform vec4 scaleBiasSpecular;
uniform sampler2D globalNormal;
uniform sampler2D blendTex0;
uniform sampler2D difftex0;
uniform sampler2D normtex0;
uniform sampler2D difftex1;
uniform sampler2D normtex1;
void main(void) {
float shadow = 1.0;
vec2 uv = oUVMisc.xy;
fragColour = vec4(,,,);
vec3 normal = expand(texture(globalNormal, uv)).rgb;
vec3 lightDir =
lightPosObjSpace.xyz - (oPosObj.xyz * lightPosObjSpace.w);
vec3 eyeDir = eyePosObjSpace - oPosObj.xyz;
vec3 diffuse = vec3(,,);
float specular = 0.0;
vec4 blendTexVal0 = texture(blendTex0, uv);
lightDir = normalize(lightDir);
eyeDir = normalize(eyeDir);
vec3 halfAngle = normalize(lightDir + eyeDir);
vec4 litRes = lit(dot(normal, lightDir), dot(normal, halfAngle), scaleBiasSpecular.z);
vec2 uv0 = layerUV0.xy;
vec4 diffuseSpecTex0 = texture(difftex0, uv0);
diffuse = diffuseSpecTex0.rgb;
vec2 uv1 = layerUV0.zw;
vec4 diffuseSpecTex1 = texture(difftex1, uv1);
diffuse = mix(diffuse, diffuseSpecTex1.rgb, blendTexVal0.r);
fragColour.rgb += ambient.rgb * diffuse + litRes.y * lightDiffuseColour * diffuse * shadow;
specular = 1.0;
fragColour.a = shadow;
}

地形组件自动生成

void
TwoLayerLightmap_ps(
in float2 uv0 : TEXCOORD0,
in float2 uvLightmap : TEXCOORD2,
in uniform sampler2D layer0,
in uniform sampler2D layer1,
in uniform sampler2D lightmap,
in float4 diffuse : COLOR0,
in float4 specular : COLOR1,
out float4 oColour : COLOR)
{
float4 c0 = tex2D(layer0, uv0);
float4 c1 = tex2D(layer1, uv0);
float3 texturedColour = lerp(c0.rgb, c1.rgb, c1.a);
float4 lightmapColour = tex2D(lightmap, uvLightmap);
float4 baseColour = diffuse * lightmapColour;
float3 finalColour = baseColour.rgb * texturedColour + specular.rgb * (-c0.a) * (-c1.a) * lightmapColour.a;
float3 resultColour = Fogging(finalColour);
oColour = float4(resultColour, baseColour.a);
} void
TwoLayer_ps(
in float2 uv0 : TEXCOORD0,
in uniform sampler2D layer0,
in uniform sampler2D layer1,
in float4 diffuse : COLOR0,
in float4 specular : COLOR1,
out float4 oColour : COLOR)
{
float4 c0 = tex2D(layer0, uv0);
float4 c1 = tex2D(layer1, uv0);
float3 texturedColour = lerp(c0.rgb, c1.rgb, c1.a);
float4 baseColour = diffuse;
float3 finalColour = baseColour.rgb * texturedColour + specular.rgb * (-c0.a) * (-c1.a);
float3 resultColour = Fogging(finalColour);
oColour = float4(resultColour, baseColour.a);
}

天龙的地形片断着色代码

  通过我们前面设置的混合纹理initBlendMaps这个方法,二者纹理都是第二层的Alpha进行线性混合,主要是天龙在最后还会用到这二个纹理的Alpha的值造成一些颜色上的区别.那么我们能不能就用天龙的着色器代码了,不用地形组件自动生成的,答案是可以.Ogre本身的地形组件提供足够我们的扩展,看如下代码:

class TLTerrainMaterial :
public TerrainMaterialGenerator
{
public:
TLTerrainMaterial(); std::string getMaterialTemplate(); void setLight(Ogre::Light* light)
{
mCompositeMapLight = light;
} void setLayerName(std::string oneLayer, std::string twoLayer = ""); void setLightMapName(std::string lightMap); class TLProfile : public Ogre::TerrainMaterialGenerator::Profile
{
public:
TLProfile(Ogre::TerrainMaterialGenerator* parent, const Ogre::String& name, const Ogre::String& desc);
~TLProfile(); bool isVertexCompressionSupported() const { return false; } Ogre::MaterialPtr generate(const Ogre::Terrain* terrain); Ogre::MaterialPtr generateForCompositeMap(const Ogre::Terrain* terrain); void setLightmapEnabled(bool enabled); Ogre::uint8 getMaxLayers(const Ogre::Terrain* terrain) const; void updateParams(const Ogre::MaterialPtr& mat, const Ogre::Terrain* terrain); void updateParamsForCompositeMap(const Ogre::MaterialPtr& mat, const Ogre::Terrain* terrain); void requestOptions(Ogre::Terrain* terrain); };
protected:
bool bTwoLayer = false;
bool bLightMap = false;
std::string oneLayerName;
std::string twoLayerName;
std::string lightMapName;
}; TLTerrainMaterial::TLTerrainMaterial()
{
mProfiles.push_back(OGRE_NEW TLProfile(this, "TLTerrainMaterial", "Profile for rendering Ogre standard material"));
setActiveProfile("TLTerrainMaterial");
} std::string TLTerrainMaterial::getMaterialTemplate()
{
std::string materialName = "Terrain/";
if (bTwoLayer)
materialName += "TwoLayer";
else
materialName += "OneLayer";
if (bLightMap)
materialName += "Lightmap";
return materialName;
} void TLTerrainMaterial::setLayerName(std::string oneLayer, std::string twoLayer)
{
oneLayerName = oneLayer;
bTwoLayer = twoLayer.size() > ;
if (bTwoLayer)
{
twoLayerName = twoLayer;
}
} void TLTerrainMaterial::setLightMapName(std::string lightMap)
{
bLightMap = lightMap.size() > ;
if (bLightMap)
{
lightMapName = lightMap;
}
} // ----------------------------------------------------------------------------------------------------------------------- TLTerrainMaterial::TLProfile::TLProfile(Ogre::TerrainMaterialGenerator* parent, const Ogre::String& name, const Ogre::String& desc)
: Ogre::TerrainMaterialGenerator::Profile(parent, name, desc)
{
}; TLTerrainMaterial::TLProfile::~TLProfile()
{
} Ogre::MaterialPtr TLTerrainMaterial::TLProfile::generate(const Ogre::Terrain* terrain)
{
auto mGenerator = ((TLTerrainMaterial*)getParent()); const String& matName = terrain->getMaterialName();
MaterialPtr mat = terrain->_getMaterial();
if (mat.isNull())
{
MaterialManager& matMgr = MaterialManager::getSingleton();
mat = matMgr.create(matName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
}
mat->removeAllTechniques();
auto templateName = mGenerator->getMaterialTemplate();
Ogre::MaterialPtr templateMaterial = Ogre::MaterialManager::getSingleton().getByName(templateName);
*mat = *(templateMaterial->clone(matName));
mat->setDiffuse(mGenerator->mCompositeMapLight->getDiffuseColour());
mat->setSpecular(mGenerator->mCompositeMapLight->getSpecularColour());
// Setup texture alias list
Ogre::AliasTextureNamePairList aliasList;
aliasList["<layer0>"] = mGenerator->oneLayerName;
if (mGenerator->bTwoLayer)
aliasList["<layer1>"] = mGenerator->twoLayerName;
if (mGenerator->bLightMap)
aliasList["<lightmap>"] = mGenerator->lightMapName;
mat->applyTextureAliases(aliasList);
updateParams(mat, terrain);
mat->load();
return mat;
} Ogre::MaterialPtr TLTerrainMaterial::TLProfile::generateForCompositeMap(const Ogre::Terrain* terrain)
{
return terrain->_getCompositeMapMaterial();
} void TLTerrainMaterial::TLProfile::setLightmapEnabled(bool enabled)
{ } Ogre::uint8 TLTerrainMaterial::TLProfile::getMaxLayers(const Ogre::Terrain* terrain) const
{
return ;
} void TLTerrainMaterial::TLProfile::updateParams(const Ogre::MaterialPtr& mat, const Ogre::Terrain* terrain)
{
} void TLTerrainMaterial::TLProfile::updateParamsForCompositeMap(const Ogre::MaterialPtr& mat, const Ogre::Terrain* terrain)
{
} void TLTerrainMaterial::TLProfile::requestOptions(Ogre::Terrain* terrain)
{
terrain->_setMorphRequired(true);
terrain->_setNormalMapRequired(true); // enable global normal map
terrain->_setLightMapRequired(false);
terrain->_setCompositeMapRequired(false);
}

TLTerrainMaterial

  简单来说,就是我们生成我们自己的TerrainMaterialGenerator与Profile,然后在地形设置中调用如下mTerrainGlobals->setDefaultMaterialGenerator(tlMaterial);这样地形组件就是用的我们的着色器代码,在这我们只是简单把设置下,所以原先里有很多设置我们用不上,直接关掉就可.

  如下是加载天龙地形文件里所有信息的完整代码,最主要的就是前面的第一段代码,已经发过的:

class TLTerrain
{
private:
std::string name;
int tileSize = ;
int xsize = ;
int zsize = ;
Vector3 scale;
std::string heightMap = "";
std::string gridInfo = "";
std::string lightMap = ""; typedef std::vector<MyGUI::UString> VectorUString;
std::vector<Ogre::String> textures;
std::vector<Pixmap*> pixmaps;
std::vector<float> heightMapData;
GridInfos* gridInfos;
SharedPtr<Image> imagePtr;
public:
TLTerrain()
{
gridInfos = new GridInfos();
imagePtr = SharedPtr<Image>(new Image());
} ~TLTerrain()
{
clear();
} void clear()
{
heightMap = "";
gridInfo = "";
lightMap = ""; gridInfos->close();
textures.clear();
heightMapData.clear(); if (pixmaps.size() > )
{
for (auto p : pixmaps)
{
delete p;
}
pixmaps.clear();
}
} void openTerrain(const std::string& fileName)
{
clear();
DataStreamHolder data = MyGUI::DataManager::getInstance().getData(fileName);
xml::Document doc;
if (!doc.open(data.getData()))
{
throw exception("");
}
xml::ElementPtr root = doc.getRoot();
name = root->findAttribute("name");
tileSize = MyGUI::utility::parseFloat(root->findAttribute("tileSize"));
xsize = MyGUI::utility::parseFloat(root->findAttribute("xsize"));
zsize = MyGUI::utility::parseFloat(root->findAttribute("zsize")); auto node = root->getElementEnumerator();
while (node.next())
{
if (node->getName() == "scale")
{
float x = MyGUI::utility::parseFloat(node->findAttribute("x"));
float y = MyGUI::utility::parseFloat(node->findAttribute("y"));
float z = MyGUI::utility::parseFloat(node->findAttribute("z"));
scale.x = x;
scale.y = y;
scale.z = z;
}
else if (node->getName() == "heightmap")
{
heightMap = node->findAttribute("filename");
loadHightMap(heightMap);
}
else if (node->getName() == "gridInfo")
{
gridInfo = node->findAttribute("filename");
gridInfos->open(gridInfo, Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME);
}
else if (node->getName() == "lightmap")
{
lightMap = node->findAttribute("filename");
}
else if (node->getName() == "textures")
{
auto xtexts = node->getElementEnumerator();
while (xtexts.next())
{
//08大理/大理方砖地.tga
auto textName = tool::UTF8ToGBK(xtexts->findAttribute("filename").c_str());
textures.push_back(textName);
}
}
else if (node->getName() == "pixmaps")
{
auto xpixs = node->getElementEnumerator();
while (xpixs.next())
{
float left = MyGUI::utility::parseFloat(xpixs->findAttribute("left"));
float top = MyGUI::utility::parseFloat(xpixs->findAttribute("top"));
float right = MyGUI::utility::parseFloat(xpixs->findAttribute("right"));
float bottom = MyGUI::utility::parseFloat(xpixs->findAttribute("bottom"));
int textureId = MyGUI::utility::parseInt(xpixs->findAttribute("textureId"));
Pixmap* map = new Pixmap(textureId, left, top, right, bottom);
pixmaps.push_back(map);
}
}
}
} void loadHightMap(const string& fileName)
{
//DataStreamHolder data = MyGUI::DataManager::getInstance().getData(fileName);
auto stream = ResourceGroupManager::getSingletonPtr()->openResource(fileName);
if (stream.isNull())
{
return;
}
stream->seek();
int* size = new int[];
stream->read(reinterpret_cast<char*>(size), );
int height = size[];
int width = size[];
if (heightMapData.size() > )
heightMapData.clear(); int dataSize = height * width * ;
heightMapData.resize(dataSize);
stream->read(reinterpret_cast<char*>(heightMapData.data()), dataSize * ); imagePtr = SharedPtr<Image>(new Image());
DataStreamPtr imgstream(new MemoryDataStream(heightMapData.data(), width * height * ));
imagePtr->loadRawData(imgstream, width, height, PF_FLOAT32_R);
} void grenate(int width, int height, TerrainInfo& importData)
{
importData.WorldSize = xsize * scale.x;
importData.TerrainSize = ;
importData.MaxBatchSize = ;
importData.MinBatchSize = ;
importData.InputScale = scale.y;
importData.HeightImage = imagePtr.get();
importData.FileName = name;
importData.ResourceGroup = DTLGroupName; auto bLoadHight = createLightTexture(lightMap); importData.LayerList.resize();
string firstLayName; createLayerTexture(width, height, firstLayName, true);
importData.LayerList[].worldSize = xsize * scale.x;
importData.LayerList[].textureNames.push_back(firstLayName); string secondLayName;
createLayerTexture(width, height, secondLayName, false);
importData.LayerList[].worldSize = xsize * scale.x;
importData.LayerList[].textureNames.push_back(secondLayName); } void createLayerTexture(int width, int height, string& textureName, bool firstLay)
{
auto layName = firstLay ? "firstLay" : "secondLay";
auto fullName = name + layName;
textureName = fullName;
auto texture = Ogre::TextureManager::getSingleton().getByName(fullName);
if (!texture.isNull())
{
return;
} auto scene = Ogre::Root::getSingleton().getSceneManager(DSceneName);
auto mRtTexture = Ogre::TextureManager::getSingleton().createManual(fullName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
Ogre::TEX_TYPE_2D, width, height, , Ogre::PF_A8R8G8B8, Ogre::TU_RENDERTARGET); Ogre::RenderTexture* renderTaget = mRtTexture->getBuffer()->getRenderTarget();
auto mRtCamera = scene->createCamera(fullName);
renderTaget->addViewport(mRtCamera);
renderTaget->getViewport()->setClearEveryFrame(false);
renderTaget->getViewport()->setBackgroundColour(ColourValue(1.0f, 1.0f, 1.0f, 1.0f));
renderTaget->getViewport()->setOverlaysEnabled(true);
renderTaget->setAutoUpdated(false);
renderTaget->setActive(true); MaterialPtr matPtr = MaterialManager::getSingleton().create
(fullName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
Ogre::Pass* pass = matPtr->getTechnique()->getPass();
pass->setLightingEnabled(false);
pass->createTextureUnitState();
pass->getTextureUnitState()->addFrameTextureName("");
auto tUnit = pass->getTextureUnitState(); Ogre::Rectangle2D* rect = new Ogre::Rectangle2D(true);
//opengl 不知是否是BUG,需要先update一下,才能用manualRender.
renderTaget->update(); auto getLocation = [&](int t, float &aleft, float &atop, float& aright, float& abottom){
int width = gridInfos->m_width;
int height = gridInfos->m_height;
int row = t / width;
int col = t % width;
aleft = (1.0f / width) * col * 2.0f - 1.0f;
atop = 1.0f - (1.0f / height) * row * 2.0f;
aright = aleft + 2.0f / width;
abottom = atop - 2.0f / height;
};
int i = ;
for (auto grid : gridInfos->m_data)
{
int gridIndex = i++;
int index = firstLay ? grid.nFirstLayer : grid.nSecondLayer;
if (index < && index >= pixmaps.size())
continue;
auto pixmap = pixmaps[index];
int textureIndex = pixmap->textureId;
auto left = pixmap->left;
auto top = pixmap->top;
auto right = pixmap->right;
auto bottom = pixmap->bottom;
//auto texture = Ogre::TextureManager::getSingletonPtr()->getByName(textures[textureIndex]);
tUnit->setFrameTextureName(textures[textureIndex], );
int op = firstLay ? grid.nFirstLayerOp : grid.nSecondLayerOp;
auto leftTop = Vector2(left, top);
auto leftBottom = Vector2(left, bottom);
auto rightTop = Vector2(right, top);
auto rightBottom = Vector2(right, bottom);
if (op > )
{
if (op & )
{
swap(leftTop, rightTop);
swap(leftBottom, rightBottom);
}
if (op & )
{
swap(leftTop, leftBottom);
swap(rightTop, rightBottom);
} if (op & )
{
swap(leftTop, rightTop);
swap(leftBottom, rightTop);
swap(rightBottom, rightTop);
} if (op & )
{
// 非正常索引
if (grid.IndexOrder == ) {
leftBottom.x = rightTop.x;
leftBottom.y = rightTop.y;
}
// 正常索引
else {
rightBottom.x = leftTop.x;
rightBottom.y = leftTop.y;
}
}
}
rect->setUVs(leftTop, leftBottom, rightTop, rightBottom);
//得到当前网格在整个屏幕上的位置(-1,1)
getLocation(gridIndex, left, top, right, bottom);
rect->setCorners(left, top, right, bottom);
Ogre::RenderOperation renderOp;
rect->getRenderOperation(renderOp);
scene->manualRender(&renderOp,
pass,
renderTaget->getViewport(),
Ogre::Matrix4::IDENTITY,
Ogre::Matrix4::IDENTITY,
Ogre::Matrix4::IDENTITY, false);
} //std::string saveFile = "d:\\" + fullName + ".png";
//renderTaget->writeContentsToFile(saveFile);
renderTaget->removeAllViewports();
scene->destroyCamera(mRtCamera);
MaterialManager::getSingleton().remove(fullName);
delete rect;
} bool createLightTexture(const string& textureName)
{
auto haveLight = lightMap.size() != ;
if (!haveLight)
return false;
try
{
auto texture = Ogre::TextureManager::getSingleton().load(textureName, DTLGroupName);
return !texture.isNull();
}
catch (...)
{
return false;
}
}
};

TLTerrain文件加载

  其中我用MyGUI里提供的XML读取类来读取相关的文件,注意如果是中文,并且要拿到Ogre中去查找资料的字符串,应该调用utf8togbk,开始这个位置直接用的utf8编码,然后在前面生成天龙的地形时,调用manualRender非常慢,怎么说了,一分钟都还没走完,我很奇怪怎么会这么慢,用VS的性能和诊断分析了下,定位到加载纹理是最要时间的,然后跑去看,才发现所有纹理都没加载上.然后比较同一字符串,在Ogre中和Mygui读出来的char比对才发现是不一样的,但是还想着宽字符啥的,但是Ogre本身也是用std::string存的,所以应该是字符编码的问题,转成gbk后,二者的char就一样了,这样用前面的manualRender渲染128*128个网格不到一秒了.

  到这整个天龙的地形就用Ogre的地形组件加载上去了.

  

Ogre 编辑器二(用Ogre的地形组件加载天龙八部地形)的更多相关文章

  1. KnockoutJS 3.X API 第六章 组件(5) 高级应用组件加载器

    无论何时使用组件绑定或自定义元素注入组件,Knockout都将使用一个或多个组件装载器获取该组件的模板和视图模型. 组件加载器的任务是异步提供任何给定组件名称的模板/视图模型对. 本节目录 默认组件加 ...

  2. Linux内核启动代码分析二之开发板相关驱动程序加载分析

    Linux内核启动代码分析二之开发板相关驱动程序加载分析 1 从linux开始启动的函数start_kernel开始分析,该函数位于linux-2.6.22/init/main.c  start_ke ...

  3. web.xml组件加载顺序

    在配置项目组件的过程中, 了解Tomcat加载组件顺序很有必要. 例如某些框架如Quartz的集群功能需要数据库的支持, 数据库的加载肯定要在框架组件加载之前. 经过查阅和Debug发现, web.x ...

  4. pyspider 示例二 升级完整版绕过懒加载,直接读取图片

    pyspider 示例二 升级完整版绕过懒加载,直接读取图片,见[升级写法处] #!/usr/bin/env python # -*- encoding: utf-8 -*- # Created on ...

  5. DB数据源之SpringBoot+MyBatis踏坑过程(二)手工配置数据源与加载Mapper.xml扫描

    DB数据源之SpringBoot+MyBatis踏坑过程(二)手工配置数据源与加载Mapper.xml扫描 liuyuhang原创,未经允许进制转载  吐槽之后应该有所改了,该方式可以作为一种过渡方式 ...

  6. [技术博客]React-Native中的组件加载、卸载与setState问题

    React-Native中的组件加载.卸载与setState问题. Warning: Can only update a mounted or mounting component. This usu ...

  7. vue学习(六)异步组件加载

    异步组件加载 首先准备-----简单的框架搭出来 <!DOCTYPE html> <html lang="zh-CN"> <head> < ...

  8. element el-tree、el-table组件加载数据前闪现 暂无数据 清除

    相信很多人在使用element  el-tree.el-table组件加载数据前会显示一个" 暂无数据 ",体验很不友好,有没有办法处理不显示呢?答案是:有的.废话不多说直接上代码 ...

  9. Ogre 编辑器一(MyGUI+Ogre整合与主界面)

    在查看Ogre例子时,想看材质要里的纹理,着色器代码都需要每个去查找,非常麻烦.也想看更新每个Ogre里的对象后有什么效果.然后看到Compositor组件与粒子组件时,想到能实时编辑着色器代码实时更 ...

随机推荐

  1. android笔记---ScrollView

    <!--在创建xml文件的时候选择ScrollView类型--> <?xml version="1.0" encoding="utf-8"?& ...

  2. angular的uiRouter服务学习(2)

    本篇接着上一篇 angular的uiRouter服务学习(1) 继续讲解uiRouter的用法 本篇主要讲解uiRouter的嵌套状态&嵌套视图 嵌套状态的方法: 状态和状态之间可以互相嵌套, ...

  3. 数据加密 - TDE透明数据加密原理

    首先需要确定你需要加密的列,Oracle 10g数据库将为包含加密列的表创建一个私密的安全加密密钥(表秘钥), 然后采用你指定的加密算法(AES或3DES)加密指定列的明文数据.此时,保护表的加密密钥 ...

  4. [Windows Azure] How to use the Windows Azure Blob Storage Service in .NET

    How to use the Windows Azure Blob Storage Service in .NET version 1.7 version 2.0 This guide will de ...

  5. Oracle字段类型及存储(一)

    Oracle中2000个byte,并不是2000个字符的意思,1个字符在Oracle中可能是1个byte到4个byte不等,需看数据库字符集的设置了. 对GBK字符集而言,ASCII码中128个字符使 ...

  6. Leetcode:Longest Substring Without Repeating Characters 解题报告

    Longest Substring Without Repeating Characters Given a string, find the length of the longest substr ...

  7. 使用spin.js优化等待ajax返回时的页面效果

    [本文出自天外归云的博客园] 最近在做一个JIRA信息统计的系统,在统计JIRA关联信息的过程中由于需要等待ajax返回结果到前端,时间较长,所以要添加一段等待时的loading画面,使用spin.j ...

  8. CSS超过指定的宽度加省略号

    /*table-layout:fixed 会使表格均等分*/ #TreeView1 table { width:290px; table-layout: fixed; } #TreeView1 td: ...

  9. highcharts图表组件通过设置tooltip属性自定义数据提示信息

    我们先来看看这样一个例子,全局配置好tooltip,数据点的提示信息能够自己根据数据点自身数据情况加以显示,代码如下所示: 01.$(function () { 02.$('#container'). ...

  10. 新浪微博 oauth2.0 redirect_uri_mismatch

    新浪微博开放平台出来很久了,现在才开始研究,貌似有点晚了.... 第一次折腾,总是出现这样那样的问题,即使照着别人成功的例子也是一样,这不,开始运行的时候,运行下面的例子,总是报error:redir ...