Irrlicht引擎

2024-01-12 14:58
文章标签 引擎 irrlicht

本文主要是介绍Irrlicht引擎,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、Irrlicht引擎简介

Irrlicht引擎是一个用C++编写的高性能实时3D引擎。该引擎支持底层图形接口Direct3DOpenGL,并且自带了软件渲染的实现。Irrlicht引擎还提供了诸如动态阴影,粒子系统,角色动画,室内和室外技术以及碰撞检测等功能特性。

Irrlicht是一个德国神话故事中的一种动物的名字,它能够发光和飞翔,可以在大部分的沼泽地附近发现它。单词"Irrlicht"是两个德国单词("irr"意思是疯狂的;而"Licht"意思是光)的组合。在英语中,它被译为"鬼火"。 

二、Irrlicht引擎的组成结构

Irrlicht引擎共分为五部分:

1)Core

该部分由一些容器类及数学库组成,如stringvector等。

对应的名字空间为:namespace irr::core

2)Scene

该部分主要负责三维场景的绘制及管理,包括场景节点,摄像机,粒子系统、mesh 资源,公告板,灯光,动画器,天空体,地形等。

Irrlicht的场景中的所有的东西都是场景节点,统一由场景管理器来管理。

对应的名字空间为:namespace irr::scene

3)Video

该部分主要负责图片纹理的载入及管理,包括纹理,材质,灯光,图片,顶点等渲 染属性的控制。

对应的名字空间为:namespace irr::video

4)GUI

该部分包括了一些二维GUI控件

对应的名字空间为:namespace irr::gui

5)FileSystem

该部分负责文件系统的读写。

对应的名字空间为:namespace irr::io

三、Irrlicht编程步骤

1、获取设备指针

在编写任何一个Irrlicht程序时,首选需要做的就是获取设备指针 

IrrlichtDevice  *device :

 video::E_DRIVER_TYPE driver_type = irr::video::EDT_OPENGL;   

 core::dimension2d<s32> screen_resolution = core::dimension2d<s32>(1280, 800);   

 u32 color_depth = 32;   

 bool is_full_screen = true;   

   

 IrrlichtDevice* device = irr::createDevice(driver_type, screen_resolution, color_depth, is_full_screen); 

driver_type为驱动类型,可以选择OPENGLDX8 或 DX9。其余几个参数分别为分辨率,颜色 深度,是否全屏。

获得 device 指针以后,就可以得到属于该 device 的四大块功能:

video::IVideoDriver* driver = device->getVideoDriver();   

scene::ISceneManager* scene_mgr = device->getSceneManager();   

gui::IGUIEnvironment* gui_env = device->getGUIEnvironment();   

io::IFileSystem* file_system = device->getFileSystem();  

2、创建3D场景

创建3D场景有三个步骤:

(1) 通过场景管理器scene_mgr添加3D物体

 // 为场景添加一个立方体,边长100  

 scene::ISceneNode* cube = scene_mgr->addCubeSceneNode(100.0f);   

(2) 为3D物体贴上纹理:

 // 载入纹理  

 video::ITexture* tex = driver->getTexture("box.jpg");   

   

 // 将纹理附加到立方体上  

 cube->setMaterialTexture(0, tex);   

   

 // 将纹理EMF_LIGHTING属性设为false  

 // 表示该纹理现实与光源无关,即为图片自身颜色  

 cube->setMaterialFlag(video::EMF_LIGHTING, false);   

   

 // 使纹理支持半透明,半透明效果与图片相同  

 cube->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL);   

(3) 添加Camera,使物体可见

 // 添加一个相机,在(700,700,-700)位置,往(0,0,0)位置拍摄。  

 scene::ICameraSceneNode* camera = scene_mgr->addCameraSceneNode(0,    

     core::vector3df(700,700,-700), core::vector3df(0,0,0));  

3、进入主循环

通过 driver 载入图片和 texture,通过 scene_mgr 3d场景添加 irrlicht 内置支持的3D对象等工作后,即可进入主循环,主循环结束时,释放 device,程序结束。其中 beginScene 的参数 SColor(alpha, r, g, b) 为背景色

1 while (device->run())   

2 {   

3     if (device->isWindowActive())   

4     {   

5         driver->beginScene(true, true, video::SColor(0, 0, 0, 0));   

6         scene_mgr->drawAll();   

7         gui_env->drawAll();   

8         driver->endScene();   

9     }   

10 }   

11 device->drop();  

值得一提的是 drop() 函数。Irrlicht中大部分类都继承自一个 IReferenceCounted 的接口,类似智能指针。Irrlicht 中的惯例是不使用 delete 删除对象,而调用该接口的 drop() 函数。在添加对象的引用时,调用 grap() 函数。

四、Irrlicht引擎之场景中的对象结构

3D对象在场景中被组织成一个树形结构,在该树中,仅有一个根节点。当在程序的主循环中调用scene_mgr->drawAll()时,系统会从场景的树形结构的根节点开始递归绘制所有的节点对象。

每一个节点对象都维护了一个“动画效果”ISceneNodeAnimator列表:

core::list<ISceneNodeAnimator*> Animators;

在绘制每一个节点对象之前,都会将其所维护的所有动画效果应用到该节点上。

“动画效果”的原理是,当节点每次被绘制之前,均先根据其维护的动画对象Animators来计算出该节点的位置、大小、纹理。这样,当一个节点不断被绘制时,就产生了动画效果。

五、Irrlicht引擎之3D对象运动原理

所谓运动,实际上是计算机在不停地绘制场景,每绘制一次称之为一帧。 当各帧中物体的位置或外观有所变化,那么它就动起来了。 在irrlicht中,绘制一帧是在run循环中完成的:

1 while (device->run())   

2 {   

3     if (device->isWindowActive())   

4     {   

5         driver->beginScene(true, true, video::SColor(0, 0, 0, 0));   

6         scene_mgr->drawAll();  // 绘制一帧  

7         driver->endScene();   

8     }   

9 }   

10 device->drop();  

我们所要做的,就是在 drawAll() 函数中,更新物体的位置及大小等属性,那么场景就动起来了。

在Irrlicht中,所有与运动相关的一切,都与 scene::ISecenNodeAnimator 这个接口相关。凡是实现这个接口的类实例,都可以通过 addAnimator() 函数加入到 ISceneNode 所维护的animators列表中。 

SceneManager drawAll() 函数在渲染(render)场景前,会调用其OnAnimate() 函数。这个函数是递归的,以保证加入场景中的每个 SceneNode 会被调用。 在OnAnimate() 函数中, SceneNode 的每一个 ISecenNodeAnimator 的 animateNode() 函数都会被调用,以更新 SceneNode 的位置、大小或纹理等属性。 

其具体的调用顺序如下: 

1. SceneManager           --> drawAll()                 绘制一帧画面

2. ISceneNode             --> OnAnimate()              SceneNode运动  

3. ISceneNodeAnimator --> animateNode(ISceneNode)      实现运动的具体函数

4. SceneManager           --> render()                  渲染

 

可见,只要实现 ISecenNodeAnimator 接口,并加入到 SceneNode 中,就能够让该SceneNode 运动起来。而至于具体如何运动,完全可由自己来定义。

六、Irrlicht引擎之消息传递原理

Irrlicht引擎中消息的传递是从device->run()开始的,首先由具体平台的操作系统接口将接收到的用户消息打包成IrrlichtSEvent结构(这一步打包过程是在device->run()中完成的),再由postEventFromUser()该消息依次传递给UserReceiver, GUI 和 3D Scene

Irrlicht 中所有处理消息的类都必须实现 IEventReciever 接口。UserReceiver 就是在CreateDevice函数中指定的一个 IEventReceiver。 也就是说,消息处理的优先级为 UserReceiver > GUI > 3D Scene

如果在程序中,没有指定UserReceiver和GUI,消息就会直接交给SceneManager

SceneManager 的消息,也由 ISceneManager 的 postEventFromUser() 传递。 这个函数的实现如下:

1 bool CSceneManager::postEventFromUser(const SEvent& event)   

2 {   

3     bool ret = false;   

4     ICameraSceneNode* cam = getActiveCamera();   

5     if (cam)   

6         ret = cam->OnEvent(event);   

7   

8     _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;   

9     return ret;   

10 }  

也就是说,只有当前Active(有效)的 ICameraSceneNode 才会接收到消息。ICameraSceneNode 会检测ISceneNodeAnimator isEventReceiverEnabled(), 如果为真则调用其OnEvent 函数。 

整理消息传递的机制如下:

 

1. IrrlichtDevice           --> run()                      搜集消息并打包

2. IrrlichtDevice           --> postEventFromUser()    传递消息到userReceiver     GUI 和 Scene

3. ISceneManager         --> postEventFromUser()       传递消息到CameraNode

4. ICameraSceneNode     --> onEvent()                  调用 Animator onEvent

5. ISceneNodeAnimator    --> onEvent()  // if enabled      响应消息。

 

可见,实现 ISceneNodeAnimator 虽然可以 SceneNode 动起来,但只有在 ICameraSceneNode 上,才能够接收和处理消息。

 

这篇关于Irrlicht引擎的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/598236

相关文章

MySQL之InnoDB存储引擎中的索引用法及说明

《MySQL之InnoDB存储引擎中的索引用法及说明》:本文主要介绍MySQL之InnoDB存储引擎中的索引用法及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录1、背景2、准备3、正篇【1】存储用户记录的数据页【2】存储目录项记录的数据页【3】聚簇索引【4】二

SpringBoot集成LiteFlow工作流引擎的完整指南

《SpringBoot集成LiteFlow工作流引擎的完整指南》LiteFlow作为一款国产轻量级规则引擎/流程引擎,以其零学习成本、高可扩展性和极致性能成为微服务架构下的理想选择,本文将详细讲解Sp... 目录一、LiteFlow核心优势二、SpringBoot集成实战三、高级特性应用1. 异步并行执行2

LiteFlow轻量级工作流引擎使用示例详解

《LiteFlow轻量级工作流引擎使用示例详解》:本文主要介绍LiteFlow是一个灵活、简洁且轻量的工作流引擎,适合用于中小型项目和微服务架构中的流程编排,本文给大家介绍LiteFlow轻量级工... 目录1. LiteFlow 主要特点2. 工作流定义方式3. LiteFlow 流程示例4. LiteF

SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程

《SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程》LiteFlow是一款专注于逻辑驱动流程编排的轻量级框架,它以组件化方式快速构建和执行业务流程,有效解耦复杂业务逻辑,下面给大... 目录一、基础概念1.1 组件(Component)1.2 规则(Rule)1.3 上下文(Conte

Python基于微信OCR引擎实现高效图片文字识别

《Python基于微信OCR引擎实现高效图片文字识别》这篇文章主要为大家详细介绍了一款基于微信OCR引擎的图片文字识别桌面应用开发全过程,可以实现从图片拖拽识别到文字提取,感兴趣的小伙伴可以跟随小编一... 目录一、项目概述1.1 开发背景1.2 技术选型1.3 核心优势二、功能详解2.1 核心功能模块2.

MySQL 存储引擎 MyISAM详解(最新推荐)

《MySQL存储引擎MyISAM详解(最新推荐)》使用MyISAM存储引擎的表占用空间很小,但是由于使用表级锁定,所以限制了读/写操作的性能,通常用于中小型的Web应用和数据仓库配置中的只读或主要... 目录mysql 5.5 之前默认的存储引擎️‍一、MyISAM 存储引擎的特性️‍二、MyISAM 的主

MySQL常见的存储引擎和区别说明

《MySQL常见的存储引擎和区别说明》MySQL支持多种存储引擎,如InnoDB、MyISAM、MEMORY、Archive、CSV和Blackhole,每种引擎有其特点和适用场景,选择存储引擎时需根... 目录mysql常见的存储引擎和区别说明1. InnoDB2. MyISAM3. MEMORY4. A

MySQL InnoDB引擎ibdata文件损坏/删除后使用frm和ibd文件恢复数据

《MySQLInnoDB引擎ibdata文件损坏/删除后使用frm和ibd文件恢复数据》mysql的ibdata文件被误删、被恶意修改,没有从库和备份数据的情况下的数据恢复,不能保证数据库所有表数据... 参考:mysql Innodb表空间卸载、迁移、装载的使用方法注意!此方法只适用于innodb_fi

Python基于火山引擎豆包大模型搭建QQ机器人详细教程(2024年最新)

《Python基于火山引擎豆包大模型搭建QQ机器人详细教程(2024年最新)》:本文主要介绍Python基于火山引擎豆包大模型搭建QQ机器人详细的相关资料,包括开通模型、配置APIKEY鉴权和SD... 目录豆包大模型概述开通模型付费安装 SDK 环境配置 API KEY 鉴权Ark 模型接口Prompt

速了解MySQL 数据库不同存储引擎

快速了解MySQL 数据库不同存储引擎 MySQL 提供了多种存储引擎,每种存储引擎都有其特定的特性和适用场景。了解这些存储引擎的特性,有助于在设计数据库时做出合理的选择。以下是 MySQL 中几种常用存储引擎的详细介绍。 1. InnoDB 特点: 事务支持:InnoDB 是一个支持 ACID(原子性、一致性、隔离性、持久性)事务的存储引擎。行级锁:使用行级锁来提高并发性,减少锁竞争