irrLicht相关_irrlicht视角跟随鼠标转动-程序员宅基地

技术标签: direct3d  iostream  引擎  textures  vector  video  

1.模型可以直接导入引擎中当作场景用是可以的,但只适用于很小的场景,如果场景较大仅靠视图体裁剪远远达不到时时渲染地效率要求,必须采用BSP、八叉树等空间划分算法。irrLicht实现了BSP算法,BSP场景打包后是*.pk3文件,制作它有专门的软件GtkRadiant。

2.

这是一个加载Quake3map的demo

由于这个demo中需要选择渲染管线,用到cin函数,所以这个函数除了添加引擎的头文件以外,还需要添加添加输入输出头文件#include <iostream>

1. video::E_DRIVER_TYPE driverType;

printf("Please select the driver you want for this example:/n"/

     " (a) Direct3D 9.0c/n (b) Direct3D 8.1/n (c) OpenGL 1.5/n"/

     " (d) Software Renderer/n (e) Burning's Software Renderer/n"/

     " (f) NullDevice/n (otherKey) exit/n/n");

char i;

std::cin >> i;

switch(i)

{

     case 'a': driverType = video::EDT_DIRECT3D9;break;

     case 'b': driverType = video::EDT_DIRECT3D8;break;

     case 'c': driverType = video::EDT_OPENGL;   break;

     case 'd': driverType = video::EDT_SOFTWARE; break;

     case 'e': driverType = video::EDT_SOFTWARE2;break;

     case 'f': driverType = video::EDT_NULL;     break;

     default: return 1;

}   

IrrlichtDevice *device = createDevice(driverType, core::dimension2d<s32>(640, 480));

typedef signed int irr::s32

if (device == 0)

return 1;

2. video::IVideoDriver* driver = device->getVideoDriver(); scene::ISceneManager* smgr = device->getSceneManager();

3. 为了显示Quake3地图,首先需要加载。该地图被打包成.pk3文件。该格式文件只是一个.zip文件格式利用函数addZipFileArchive可以读到这个文件。

   device->getFileSystem()->addZipFileArchive("../../media/map-20kdm2.pk3");

4. 通过函数getMesh()加载模型。并得到一个IAnimatedMesh类型指针。我们知道,Quake3 map中并不是所有的模型都是动态的,大部分都是静止的拥有材质的几何体。仅仅只有一帧是动态的。所以,我们通过取得第一帧得到动态模型。然后利用八叉树结点绑定。scene::IAnimatedMesh* mesh = smgr->getMesh("20kdm2.bsp");

   scene::ISceneNode* node = 0;

if (mesh)

        node = smgr->addOctTreeSceneNode(mesh->getMesh(0));

5. 由于level并不是在原点,所以需要将其移动。 node->setPosition(core::vector3df(-1300,-144,-1249));

6. 需要一个观察Quake3 map的照相机。可以创建一个可以控制的照相机。Irrlicht引擎提供多种不同的照相机供大家选择。例如:Maya—鼠标左键用于控制旋转;Zoom—鼠标右键控制移动。在这个demo中,创建一个类似FPS移动的camera。同时,利用getCursorControl()->setVisible(false)让鼠标不可见。

smgr->addCameraSceneNodeFPS();//利用该函数实现对鼠标的控制

device->getCursorControl()->setVisible(false);

7. 渲染

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

smgr->drawAll();

driver->endScene();

int fps = driver->getFPS();

if (lastFPS != fps)

{

     core::stringw str = L"Irrlicht Engine - Quake 3 Map example [";

     str += driver->getName();//得到所选的渲染管线的名字

     str += "] FPS:";

     str += fps;

     device->setWindowCaption(str.c_str());

     lastFPS = fps;

}

3.双字节

MultiByteToWideChar将ANSI字符转换成Unicode字符,使WideCharToMultiByte将Unicode字符转换成ANSI字。

ANSI、Unicode和宽字符之间的转换

方法一,使用MultiByteToWideChar将ANSI字符转换成Unicode字符,使用WideCharToMultiByte将Unicode字符转换成ANSI字符。

方法二,使用“_T”将ANSI转换成“一般”类型字符串,使用“L”将ANSI转换成Unicode,而在托管C++环境中还可使用S将ANSI字符串转换成String*对象。例如:

TCHAR tstr[] = _T("this is a test");

wchar_t wszStr[] = L"This is a test";

String* str = S”This is a test”;

方法三,使用ATL 7.0的转换宏和类。ATL7.0在原有3.0基础上完善和增加了许多字符串转换宏以及提供相应的类,它具有如图3所示的统一形式:

  其中,第一个C表示“类”,以便于ATL 3.0宏相区别,第二个C表示常量,2表示“to”,EX表示要开辟一定大小的缓冲。SourceType和DestinationType可以是A、T、W和OLE,其含义分别是ANSI、Unicode、“一般”类型和OLE字符串。例如,CA2CT就是将ANSI转换成一般类型的字符串常量。下面是一些示例代码:

LPTSTR tstr= CA2TEX<16>("this is a test");

LPCTSTR tcstr= CA2CT("this is a test");

wchar_t wszStr[] = L"This is a test";

char* chstr = CW2A(wszStr);

4.

之前利用事件接受类进行按键的处理。在这个demo里,利用该类创建各种我们希望得到的按钮。感觉速度比Ogre快多了哦。

同样是创建一个我们需要响应哪些事件的类,该类继承IEventReceiver。同样该类就只对OnEvent进行重写。在该函数中,具体实现我们需要响应的事件。

为了能响应各个不同的事件,首先需要得到事件接收对象。通过不同的按钮对象,由不同的事件类型,也即是下面代码中的EventType (具体类型在类ieventreceiver中);然后根据按钮的id值,具体到每个按钮。在创建按钮的时候,创建函数中的最后一个参数值Id值。

class MyEventReceiver : public IEventReceiver

{

public:

      virtual bool OnEvent(SEvent event)

      {

                if (event.EventType == EET_GUI_EVENT)

                {

                       s32 id = event.GUIEvent.Caller->getID();//得到id值

                       IGUIEnvironment* env = device->getGUIEnvironment();

            switch(event.GUIEvent.EventType)

            {

case EGET_SCROLL_BAR_CHANGED:

       if (id == 104)//这里的104就和下面addScrollBar中最后的参数项对应

       {

                 s32 pos = ((IGUIScrollBar*)event.GUIEvent.Caller)->getPos();

                                              

                 for (s32 i=0; i<EGDC_COUNT ; ++i)

                 {    // getSkin就是得到该gui的皮肤,并可以通过getColor取得当前皮肤颜色

                           SColor col = env->getSkin()->getColor ((EGUI_DEFAULT_COLOR)i);

                           col.setAlpha(pos);

                           env->getSkin()->setColor((EGUI_DEFAULT_COLOR)i, col);

                 }

       }

break;

IGUIScrollBar* scrollbar = env->addScrollBar(true,

               rect<s32>(150, 45, 350, 60), 0, 104);//在main函数中创建

只要是用到gui,都必须做:

1. MyEventReceiver receiver;

device->setEventReceiver(&receiver);//将设备和事件接受对象绑定

2. IGUIEnvironment* env = device->getGUIEnvironment();//得到gui环境

3. 通过env创建我们需要的按钮

4. 在BeginScene中env->drawAll();

5.effect

水的特效:

利用函数addHillPlaneMesh创建一个地面的网格模型,其实就是把该函数中的hillHeight设置为1就ok;然后利用函数addWaterSurfaceSceneNode创建一个节点;最后设置节点位置、以及帖图。并将该材质类型设置成材质反射。

2.      动态的光节点.其实就是利用一个scene::ISceneNodeAnimator对象;将这个对象通过如下函数将其绑定在一块

ISceneNode->addAnimator(ISceneNodeAnimator* animator)。场景管理器中有4种函数可以返回动态节点的。

ISceneNodeAnimator*

createRotationAnimator(const core::vector3df& rotationPerSecond) = 0;

ISceneNodeAnimator* createFlyCircleAnimator(const core::vector3df& center,

              f32 radius, f32 speed= 0.001f, const core::vector3df& direction = core::vector3df ( 0.f, 1.f, 0.f ) ) = 0;

ISceneNodeAnimator* createFlyStraightAnimator(const core::vector3df&   startPoint,const core::vector3df& endPoint, u32 timeForWay, bool loop=false) = 0;

ISceneNodeAnimator* createTextureAnimator(const core::array<video::ITexture*>& textures,

              s32 timePerFrame, bool loop=true) = 0;

如:node = smgr->addLightSceneNode(0, core::vector3df(0,0,0),

         video::SColorf(1.0f, 0.6f, 0.7f, 1.0f), 600.0f);

         scene::ISceneNodeAnimator* anim = 0;

         anim = smgr->createFlyCircleAnimator (core::vector3df(0,150,0),250.0f);

         node->addAnimator(anim);

anim->drop();

3.      阴影

     mesh = smgr->getMesh("../../media/dwarf.x");//读取x文件

     scene::IAnimatedMeshSceneNode* anode = 0;

     anode = smgr->addAnimatedMeshSceneNode(mesh);

     anode->setPosition(core::vector3df(-50,20,-60));

     anode->setAnimationSpeed(15);

     anode->addShadowVolumeSceneNode();//添加阴影

     smgr->setShadowColor(video::SColor(150,0,0,0));//阴影颜色设

6.粒子

1.      粒子系统

①. 创建一个粒子节点。并将该节点和场景管理器绑定(其中的false表示不用默认的发射器)设置节点位置、缩放程度以及粒子大小

        scene::IParticleSystemSceneNode* ps = 0;

        ps = smgr->addParticleSystemSceneNode(false);

        ps->setPosition(core::vector3df(-70,60,40));

        ps->setScale(core::vector3df(2,2,2));

     ps->setParticleSize(core::dimension2d<f32>( 20.0f, 20.0f));

     ②. 创建一个盒装粒子发射器(其实也可以创建一个点发射器)  

         core::aabbox3df& box: 发射器盒子尺寸; direction: 粒子发射的方向和速度

         minParticlesPerSecond、maxParticlesPerSecond: 每秒钟最小和最大发射粒子数目

         minStartColor、maxStartColor: 每一个粒子的颜色是在这2个颜色之间进行插值得到的

         lifeTimeMin、lifeTimeMax: 每个粒子的最小和最长的生命周期

         maxAngleDegrees: 沿着发射方向,最大的发射角度

          scene::IParticleEmitter* em = ps->createBoxEmitter(

              core::aabbox3d<f32>(-7,0,-7,7,1,7),core::vector3df(0.0f,0.06f,0.0f),

              80,100,video::SColor(0,255,255,255), video::SColor(0,255,255,255),800,2000);

         //将粒子节点和发射器绑定,然后drop发射器

         ps->setEmitter(em);

           em->drop();

/* createFadeOutParticleAffector创建一个粒子退色的影响器。这个影响器可以对每一个粒子的颜色进行修改,并且设置粒子消亡时的最后颜色

   targetColor: 消亡的颜色

   timeNeededToFadeOut: 粒子从产生到消亡所需的时间

*/

        scene::IParticleAffector* paf = ps->createFadeOutParticleAffector();

         //蒋该影响器和粒子节点绑定,并drop影响器

        ps->addAffector(paf);

         paf->drop();

        //设置粒子的材质

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

        ps->setMaterialTexture(0, driver->getTexture("../../media/fire.bmp"));

        ps->setMaterialType(video::EMT_TRANSPARENT_VERTEX_ALPHA);

 
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/huangchonghai/article/details/2906448

智能推荐

《第一行代码》(第二版)广播的问题及其解决_代码里的广播错误-程序员宅基地

文章浏览阅读2.6k次,点赞5次,收藏13次。1)5.2.1弹出两次已连接或者未连接这是因为你同时打开了流量和WiFi,他就会发出两次广播。2)5.3.1中发送自定义广播问题标准广播未能弹出消息:Intent intent=new Intent("com.example.broadcasttest.MY_BROADCAST");sendBroadcast(intent);上述已经失效了。修改:Intent intent=new Intent("com.example.broadcasttest...._代码里的广播错误

K8s 学习者绝对不能错过的最全知识图谱(内含 58个知识点链接)-程序员宅基地

文章浏览阅读249次。作者 |平名 阿里服务端开发技术专家导读:Kubernetes 作为云原生时代的“操作系统”,熟悉和使用它是每名用户的必备技能。本篇文章概述了容器服务 Kubernet..._k8知识库

TencentOS3.1安装PHP+Nginx+redis测试系统_tencentos-3.1-程序员宅基地

文章浏览阅读923次。分别是etc/pear.conf,etc/php-fpm.conf, etc/php-fpm.d/www.conf,lib/php.ini。php8安装基本一致,因为一个服务期内有2个版本,所以注意修改不同的安装目录和端口号。可以直接使用sbin下的nginx命令启动服务。完成编译安装需要gcc支持,如果没有,使用如下命令安装。安装过程基本一致,下面是安装7.1.33的步骤。执行如下命令,检查已经安装的包和可安装的包。执行如下命令,检查已经安装的包和可安装的包。执行如下命令,检查已经安装的包和可安装的包。_tencentos-3.1

urllib.request.urlopen()基本使用_urllib.request.urlopen(url)-程序员宅基地

文章浏览阅读3.1w次,点赞21次,收藏75次。import urllib.requesturl = 'https://www.python.org'# 方式一response = urllib.request.urlopen(url)print(type(response)) # <class 'http.client.HTTPResponse'># 方式二request = urllib.request.Req..._urllib.request.urlopen(url)

如何用ChatGPT+GEE+ENVI+Python进行高光谱,多光谱成像遥感数据处理?-程序员宅基地

文章浏览阅读1.5k次,点赞12次,收藏15次。如何用ChatGPT+GEE+ENVI+Python进行高光谱,多光谱成像遥感数据处理?

RS485总线常识_rs485 差分走綫間距-程序员宅基地

文章浏览阅读1.2k次。RS485总线常识 2010-10-12 15:56:36| 分类: 知识储备 | 标签:rs485 总线 传输 差分 |字号大中小 订阅RS485总线RS485采用平衡发送和差分接收方式实现通信:发送端将串行口的TTL电平信号转换成差分信号A,B两路输出,经过线缆传输之后在接收端将差分信号还原成TTL电平信号。由于传输线通常使用双绞线,又是差分传输,所_rs485 差分走綫間距

随便推点

移植、制作uboot、Linux(一)_uboot制作-程序员宅基地

文章浏览阅读621次。u-boot、linux烧录_uboot制作

windows下安装git和gitbash安装教程_64-bit git for windows setup.-程序员宅基地

文章浏览阅读1.2w次,点赞10次,收藏44次。windos上git安装,git bash安装_64-bit git for windows setup.

环形链表(算法java)_java 实现环形链表-程序员宅基地

文章浏览阅读196次。环形链表(算法java)的两种解决方法_java 实现环形链表

docker部署Airflow(修改URL-path、更换postgres -->myslq数据库、LDAP登录)_airflow docker-程序员宅基地

文章浏览阅读5.7k次。Airflow什么是 Airflow?Airflow 的架构Airflow 解决哪些问题一、docker-compose 安装airflow(postgres)1、创建启动文件airflow-docker-compose.yml.1.1、添加挂载卷,需要修改airflow-docker-compose.yml的位置2、创建本地配置文件airflow.cfg2.1、如果想修改WEB URL地址,需要修改airflow.cfg中以下两个地方3、之后up -d直接启动即可web访问地址:二、存储数据库更换post_airflow docker

计算机毕业设计springboot高校教务管理系统532k79【附源码+数据库+部署+LW】-程序员宅基地

文章浏览阅读28次。选题背景:随着社会的发展和教育的普及,高校教务管理系统在现代高等教育中扮演着至关重要的角色。传统的手工管理方式已经无法满足高校日益增长的规模和复杂的管理需求。因此,开发一套高效、智能的教务管理系统成为了当今高校管理的迫切需求。选题意义:高校教务管理系统的开发具有重要的意义和价值。首先,它可以提高高校教务管理的效率和准确性。通过自动化处理学生选课、排课、考试安排等繁琐的事务,大大减轻了教务人员的工作负担,提高了工作效率。同时,系统可以实时更新学生信息和课程信息,减少了数据错误和冗余,保证了管理的准确性

javaint接收float_Java Integer转换double,float,int,long,string-程序员宅基地

文章浏览阅读132次。首页>基础教程>常用类>常用 Integer类Java Integer转换double,float,int,long,stringjava中Integer类可以很方便的转换成double,float,int,long,string等类型,都有固定的方法进行转换。方法double doubleValue() //以 double 类型返回该 Integer 的值。flo..._java integet接收float类型的参数

推荐文章

热门文章

相关标签