• Advertisement
Sign in to follow this  

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

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

If you intended to correct an error in the post then please contact us.

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.






Share this post

Link to post
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 )
         return *this;
Their original code can be found here:
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 this post

Link to post
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 this post

Link to post
Share on other sites

Or call buildProjectionMatrixOrthoLH instead.

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 this post

Link to post
Share on other sites

One last question, I am trying to use




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,

    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());

        ps = device->getSceneManager()->addParticleSystemSceneNode(false);
    //irr::scene::IParticleSystemSceneNode* ps = device->getSceneManager()->addParticleSystemSceneNode(false);
    //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));
        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));

    //irr::scene::IParticleAffector* paf = ps->createFadeOutParticleAffector();
        paf = ps->createFadeOutParticleAffector();
        ps->setMaterialFlag(irr::video::EMF_LIGHTING, false);
        ps->setMaterialFlag(irr::video::EMF_ZWRITE_ENABLE, false);
        ps->setMaterialTexture(0, driver->getTexture("media/portal6.png"));
        ps->setMaterialFlag(irr::video::EMF_LIGHTING, false);
        ps->setMaterialFlag(irr::video::EMF_ZWRITE_ENABLE, false);


Edited by MARS_999

Share this post

Link to post
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

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement