Multiple devices???

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
speculatius
Posts: 15
Joined: Wed Nov 28, 2007 12:49 pm

Multiple devices???

Post by speculatius »

Hi,

i am trying to create more devices. ViewPorts are not enough for me, i need to project more different scenes. Is it possible?

I am using createDeviceEx for open device in win32 window (or more precisely wxWidgets::wxFrame). It seems, that only last created device/window is functional, and the others dont respond to my calls. Every irr-call is protected by mutex. Do i something wrong?

Here is my code based on wxIrrlicht (http://wxforum.shadonet.com/viewtopic.php?t=17090)

--- Display.h ---

Code: Select all

class Display: public wxControl {

	DECLARE_EVENT_TABLE();

protected:
	void OnPaint(wxPaintEvent& event);
	void OnSize(wxSizeEvent& event);
	void OnEraseBackground(wxEraseEvent& event) {}
	void OnTimer(wxTimerEvent& event);
	void OnMouse(wxMouseEvent& event);
	void OnKey(wxKeyEvent& event);

	IrrlichtDevice* device;
	video::IVideoDriver* driver;
	scene::ISceneManager* smgr;
	scene::ICameraSceneNode* camera;
	scene::ILightSceneNode* light;
	wxTimer timerRender;
	bool renderingActive;

	static wxMutex mutexIrr;

public:
	Display(wxWindow* parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL, const wxString& name = wxPanelNameStr);
	virtual ~Display();

	void InitIrr();
	void StartRendering();
	void StopRendering();
	void Render();

	IrrlichtDevice* GetDevice() const { return device; }
	video::IVideoDriver* GetVideoDriver() const { return driver; }
	scene::ISceneManager* GetSceneManager() const { return smgr; }
};
--- Display.cpp ---

Code: Select all

wxMutex Display::mutexIrr;

BEGIN_EVENT_TABLE(Display, wxControl)
    EVT_TIMER(TIMER_RENDER_ID, Display::OnTimer)
    EVT_SIZE(Display::OnSize)
    EVT_PAINT(Display::OnPaint)
    EVT_ERASE_BACKGROUND(Display::OnEraseBackground)
    EVT_MOUSE_EVENTS(Display::OnMouse)
    EVT_KEY_DOWN(Display::OnKey)
    EVT_KEY_UP(Display::OnKey)
END_EVENT_TABLE()

Display::Display(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name)
	: wxControl(parent, id, pos, size, style, wxDefaultValidator, name),
	device(0),
    driver(0),
    smgr(0),
    camera(0),
	timerRender(this, TIMER_RENDER_ID) {
 		InitIrr();
		SetBackgroundStyle(wxBG_STYLE_CUSTOM);
		StartRendering();
}

Display::~Display() {

	mutexIrr.Lock();
	device->drop();
	mutexIrr.Unlock();
}

void Display::InitIrr() {

	mutexIrr.Lock();

	core::dimension2d<s32> irrSize(GetClientSize().GetX(), GetClientSize().GetY());

	SIrrlichtCreationParameters params;
	params.DriverType = video::EDT_OPENGL;
	params.WindowSize = irrSize;
	params.WindowId = this->GetHandle();

    device = createDeviceEx(params);

    if (device == NULL)
        throw BasicException("Display::InitIrr - Cannot create irrlicht device.");

	driver = device->getVideoDriver();
	smgr = device->getSceneManager();

	driver->OnResize(irrSize);

	mutexIrr.Unlock();
}

void Display::StartRendering() {
	renderingActive = true;
	timerRender.Start(TIMER_RENDER_PERIOD, true);
}

void Display::StopRendering(){
	renderingActive = false;
	timerRender.Stop();
}

void Display::Render() {

	mutexIrr.Lock();

		if(!device->run()) {
			mutexIrr.Unlock();
			return;
		}

		driver->beginScene(true, true, video::SColor(0,0,0,0));
		smgr->drawAll();
		driver->endScene();

	mutexIrr.Unlock();
}

void Display::OnPaint(wxPaintEvent& event){

    wxPaintDC paint_dc(this);
    Render();
}

void Display::OnSize(wxSizeEvent& event) {

	mutexIrr.Lock();

    s32 w;
    s32 h;

    GetClientSize(&w, &h);
    core::dimension2d<s32> size(w, h);
	driver->OnResize(size);

    if (camera) {
       camera->setAspectRatio((float)w / (float)h);
	}

	mutexIrr.Unlock();

	Render();
}

void Display::OnTimer(wxTimerEvent& event) {

    Render();
	if(renderingActive)
		timerRender.Start(TIMER_RENDER_PERIOD, true);
}

// ... OnMouse and OnKey are not interesting ...

Then i simply create some frames with this control inside, but only last frame really draws scene. Camera and light are created in inherited class...

Thanks for your responses...
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

You must use just one device. But you can pass your window id in endScene() in order to switch the render context (at least for DirectX).
speculatius
Posts: 15
Joined: Wed Nov 28, 2007 12:49 pm

Post by speculatius »

Yes, this approach seem to be more usefull. I found out, that i can have one device for all windows, but every window can have its own SceneManager (see SceneManager::createNewSceneManager). That is exactly what i need. However, there is one more problem. EndScene(windowID) is valid only for Direct3D, but i am using OpenGL. In this forum http://www.irrlicht3d.org/pivot/entry.php?id=347 user named Ros is explainig, how is it possible for OpenGL. Can you implement his idea?

Thanks...
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

IMHO for OpenGL we have to move the parameter from endScene to beginScene. Because OpenGL needs to switch contexts before rendering starts.
I'd need a sample application which sets up a render window for either D3D or OpenGL (choosable by a compiler define) in order to test this, though (because I don't know how to set up the win32 Windows properly).
speculatius
Posts: 15
Joined: Wed Nov 28, 2007 12:49 pm

Post by speculatius »

Mrcdrc point me at his topic http://irrlicht.sourceforge.net/phpBB2/ ... highlight=. He said that there is still some problem with "docking/undicking", but he will try to fix it...
Post Reply