开源3D游戏引擎Irrlicht简介
Irrlicht简介
Irrlicht在国内也被叫做“鬼火”引擎,是一款用C++编写的开放源代码的高性能游戏引擎。而且是跨平台的,具有很好的移植性,Irrlicht支持OpenGl、Direcx3D渲染,引擎本身也实现了一套自己的渲染系统。在商业引擎中能够找到的艺术特性,Irrlicht基本都支持。目前有很多项目中都使用到它,Irrlicht社区也比较活跃,可以在互联网上找到不少Irrlicht增强工具,例如irrEdit、irrKlang等。在众多开源游戏引擎中,Irrlicht也是比较受笔者青睐的一款。
Irrlicht官方网站:http://irrlicht.sourceforge.net/
Irrlicht下载与使用
Irrlicht目前最新稳定版本为1.8.1,项目发布在sourceforge平台上,用户可以通过sourceforge网站首页面搜索功能找到Irrlicht项目下载地址,或者从Irrlicht官网获取下载链接。
下载地址:http://irrlicht.sourceforge.net/downloads/
1.目录结构
解压后目录结构如下:
bin:不同平台编译Irrlicht生成的可执行文件和动态库文件放在该目录中。
doc : 该目录中为Irrlicht API文档。
examples : Irrlicht官方提供的案例程序存放在该目录中。
include : 存放引擎所有头文件。
lib : 该目录存放Irrlicht引擎编译过后生成的静态库。
media : 官方案例所需资源文件存放在此目录中。
source : 存放引擎源码。
tools : 该目录下为Irrlicht引擎相关工具。如irrEdit、GUIEditor等。
2.官方案例
Irrlicht使用起来是非常方便的,这也是笔者比较喜欢它的原因之一。为了方便用户学习和使用引擎,Irrlicht官方提供了大量的例子程序,而且都比较具有代表性。
打开examples目录,Irrlicht已经为目前主流开发工具Windows平台下Visual Studio、MacOS下的Xcode以及Linux平台下的GNU MAKE做好了项目配置。
笔者是在Windows操作系统下使用VS2012进行演示,双击BuildAllExamples_vc11.sln打开解决方案,无需做任何配置即可编译运行程序。
编译运行Collision案例程序:
看起来效果是不是很炫呢?Irrlicht为我们做了大量的封装,即便看似如此复杂的程序,实际代码不超过200行。
#include <irrlicht.h>
#include "driverChoice.h"
using namespace irr;
#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif
enum
{
ID_IsNotPickable = 0,
IDFlag_IsPickable = 1 << 0,
IDFlag_IsHighlightable = 1 << 1
};
int main()
{
video::E_DRIVER_TYPE driverType=video::EDT_OPENGL;//driverChoiceConsole();
if (driverType==video::EDT_COUNT)
return 1;
IrrlichtDevice *device =
createDevice(driverType, core::dimension2d<u32>(1024, 768), 16, false);
if (device == 0)
return 1; // could not create selected driver.
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
device->getFileSystem()->addFileArchive("../../media/map-20kdm2.pk3");
scene::IAnimatedMesh* q3levelmesh = smgr->getMesh("20kdm2.bsp");
scene::IMeshSceneNode* q3node = 0;
if (q3levelmesh)
q3node = smgr->addOctreeSceneNode(q3levelmesh->getMesh(0), 0, IDFlag_IsPickable);
scene::ITriangleSelector* selector = 0;
if (q3node)
{
q3node->setPosition(core::vector3df(-1350,-130,-1400));
selector = smgr->createOctreeTriangleSelector(
q3node->getMesh(), q3node, 128);
q3node->setTriangleSelector(selector);
}
scene::ICameraSceneNode* camera =
smgr->addCameraSceneNodeFPS(0, 100.0f, .3f, ID_IsNotPickable, 0, 0, true, 3.f);
camera->setPosition(core::vector3df(50,50,-60));
camera->setTarget(core::vector3df(-70,30,-60));
if (selector)
{
scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(
selector, camera, core::vector3df(30,50,30),
core::vector3df(0,-10,0), core::vector3df(0,30,0));
selector->drop(); // As soon as we're done with the selector, drop it.
camera->addAnimator(anim);
anim->drop();
}
device->getCursorControl()->setVisible(false);
scene::IBillboardSceneNode * bill = smgr->addBillboardSceneNode();
bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR );
bill->setMaterialTexture(0, driver->getTexture("../../media/particle.bmp"));
bill->setMaterialFlag(video::EMF_LIGHTING, false);
bill->setMaterialFlag(video::EMF_ZBUFFER, false);
bill->setSize(core::dimension2d<f32>(20.0f, 20.0f));
bill->setID(ID_IsNotPickable); // This ensures that we don't accidentally ray-pick it
scene::IAnimatedMeshSceneNode* node = 0;
video::SMaterial material;
node = smgr->addAnimatedMeshSceneNode(smgr->getMesh("../../media/faerie.md2"),
0, IDFlag_IsPickable | IDFlag_IsHighlightable);
node->setPosition(core::vector3df(-90,-15,-140)); // Put its feet on the floor.
node->setScale(core::vector3df(1.6f)); // Make it appear realistically scaled
node->setMD2Animation(scene::EMAT_POINT);
node->setAnimationSpeed(20.f);
material.setTexture(0, driver->getTexture("../../media/faerie2.bmp"));
material.Lighting = true;
material.NormalizeNormals = true;
node->getMaterial(0) = material;
selector = smgr->createTriangleSelector(node);
node->setTriangleSelector(selector);
selector->drop(); // We're done with this selector, so drop it now.
node = smgr->addAnimatedMeshSceneNode(smgr->getMesh("../../media/ninja.b3d"),
0, IDFlag_IsPickable | IDFlag_IsHighlightable);
node->setScale(core::vector3df(10));
node->setPosition(core::vector3df(-75,-66,-80));
node->setRotation(core::vector3df(0,90,0));
node->setAnimationSpeed(8.f);
node->getMaterial(0).NormalizeNormals = true;
node->getMaterial(0).Lighting = true;
selector = smgr->createTriangleSelector(node);
node->setTriangleSelector(selector);
selector->drop();
node = smgr->addAnimatedMeshSceneNode(smgr->getMesh("../../media/dwarf.x"),
0, IDFlag_IsPickable | IDFlag_IsHighlightable);
node->setPosition(core::vector3df(-70,-66,-30)); // Put its feet on the floor.
node->setRotation(core::vector3df(0,-90,0)); // And turn it towards the camera.
node->setAnimationSpeed(20.f);
node->getMaterial(0).Lighting = true;
selector = smgr->createTriangleSelector(node);
node->setTriangleSelector(selector);
selector->drop();
node = smgr->addAnimatedMeshSceneNode(smgr->getMesh("../../media/yodan.mdl"),
0, IDFlag_IsPickable | IDFlag_IsHighlightable);
node->setPosition(core::vector3df(-90,-25,20));
node->setScale(core::vector3df(0.8f));
node->getMaterial(0).Lighting = true;
node->setAnimationSpeed(20.f);
// Just do the same as we did above.
selector = smgr->createTriangleSelector(node);
node->setTriangleSelector(selector);
selector->drop();
material.setTexture(0, 0);
material.Lighting = false;
scene::ILightSceneNode * light = smgr->addLightSceneNode(0, core::vector3df(-60,100,400),
video::SColorf(1.0f,1.0f,1.0f,1.0f), 600.0f);
light->setID(ID_IsNotPickable); // Make it an invalid target for selection.
scene::ISceneNode* highlightedSceneNode = 0;
scene::ISceneCollisionManager* collMan = smgr->getSceneCollisionManager();
int lastFPS = -1;
material.Wireframe=true;
while(device->run())
if (device->isWindowActive())
{
driver->beginScene(true, true, 0);
smgr->drawAll();
if (highlightedSceneNode)
{
highlightedSceneNode->setMaterialFlag(video::EMF_LIGHTING, true);
highlightedSceneNode = 0;
}
core::line3d<f32> ray;
ray.start = camera->getPosition();
ray.end = ray.start + (camera->getTarget() - ray.start).normalize() * 1000.0f;
core::vector3df intersection;
core::triangle3df hitTriangle;
scene::ISceneNode * selectedSceneNode =
collMan->getSceneNodeAndCollisionPointFromRay(
ray,
intersection,
hitTriangle,
IDFlag_IsPickable,
0);
if(selectedSceneNode)
{
bill->setPosition(intersection);
driver->setTransform(video::ETS_WORLD, core::matrix4());
driver->setMaterial(material);
driver->draw3DTriangle(hitTriangle, video::SColor(0,255,0,0));
if((selectedSceneNode->getID() & IDFlag_IsHighlightable) == IDFlag_IsHighlightable)
{
highlightedSceneNode = selectedSceneNode;
highlightedSceneNode->setMaterialFlag(video::EMF_LIGHTING, false);
}
}
driver->endScene();
int fps = driver->getFPS();
if (lastFPS != fps)
{
core::stringw str = L"Collision detection example - Irrlicht Engine [";
str += driver->getName();
str += "] FPS:";
str += fps;
device->setWindowCaption(str.c_str());
lastFPS = fps;
}
}
device->drop();
return 0;
}
开源3D游戏引擎Irrlicht简介的更多相关文章
- 基于Java的开源3D游戏引擎jMonkeyEngine
jMonkeyEngine简介 jMonkeyEngine是一款纯Java语言编写的游戏引擎,继承了Java应用跨平台的特性,而且是开放源代码的,遵循BSD开源协议,BSD开源协议用一句简单的话概括就 ...
- 转载:[转]如何学好3D游戏引擎编程
[转]如何学好3D游戏引擎编程 Albert 本帖被 gamengines 从 游戏引擎(Game Engine) 此文为转载,但是值得一看. 此篇文章献给那些为了游戏编程不怕困难的热血青年,它的 ...
- 记录一下八款开源 Android 游戏引擎
记录一下八款开源 Android 游戏引擎 虽然android学了点点,然后现在又没学了(我为啥这么没有恒心呢大哭).以后有时间还是要继续学android的,一定要啊!虽然现在没学android游戏编 ...
- 排名前10的H5、Js 3D游戏引擎和框架
由于很多人都在用JavaScript.HTML5和WebGL技术创建基于浏览器的3D游戏,所有JavaScript 3D游戏引擎是一个人们主题.基于浏览器的游戏最棒的地方是平台独立,它们能在iOS.A ...
- 棒!使用.NET Core构建3D游戏引擎
原文地址:https://mellinoe.wordpress.com/2017/01/18/net-core-game-engine/ 作者:ERIC MELLINO 翻译:杨晓东(Savorboa ...
- Android 八款开源 Android 游戏引擎
原文地址 本文内容 Angle Rokon LGame AndEngine libgdx jPCT Alien3d Catcake 最近无意间看到一篇关于 Android 搜索引擎的文章,于是搜索了, ...
- 八款开源 Android 游戏引擎[转]
记录一下,以备不时之需~~~~~ 虽然android学了点点,然后现在又没学了(我为啥这么没有恒心呢大哭).以后有时间还是要继续学android的,一定要啊!虽然现在没学android游戏编程,不过还 ...
- [转]八款开源Android游戏引擎
八款开源Android游戏引擎 1.Angle Angle是一款专为Android平台设计的,敏捷且适合快速开发的2D游戏引擎,基于OpenGL ES技术开发.该引擎全部用Java代码编写,并且可以根 ...
- 国内开源html5游戏引擎全收录
本文引自<国内开源html5游戏引擎全收录> 游戏开发这潭水太深,英文水平太差,不敢看国外的, 而且这几年国内技术水平也挺高了不少,特别是JS方面.(我个人感觉) 最近看了几个国产的js游 ...
随机推荐
- Java多线程-基础知识
一. 进程是执行中的程序,程序是静态的(我们写完以后不运行就一直放在那里),进程是执行中的程序,是动态概念的.一个进程可以有多个线程. 二. 多线程包含两个或两个以上并发运行的部分,把程序中每个这样并 ...
- 国庆 day 2 上午
一道图论神题(god) Time Limit:1000ms Memory Limit:128MB 题目描述 LYK有一张无向图G={V,E},这张无向图有n个点m条边组成.并且这是一张带权图,只有 ...
- VS2008 集成Lua解释器
1. 登陆官网下载源代码 -> www.lua.org -> get started -> installing 选择系统类型(这里是Windows的,所下面载 luaDist) ...
- nginx 1.5 支持websocket
proxy_pass http://backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set ...
- systemverilog中堵塞和非堵塞事件以及同步
一.SV中非堵塞事件 module test; event ev1, ev2; //belong to logic function part always@(ev1) $display(" ...
- 什么是SVN(Subversion)? 为什么要用SVN? (2011-09-05 15:09:47) 转载 ▼
转自:http://blog.sina.com.cn/s/blog_54ccd3500100tkvo.html 什么是SVN(Subversion)? 有一个简单但不十分精确比喻: SVN = 版本控 ...
- Python TurtleWorld configuration and simple test
TurtleWorld provides a set of functions for drawing lines by steering turtles around the screen. You ...
- AngularJs轻松入门(六)表单校验
表单数据的校验对于提高WEB安全性意义不大,因为服务器接收到的请求不一定来自我们的前端页面,有可能来自别的站点,黑客可以自己做一个表单,把数据提交到我们的服务器(即跨站伪造请求),这样就绕过了前端页面 ...
- ListView有Header时的position情况
问题: headerView 为第0个view,item 的 pos会从1开始. 解决方式: position减去 listView.getHeaderViewsCount().例如我想得到list ...
- 51Nod 不重叠的线段(贪心)
X轴上有N条线段,每条线段有1个起点S和终点E.最多能够选出多少条互不重叠的线段.(注:起点或终点重叠,不算重叠). 例如:[1 5][2 3][3 6],可以选[2 3][3 6],这2条线段互不重 ...