Code: Select all
// flip z to compensate OpenGLs right-hand coordinate system
glmat[12] *= -1.0f;
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;
}