当前位置: 首页 > 工具软件 > Irrlicht > 使用案例 >

irrlicht 学习笔记 - 从入门到放弃

仉梓
2023-12-01

irrlicht 学习笔记 - 从入门到放弃


这是一个游戏引擎开发者 irrlicht 的学习笔记


写于最后

花了一天,通过对irrlicht进行粗略的学习。

知道了基本的使用,如何加载资源,创建节点,如何加载地图,GUI,碰撞检测,内置效果,可编程渲染管线,逐像素光照,地形渲染,渲染到纹理,分屏,光照管理,xml文件读写,自定义Mesh,遮挡查询,字体使用与创建等。

但是也发现了一些问题,irrlicht的没有高级的编程思想,仅提供了一些基本的渲染引擎功能,不易扩展。无法支持汉字。从支持的平台以及特性来看,属于远古产物,技术已属于淘汰队列。

从性能上看,只有遮挡查询优化。

做个小demo是可以的。

可以放弃了


学习过程

  1. 下载 irrlicht Irrlicht Engine - A free open source 3D engine (sourceforge.io)

  2. 编译

    (1) 打开 irrlicht/examples/BuildAllExamples_vc12.sln

    (2) 运行samples

  3. 相关文档 Irrlicht 3D Engine: Irrlicht Engine 1.8 API documentation (sourceforge.io)

  4. 使用vscode 打开 irrlicht 文件夹

    分析文件结构,分为bin, doc, examples, include, lib, media, source, tools, changes.txt, readme.txt

  5. 阅读 readme.txt

    (1). 文件结构概述

    • bin : 已编译的库Irrlicht.dll 和一些已编译的演示和示例应用程序,只需启动它们即可查看Irrlicht引擎的运行情况。只有Windows的。
    • doc : 文档
    • examples : c++的示例和教程.
    • include : 引擎的头文件
    • lib : 引擎的库文件
    • media : examples的图形和音频文件
    • source : 引擎的资源文件
    • tools : 有用的工具

    (2)其他…

  6. 打开 include 文件夹

    发现一些以C,E,I ,S 开头的.h文件,随便打开几个,发现

    • I 开头的是 纯虚接口类
    • C 开头的是 接口实现类
    • E 是枚举值
    • S 是结构体
    • 一些其他的数据结构,例如 vector2d, vector3d, 等
  7. 打开 source 文件夹

    • source/irrlicht
    • 发现一些文件夹,以及一些文件
    • aesGladman : aes加密算法
    • bzip2 : zip相关(压缩)
    • jpeglib : jpeg相关
    • libpng : png相关
    • lzma : 压缩算法
    • zlib : zlib相关(压缩)
    • MacOSX : macOS 专用
    • 一堆以 C 开头的文件,打开几个,发现是 include 中接口的实现,以及其他功能
  8. 打开 tools 文件夹

    • FileToHeader
    • GUIEditor
    • IrrEdit
    • IrrFontTool
    • MeshConverter
  9. 回到 include 文件夹

    打开一个 I 开头的文件,发现继承于 IReferenceCounted,打开IReferceneCounted.h,从名称以及内容得出是引用计数类。基本得出内存管理机制是引用计数。

    把该文件夹下所有的文件名看一遍,

    大致包含

    indexbuffer, vertex buffer, mesh, scene, file, scene, light, particle, animate, texture, material, vertex2d, vertex3d, map, rect, quaternion, position2d, plane3d, matrix4,line, skybox等

    从这些文件可以得出,这些都是游戏引擎的渲染部分相关的代码。

    初步得出, irrlicht是一个渲染引擎。

  10. 打开 source 文件夹

    大致浏览里面的文件,发现基本上都是 include 中的实现。

    一些新的文件,以D3D8, D3D9, OpenGL, SoftDriver, xxxLoader, DeviceWin32,DeviceWinCE, DeviceLinux

    得出 它 支持 支持D3D8, D3D9,OpenGL, SoftDriver

    支持MacOS, Windows, Linux, STL, FB(framebuffer)

    从支持的api D3D8,D3D9, SoftDriver可以看出,这是一个远古产物。

  11. 运行Samples

* 01.HelloWorld

(1) 窗口标题:Hello World! - Irrlicht Engine Demo

(2) 有一行文字 : Hello World! This is the Irrlicht Software renderer!

(3) 有一个动态模型

代码

    IrrlichtDevice *device =
		createDevice(video::EDT_SOFTWARE,  // 软件渲染
        dimension2d<u32>(640, 480), // 窗口大小 640x480
        16, // 16位像素,非全屏,忽略
        false, // 非全屏
        false, // 无模板缓存
        false, // 无垂直同步
        0 // 无事件接收器
    );
    
    device->setWindowCaption(L"Hello World! - Irrlicht Engine Demo");
    // 设置窗口标题
	IVideoDriver* driver = device->getVideoDriver();
    // 获取视频驱动,上面指定的 SOFTWARE
	ISceneManager* smgr = device->getSceneManager();
    // 获取场景管理器
	IGUIEnvironment* guienv = device->getGUIEnvironment();
    // 获取GUI环境

从这一些获取可以得出一些信息,
VideoDriver, SceneManager, GUIEnvionment 属于内部对象,创建设备时会被创建,有可能会创建其他内部对象。

    // 添加一个静态文本框
	guienv->addStaticText(L"Hello World! This is the Irrlicht Software renderer!",
		rect<s32>(10,10,260,22), true);
		
    // 使用场景管理器,加载Mesh
    IAnimatedMesh* mesh = smgr->getMesh("../../media/sydney.md2");
// 使用场景管理器添加一个动画Mesh
IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh );
	if (node)
	{
		node->setMaterialFlag(EMF_LIGHTING, false);// 给动画添加材质,不需要光照。
		
		node->setMD2Animation(scene::EMAT_STAND);// 设置站立动画
		
		ITexture* texture = driver->getTexture("../../media/sydney.bmp");// 加载纹理
		
		node->setMaterialTexture( 0, texture);// 设置材质纹理
		
	}
// 增加一个相机
	smgr->addCameraSceneNode(0, vector3df(0,30,-40), vector3df(0,5,0));
	
	while(device->run())
	{
		
		driver->beginScene(true, true, SColor(255,100,101,140));// 场景开始
        
		smgr->drawAll(); // 渲染场景
		
		guienv->drawAll(); // 渲染GUI

		driver->endScene(); // 场景结束
	}
	
    device->drop(); // 释放device

从HelloWorld可以得出,基本的代码顺序,

  1. createdevice
  2. getVideoDriver, …
  3. sceneManager->addxxxNode()
  4. while(device->run())
  5. videoDriver->beginScene(…)
  6. sceneManager->drawAll()
  7. guienv->drawAll()
  8. videoDriver->endScene()
  • 发现的一些问题
  1. VideoDriver->beginScene(bool backBuffer, bool zBuffer, SColor color)

    从参数可以猜测,这是清空缓存,

    所以这个函数实际功能可能是 beginDrawScene,

    但是在beginScene和endScene中间有guienv->drawAll,

    从场景管理器与GUI环境分开猜测,UI应该不属于场景,

    那么beginScene实际应该是 beginDraw.

    endScene应该是 endDraw

  2. 从运行的loop的内容发现,都是绘制的功能,

    videoDriver->beginScene

    sceneManager->drawAll

    guienv->drawAll

    videoDriver->endScene

    猜测,场景/UI/动画的更新操作应该在 device->run()里。

    通过调试发现,run()里面并没有涉及update的操作。

    那么,猜测场景/UI的更新应该在 drawAll内部.

    调试发现,sceneManager::drawAll函数代码较多,放弃深入。

* 02.Quake3Map

从 quake3里加载地图

通过看代码发现新的东西

  • device->getFileSystem()->addFileArchive("")

    通过注释,发现这个是添加文件缓存功能,下次读取相同的文件时,可以从缓存中读取,加快读取速度。

  • smgr->addOctreeSceneNode

    可以得出,场景使用八叉树管理

  • smgr->addCameraSceneNodeFPS()

    FPS统计功能

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

    隐藏光标

  • device->isWindowActive()

    窗口是否活动的

  • device->yield()

    窗口非活动状态,等待, Pause状态

* 03.CustomSceneNode

自定义场景节点

从 class CSampleSceneNode 可以得知,自定义节点,有一个aab碰撞盒,有顶点,有材质。

// 注册节点渲染
	virtual void OnRegisterSceneNode()
	{
		if (IsVisible)
			SceneManager->registerNodeForRendering(this);

		ISceneNode::OnRegisterSceneNode();
	}

如果需要渲染节点,需要把在sceneManager中注册节点

isVisible的时候注册?

没有发现 unregisterNodeForRendering

猜测它是每一帧都去注册

通过调试发现,确实如此

// 如何渲染节点
	virtual void render()
	{
		u16 indices[] = {	0,2,3, 2,1,3, 1,0,3, 2,0,1	};
		video::IVideoDriver* driver = SceneManager->getVideoDriver();

		driver->setMaterial(Material);
		driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
		driver->drawVertexPrimitiveList(&Vertices[0], 4, &indices[0], 4, video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT);
	}
// 获取aab碰撞盒
	virtual const core::aabbox3d<f32>& getBoundingBox() const
	{
		return Box;
	}

// 获取材质数量
	virtual u32 getMaterialCount() const
	{
		return 1;
	}

// 获取材质
	virtual video::SMaterial& getMaterial(u32 i)
	{
		return Material;
	}	
// 创建一个旋转动画
    	scene::ISceneNodeAnimator* anim =
		smgr->createRotationAnimator(core::vector3df(0.8f, 0, 0.8f));

	if(anim)
	{
        // 自定义节点添加旋转动画
		myNode->addAnimator(anim);
        // ...
    }

* 04.Movement

移动

创建一些模型/动画,通过按键控制

这是一个极度坑爹的场景,没有判断pause,导致应用pause状态还在运行,光光标无法移出窗口以外的区域

  • 创建了一个 class MyEventReceiver,能响应一些内部事件,例如,按键事件。
    具体消息,查看 IEventReceiver.h

  • 创建动画节点

    
        scene::IAnimatedMeshSceneNode* anms =
    	    smgr->addAnimatedMeshSceneNode(smgr->getMesh("../../media/ninja.b3d")); // 加载模型,创建动画节点
    
        anms->setFrameLoop(0, 13); // 设置循环帧
        anms->setAnimationSpeed(15); // 设置动画速度
    
        anms->setScale(core::vector3df(2.f,2.f,2.f)); // 设置缩放
        anms->setRotation(core::vector3df(0,-90,0)); // 设置旋转
    
  • 创建静态Text,颜色为白色

    gui::IGUIStaticText* diagnostics = device->getGUIEnvironment()->addStaticText(
    	L"", core::rect<s32>(10, 10, 400, 20));
    diagnostics->setOverrideColor(video::SColor(255, 255, 255, 0));
    
  • fix bug

    while(device->run())
    {
        // 判断窗口是否活动的
    	if (!device->isWindowActive())
    	{
    		device->yield();
    		continue;
    	}
        // ...
    }
    

* 05.UserInterface

演示一些基本的UI

  • 设置 ui 字体
    IGUISkin* skin = env->getSkin();
    IGUIFont* font = env->getFont("../../media/fonthaettenschweiler.bmp");
    if (font)
    	skin->setFont(font);
    
    skin->setFont(env->getBuiltInFont(), EGDF_TOOLTIP);
    
    

打开 fonthaettenschweiler.bmp 会发现,这是一个ascii码字体图片,

全局搜索truetype, 发现没有,不支持truetype字体。

那么对汉字的支持有点尴尬了。

  • 创建一个scrollbar,并设置ID,当scrollbar变化时,会发送 event,通过 EventReceiver 得到事件

    IGUIScrollBar* scrollbar = env->addScrollBar(true,
                rect<s32>(150, 45, 350, 60), 0, GUI_ID_TRANSPARENCY_SCROLL_BAR);
    
  • 整体设置UI透明度

    setSkinTransparency( scrollbar->getPos(), env->getSkin());
    
    // 获取ui皮肤所有的颜色设置,修改alpha
    void setSkinTransparency(s32 alpha, irr::gui::IGUISkin * skin)
    {
        for (s32 i=0; i<irr::gui::EGDC_COUNT ; ++i)
        {
            video::SColor col = skin->getColor((EGUI_DEFAULT_COLOR)i);
            col.setAlpha(alpha);
            skin->setColor((EGUI_DEFAULT_COLOR)i, col);
        }
    }
    
    

    通过 setSkinTransparency 可知,ui被分成了不同的部分,每一个部分可以设置不同的颜色。

* 06.2DGraphics

2D功能

  • 把图片中与指定位置像素值相同的像素变成透明的

    video::ITexture* images = driver->getTexture("../../media/2ddemo.png");
    driver->makeColorKeyTexture(images, core::position2d<s32>(0,0));
    
    

    (鸡肋的功能)

  • 设置材质属性

    driver->getMaterial2D().TextureLayer[0].BilinearFilter=true;
    driver->getMaterial2D().AntiAliasing=video::EAAM_FULL_BASIC;
    

    抗锯齿是材质属性?

  • 绘制2D图片

    driver->draw2DImage(images, core::position2d<s32>(50,50),
        core::rect<s32>(0,0,342,224), 0,
    video::SColor(255,255,255,255), true);
    
  • 绘制文字

    font2->draw(L"Also mixing with 3d graphics is possible.",
    	core::rect<s32>(130,20,300,60),
    	video::SColor(255,time % 255,time % 255,255));
    
  • 使用2D材质绘制图片

    driver->enableMaterial2D();
    driver->draw2DImage(images, core::rect<s32>(10,10,108,48),
    	core::rect<s32>(354,87,442,118));
    driver->enableMaterial2D(false);
    
  • 绘制2D矩形

     driver->draw2DRectangle(...)
    

* 07.Collision

碰撞

  • 创建可被选中的节点

    q3node = smgr->addOctreeSceneNode(q3levelmesh->getMesh(0), 0, IDFlag_IsPickable);
    
  • 创建八叉树三角形选择器

    auto selector = smgr->createOctreeTriangleSelector(q3node->getMesh(), q3node, 128);
    
    q3node->setTriangleSelector(selector);
    

    创建三角形选择器时,指定了q3node,q3node还需要设置选择器?

    创建的时候,指定的node做什么用?

    待探究!

  • 创建场景动画碰撞与响应器,并设置给相机

    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();  // And likewise, drop the animator when we're done referring to it.
    
  • 创建billboard

    scene::IBillboardSceneNode * bill = smgr->addBillboardSceneNode();
    // ...
    bill->setID(ID_IsNotPickable);
    

    设置了一个特殊用途的ID?

    enum
    {
        ID_IsNotPickable = 0,
    
        IDFlag_IsPickable = 1 << 0,
    
        IDFlag_IsHighlightable = 1 << 1
    };
    
  • 获取碰撞检测器

    scene::ISceneCollisionManager* collMan = smgr->getSceneCollisionManager();
    
  • 获取交互射线

    	core::line3d<f32> ray;
      	ray.start = camera->getPosition();
      	ray.end = ray.start + (camera->getTarget() - ray.start).normalize() * 1000.0f;
    

    相机正前方到正前方1000的一条射线

  • 射线交互

    scene::ISceneNode * selectedSceneNode =
      		collMan->getSceneNodeAndCollisionPointFromRay(
      				ray,
      				intersection, // This will be the position of the collision
      				hitTriangle, // This will be the triangle hit in the collision
      				IDFlag_IsPickable, // This ensures that only nodes that we have
      						// set up to be pickable are considered
      				0); // Check the entire scene (this is actually the implicit default)
    
    

    第四个参数 idBitMask = IDFlag_IsPickable,它是一个按位运算的值,也就是有相同位的是同一个layer。

    也就是说可以通过sceneNode的ID来区分不同的交互层。

* 08.SpecialFX

内置的效果

  • 房间的平面纹理贴图(三向贴图,Triplanar Mapping)
smgr->getMeshManipulator()->makePlanarTextureMapping(mesh->getMesh(0), 0.004f);
  • 添加地形

     mesh = smgr->addHillPlaneMesh( "myHill",
    		core::dimension2d<f32>(20,20),
    		core::dimension2d<u32>(40,40), 0, 0,
    		core::dimension2d<f32>(0,0),
    		core::dimension2d<f32>(10,10));
      ```
    
    
    
  • 水面效果

    node = smgr->addWaterSurfaceSceneNode(mesh->getMesh(0), 3.0f, 300.0f, 30.0f);
    
  • 粒子效果

     // 创建粒子效果节点
    scene::IParticleSystemSceneNode* ps =
      	smgr->addParticleSystemSceneNode(false);
    
      // 创建方形发射器
      scene::IParticleEmitter* em = ps->createBoxEmitter(
      	core::aabbox3d<f32>(-7,0,-7,7,1,7), // emitter size
      	core::vector3df(0.0f,0.06f,0.0f),   // initial direction
      	80,100,                             // emit rate
      	video::SColor(0,255,255,255),       // darkest color
      	video::SColor(0,255,255,255),       // brightest color
      	800,2000,0,                         // min and max age, angle
      	core::dimension2df(10.f,10.f),         // min size
      	core::dimension2df(20.f,20.f));        // max size
    
      // 设置发射器
      ps->setEmitter(em); // this grabs the emitter
    
      // 创建淡出粒子效果影响器
      scene::IParticleAffector* paf = ps->createFadeOutParticleAffector();
    
      // 设置影响器
      ps->addAffector(paf); // same goes for the affector
    
  • 体积光节点

      scene::IVolumeLightSceneNode * n = smgr->addVolumeLightSceneNode(0, -1,
      			32,                              // Subdivisions on U axis
      			32,                              // Subdivisions on V axis
      			video::SColor(0, 255, 255, 255), // foot color
      			video::SColor(0, 0, 0, 0));      // tail color
    
  • 纹理动画

    scene::ISceneNodeAnimator* glow = smgr->createTextureAnimator(textures, 150);
    
  • 增加阴影节点

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

* 09.Meshviewer

  • 设置COLLADA mesh加载单例

    smgr->getParameters()->setAttribute(scene::COLLADA_CREATE_SCENE_INSTANCES, true);
    
  • 设置纹理创建标志

    driver->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, true);
    
  • 读取xml

    Device->getFileSystem()->createXMLReader( L"config.xml");
    
  • 创建菜单

    gui::IGUIContextMenu* menu = env->addMenu();
    
  • 增加菜单项

    menu->addItem(L"File", -1, true, true);
    submenu->addItem(L"Open Model File & Texture...", GUI_ID_OPEN_MODEL); // 指定CommandID
    
  • 获取子菜单

    submenu = menu->getSubMenu(0);
    
  • 增加分割符

    submenu->addSeparator();
    
  • 创建toolbar

    gui::IGUIToolBar* bar = env->addToolBar();
    
  • 添加按钮

    bar->addButton(GUI_ID_BUTTON_OPEN_MODEL, 0, L"Open a model",image, 0, false, true); // 指定ID
    
  • 导入场景

    Device->getSceneManager()->loadScene(filename);
    
  • 获取场景中的指定类型的节点

    Device->getSceneManager()->getSceneNodesFromType(scene::ESNT_ANIMATED_MESH, outNodes);
    
  • 显示MessageBox

    Device->getGUIEnvironment()->addMessageBox(
      		Caption.c_str(), L"The model could not be loaded. " \
      		L"Maybe it is not a supported file format.");
    
  • 设置Debug数据是否显示

    Model->setDebugDataVisible(scene::EDS_OFF);
    
  • 通过ID获取GUI

    gui::IGUIContextMenu* menu = (gui::IGUIContextMenu*)Device->getGUIEnvironment()->getRootGUIElement()->getElementFromId(GUI_ID_TOGGLE_DEBUG_INFO, true);
    
  • 设置项是否被选中

    menu->setItemChecked(item, false);
    
  • 增加天空盒

    SkyBox = smgr->addSkyBoxSceneNode(
      	driver->getTexture("irrlicht2_up.jpg"),
      	driver->getTexture("irrlicht2_dn.jpg"),
      	driver->getTexture("irrlicht2_lf.jpg"),
      	driver->getTexture("irrlicht2_rt.jpg"),
      	driver->getTexture("irrlicht2_ft.jpg"),
      	driver->getTexture("irrlicht2_bk.jpg"));
    
  • 增加一个maya类型的相机

    Camera[0] = smgr->addCameraSceneNodeMaya();
    
  • 设置对其方式

    img->setAlignment(EGUIA_UPPERLEFT, EGUIA_UPPERLEFT,
      		EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT);
    

* 10.Shaders

使用shader,可编程渲染管线

  • 查询特性

    driver->queryFeature(video::EVDF_PIXEL_SHADER_1_1);
    driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1);
    
  • 获取GPU程序服务器

    video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
    
  • 加载shader材质

    newMaterialType1 = gpu->addHighLevelShaderMaterialFromFiles(
      			vsFileName, "vertexMain", video::EVST_VS_1_1,
      			psFileName, "pixelMain", video::EPST_PS_1_1,
      			mc, video::EMT_SOLID, 0, shadingLanguage);
    
      		newMaterialType2 = gpu->addHighLevelShaderMaterialFromFiles(
      			vsFileName, "vertexMain", video::EVST_VS_1_1,
      			psFileName, "pixelMain", video::EPST_PS_1_1,
      			mc, video::EMT_TRANSPARENT_ADD_COLOR, 0 , shadingLanguage);
    

* 11.PerPixelLighting

逐像素光照

  • 设置雾化

    driver->setFog(video::SColor(0,138,125,81), video::EFT_FOG_LINEAR, 250, 1000, .003f, true, false);
    
  • 设置法线贴图纹理

    driver->makeNormalMapTexture(normalMap, 9.0f);
    
  • 创建带切线Mesh

    scene::IMesh* tangentMesh = smgr->getMeshManipulator()->
      			createMeshWithTangents(roomMesh->getMesh(0));
    
  • 设置顶点透明度

    manipulator->setVertexColorAlpha(tangentSphereMesh, 200);
    
  • 设置transform

      core::matrix4 m;
      m.setScale ( core::vector3df(50,50,50) );// 放大矩阵
      manipulator->transform( tangentSphereMesh, m ); 
    
  • 设置事件接收器

    	MyEventReceiver receiver(room, earth, env, driver);
      device->setEventReceiver(&receiver);
    

* 12.TerrainRendering

地形渲染

  • 创建地形

    scene::ITerrainSceneNode* terrain = smgr->addTerrainSceneNode(
      	"../../media/terrain-heightmap.bmp",
      	0,					// parent node
      	-1,					// node id
      	core::vector3df(0.f, 0.f, 0.f),		// position
      	core::vector3df(0.f, 0.f, 0.f),		// rotation
      	core::vector3df(40.f, 4.4f, 40.f),	// scale
      	video::SColor ( 255, 255, 255, 255 ),	// vertexColor
      	5,					// maxLOD
      	scene::ETPS_17,				// patchSize
      	4					// smoothFactor
      	);
    
  • 创建/设置地形三角形选择器

    	scene::ITriangleSelector* selector
      	= smgr->createTerrainTriangleSelector(terrain, 0);
      terrain->setTriangleSelector(selector);
    
  • 创建动态mesh,并获取地形LOD 0的mesh

    	scene::CDynamicMeshBuffer* buffer = new scene::CDynamicMeshBuffer(video::EVT_2TCOORDS, video::EIT_16BIT);
      terrain->getMeshBufferForLOD(*buffer, 0);
      video::S3DVertex2TCoords* data = (video::S3DVertex2TCoords*)buffer->getVertexBuffer().getData();
      // Work on data or get the IndexBuffer with a similar call.
      buffer->drop(); // When done drop the buffer again.
    
  • 增加穹顶天空盒

    	scene::ISceneNode* skydome=smgr->addSkyDomeSceneNode(driver->getTexture("../../media/skydome.jpg"),16,8,0.95f,2.0f);
    
    

* 13.RenderToTexture

渲染到纹理

  • 创建渲染目标纹理

    rt = driver->addRenderTargetTexture(core::dimension2d<u32>(256,256), "RTT1");
    
  • 设置渲染目标纹理

    driver->setRenderTarget(rt, true, true, video::SColor(0,0,0,255));
    driver->setRenderTarget(0, true, true, 0);// 设置默认RTT
    
  • 设置活动的相机

    smgr->setActiveCamera(fpsCamera);
    

* 14.Win32Window

Win32多窗口程序

这个就没啥好看的了,属于windows编程
通过创建的HWND窗口句柄,指定windowID来指定渲染到哪个窗口。

* 15.LoadIrrFile

  • 从 .irr 文件加载场景
    smgr->loadScene("../../media/example.irr");
    

* 16.Quake3MapShader

导入Quake 3 map

* 17.HelloWorld_Mobile

windows mobile

* 18.SplitScreen

分屏

		if (SplitScreen)
		{
			//Activate camera1
			smgr->setActiveCamera(camera[0]);
			//Set viewpoint to the first quarter (left top)
			driver->setViewPort(rect<s32>(0,0,ResX/2,ResY/2));
			//Draw scene
			smgr->drawAll();
			//Activate camera2
			smgr->setActiveCamera(camera[1]);
			//Set viewpoint to the second quarter (right top)
			driver->setViewPort(rect<s32>(ResX/2,0,ResX,ResY/2));
			//Draw scene
			smgr->drawAll();
			//Activate camera3
			smgr->setActiveCamera(camera[2]);
			//Set viewpoint to the third quarter (left bottom)
			driver->setViewPort(rect<s32>(0,ResY/2,ResX/2,ResY));
			//Draw scene
			smgr->drawAll();
			//Set viewport the last quarter (right bottom)
			driver->setViewPort(rect<s32>(ResX/2,ResY/2,ResX,ResY));
		}
		//Activate camera4
		smgr->setActiveCamera(camera[3]);
		//Draw scene
		smgr->drawAll();

创建4个相机,渲染时,分别启用每个相机,并指定视口,然后渲染所有场景

* 19.MouseAndJoystick

鼠标和摇杆

通过 IEventReceiver 的 OnEvent(const SEvent& event) 获取

* 20.ManagedLights

光照管理

  • 设置光照管理器
    smgr->setLightManager(0);
    

重载 IEventReceiver::OnPreRender(core::arrayscene::ISceneNode* & lightList)

可以获取所有的光照信息,可以在每个渲染阶段修改

* 21.Quake3Explorer

展示如何导入不同的Quake 3 地图

  • 从菜单中在运行时加载BSP存档

  • 从菜单中加载地图。显示屏幕截图

    截图

    Device->getVideoDriver()->createScreenShot();
    
  • 从菜单中设置运行时的视频驱动程序

  • 在运行时调整GammaLevel

    Device->setGammaRamp
    
  • 为着色器创建场景节点

  • 加载EntityList并创建实体场景节点

  • 创造有武器和碰撞反应的玩家

  • 演奏音乐

    需要 irrKlang : https://www.ambiera.com/irrklang/

* 22.MaterialViewer

材质设置并查看结果。仅使用默认的非着色器材质。

* 23.SMeshHandling

创建自定义Mesh

* 24.CursorControl

光标控制

  • 设置 icon
    Device->getCursorControl()->changeIcon(...)
    Device->getCursorControl()->setActiveIcon( ECURSOR_ICON);
    

* 25.XmlHandling

XML文件读写

* 26.OcclusionQuery

使用遮挡查询功能加快渲染速度

  • 遮挡查询功能
    driver->addOcclusionQuery(node, mesh); // 增加遮挡查询
    
    driver->runAllOcclusionQueries(false); // 运行遮挡查询
    driver->updateAllOcclusionQueries(); // 更新状态
    nodeVisible=driver->getOcclusionQueryResult(node)>0; // 获取结果
    

* Demo

* FontTool

仅支持ascii

* GUIEditor

gui编辑器

 类似资料: