Imagine this as a supplement to Tutorial 14, which explained how to use Irrlicht in a win32 window. However, using it in WinForms takes a bit of a different approach, using Threading.
Note: I am not sure if this is the ideal way to do this (I'm a bit new to threads myself); let me know if you spot any bad design choices!
---------------
The final product will be a window that has Irrlicht running visuals inside of it.
1) Create a new Windows Forms Application in Visual Studio.
2) Create a new class: I called it IrrlichtManager. This is the main interface to all your Irrlicht operations.
3) Here is the implementation of the class:
Code: Select all
#pragma
once
#include "stdafx.h"
using namespace irr;
public ref class IrrlichtManager
{
private:
IrrlichtDevice* _device;
scene::ISceneManager* _smgr;
video::IVideoDriver* _driver;
bool _isRunning;
public:
IrrlichtManager(IrrlichtDevice* device);
void Init();
void Close();
void SetCubeVisiblity(bool isVisible);
private:
void run();
};
#include "stdafx.h"
#include "IrrlichtManager.h"
// constructor
IrrlichtManager::IrrlichtManager(IrrlichtDevice* device)
: _device (device)
, _smgr (_device->getSceneManager())
, _driver (_device->getVideoDriver())
, _isRunning (true)
{
}
// Set up some visuals, and begin running the device.
// This method will be the function pointer for the Irrlicht thread.
void IrrlichtManager::Init()
{
scene::ICameraSceneNode* cam = _smgr->addCameraSceneNode();
cam->setTarget(core::vector3df(0,0,0));
scene::ISceneNodeAnimator* anim = _smgr->createFlyCircleAnimator(core::vector3df(0,15,0), 30.0f);
cam->addAnimator(anim);
anim->drop();
scene::ISceneNode* cube = _smgr->addCubeSceneNode(20);
cube->setID(10);
cube->setMaterialTexture(0, _driver->getTexture("../media/wall.bmp"));
cube->setMaterialTexture(1, _driver->getTexture("../media/water.jpg"));
cube->setMaterialFlag( video::EMF_LIGHTING, false );
cube->setMaterialType( video::EMT_REFLECTION_2_LAYER );
_smgr->addSkyBoxSceneNode(
_driver->getTexture("../media/irrlicht2_up.jpg"),
_driver->getTexture("../media/irrlicht2_dn.jpg"),
_driver->getTexture("../media/irrlicht2_lf.jpg"),
_driver->getTexture("../media/irrlicht2_rt.jpg"),
_driver->getTexture("../media/irrlicht2_ft.jpg"),
_driver->getTexture("../media/irrlicht2_bk.jpg"));
run();
}
// Stop running and dispose of the device
void IrrlichtManager::Close()
{
_device->closeDevice();
_isRunning = false;
}
// This method is to demonstrate how to interact with the device
void IrrlichtManager::SetCubeVisiblity(bool isVisible)
{
scene::ISceneNode* node = _smgr->getSceneNodeFromId(10);
node->setVisible(isVisible);
}
// The main Irrlicht loop
void IrrlichtManager::run()
{
while (_device->run() && _isRunning == true)
{
_driver->beginScene(true, true, 0);
_smgr->drawAll();
_driver->endScene();
}
_device->drop();
}
5) Now you need to add the Irrlicht window to the form. Open up "Form1.h". Add "using namespace irr;" and "using namespace System::Threading;" to the file. Now, Locate the constructor. Add the following code so that the code around the constructor looks like this:
Code: Select all
public:
Thread^ irrThread;
IrrlichtManager^ irrMgr;
IrrlichtDevice* device;
Form1()
{
InitializeComponent();
SIrrlichtCreationParameters param;
param.WindowId = reinterpret_cast<void*>(this->pictureBox1->Handle.ToPointer());
device = createDeviceEx(param);
irrMgr = gcnew IrrlichtManager(device);
irrThread = gcnew Thread(gcnew ThreadStart (irrMgr, &IrrlichtManager::Init));
irrThread->Start();
}
6) Now we will add code for the button. Clicking on this button will toggle the visibility of the cube node. This is just to show one way of interacting with the Irrlicht device. Go back to the Form1.h Designer and double click on button1. It should take you have to Form1.h with a method generated for you.
Make it look like this:
Code: Select all
void button1_Click(System::Object^ sender, EventArgs^ e)
{
static bool visible = true;
visible = !visible;
irrMgr->SetCubeVisiblity(visible);
}
Code: Select all
void Form1_FormClosing (System::Object^ sender, FormClosingEventArgs^ e)
{
irrMgr->Close();
irrThread->Join();
}
Now we just add the right references. My stdafx.h file looks like this:
Code: Select all
#pragma once
#pragma comment( lib, "irrlicht.lib" )
#pragma unmanaged
#include <irrlicht.h>
#pragma managed
#include "IrrlichtManager.h"
9) You're done! Compile it and hopefully it will work. This is what it should look like:
The camera should be rotating around the cube. When you click the button, the cube should disappear or appear.
For further information, it's a good idea to read up on Threading and the Windows Form Designer.
I hope this helps you get started on your project!