利用SimpleRenderable实现DirectX 9 3D 游戏设计入门中 第十三章 地形渲染基础的简单地形,只是简单的实现了地形的基本框架,顶点,索引,纹理等,为简单起见高度都为1,适合新手做入门的学习,高手可以飘过了,效果图:

Terrain.h:

#ifndef _TERRAIN_H_
#define _TERRAIN_H_ #include <Ogre.h>
#include "Common.h" using namespace Ogre; #define VERTEX_POS_BINDING 0 class CTerrain :public SimpleRenderable
{
public:
//numVertsPerCol,numVertsPerRow为奇数时m_width,m_depth必定为偶数
CTerrain(int numVertsPerRow=,int numVertsPerCol=,int cellSize=,float heightScal=1.0f);
~CTerrain(); public:
bool InitData();
void LoadHeightmap();
void CreateVertexData();
void CreateIndexData(); // Overridden from MovableObject
virtual Real getBoundingRadius() const;
virtual const AxisAlignedBox& getBoundingBox() const; // Overridden from Renderable
virtual Real getSquaredViewDepth(const Ogre::Camera* cam) const;
private:
String m_heightMapPath;//高度图
float *m_heightMap;//高度数据
float m_heightScal;//高度缩放值
int m_numVertsPerRow;//每行顶点数
int m_numVertsPerCol;//每列顶点数
int m_numCellsPerRow;//每行格子数
int m_numCellsPerCol;//每列格子数
int m_cellSize;//格子边长
int m_numVerts;//顶点总数
int m_numTriangles;//三角形总数
int m_width;//地形宽度
int m_depth;//地形深度
bool m_bSaveData;//是否保存顶点信息 AxisAlignedBox mAABB;
Real mBoundingRadius;
VertexData *pVertexData;
IndexData *pIndexData;
}; #endif

Terrain.cpp:

#include "Terrain.h"
#include <fstream> CTerrain::CTerrain(int numVertsPerRow,int numVertsPerCol,int cellSize,float heightScal)
{
m_numVertsPerRow=numVertsPerRow;
m_numVertsPerCol=numVertsPerCol;
m_heightScal=heightScal;
m_cellSize=cellSize;
m_heightMapPath="";
m_bSaveData=true; m_numCellsPerRow=m_numVertsPerRow-;
m_numCellsPerCol=m_numVertsPerCol-;
m_numVerts=m_numVertsPerRow*m_numVertsPerCol;
m_numTriangles=m_numCellsPerRow*m_numCellsPerCol*;
m_width=m_numCellsPerRow*m_cellSize;
m_depth=m_numCellsPerCol*m_cellSize; m_heightMap=new float[m_numVerts];
} CTerrain::~CTerrain()
{
safeDelArry(m_heightMap); OGRE_DELETE(mRenderOp.vertexData);
OGRE_DELETE(mRenderOp.indexData);
} bool CTerrain::InitData()
{
LoadHeightmap();
CreateVertexData();
CreateIndexData(); return true;
} void CTerrain::LoadHeightmap()
{
for (int i=;i<m_numVerts;i++)
{
m_heightMap[i]=1.0f;
}
} void CTerrain::CreateVertexData()
{
mRenderOp.vertexData=new VertexData();
pVertexData=mRenderOp.vertexData;
pVertexData->vertexCount=m_numVerts;
pVertexData->vertexStart=;
mRenderOp.operationType=RenderOperation::OT_TRIANGLE_LIST;
mRenderOp.useIndexes=true;
VertexDeclaration *decl=pVertexData->vertexDeclaration;
VertexBufferBinding *bind=pVertexData->vertexBufferBinding; size_t vOffset=,textCoordSet=;
decl->addElement(,vOffset,VET_FLOAT3,VES_POSITION);
vOffset=vOffset+VertexElement::getTypeSize(VET_FLOAT3);
decl->addElement(,vOffset,VET_COLOUR,VES_DIFFUSE);
vOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR);
decl->addElement(,vOffset,VET_FLOAT2,VES_TEXTURE_COORDINATES,textCoordSet++);
vOffset=vOffset+VertexElement::getTypeSize(VET_FLOAT2);
decl->addElement(,vOffset,VET_FLOAT2,VES_TEXTURE_COORDINATES,textCoordSet++); HardwareVertexBufferSharedPtr pVerBuff;
pVerBuff=HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(),m_numVerts,HardwareBuffer::HBU_STATIC_WRITE_ONLY,false); float *pLock=static_cast<float *>(pVerBuff->lock(,pVerBuff->getSizeInBytes(),HardwareBuffer::HBL_DISCARD)); RGBA colour,*pColour;
RenderSystem *rs=Ogre::Root::getSingleton().getRenderSystem();
rs->convertColourValue(ColourValue(1.0f,1.0f,1.0f),&colour);
float start_x,end_x,start_z,end_z;
int index=;
start_x=-m_width/;
end_x=-start_x;
start_z=-m_depth/;
end_z=-start_z; std::ofstream of;
bool bopen=false;
if (m_bSaveData)
{
of.open(L"vertexInfo.txt",std::ios::out|std::ios::trunc);
if (of.is_open())
{
bopen=true;
of<<"------------------------------------------\r\n";
of<<"vertex data info:\r\n";
}else
{
MessageBox( NULL, L"INFO",L"An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
}
}
float y=0.0f,tu=0.0f,tv=0.0f;
int h=,c=;
char tmepChar[]={};
for (float z=start_z;z<=end_z;z+=m_cellSize)
{
tu=h*m_cellSize/(float)m_width;
h++;
c=;
for (float x=start_x;x<=end_x;x+=m_cellSize)
{
tv=c*m_cellSize/(float)m_depth;
c++; y=m_heightMap[index++];
*pLock=x;
pLock++;
*pLock=y;
pLock++;
*pLock=z;
pLock++; pColour=static_cast<RGBA *>(static_cast<void *>(pLock));
*pColour=colour;
pColour++;
pLock=static_cast<float *>(static_cast<void *>(pColour)); *pLock=tu;
pLock++;
*pLock=tv;
pLock++; *pLock=tu;
pLock++;
*pLock=tv;
pLock++; if (m_bSaveData&&bopen)
{
sprintf(tmepChar,"x=%f y=%f z=%f u=%f v=%f\r\n",x,y,z,tu,tv);
of<<tmepChar;
} } }
pVerBuff->unlock();
bind->setBinding(,pVerBuff); if (m_bSaveData&&bopen)
of.close(); float boxHeght=20.0f;
float vertices[][] = {
start_x, boxHeght, start_z, // A
-start_x, boxHeght, start_z, // B
start_x, boxHeght, -start_z, // C
-start_x, boxHeght, -start_z, // D start_x, boxHeght, start_z, // A
-start_x, boxHeght, start_z, // B
start_x, boxHeght, -start_z, // C
-start_x, boxHeght, -start_z, // D
}; for (int i=;i<;i++)
{
mAABB.merge(Ogre::Vector3(vertices[i][], vertices[i][], vertices[i][]));
}
mBoundingRadius = Ogre::Math::boundingRadiusFromAABB(mAABB); }
/*A---------B
- -
- -
- -
C-----------D
*/
void CTerrain::CreateIndexData()
{
mRenderOp.indexData=new IndexData();
pIndexData=mRenderOp.indexData;
pIndexData->indexStart=;
pIndexData->indexCount=m_numTriangles*;
pIndexData->indexBuffer=HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT,pIndexData->indexCount,HardwareBuffer::HBU_STATIC_WRITE_ONLY);
unsigned short *pIndexLock=static_cast<unsigned short *>(pIndexData->indexBuffer->lock(, pIndexData->indexBuffer->getSizeInBytes(),HardwareBuffer::HBL_DISCARD)); std::ofstream of;
bool bopen=false;
if (m_bSaveData)
{
of.open(L"indexInfo.txt",std::ios::out|std::ios::trunc);
if (of.is_open())
{
bopen=true;
of<<"------------------------------------------\r\n";
of<<"index data info:\r\n";
}else
{
MessageBox( NULL, L"INFO",L"An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
}
} char tmepChar[]={};
unsigned short uvalue[];
int index=; for (unsigned short row=;row<m_numCellsPerCol;row++)
{
for (unsigned short col=;col<m_numCellsPerRow;col++)
{
//ACB
uvalue[]=row*m_numVertsPerRow+col;
*pIndexLock=uvalue[];
pIndexLock++;
uvalue[]=(row+)*m_numVertsPerRow+col;
*pIndexLock=uvalue[];
pIndexLock++;
uvalue[]=row*m_numVertsPerRow+col+;//
*pIndexLock=uvalue[];
pIndexLock++;
//CDB
uvalue[]=uvalue[];
uvalue[]=uvalue[];
uvalue[]=(row+)*m_numVertsPerRow+col+;
*pIndexLock=uvalue[];
pIndexLock++;
*pIndexLock=uvalue[];
pIndexLock++;
*pIndexLock=uvalue[];
pIndexLock++; if (m_bSaveData&&bopen)
{
for (int j=;j<;j++)
{
sprintf(tmepChar,"index%d=%u ",index++,uvalue[j]);
of<<tmepChar;
if (j==)
{
of<<std::endl;
}
} }
}
}
pIndexData->indexBuffer->unlock();
if (m_bSaveData&&bopen)
{
of.close();
}
} Real CTerrain::getBoundingRadius() const
{
return mBoundingRadius;
} Real CTerrain::getSquaredViewDepth(const Ogre::Camera* cam) const
{
assert(mParentNode);
return mParentNode->getSquaredViewDepth(cam);
} const AxisAlignedBox& CTerrain::getBoundingBox() const
{
return mAABB;
}

创建地形:

void CApplication::CreateTerrain()
{
pTerrain=new CTerrain(,,,1.0f);
pTerrain->InitData();
pTerrain->setMaterial("Examples/Terrain_Material");
SceneNode *node =pSceneManager->getRootSceneNode()->createChildSceneNode("TerrainNode",Vector3(,,));
node->attachObject(pTerrain);
node->showBoundingBox(true);
}

材质:

material Examples/Terrain_Material : Examples/OgreDance
{
technique
{
pass
{
lighting off
//scene_blend alpha_blend
//cull_hardware none
//cull_software none texture_unit
{
texture dirt_grayrocky_diffusespecular.dds
tex_address_mode wrap
}
texture_unit
{
//colour_op_ex add src_texture src_current
//colour_op_multipass_fallback one one texture grass_green-01_diffusespecular.dds
tex_address_mode wrap
}
}
}
}

Ogre实现简单地形的更多相关文章

  1. Directx11学习笔记【十三】 实现一个简单地形

    本文由zhangbaochong原创,转载请注明出处http://www.cnblogs.com/zhangbaochong/p/5510294.html 上一个教程我们实现了渲染一个会旋转的立方体, ...

  2. 转:Ogre TerrainGroup地形赏析

    1.1  参考 http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Ogre+Terrain+System http://www.ogre3d.org ...

  3. Ogre 编辑器二(用Ogre的地形组件加载天龙八部地形)

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

  4. Ogre 1.8 terrain 和 paging 组件

    以下转自:http://hi.baidu.com/xocoder/item/e8d87cf53d87612b753c4cfd OGRE地形生成 OGRE可以通过两个接口来生成地形,分别是void Te ...

  5. 转:高层游戏引擎——基于OGRE所实现的高层游戏引擎框架

    高层游戏引擎——基于OGRE所实现的高层游戏引擎框架 这是意念自己的毕业论文,在一个具体的实践之中,意念主要负责的是物件和GUI之外的其他游戏系统.意念才学疏陋,望众位前辈不吝赐教.由于代码质量不高. ...

  6. Directx11学习笔记【二十二】 用高度图实现地形

    本文由zhangbaochong原创,转载请注明出处http://www.cnblogs.com/zhangbaochong/p/5827714.html 在前面我们曾经实现过简单的地形(Direct ...

  7. Directx教程(29) 简单的光照模型(8)

    原文:Directx教程(29) 简单的光照模型(8)      现在我们新建一个工程myTutorialD3D_23,在这个工程中,对前面一章的代码进行一些整理: 1.我们在顶点属性中增加材质的的漫 ...

  8. Directx11学习笔记【十五】 基本几何体的绘制

    本文由zhangbaochong原创,转载请注明出处http://www.cnblogs.com/zhangbaochong/p/5573970.html 前面实现简单地形的教程,我们只是绘制了一个网 ...

  9. Unity 个人用过的地面检测方案总结

    Unity 个人用过的地面检测方案总结 1.普通射线 在角色坐标(一般是脚底),发射一根向下的射线,长度大约为0.2, 只适用于简单地形,实际使用中常常遇到以下问题 用的collider去碰撞地面时, ...

随机推荐

  1. android之自定义ViewGroup和自动换行的布局的实现

    viewgroup简单说就是可以装view的view.今天遇到一个问题,就是需要一个可以自动根据一行中view的宽度自动换行的布局,网上 找了下,没有相关的例子,但是找到了思路:自定义一个viewgr ...

  2. 认识CoreData-基础使用

    第一篇文章中并没有讲CoreData的具体用法,只是对CoreData做了一个详细的介绍,算是一个开始和总结吧. 这篇文章中会主要讲CoreData的基础使用,以及在使用中需要注意的一些细节.因为文章 ...

  3. C# Obsolete

    Obsolete 属性将某个程序实体标记为一个建议不再使用的实体.每次使用被标记为已过时的实体时,随后将生成警告或错误,这取决于属性是如何配置的 如果把false 改成 true 的话那么GetNam ...

  4. sklearn两种保存模型的方式

    作者:卢嘉颖 链接:https://www.zhihu.com/question/27187105/answer/97334347 来源:知乎 著作权归作者所有,转载请联系作者获得授权. 1. pic ...

  5. 【慕课网学习笔记】Java共享变量的可见性和原子性

    1. Java内存模型(Java Memory Model, JMM) Java的内存模型如下,所有变量都存储在主内存中,每个线程都有自己的工作内存. 共享变量:如果一个变量在多个线程中都使用到了,那 ...

  6. Base64 encode/decode large file

    转载:http://www.cnblogs.com/jzywh/archive/2008/04/20/base64_encode_large_file.html The class System.Co ...

  7. PhotoView开源项目剖析

    http://blog.csdn.net/wu928320442/article/details/43056731 介绍 上一节呢,我们介绍了怎么下载和编译Android源码,这节呢,我们来讨论Pho ...

  8. 主机访问 虚拟机web注意事项

    在这里, 我通过NAT的方式, 通过主机访问虚拟机. 需要做的是, 将主机中访问的端口, 映射为虚拟机的'编辑->虚拟网络编辑器->vmnet8', 如下图 在弹出的'映射传入端口'界面中 ...

  9. 【转载】Oracle层次查询和分析函数

    摘要 一组连续的数,去掉中间一些数,如何求出剩下的数的区间(即号段)?知道号段的起止,如何求出该号段内所有的数?知道一个大的号段范围和已经取过的号段,如何求出可用的号段?利用Oracle提供的强大的查 ...

  10. 学习笔记_Filter小结(过滤器JavaWeb三大组件之一)

    Filter小结 Filter的三个方法: l  void init(FilterConfig):在Tomcat启动时被调用: l  void destroy():在Tomcat关闭时被调用: l  ...