[No bug] Issues with drawing outside the render loop

You discovered a bug in the engine, and you are sure that it is not a problem of your code? Just post it in here. Please read the bug posting guidelines first.
Post Reply
randomMesh
Posts: 1186
Joined: Fri Dec 29, 2006 12:04 am

[No bug] Issues with drawing outside the render loop

Post by randomMesh »

Drawing a line with driver->draw3DLine() in windowed mode outside the render loops works fine.
But in fullscreen mode, the rendering of the other stuff stops somehow.

Here's a minimal compilable example to demonstrate the problem.

Run it and press the left mouse button to draw a line. Then change to fullscreen mode and do again.

Code: Select all

#include <irrlicht.h>

class EventReceiver : public irr::IEventReceiver
{

public:

	EventReceiver(irr::IrrlichtDevice* device) :
		device(device), mouseButton(false)
	{

	}

	bool OnEvent(const irr::SEvent& event)
	{
		switch(event.EventType)
		{
			case irr::EET_MOUSE_INPUT_EVENT:
			{
			    switch (event.MouseInput.Event)
			    {
					case irr::EMIE_LMOUSE_PRESSED_DOWN: mouseButton = true; return true;
					case irr::EMIE_LMOUSE_LEFT_UP: mouseButton = false; return true;
					default: return false;
			    }
			}
			break;

			case irr::EET_KEY_INPUT_EVENT:
			{
				if (!event.KeyInput.PressedDown)
				{
					switch (event.KeyInput.Key)
					{
						case irr::KEY_ESCAPE: device->closeDevice(); return true;
						default: return false;
					}
				}
				else return false;
			}
			break;

			default: return false;
		}

	}

	bool isMouseButtonPressed() const { return mouseButton; }

private:

	irr::IrrlichtDevice* device;

	bool mouseButton;
};

static void drawRay(irr::video::IVideoDriver* driver, const irr::core::vector3df& start, const irr::core::vector3df& end)
{
	irr::video::SMaterial mat;
	mat.Lighting = false;

	driver->beginScene(false, false, irr::video::SColor());
	driver->setMaterial(mat);
	driver->setTransform(irr::video::ETS_WORLD, irr::core::matrix4());
	driver->draw3DLine(start, end, irr::video::SColor(255, 0, 0 , 255));
	driver->endScene();
}

int main()
{
	/*
	 * Testcase for my problem.
	 *
	 * Press left mouse button to draw a line via driver->draw3DLine()
	 *
	 * All works fine in windowed mode, but in fullscreen mode, the rendering of the sphere somehow stops.
	 */

	irr::IrrlichtDevice* device = 0;
	device = irr::createDevice(irr::video::EDT_OPENGL, irr::core::dimension2di(800, 600), 16, false);
	if (device == 0) return 1;

	EventReceiver receiver(device);
	device->setEventReceiver(&receiver);

	irr::video::IVideoDriver* driver = device->getVideoDriver();
	irr::scene::ISceneManager* smgr = device->getSceneManager();

	irr::scene::ISceneNode* node = smgr->addSphereSceneNode();

	irr::scene::ISceneNodeAnimator* anim = smgr->createFlyCircleAnimator(irr::core::vector3df(0,0,30), 20.0f);
	node->addAnimator(anim);
	anim->drop();

	smgr->addCameraSceneNode();

	while(device->run())
	{
		if (device->isWindowActive())
		{
			if (receiver.isMouseButtonPressed())
				drawRay(driver, node->getAbsolutePosition(), irr::core::vector3df(0.0f, 0.0f, 30.0f));

			driver->beginScene(true, true, irr::video::SColor(255, 255, 255, 255));
			smgr->drawAll();
			driver->endScene();
		}
	}

	device->drop();

	return 0;
}

Windows XP, MinGW, latest SVN trunk release build.
Last edited by randomMesh on Wed Aug 13, 2008 9:18 pm, edited 1 time in total.
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

of course, and if you look sharp in windowed mode you'll see it flickers too !!! :lol:
the reson is because you clean the screen, draw the line, clean the screen again and draw the scene... ;)

just don't clear the screen in drawRay(...) and call it after beginScene and before endScene in your main loop...

change drawRay to this:

Code: Select all

static void drawRay(irr::video::IVideoDriver* driver, const irr::core::vector3df& start, const irr::core::vector3df& end)
{
   irr::video::SMaterial mat;
   mat.Lighting = false;

//   driver->beginScene(false, false, irr::video::SColor());
   driver->setMaterial(mat);
   driver->setTransform(irr::video::ETS_WORLD, irr::core::matrix4());
   driver->draw3DLine(start, end, irr::video::SColor(255, 0, 0 , 255));
//   driver->endScene();
} 
and in your main loop this:

Code: Select all

if (device->isWindowActive())
{
   driver->beginScene(true, true, irr::video::SColor(255, 255, 255, 255));
   smgr->drawAll();
   if (receiver.isMouseButtonPressed())
      drawRay(driver, node->getAbsolutePosition(), irr::core::vector3df(0.0f, 0.0f, 30.0f));
   driver->endScene();
}
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
randomMesh
Posts: 1186
Joined: Fri Dec 29, 2006 12:04 am

Post by randomMesh »

Sorry, you got me wrong there. I have to call the drawRay() function outside the render loop. This is just a small example.

In my game, there's an updateGame() which is called outside the driver->beginnScene() due to using a statemanager. The rendering is done in the global state and the updating in another game state. This updateGame() sometimes draws some lines for debugging output.

And i don't complain about flickering, but the rendering of all other stuff just stops.

I posted this here in the bug forum since it already worked some SVN revisions ago.
alexionne
Posts: 55
Joined: Fri Jun 22, 2007 9:55 am
Location: Novi Sad, Serbia

Post by alexionne »

It is really not good idea to mix two beginScene/endScene calls in one "frame", because those two calls actually become two frames, and there is absolutely no guarantee which one of them will be shown at the time graphic card sends data to monitor.

So, here's an idea how to solve your problem: setup some global array of debug lines - let's call it DebugLines :-) Now, inside updateGame() instead of directly rendering lines, put them in DebugLines. Then, just before you call endScene, draw all those lines, and remove them from DebugLines array. That way it doesn't matter if you update your game before or after render part (beginScene/endScene) - your lines will be rendered.

Best!
randomMesh
Posts: 1186
Joined: Fri Dec 29, 2006 12:04 am

Post by randomMesh »

Thanks, i just implemented your suggestion and it works fine. :)
Post Reply