Multiple screens

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
GrigoriosSokratis
Posts: 34
Joined: Wed Apr 25, 2007 3:48 am

Multiple screens

Post by GrigoriosSokratis »

Hi there guys, I'd appreciate if anyone could help me with the following problem.

I'm doing a game engine in Win32 API C++ that implements Irrlicht as the graphic engine.

The problem as is showed in the posted picture is that as it has a somewhat GameStudio or 3D studio like GUI, I want to work with different views of the same thing simultaneously (Top view, front, perspective, etc). Unfortunately I just can make it show up in only one of the four views.

I first tested the lower right child window of the MDI and everything went just right, then I implemented the same thing in the remaining windows, but Irrlicht only shows up in the latest loaded window.

In the picture I'm testing it with 3 windows and only the 3rd (lower left) in purple world background, shows up while the 1st and 2nd windows show in deep black with no device loaded on them. The same happens if I use just one device for all the windows

Then I tried with different devices for each of the three windows and the same happens.

Here are the image of the situation and the important part of the code:

Image
bool CDeviceDriver::bGREBasics(HWND hChildMDI)
{
param.WindowId = (s32)hChildMDI;
param.DriverType = EDT_OPENGL;
device = createDeviceEx(param);

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



smgr->addCameraSceneNode(0, vector3df(0,30,-40), vector3df(0,5,0));

return 0;
}

bool CDeviceDriver::bGREBasics1(HWND hChildMDI1)
{
param1.WindowId = (s32)hChildMDI1;
param1.DriverType = EDT_OPENGL;
device1 = createDeviceEx(param1);

driver1 = device1->getVideoDriver();
smgr1 = device1->getSceneManager();

smgr1->addCameraSceneNode(0, vector3df(0,30,-40), vector3df(0,5,0));

return 0;
}

bool CDeviceDriver::bGREBasics2(HWND hChildMDI2)
{
param2.WindowId = (s32)hChildMDI2;
param2.DriverType = EDT_OPENGL;
device2 = createDeviceEx(param2);

driver2 = device2->getVideoDriver();
smgr2 = device2->getSceneManager();

smgr2->addCameraSceneNode(0, vector3df(0,30,-40), vector3df(0,5,0));

return 0;
}

bool CDeviceDriver::bRunGRE()
{
device->getTimer()->tick();
driver->beginScene(true, true, SColor(255,255,101,140));
smgr->drawAll();


device1->getTimer()->tick();
driver1->beginScene(true, true, SColor(255,215,101,140));
smgr1->drawAll();


device2->getTimer()->tick();
driver2->beginScene(true, true, SColor(255,125,101,140));
smgr2->drawAll();
driver2->endScene();
driver1->endScene();
driver->endScene();
return 0;
}
Note: The I left the fourth window (upper left) empty with nothing on it for the moment as I'm trying to solve it in just three windows before continuing.

Any help appreciated.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

Instead of making multiple windows, it _might_ be easier to use viewports. The video driver has a setViewPort() method that lets you set the area that will be rendered into.

All you would do is create a single scene manager, and 4 cameras, one for each viewport. For each view you would set the render area, set the active camera, and render the scene. Something like this might work...

Code: Select all

bool CDeviceDriver::bRunGRE() 
{
  const core::dimension2d<s32> screenSize(driver->getScreenSize());
  const core::position2d<s32> screenCenter(screenSize.Width / 2, screenSize.Height / 2);

  // give the simulation a tick
  device->getTimer()->tick();
 
  if (driver->beginScene(true, true, SColor(255,255,101,140)); 
  {
    core::rect<s32> rect;

    // draw the upper left quadrant
    rect.UpperLeftCorner.X = 0;
    rect.UpperLeftCorner.Y = 0;
    rect.LowerRightCorner.X = screenCenter.X;
    rect.LowerRightCorner.Y = screenCenter.Y;

    driver->setViewPort(rect);
    smgr->setActiveCamera(cameras[0]);
    smgr->drawAll();

    // draw the upper right quadrant
    rect.UpperLeftCorner.X = screenCenter.X + 1;
    rect.LowerRightCorner.X = screenSize.Width;

    driver->setViewPort(rect);
    smgr->setActiveCamera(cameras[1]);
    smgr->drawAll();

    // draw the lower right quadrant
    rect.UpperLeftCorner.Y = screenCenter.Y + 1;
    rect.LowerRightCorner.Y = screenSize.Height;

    driver->setViewPort(rect);
    smgr->setActiveCamera(cameras[2]);
    smgr->drawAll();

    // draw the lower left quadrant
    rect.UpperLeftCorner.X = 0;
    rect.LowerRightCorner.X = screenCenter.X;

    driver->setViewPort(rect);
    smgr->setActiveCamera(cameras[3]);
    smgr->drawAll();

    driver->endScene();
  }

  return 0; 
}
The other way that you could do this would be to look at the CGUIViewPort that I posted a while ago. You could modify it to share a single scene manager and to have its own camera. That way each view could easily send mouse/keybard input to the appropriate camera. If you did that all you would have to do would be to create 4 viewports and render the gui. Each of the viewports would handle the keyboard/mouse input. The only hitch would be to make sure that the viewport sizes were scaled with the irrlicht window size.

Travis
abraham
Posts: 30
Joined: Wed Jul 19, 2006 8:56 am

Post by abraham »

nice job,keep up:)
n7600gt 256mb ram 128bit
AMD 3200+
GA-K8NF-9 gigabyte
GrigoriosSokratis
Posts: 34
Joined: Wed Apr 25, 2007 3:48 am

Post by GrigoriosSokratis »

Yes I tried it but the results aren't what I expected. Actually the aim of the program is to have each different view in its own child MDI window.

So, again it doesn't allow me to have two different windows with irrlicht loaded on them at the same time.

So the problem is that it doesn't allow me to load the device using 2 WindowId params, rendering only the one loaded later and thus leaving the first one unrendered in deep black.

SIrrlichtCreationParameters param;


bool CDeviceDriver::bGREBasics(HWND hChildMDI)
{
param.WindowId = (s32)hChildMDI;
param.DriverType = EDT_OPENGL;
device = createDeviceEx(param);

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

}

bool CDeviceDriver::bGREBasics1(HWND hChildMDI1)
{
param.WindowId = (s32)hChildMDI1;
param.DriverType = EDT_OPENGL;
device = createDeviceEx(param);

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

}

bool CDeviceDriver::bRunGRE()
{
device->getTimer()->tick();

if (driver->beginScene(true, true, SColor(255,255,101,140)))
{
smgr->drawAll();
driver2->endScene();
}
return 0;
}

Your idea is very nice but it doesn't fit with the final look I want to get in this engine with MDI view windows that will make it more user friendly, than splitting a single window into 4.

Any help on this, appreciated.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

So, again it doesn't allow me to have two different windows with irrlicht loaded on them at the same time.
In my experience, Irrlicht doesn't work well with multiple devices. You can't get it to render to all of them, and all hell breaks loose if you close one of the windows. That is why I suggested using viewports. You _may_ be able to render to multiple windows by passing the HWND of the window to render on to in the endRender() call. If that works, then you're all set.
Your idea is very nice but it doesn't fit with the final look I want to get in this engine with MDI view windows that will make it more user friendly, than splitting a single window into 4.
In my limited experience with modelling software, the viewport is split as I'm suggesting. There are not multiple Win32 windows. If you insist on using multiple 'windows', you could create gui windows with viewports controls in them [again, see the CGUIViewport mentioned above]. That would give you multiple viewports that you can drag and move around, but only inside the primary rendering area.

Travis
GrigoriosSokratis
Posts: 34
Joined: Wed Apr 25, 2007 3:48 am

Post by GrigoriosSokratis »

Finally it worked!!!!!!! Guys, I've read this community was very kind in different sites and actually it's, as I experienced it now.

As for the problem I took the chance and wrote a mail to Nikolaus and he helped me within just 2 hours (unbelievable nowadays! He's really a kind guy)

And the solution was waaaay simple, it just needed the use of endScene()

So the code now would go like this:
bool CDeviceDriver::bRunGRE(HWND hChildMDI, HWND hChildMDI1, HWND hChildMDI2, HWND hChildMDI3)
{
device->getTimer()->tick();
driver->beginScene(true, true, SColor(255,255,101,140));


smgr->addCameraSceneNode(0, vector3df(0,30,-40), vector3df(0,5,0));
smgr->drawAll();

driver->endScene(param.WindowId = (s32)hChildMDI1, 0);

driver->beginScene(true, true, SColor(255,255,101,140));


smgr->addCameraSceneNode(0, vector3df(0,30,-40), vector3df(0,5,0));
smgr->drawAll();

driver->endScene(param.WindowId = (s32)hChildMDI2, 0);

driver->beginScene(true, true, SColor(255,255,101,140));


smgr->addCameraSceneNode(0, vector3df(0,30,-40), vector3df(0,5,0));
smgr->drawAll();

driver->endScene(param.WindowId = (s32)hChildMDI3, 0);

driver->beginScene(true, true, SColor(255,255,101,140));


smgr->addCameraSceneNode(0, vector3df(0,30,-40), vector3df(0,5,0));
smgr->drawAll();

driver->endScene(param.WindowId = (s32)hChildMDI, 0);
return 0;
}
And voila the four viewports!!!!!

Now I'll position the cameras to align the respective desired views, and I can continue my Game Engine project.

So remember the secret is on endScene() for anyone else who will ever run across this same issue. There, as you see in the code, you have to add in the first parameter the window id of the other windows you want to have Irrlicht rendered.

And here's how it looks:

Image

Guys, now as an old user of other graphic engines like OGRE and Crystal Space I can say that Irrlicht is the best (technically as well as in tutorials, and community coverage).
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Wow that looks great. Glad it worked.

Faith in the power of Irrlicht +1 :lol:
Virion
Competition winner
Posts: 2149
Joined: Mon Dec 18, 2006 5:04 am

Post by Virion »

Looking forward to your project. :D
My company: https://kloena.com
My profile: https://zhieng.com
My co-working space: https://deskspace.info
My game engine: https://kemena3d.com
forX
Posts: 22
Joined: Thu Sep 09, 2010 6:26 am

Post by forX »

I'm noob

did u edit the endScene function?
TCM
Posts: 53
Joined: Mon May 24, 2010 9:29 pm

Post by TCM »

forX wrote:did u edit the endScene function?
No. The endScene is not modified. The version used here is for an older version of the engine. For the new version(s) (including 1.7.1) you must use the parameter in beginScene. I guess this makes more sense.

TCM
Virion
Competition winner
Posts: 2149
Joined: Mon Dec 18, 2006 5:04 am

Post by Virion »

the power of niko :lol:
My company: https://kloena.com
My profile: https://zhieng.com
My co-working space: https://deskspace.info
My game engine: https://kemena3d.com
Post Reply