# Why is my screen centered 0,0 in the middle of screen?

This topic is 2315 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I am using Irrlicht 1.8 and when I try and setup a orthogonal projection with buildProjectionMatrixOrthoRH(), if I position the object it's (0,0) origin is the middle of the screen... I would like to have the coordinates start with the top or bottom left as the 0,0 point.

If I call draw2DPolygon() the top left is (0,0) and if I call drawIndexedTriangleFan() or draw2DVertexPrimitiveList() the center of the screen is (0,0)

I am not sure why this is, but need to get this solved.

http://irrlicht.sourceforge.net/forum/viewtopic.php?f=1&t=48773

##### Share on other sites
I don’t know the Irrlicht API but there is no way to accomplish what you want with that method; it automatically centers the projection.
Most API’s would give you an “offset” version of the same method, but apparently Irrlicht does not.

So you have to make one yourself.
Here is the code that would be plug-and-play for their matrix library:
     // Builds a customized, right-handed orthographic projection matrix.
template <class T>
inline CMatrix4<T>& CMatrix4<T>::buildProjectionMatrixOrthoOffCenterRH(
f32 left, f32 right, f32 bottom, f32 top, f32 zNear, f32 zFar)
{
T width = (T)(right-left);
T height = (T)(top-bottom);
_IRR_DEBUG_BREAK_IF(width==0.f); //divide by zero
_IRR_DEBUG_BREAK_IF(height==0.f); //divide by zero
_IRR_DEBUG_BREAK_IF(zNear==zFar); //divide by zero

M[0] = (T)(2/width);
M[1] = 0;
M[2] = 0;
M[3] = 0;

M[4] = 0;
M[5] = (T)(2/height);
M[6] = 0;
M[7] = 0;

M[8] = 0;
M[9] = 0;
M[10] = (T)(1/(zNear-zFar));
M[11] = 0;

M[12] = (T)((left+right)/(left-right));
M[13] = (T)((top+bottom)/(bottom-top));
M[14] = (T)(zNear/(zNear-zFar));
M[15] = 1;

#if defined ( USE_MATRIX_TEST )
definitelyIdentityMatrix=false;
#endif
return *this;
}
Their original code can be found here:
http://irrlicht.sourceforge.net/docu/matrix4_8h_source.html
buildProjectionMatrixOrthoRH() is defined on line 01639, and I based my version off that. Both are right-handed and row-major.

L. Spiro Edited by L. Spiro

##### Share on other sites
L. Spiro

THANK you! That did the trick!!! Odd that the developers at Irrlicht don't have the ability to choose this seems simple to add the parameter on calling the buildProjectionMatrixOrthoRH() to make it offset... :)

##### Share on other sites

Another option is to add a translation (by width / 2 and height / 2) to your transforms.

##### Share on other sites

One last quick question, how can I change the buildProjectionMatrixOrthoOffCenterRH() to be LH()?

Thanks!

##### Share on other sites

M[10] = (T)(1/(zFar-zNear));

##### Share on other sites

Which works if combined with your previous post (manually doing translations).

If you want the matrix to handle the translations for you, then you need L. Spiro's implementation.

##### Share on other sites

One last question, I am trying to use

irr::scene::IParticleEmitter

with this custom Projection matrix and it will not render the position correctly? Do I need to make my own particle class to use this?

It renders the effect at 0,0,0 when I set position to that, but if I use 400, 0, their isn't anything on screen. Screen size is 800,600 so it should be at middle bottom of screen...


void NX::Effect::DrawEffect(irr::IrrlichtDevice* device,
irr::video::IVideoDriver* driver)
{
NX::App* p = NX::App::Get();

irr::core::matrix4 oldProjMat  = driver->getTransform(irr::video::ETS_PROJECTION);
irr::core::matrix4 oldViewMat  = driver->getTransform(irr::video::ETS_VIEW);
irr::core::matrix4 oldWorldMat = driver->getTransform(irr::video::ETS_WORLD);

irr::core::matrix4 projMatrix;
NX::BuildProjMatrixOrthoOffCenterRH(0.0f, p->GetAppConfig()->screenSize.Width,
0.0f, p->GetAppConfig()->screenSize.Height,
-1.0f, 100.0f,
projMatrix);

driver->setTransform(irr::video::ETS_PROJECTION, projMatrix);
driver->setTransform(irr::video::ETS_VIEW,  irr::core::matrix4());
driver->setTransform(irr::video::ETS_WORLD, irr::core::matrix4());

if(!ps)
//irr::scene::IParticleEmitter* em         = ps->createRingEmitter(pos, .005f, .05f);

//em->setMinStartSize(irr::core::dimension2d<irr::f32>(.1f, .1f));
//em->setMaxStartSize(irr::core::dimension2d<irr::f32>(.5f, .5f));

//irr::scene::IParticleEmitter* em = ps->createRingEmitter(pos, 0.0f, 5.0f, irr::core::vector3df(0.0f, 0.0f, .01f));
if(!em)
{
em = ps->createRingEmitter(pos, 0.0f, 1.0f, irr::core::vector3df(0.0f, 0.0f, 0.0f));
em->setMinStartSize(irr::core::dimension2d<irr::f32>(1.0f, 1.0f));
em->setMaxStartSize(irr::core::dimension2d<irr::f32>(1.0f, 1.0f));
ps->setEmitter(em);
em->drop();
}

if(!paf)
{
paf->drop();
ps->setMaterialFlag(irr::video::EMF_LIGHTING, false);
ps->setMaterialFlag(irr::video::EMF_ZWRITE_ENABLE, false);
ps->setMaterialTexture(0, driver->getTexture("media/portal6.png"));
}
else
{
ps->setMaterialFlag(irr::video::EMF_LIGHTING, false);
ps->setMaterialFlag(irr::video::EMF_ZWRITE_ENABLE, false);
driver->enableMaterial2D(true);
}
}


Thanks!

Edited by MARS_999

##### Share on other sites

I would expect [0, 0] to be the upper-left, not the lower-left.

In any case, using the new projection matrix, [400, 300] is exactly the same as [0, 0] in the previous projection matrix (center of the screen).

I would suggest using that as your test case as it may very well be that your particles are all shooting upwards and since your Y is 0, all particles start at the top of the screen and fly even further off the top of the screen, meaning you can never see them.

L. Spiro

• ### Game Developer Survey

We are looking for qualified game developers to participate in a 10-minute online survey. Qualified participants will be offered a \$15 incentive for your time and insights. Click here to start!

• 16
• 13
• 9
• 11
• 15