游戏开发论坛

 找回密码
 立即注册
搜索
查看: 8702|回复: 2

用Ogre画三角形

[复制链接]

1万

主题

1万

帖子

2万

积分

管理员

中级会员

Rank: 9Rank: 9Rank: 9

积分
20535
发表于 2011-9-19 14:06:00 | 显示全部楼层 |阅读模式
作者:trcj1
博客:FadeIn to Bloom


  成熟图像引擎往往对底层操作做了层层封装,用户或许能轻易地将复杂模型加入到游戏里,却在画一个三角形时摸不着头脑。本文阐述如何在Ogre里画三角形,如果有些许DirectX或者OpenGL的基础知识,理解起来会更加容易。


  1.   Ogre用树结构来组织场景,所有希望被遍历到的实体都需要挂接在树节点下,此类有挂接能
  2. 力的实体需要继承自MovableObject类;而如果实体想被赋予渲染的能力,则要继承Renderable类。
  3. 如此一来,我们的三角形类如下:


  4.         class Triangle : public Ogre::MovableObject, public Ogre::Renderable

  5.   
  6.   接下来要做的基本上就是填充两个父类中的十多个纯虚方法,这里我们仅挑出最主要的几个
  7. 进行说明。

  8.   1. 来自MovableObject的_updateRenderQueue()函数。它在场景遍历到本实体时被调用,你
  9. 可以选择此时将待渲染的对象加入到渲染队列中,由于我们的三角形本身即继承自Renderable,
  10. 所以我们将自己加入到队列里:


  11. void Triangle::_updateRenderQueue(Ogre::RenderQueue* queue)
  12. {
  13.         queue->addRenderable(this);
  14. }


  15.   2. 接着是来自Renderable的getRenderOperation()函数。它在渲染队列稍后遍历每一个待渲
  16. 单位时被调用,你需要选择这个时刻把渲染相关的数据(顶点数据、组织方式、数目、索引等等)
  17. 以RenderOperation数据结构的形式提交给引擎。可见RenderOperation决定了你将渲染出何种东西,
  18. 其实本文展示的核心即是对RenderOperation的定制。

  19.   我们在初始化三角形时构建RenderOperation相关数据:


  20. void Triangle::_createBuffers()
  21. {
  22.         // 三角形的三个顶点位置数据
  23.         float vertices[3][3] = {
  24.                 -1.0f, 1.0f, 0.0f,        // 0 position
  25.                 1.0f, 1.0f, 0.0f,        // 1 position
  26.                 0.0f, -1.0f, 0.0f,        // 2 position
  27.         };

  28.         // 顶点颜色
  29.         Ogre::RenderSystem* rs = Ogre::Root::getSingleton().getRenderSystem();
  30.         Ogre::RGBA colours[3];
  31.         rs->convertColourValue(Ogre::ColourValue(1.0f, 0.0f, 0.0f), &colours[0]);        // 0 colour
  32.         rs->convertColourValue(Ogre::ColourValue(0.0f, 1.0f, 0.0f), &colours[1]);        // 1 colour
  33.         rs->convertColourValue(Ogre::ColourValue(0.0f, 0.0f, 1.0f), &colours[2]);        // 2 colour

  34.         // 顶点索引
  35.         Ogre::ushort faces[3] = {
  36.                 0, 1, 2,        // 0 face
  37.         };

  38.         // 创建VertexData对象管理顶点数据
  39.         mVertexData = new Ogre::VertexData();
  40.         mVertexData->vertexStart = 0;
  41.         mVertexData->vertexCount = 3;

  42.         Ogre::VertexDeclaration* decl = mVertexData->vertexDeclaration;
  43.         Ogre::VertexBufferBinding* binding = mVertexData->vertexBufferBinding;

  44.         // 设置顶点声明,我们的顶点声明仅有一个数据流且只包含位置、颜色
  45.         size_t offset = 0;
  46.         decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
  47.         offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
  48.         decl->addElement(0, offset, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE);
  49.         offset += Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR);

  50.         // 创建顶点缓存并将顶点数据填充进去
  51.         Ogre::HardwareVertexBufferSharedPtr vertexBuffer = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
  52.                 decl->getVertexSize(0), 3,
  53.                 Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
  54.         float* lockPtr = static_cast<float*>(vertexBuffer->lock(0, vertexBuffer->getSizeInBytes(), Ogre::HardwareBuffer::HBL_DISCARD));
  55.         Ogre::RGBA* pCol;
  56.         for (int i = 0; i < 3; ++i)
  57.         {
  58.                 *lockPtr++ = vertices[i][0];
  59.                 *lockPtr++ = vertices[i][1];
  60.                 *lockPtr++ = vertices[i][2];
  61.                 pCol = static_cast<Ogre::RGBA*>(static_cast<void*>(lockPtr));
  62.                 *pCol++ = colours[i];
  63.                 lockPtr = static_cast<float*>(static_cast<void*>(pCol));
  64.         }
  65.         vertexBuffer->unlock();

  66.         // 将顶点缓存绑定到0号数据流
  67.         binding->setBinding(0, vertexBuffer);

  68.         // 创建IndexData对象管理顶点索引
  69.         mIndexData = new Ogre::IndexData();
  70.         mIndexData->indexStart = 0;
  71.         mIndexData->indexCount = 3;
  72.        
  73.         // 创建顶点索引缓存并填充数据
  74.         mIndexData->indexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
  75.                 Ogre::HardwareIndexBuffer::IT_16BIT,
  76.                 mIndexData->indexCount,
  77.                 Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
  78.         mIndexData->indexBuffer->writeData(0, mIndexData->indexBuffer->getSizeInBytes(), faces, true);

  79.         // 设置包围盒
  80.         mAABB.merge(Ogre::Vector3(vertices[0][1], vertices[0][2], vertices[0][3]));
  81.         mAABB.merge(Ogre::Vector3(vertices[1][1], vertices[1][2], vertices[1][3]));
  82.         mAABB.merge(Ogre::Vector3(vertices[2][1], vertices[2][2], vertices[2][3]));
  83.         mBoundingRadius = Ogre::Math::boundingRadiusFromAABB(mAABB);
  84. }
  85.   

  86.   然后在getRenderOperation()函数中将其提交上去:
  87.   

  88. void Triangle::getRenderOperation(Ogre::RenderOperation& op)
  89. {
  90.         op.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
  91.         op.useIndexes = true;
  92.         op.vertexData = mVertexData;
  93.         op.indexData = mIndexData;
  94. }


  95.   3. 最后还需要提一下来自Renderable的getMaterial()函数,顾名思义,引擎籍此获知待渲物
  96. 体的材质,这里我们创建一个只使用物体顶点色的材质:


  97.         Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().create("TriangleMaterial", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
  98.         material->getTechnique(0)->getPass(0)->setLightingEnabled(false);
  99.         material->getTechnique(0)->getPass(0)->setCullingMode(Ogre::CULL_NONE);


  100.   之后这个材质将通过setMaterialName()函数赋给三角形以供其渲染时刻提交。

  101.   完成了以上步骤,在主构建函数里进行如下调用:
  102.   

  103.         Ogre::SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode("TriangleNode");
  104.         mTriangle = new Triangle();
  105.         mTriangle->setMaterialName("TriangleMaterial");
  106.         node->attachObject(mTriangle);


  107.   运行程序,你将看到一枚彩色的三角形。
复制代码

  


  某种程度上,在3D世界里,学会了画三角形,你就学会了画任何东西。

  文章配套工程源码可移步此处下载:http://download.csdn.net/source/3562886,开发环境为VS2008+ Ogre1.7.3。

下载配套代码

3

主题

53

帖子

104

积分

注册会员

Rank: 2

积分
104
发表于 2011-9-19 20:39:00 | 显示全部楼层

Re:用Ogre画三角形

Ogre中有个ManualObject,用来画这些基本型可方便多啦

0

主题

107

帖子

109

积分

注册会员

Rank: 2

积分
109
发表于 2011-9-20 11:29:00 | 显示全部楼层

Re:用Ogre画三角形

学了OPENGL之后不久就把这套基本型的算法给扔掉了。。。
工作中基本用不到,现在都是直接贴图的。。。
三角函数倒是一直在用。。。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-7-19 14:50

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表