[not a bug]IVideoDriver::setViewPort() broken

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
Nalin
Posts: 194
Joined: Thu Mar 30, 2006 12:34 am
Location: Lacey, WA, USA
Contact:

[not a bug]IVideoDriver::setViewPort() broken

Post by Nalin »

setViewPort() seems to constantly want to draw on the top-left corner of the window no matter what you set the x and y coordinates to be. Here is a sample file that tries to draw a cube from four different positions, each with a different viewport (each viewport takes up a quarter of the screen.) What ends up happening is that all viewports are drawn in the top-left quadrant of the window. Note that this happens in both OpenGL and DirectX.

Code: Select all

#include <windows.h>
#include <irrlicht.h>
using namespace irr;

#pragma comment(lib, "Irrlicht.lib")

int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
	//IrrlichtDevice* device = irr::createDevice( video::EDT_OPENGL, core::dimension2d<s32>(800,600) );
	IrrlichtDevice* device = irr::createDevice( video::EDT_DIRECT3D9, core::dimension2d<s32>(800,600) );

	video::IVideoDriver* driver = device->getVideoDriver();
	scene::ISceneManager* scene = device->getSceneManager();
	scene::ICameraSceneNode* camera0 = scene->addCameraSceneNode();
	scene::ICameraSceneNode* camera1 = scene->addCameraSceneNode();
	scene::ICameraSceneNode* camera2 = scene->addCameraSceneNode();
	scene::ICameraSceneNode* camera3 = scene->addCameraSceneNodeMaya();

	// Move camera0-2 and point at origin.
	camera0->setPosition( core::vector3df( 0.0f, 0.0f, -50.0f ) );
	camera0->setTarget( core::vector3df( 0.0f, 0.0f, 0.0f ) );
	camera1->setPosition( core::vector3df( 0.0f, 50.0f, -50.0f ) );
	camera1->setTarget( core::vector3df( 0.0f, 0.0f, 0.0f ) );
	camera2->setPosition( core::vector3df( -50.0f, 50.0f, 0.0f ) );
	camera2->setTarget( core::vector3df( 0.0f, 0.0f, 0.0f ) );

	// Add a cube.
	scene::IMeshSceneNode* cube = scene->addCubeSceneNode();

	while ( device->run() )
	{
		// Get screen size.
		core::dimension2d<s32> screensize = driver->getScreenSize();

		// Begin scene.
		driver->beginScene( true, true, video::SColor( 255, 255, 255, 255 ) );

		// First camera.
		scene->setActiveCamera( camera0 );
		driver->setViewPort( core::rect<s32>( 0, 0, screensize.Width / 2, screensize.Height / 2 ) );
		scene->drawAll();

		// Second camera.
		scene->setActiveCamera( camera1 );
		driver->setViewPort( core::rect<s32>( screensize.Width / 2, 0, screensize.Width / 2, screensize.Height / 2 ) );
		scene->drawAll();

		// Third camera.
		scene->setActiveCamera( camera2 );
		driver->setViewPort( core::rect<s32>( 0, screensize.Height / 2, screensize.Width / 2, screensize.Height / 2 ) );
		scene->drawAll();

		// Fourth camera.
		scene->setActiveCamera( camera3 );
		driver->setViewPort( core::rect<s32>( screensize.Width / 2, screensize.Height / 2, screensize.Width / 2, screensize.Height / 2 ) );
		scene->drawAll();

		// End scene.
		driver->endScene();

		device->yield();
	}

	return 0;
}
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

The problem is that you are using core::rect<> incorrectly. The third and fourth parameter to the core::rect<> constructor are not width and height, they are the X and Y position of the bottom right corner of the rectangle.

So, the second, third and fourth setViewPort() calls you have above are wrong. They all make view rectangles that are either zero pixels tall, wide, or both. To avoid problems in the driver, the setViewPort() call guards against invalid rectangles.

Code: Select all

  803 	HRESULT hr = D3DERR_INVALIDCALL;
  804 	if (vp.getHeight()>0 && vp.getWidth()>0)
  805 		hr = pID3DDevice->SetViewport(&viewPort);
  806 
  807 	if (FAILED(hr))
  808 		os::Printer::log("Failed setting the viewport.", ELL_WARNING);
You might notice the error message that spews to the console when you run your code...

Travis
Nalin
Posts: 194
Joined: Thu Mar 30, 2006 12:34 am
Location: Lacey, WA, USA
Contact:

Post by Nalin »

Well, thanks for letting me know. Kind of embarrassing that I didn't think of that before. If I would have turned on the console for my debug builds this probably would have been a non-issue.
Dorth
Posts: 931
Joined: Sat May 26, 2007 11:03 pm

Post by Dorth »

An easy and good workaround is to declare your rect<> like this:
rect<>(position2d<>,dimension2d<>)
(you can typedef position2d and dimension2d of course)
Post Reply