Projection matrix bug in OpenGL driver

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
rvl2
Posts: 6
Joined: Sun Aug 23, 2009 10:43 am

Projection matrix bug in OpenGL driver

Post by rvl2 »

COpenGLDriver.cpp has the following lines in COpenGLDriver::setTransform(...) method

Code: Select all

// flip z to compensate OpenGLs right-hand coordinate system
glmat[12] *= -1.0f;
The comment is very strange as in OpenGL matrix glmat[12] is x-offset.
The bug is not visible in usual cases because native Irrlicht camera nodes have projection matrix with glmat[12] = 0. But for custom projections the problem exists and the following program demonstrates it.

Code: Select all

#include <irrlicht.h>
#include <iostream>

using namespace irr;
using namespace irr::core;
using namespace irr::video;

#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif


int main()
{
	video::E_DRIVER_TYPE driverType;

	printf("Please select the driver you want for this example:\n"\
		" (a) Direct3D 9.0c\n (b) OpenGL 1.5\n"\
		" (c) Burning's Software Renderer\n"\
		" (otherKey) exit\n\n");

	char i;
	std::cin >> i;

	switch(i)
	{
		case 'a': driverType = video::EDT_DIRECT3D9;break;
		case 'b': driverType = video::EDT_OPENGL;   break;
		case 'c': driverType = video::EDT_BURNINGSVIDEO;break;
		default: return 0;
	}
	
	IrrlichtDevice *device = createDevice(driverType,
		core::dimension2d<u32>(640, 480));

	if (device == 0)
		return 1;

	device->setWindowCaption(L"Irrlicht Engine - Projection matrix test");

	video::IVideoDriver* driver = device->getVideoDriver();

	while(device->run() && driver)
	{
		if (device->isWindowActive())
		{
			driver->beginScene(true, false, SColor(255,0,0,0));
			
			SMaterial mat;
			mat.MaterialType = EMT_SOLID;
			mat.Lighting = false;
			mat.ZBuffer = false;
			mat.ZWriteEnable = false;
			mat.Thickness = 1;

			driver->setMaterial(mat);

			core::dimension2d<u32> dims = driver->getCurrentRenderTargetSize();
			//apply custom projection, no offset
			core::matrix4 pmtx = matrix4().buildProjectionMatrixOrthoLH(dims.Width, dims.Height, 0, 100);
			driver->setTransform(ETS_PROJECTION, pmtx);
			driver->setTransform(ETS_VIEW, matrix4());
			driver->setTransform(ETS_WORLD, matrix4());
			
			//the red cross appears at center
			driver->draw3DLine(vector3df(0,-50,1), vector3df(0,50,1), SColor(255,255,0,0));
			driver->draw3DLine(vector3df(-50,0,1), vector3df(50,0,1), SColor(255,255,0,0));
			
			//apply custom projection, offset to right-top
			pmtx.setTranslation(vector3df(0.7, 0.7, 0));
			driver->setTransform(ETS_PROJECTION, pmtx);
			driver->setTransform(ETS_VIEW, matrix4());
			driver->setTransform(ETS_WORLD, matrix4());

			//The green cross must be in right-top corner. But for OpenGL driver it is in left-top corner
			driver->draw3DLine(vector3df(0,-50,1), vector3df(0,50,1), SColor(255,0,255,0));
			driver->draw3DLine(vector3df(-50,0,1), vector3df(50,0,1), SColor(255,0,255,0));

			driver->endScene();
		}
	}

	device->drop();

	return 0;
}
To fix the problem those two lines in COpenGLDriver.cpp must be removed.
Post Reply