1.OGRE简介
OGRE(Object -Oriented Grapjics Rendering Engine),即面向对象的3D引擎,诞生于1999年。它是为了让开发人员更加容易、更直接地利用硬件加速的3D图形系统开发应用。这类库隐藏了底层系统库Direct3D和OpenGL的所有细节,并支持多种高级特性,提供了一个基于现实世界对象和其他直观类的接口。
OGRE几乎拥有了商业3D渲染引擎的全部特性,甚至有些方面超越了它们:(1)自动处理渲染状态和空间裁剪;(2)支持所有纹理混合和绑定技术,同时支持对GPU编程技术,支持汇编语言和所有高级语言形式的各种着色器,其中高级语言包括:Cg、HLSL和GLSL;(3)强大且成熟的材质管理和脚本系统,可以不动一行代码去进行材质维护;(4)支持多种纹理图片格式,包括:PNG、TGA、DDS、TIF、GIF、JPG,同时支持特殊格式的纹理;(5)全面支持对顶点和索引缓存(Vertex and index buffers)、顶点声明(vertex delcarations)以及贴图缓存(bufffer mappings);(6)给出以插件方式链接不同场景结构的接口,允许你使用适合自己应用程序的场景体系;(7)成熟且可扩展的资源管理和载人系统,文件系统所支持的文件包括Zip,pk3格式等。
参考文章:三维渲染引擎OGRE与OSG的比较综述
2.OGRE基本类
(图片源自OGRE API)
最上面的是Root对象,是我们进入OGRE系统的方式,它包括了场景管理器,渲染系统和渲染窗口,加载插件等所有基本的东西。
大部分OGRE的其他类分为3种:
(1)Scene Management(场景管理)
它是关于场景的内容,如何构造,从摄像机看它的方式等,你只需要告诉它你想在哪几个位置,用什么材料,从哪个视角观察,它便可以完成工作。
(2)Resource Mangement(资源管理)
不论是几何,纹理,字体还是其他的渲染都需要资源,对这些资源的架加载,重新使用及卸载进行仔细管理是十分重要的。
(3)Rendering(渲染)
最后,需要在屏幕上显示-这是关于渲染管线的低级,特定渲染系统API对象(如缓冲区,渲染状态等)以及把它送入渲染管线。场景管理子系统中的类用它来获得高等级的屏幕场景信息。
3.The Root object
Ogre::Root对象是OGRE系统的入口。这个对象必须先被创建,最后被销毁。
root对象允许我们配置系统,比如Ogre::Root::showConfigDialog方法(这是一个非常方便的方法),它执行所有渲染系统选项检测并显示一个对话框,供用户自定义分辨率,颜色深度,全屏选项等。它还设置用户选择的选项,以便我们可以直接初始化系统。
root对象也是我们获取系统中其他对象指针的方法,比如Ogre::SceneManger,Ogre::RenderSystem和其他资源管理器。
如果在连续渲染模式下运行OGRE,即希望始终尽快刷新所有渲染目标(游戏和演示的规范,而不是窗口实用程序的规范),root对象有一个名为 Root :: startRendering的方法,当被调用时将进入一个连续的渲染循环,它只会在所有渲染窗口关闭或者任何Ogre :: FrameListener对象表明他们想要停止循环时结束。
4.The RenderSystem object
Ogre::RenderSystem类是一个定义底层3D API接口的抽象类。它负责将渲染操作发送到API并设置所有各种渲染选项。此类是抽象的,因为所有实现都是特定于呈现API的 - 每个呈现API都有特定于API的子类(例如,DirectDD的D3DRenderSystem)。 在通过Ogre :: Root :: initialise初始化系统之后,可以通过Ogre :: Root :: getRenderSystem()方法获得所选渲染API的Ogre :: RenderSystem对象。
但是,典型的应用程序通常不需要直接操作Ogre :: RenderSystem对象 - 在Ogre :: SceneManager,Material和其他面向场景的类上应该可以获得渲染对象和自定义设置所需的一切。除非你想要创建多个渲染窗口(在这种情况下完全独立的窗口,而不是像通过RenderWindow类完成的分屏效果的多个视口)或访问需要访问RenderSystem对象的其他高级功能。
5.The Scene Manager Object
除了Ogre :: Root对象之外,从应用程序的角度来看,这可能是系统中最关键的部分。当然它将是应用程序最常使用的对象。 Ogre :: SceneManager负责引擎要渲染的场景内容。 它负责使用它认为最好的任何技术来组织内容,用于创建和管理所有相机,可移动对象(实体),灯光和材料(对象的表面属性),以及管理“世界几何” (这是一种庞大的静态几何体,通常用于表示场景的不可移动部分)。
当你想为场景创建一个摄像机时,你用的是SceneManager。 它也是您从场景中检索或移除灯光的地方。 您的应用程序不需要保留对象列表,如果需要,SceneManager会保留所有场景对象的命名集供您访问。
当渲染场景时,SceneManager还将场景发送到RenderSystem对象。 您永远不必直接调用Ogre :: SceneManager :: _ renderScene方法 - 每当要求渲染目标更新时,它都会自动调用。
因此,与SceneManager的大多数交互都是在场景设置期间进行的。 您可能会调用大量方法(可能由包含场景数据的某个输入文件驱动)以设置场景。 如果创建自己的FrameListener对象,也可以在渲染周期中动态修改场景的内容。
由于不同的场景类型需要非常不同的算法方法来决定将哪些对象发送到RenderSystem以获得良好的渲染性能,因此SceneManager类被设计为针对不同场景类型进行子类化。默认的SceneManager对象将渲染场景,但它很少或没有场景组织,在大场景的情况下,你不应期望结果是高性能的。目的是为每种类型的场景创建专门化,使得在表面下,子类将优化场景组织以获得最佳性能,给出可以对该场景类型做出的假设。一个例子是BspSceneManager,它基于二进制空间分区(BSP)树优化大型室内级别的渲染。
使用OGRE的应用程序不必知道哪些子类可用。应用程序只是调用Ogre :: Root :: createSceneManager(..)作为参数传递许多场景类型之一(例如Ogre :: ST_GENERIC,Ogre :: ST_INTERIOR等)。 OGRE将自动使用可用于该场景类型的最佳SceneManager子类,或者如果没有实参,则默认使用基本的SceneManager。 这允许OGRE的开发者稍后添加新的场景特化,从而优化先前未优化的场景类型,而无需用户应用程序改变任何代码。
6.The ResourceGroupManger Object
Ogre :: ResourceGroupManager类实际上是用于加载可重用资源(如纹理和网格)的“中心”。它是你为资源定义组的地方,因此可以在需要时卸载和重新加载它们。服务它的是许多资源管理器,它们管理各种类型的资源,如Ogre :: TextureManager或Ogre :: MeshManager。
ResourceManagers确保资源仅加载一次并在整个OGRE引擎中共享。他们还管理他们所关注资源的内存需求。他们还可以在多个位置搜索所需的资源,包括多个搜索路径和压缩档案(ZIP文件)。
大多数情况下,您不会直接与资源管理器进行交互。资源管理器将根据需要由OGRE系统的其他部分调用,例如,当您请求将纹理添加到Material时,将为您调用Ogre :: TextureManager。如果您愿意,可以直接调用相应的资源管理器来预加载资源(例如,如果您希望稍后阻止磁盘访问),但大多数时候可以让OGRE决定何时执行此操作。
您要做的一件事是告诉资源管理器在哪里寻找资源。 您可以通过Ogre :: ResourceGroupManager :: addResourceLocation执行此操作。
正如其名称所述,ResourceGroupManager将资源组织在Groups中。这些定义了一组应作为一个单元加载/卸载的资源。例如,它可能是用于游戏关卡的所有资源。 默认情况下,使用“常规”组,该组仅在关闭时卸载。 要定义自己的组,请使用Ogre :: ResourceGroupManager :: createResourceGroup。
因为引擎中每个资源管理器只有1个实例,所以如果你想获取对资源管理器的引用,请使用以下语法:
Ogre::TextureManager::getSingleton().someMethod()
Ogre::MeshManager::getSingleton().someMethod()
7.The Mesh Object
Ogre :: Mesh对象表示离散模型,这是一组自包含的几何体,通常在世界范围内相当小。假设Ogre :: Mesh对象表示可移动对象,并且不用于通常用于创建背景的蔓延级别几何体。
Ogre :: Mesh对象是一种资源,由MeshManager资源管理器管理。 它们通常从OGRE的自定义对象格式“.mesh”格式加载。网格文件通常通过从建模工具导出来创建,并且可以通过各种网格工具进行操作。
mesh对象是世界上各个可移动物体的基础,称为实体。
8.Entities
实体是场景中可移动对象的实例。 它可以是汽车,人,狗,手里剑,等等。 唯一的假设是它不一定在世界上有固定的位置。
实体基于离散网格,即几何的集合,它们是自包含的并且通常在世界范围内相当小,由Ogre :: Mesh对象表示。 多个实体可以基于相同的网格,因为通常您希望在场景中创建相同类型对象的多个副本。
您可以通过调用Ogre :: SceneManager :: createEntity方法创建一个实体,为其指定名称并指定它将基于的网格对象的名称(例如'muscleboundhero.mesh')。 Ogre :: SceneManager将通过为您调用Ogre :: MeshManager资源管理器来确保加载网格。 只会加载一个Mesh副本。
在将它们附加到Ogre :: SceneNode之前,Ogre :: Entities不被视为场景的一部分(参见下面的部分)。 通过将实体附加到SceneNodes,您可以在实体的位置和方向之间创建复杂的层次关系。 然后,您可以修改节点的位置以间接影响实体位置。
当加载Ogre :: Mesh时,它会自动定义许多材料。可以将多个材料附着到mesh上 - mesh的不同部分可以使用不同的材料。从mesh创建的任何实体都将自动使用默认材质。 但是,如果你愿意,可以在每个实体的基础上更改此设置,以便你可以基于相同的网格但使用不同的纹理等创建多个实体。
要了解其工作原理,您必须知道所有Mesh对象实际上都是由Ogre :: SubMesh对象组成,每个对象使用一个Material表示网格的一部分。 如果Ogre :: Mesh只使用一个Ogre :: Material,它将只有一个Ogre :: SubMesh。
当基于此Mesh创建Ogre :: Entity时,它由(可能)多个Ogre :: SubEntity对象组成,每个对象与原始Mesh中的Ogre :: SubMesh对象1对1匹配。 您可以使用Ogre :: Entity :: getSubEntity方法访问Ogre :: SubEntity对象。 一旦引用了Ogre :: SubEntity,就可以通过调用它的setMaterialName方法来更改它使用的材质。 通过这种方式,您可以使Ogre :: Entity偏离默认材质,从而创建一个单独的外观版本。
9.Materials
Ogre :: Material对象控制场景中对象的渲染方式。它指定了对象具有的基本表面属性,例如颜色的反射率,光泽度等,存在多少纹理图层,图像在它们上面以及如何将它们混合在一起,应用了哪些特殊效果,例如环境贴图,什么是剔除模式 使用,如何过滤纹理等。
可以通过编程方式设置材质,方法是调用Ogre :: MaterialManager :: create并调整设置,或者在运行时加载的“脚本”中指定它。
基本上,除了它的形状外,关于物体外观的所有内容都由Material类控制。
Ogre :: MaterialManager类管理场景可用的主材料列表。 应用程序可以通过调用Ogre :: MaterialManager :: create或通过加载Mesh(它将加载材料属性)来添加列表。
默认设置以单个技术开始,具有单个不可编程的通道:
ambient = ColourValue::White
diffuse = ColourValue::White
specular = ColourValue::Black
emissive = ColourValue::Black
shininess = 0 (not shiny)
No texture unit settings (& hence no textures)
SourceBlendFactor = Ogre::SBF_ONE
DestBlendFactor = Ogre::SBF_ZERO (no blend, replace with new colour)
Depth buffer checking on
Depth buffer writing on
Depth buffer comparison function = Ogre::CMPF_LESS_EQUAL
Colour buffer writing on for all channels
Culling mode = Ogre::CULL_CLOCKWISE
Ambient lighting = ColourValue(0.5, 0.5, 0.5) (mid-grey)
Dynamic lighting enabled
Gourad shading mode
Bilinear texture filtering
您可以通过调用Ogre :: MaterialManager :: getDefaultSettings()并对返回的Material进行必要的更改来更改这些设置。
如果实体使用Ogre :: Mesh对象,则实体会自动将Material与它们相关联,因为Ogre :: Mesh对象通常会在加载时设置它所需的材质。你还可以按实体中的说明自定义实体使用的材料。 只需创建一个新材质,按你喜欢的方式设置它(如果你喜欢使用标准赋值语句,可以将现有材质复制到其中)并使用Ogre :: SubEntity :: setMaterialName()将SubEntity条目指向它。
10.Overlays
叠加允许您在正常场景内容之上渲染2D和3D元素,以创建像平视显示器(HUD),菜单系统,状态面板等效果。OGRE标准的帧速率统计面板是叠加的示例。叠加层可以包含2D或3D元素。 2D元素用于HUD,3D元素可用于创建驾驶舱或您希望在场景的其余部分上呈现的任何其他3D对象。
您可以通过Ogre :: OverlayManager :: create方法创建叠加层,也可以在.overlay脚本中定义叠加层.实际上后者可能是最实用的,因为它更容易调整(无需重新编译代码)。请注意,你可以根据需要定义尽可能多的叠加层:它们都隐藏起来,并通过调用Ogre :: Overlay :: show来显示它们。 你还可以一次显示多个叠加层,它们的Z顺序由Ogre :: Overlay :: setZOrder()方法确定。
关于整合的说明
OverlaySystem是它自己的组件,需要手动初始化它,使用以下两行代码(mSceneMgr是指向当前Ogre :: SceneManager的指针):
Ogre::OverlaySystem* pOverlaySystem = new Ogre::OverlaySystem();
mSceneMgr->addRenderQueueListener(pOverlaySystem);
向叠加层添加2D元素
只有OverlayContainers可以直接添加到叠加层。 原因是每个级别的容器都建立了包含在其中的元素的Zorder,因此如果嵌套多个容器,则内部容器具有比外部容器更高的Z顺序,以确保它们正确显示。 要向叠加层添加容器(例如Panel),只需调用Ogre :: Overlay :: add2D即可。
如果要将子元素添加到该容器,请调用Ogre :: OverlayContainer :: addChild。 子元素可以是Ogre :: OverlayElements或Ogre :: OverlayContainer实例本身。 请记住,子元素的位置相对于其父元素的左上角。
关于2D坐标的词
OGRE允许您根据2个坐标系放置和调整元素:relative and pixel based
Pixel Mode(像素模式)
当你想要为叠加项目指定确切大小时,此模式非常有用,如果提高屏幕分辨率(实际上你可能想要这样),您不介意屏幕上的这些项目是否变小。在此模式下,以任何分辨率可靠地放置屏幕中间或右侧或底部的唯一方法是使用对齐选项,而在相对模式下,只需使用正确的相对坐标即可。此模式非常简单,屏幕的左上角是(0,0),屏幕的右下角取决于分辨率。如上所述,如果要在不知道分辨率的情况下将像素项放置在这些位置,可以使用对齐选项使水平和垂直坐标原点位于屏幕的右侧,底部或中心。
Relative Mode(相对模式)
无论分辨率如何,当你希望覆盖中的项目在屏幕上具有相同的大小时,此模式非常有用。
在相对模式中,屏幕的左上角是(0,0),右下角是(1,1)。 因此,如果将元素放置在(0.5,0.5),则无论应用程序运行的分辨率如何,它的左上角都会准确放置在屏幕的中心。同样的原则适用于大小; 如果将元素的宽度设置为0.5,它占据了屏幕宽度的一半。请注意,因为屏幕的宽高比通常为1.3333:1(宽度:高度),所以尺寸为(0.25,0.25)的元素将不是正方形,但它将占据屏幕面积的1/16。如果你想要方形区域,你将不得不使用典型的宽高比进行补偿,例如: 请改用(0.1875,0.25)。
Transforming Overlays
叠加的另一个很好的功能是能够旋转,滚动和缩放它们作为一个整体。 你可以使用它来放大/缩小菜单系统,从屏幕外放下它们和其他好的效果。
11.GUI system
尽管您可以使用Trays系统创建简单的GUI,但叠加层仅适用于非交互式屏幕元素。
以上内容参考自 OGRE API