Page 1 of 1

URGENT!! About smgr->clear()

Posted: Sat Mar 10, 2007 3:14 pm
by Thomaskkc
I have the process that when the user click a button, it will jump from 1 scene to another, however i use the same device such that it can open in the same window

and the problem is that i have posted before the first drawing is still in the second drawing, and i found that smgr->clear() said that it can clear the node, but when i call this, it break and throw exception in this line

so i'd like to ask that is that smgr->clear() useful to my problem or not? Or have another better solutions?

I need to solve this problem inmediately, so i'm pleased to hear if there any suggestions, thx all~

Posted: Sat Mar 10, 2007 4:01 pm
by Midnight
are you doing it after you drop the scene?

Posted: Sat Mar 10, 2007 4:24 pm
by Thomaskkc
the flow is

device -> create

event receiver -> call sec operation(pass device)
run operation 2

while loop
{
draw things
}
device->drop

in sec operation
use device passed from the first

device->beginscene
draw thing
device->endscene

event receiver -> still using the first one (call back to first scene)
run operation 1(pass Device)

then operation 1
{
device -> checked that is back
device->Device (passed back), but not create device
}

but the drawing is overlap and overlap and overlap again in both scene 1 & 2
so how to clear the scene before calling operation but use the same device?

Posted: Sat Mar 10, 2007 4:27 pm
by JP
When you drop the device you're deleting the device basically and so the scene manager will then be Null so calling smgr->clear() will crash.

Posted: Sat Mar 10, 2007 5:59 pm
by Thomaskkc
then how about when i call it at first, that is calling smgr->clear() before drop()
it still crash, why??

it not like that if i have string a = "abc"

then i run a = ""
a = "def"

then a is def and assign a new value?

is that possible in device or smgr?

Posted: Sat Mar 10, 2007 6:43 pm
by vitek
Just don't drop the device at all until the program is completely done. You can just ckear the scene and not drop the device.

You should be able to do something like this...

Code: Select all

class MyEventReceiver : public IEventReceiver
{
  IrrlichtDevice* Device;
  u32 LoadedScene;
public:
  MyEventReceiver(IrrlichtDevice* dev)
    : Device(dev)
    , LoadedScene(0)
  {
  }

  virtual bool OnEvent(SEvent event)
  {
    if (event.EventType == EET_KEY_INPUT_EVENT &&
        event.KeyInput.PressedDown)
    {
      switch(event.KeyInput.Key)
      {
        case KEY_KEY_A:
          if (LoadedScene != 1)
          {
            Device->getSceneManager()->clear();
            Device->getSceneManager()->loadScene("../../media/scene1.irr");
            LoadedScene = 1;
            return true;
          }
        case KEY_KEY_B:
          if (LoadedScene != 2)
          {
            Device->getSceneManager()->clear();
            Device->getSceneManager()->loadScene("../../media/scene2.irr");
            LoadedScene = 2;
            return true;
          }
      }
    }

    return false;
  }
};
You keep your render loop the same, and don't destroy the device. If you need to do some per scene setup you do it in the event receiver.

Another option would be to create another scene manager with smgr->createNewSceneManager(). You would load your additional scene into the second scene manager. You would stop calling drawAll() on the original scene manager and start calling it on the new one. When you want to switch back you switch which one you are drawing...

Travis

Posted: Sun Mar 11, 2007 4:45 am
by Thomaskkc
how about
smgr->getMeshCache()->removeMesh(mesh)??

i have call this after the drawing process
but still no effect

Posted: Sun Mar 11, 2007 6:08 am
by Thomaskkc
smgr->getMeshCache()->removeMesh(mesh) is just remove the mesh from the memory
but how can i remove the mesh and drawing?

Posted: Sun Mar 11, 2007 9:36 am
by Thomaskkc
anyone knows??

Posted: Sun Mar 11, 2007 9:49 am
by Thomaskkc

Code: Select all

void Museum::runMuseum(int win_width, int win_height, s32 id, float x, float y, float z, bool backward, IrrlichtDevice* input_d)
{
	if (false == backward) 
	{
		Params.AntiAlias = false;
		Params.Bits = 32;
		Params.DriverType = video::EDT_DIRECT3D9;
		Params.EventReceiver = 0;
		Params.Fullscreen = false;
		Params.HighPrecisionFPU = true;
		Params.Stencilbuffer = true;
		Params.Vsync = true;
		Params.WindowId = 0;
		Params.WindowSize = dimension2d<s32>(win_width, win_height);

		Museumdevice = createDeviceEx(Params);
	}
	else <-- backward = true mean back from scene 2
	{
		Museumdevice = input_d;
	}
	
	Museumdriver = Museumdevice->getVideoDriver();
	smgr = Museumdevice->getSceneManager();
	guienv = Museumdevice->getGUIEnvironment();
	node = 0;
	Selector = 0;
	camera = 0;
	m_pMetaSelector = smgr->createMetaTriangleSelector();

	Museumdevice->setWindowCaption(L"Virtual Museum Tour");

	mesh = smgr->getMesh("FYPmedia/Museum/MainMuseum.obj"); <-- is that backward = true then not getMesh?

	AddInformationBox(guienv, win_width, win_height);

	gui::IGUIFont* font = guienv->getFont("FYPmedia/Museum/fontcourier.bmp");
	if (font)
		guienv->getSkin()->setFont(font);

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

	if (node)
	{
        Selector = smgr->createTriangleSelector(mesh->getMesh(0), node); 
		node->setTriangleSelector(Selector); 
		node->getTriangleSelector();

		// Add the level's triangle selector to the main collision bucket 
		m_pMetaSelector->addTriangleSelector(Selector); 
		Selector->drop();
	}

	SetMaterialColor(node);

	SetLighting();

	if (false == backward)
		LoadModelInMuseum();

	if (id == 2)
	{
		GuideTourPath();
	}
	else if (id == 3)
	{
		camera = smgr->addCameraSceneNodeFPS(0,300.0f,600.0f,-1,0,0,true);
		camera->setPosition(vector3df(x,y,z));

		//create collision response
		m_pAnim = smgr->createCollisionResponseAnimator(m_pMetaSelector, camera, irr::core::vector3df(30,60,30), irr::core::vector3df(0,-100.0f,0), irr::core::vector3df(0,35,0)); 
		camera->addAnimator(m_pAnim); 
		m_pAnim->drop(); 
	}

	camera->setFarValue(4000);

	EventReceiver Receiver(Museumdevice, camera, mesh, 1);
	Museumdevice->setEventReceiver(&Receiver);

	while(Museumdevice->run() && Museumdriver) <-- when backward, it throw exception in this line when exit
	{
		if (Museumdevice->isWindowActive())
		{
			Museumdriver->beginScene(true, true, SColor(255,100,101,140));

			if (true == Receiver.ActiveEventFunction())
			{
				camera->setInputReceiverEnabled(true);
				Museumdevice->getCursorControl()->setVisible(false);
			}
			else
			{
				Museumdevice->getCursorControl()->setVisible(true);
				camera->setInputReceiverEnabled(false);

				Sleep(50);
			}

			smgr->drawAll();

			if (true == Receiver.DisplayInformation())
			{
				guienv->drawAll();
			}

			Museumdriver->endScene();
		}
		else
		{
			Museumdevice->getCursorControl()->setVisible(true);
			camera->setInputReceiverEnabled(false);

			Sleep(50);
		}
	}

	smgr->getMeshCache()->removeMesh(mesh);	

	Museumdevice->drop();
}

Posted: Sun Mar 11, 2007 9:55 am
by bitplane
scroll up and read what travis wrote. if you don't understand, ask for clarification.

dropping the device deletes it, which closes the window. you are doing the same as doing: stringc* a = new stringc("abc"); delete a; *a = "crash";
there's nothing wrong with smgr->clear(), the problem is you deleted your device.

edit: oh, so now you have a different problem?

Posted: Sun Mar 11, 2007 10:04 am
by Thomaskkc
yup, i havn't call the drop() in the scene 2 but still can't clear the mesh/drawing when call the scene in second time

the problem that is not drop, i understand that drop means delete the device, but how can i clear the mesh when load in second time?

my confuse is that the mesh can't be clear when call in second time
then the mesh is overlaped and that's not my expectation

so the problem is how to clear the mesh when before loading the sec time?
i have try both smgr->clear() & smgr->getMeshCash()->removeMesh(mesh) before loading the mesh, but it throw exception in that line

and id i call it at the end of the function that after drawing, it still no effect and still overlap in sec call

Posted: Sun Mar 11, 2007 10:27 am
by JP
To remove a node from drawing (not a mesh, the mesh is just the information about vertices and polys etc. not the actual onscreen thing that's being drawn, though deleting the mesh whilst a node is still using it will cause a crash). So to get rid of the node you do node->remove() i think.

Check out the API ;)

Posted: Sun Mar 11, 2007 10:45 am
by Thomaskkc
JP

i have try to set node->remove()

but i can't run this at the beginning of the function
if at the end, then nth is drawn

i think at the beginning it throw exception is that node is NULL
but i check if this is not NULL, then node->remove()

however, it still run not NULL
so what's suppose to do?