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

Started by
20 comments, last by MARS_999 10 years, 10 months ago

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

Advertisement
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

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

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... :)

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

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

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

Thanks!

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

Or call buildProjectionMatrixOrthoLH instead.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

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.

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

    //irr::scene::IParticleAffector* paf = ps->createFadeOutParticleAffector();
    if(!paf)
    {
        paf = ps->createFadeOutParticleAffector();
        ps->addAffector(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"));
        ps->setMaterialType(irr::video::EMT_TRANSPARENT_ADD_COLOR);
    }
    else
    {
        ps->setMaterialFlag(irr::video::EMF_LIGHTING, false);
        ps->setMaterialFlag(irr::video::EMF_ZWRITE_ENABLE, false);
        ps->setMaterialType(irr::video::EMT_TRANSPARENT_ADD_COLOR);
        driver->enableMaterial2D(true);
    }
}

Thanks!

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

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

This topic is closed to new replies.

Advertisement