• Create Account

We need 1 more developer from Canada and 12 more from Australia to help us complete a research survey.

Support our site by taking a quick sponsored survey and win a chance at a \$50 Amazon gift card. Click here to get started!

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

Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

21 replies to this topic

#1MARS_999  Members   -  Reputation: 1383

Like
1Likes
Like

Posted 11 June 2013 - 05:15 PM

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

#2L. Spiro  Crossbones+   -  Reputation: 21366

Like
4Likes
Like

Posted 11 June 2013 - 06:16 PM

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, 11 June 2013 - 06:20 PM.

#3MARS_999  Members   -  Reputation: 1383

Like
1Likes
Like

Posted 11 June 2013 - 07:01 PM

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

#4mhagain  Crossbones+   -  Reputation: 9956

Like
1Likes
Like

Posted 11 June 2013 - 07:43 PM

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

It appears that the gentleman thought C++ was extremely difficult and he was overjoyed that the machine was absorbing it; he understood that good C++ is difficult but the best C++ is well-nigh unintelligible.

#5MARS_999  Members   -  Reputation: 1383

Like
1Likes
Like

Posted 11 June 2013 - 11:09 PM

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

Thanks!

#6Dave Hunt  Crossbones+   -  Reputation: 4044

Like
0Likes
Like

Posted 11 June 2013 - 11:37 PM

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

#7mhagain  Crossbones+   -  Reputation: 9956

Like
0Likes
Like

Posted 12 June 2013 - 03:07 AM

It appears that the gentleman thought C++ was extremely difficult and he was overjoyed that the machine was absorbing it; he understood that good C++ is difficult but the best C++ is well-nigh unintelligible.

#8Dave Hunt  Crossbones+   -  Reputation: 4044

Like
0Likes
Like

Posted 12 June 2013 - 09:30 AM

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.

#9MARS_999  Members   -  Reputation: 1383

Like
0Likes
Like

Posted 13 June 2013 - 07:29 AM

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, 13 June 2013 - 07:31 AM.

#10L. Spiro  Crossbones+   -  Reputation: 21366

Like
0Likes
Like

Posted 13 June 2013 - 05:24 PM

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

#11MARS_999  Members   -  Reputation: 1383

Like
0Likes
Like

Posted 13 June 2013 - 07:34 PM

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 don't think so, I changed to Z axis and tried 0,0,0 for the position and it's still at center of screen... If I use 10,0,0 it move way over to the right side barely visible...

So for some reason the uploaded projection matrix isn't working?

#12L. Spiro  Crossbones+   -  Reputation: 21366

Like
0Likes
Like

Posted 13 June 2013 - 08:47 PM

I see a bunch of preparation code but no draw call.  By the time the draw call is issued you probably have a perspective matrix applied.  If the particles get small as you increase/decrease their Z then you have a perspective projection.

L. Spiro

#13MARS_999  Members   -  Reputation: 1383

Like
0Likes
Like

Posted 14 June 2013 - 12:30 AM

I see a bunch of preparation code but no draw call.  By the time the draw call is issued you probably have a perspective matrix applied.  If the particles get small as you increase/decrease their Z then you have a perspective projection.

L. Spiro

i am using this example.

http://irrlicht.sourceforge.net/docu/example008.html

they have no draw*() calls...

thanks

#14JTippetts  Moderators   -  Reputation: 10334

Like
1Likes
Like

Posted 14 June 2013 - 07:18 AM

That example creates a camera. If you are creating a camera in your code as well (following the example) then the camera will probably overwrite your direct driver::setTransform() calls during scene rendering. Why are you trying to bypass the built-in camera system and setting driver transform state directly? Just create an ICameraSceneNode as in the example, and manipulate that to get your desired perspective and view transforms. ICameraSceneNode even includes a method for setting the projection matrix directly.

#15MARS_999  Members   -  Reputation: 1383

Like
0Likes
Like

Posted 14 June 2013 - 08:26 AM

I am not using any camera at all in my code. I am just keeping the camera at 0,0,0 and rendering a screen and just want to work with the screen coordinates in x,y ortho view. This is a simple 2d game that never moves the camera...

Hello Josh!!!

#16Dave Hunt  Crossbones+   -  Reputation: 4044

Like
0Likes
Like

Posted 14 June 2013 - 08:39 AM

Yes, but the scene manager applies the camera's projection before rendering the scene, so any projection mucking you've done prior the the scene being rendered gets undone. You need to set the camera's projection matrix to ortho instead of mucking about with the device directly as JTippetts pointed out.

#17MARS_999  Members   -  Reputation: 1383

Like
0Likes
Like

Posted 16 June 2013 - 12:37 AM

I am using this code.

    irr::core::matrix4 projMatrix;
projMatrix = projMatrix.buildProjectionMatrixOrthoRH(config.screenSize.Width, config.screenSize.Height, 1.0f, 100.0f);
camera->setProjectionMatrix(projMatrix, true);


and no luck...

Thanks!

#18L. Spiro  Crossbones+   -  Reputation: 21366

Like
1Likes
Like

Posted 16 June 2013 - 02:24 AM

The main point is that we don’t know what happens inside the camera class in Irrlicht, so we don’t know what to make of the evidence, frankly.

There could be a number of things that would cause that matrix to be overwritten by the camera class itself.

Evidence suggests that a perspective projection is what gets fed to the graphics card at the end of the day, so you need to be searching by yourself for how that could possibly happen.  While you continue trying things to correct this problem, if they don’t work you need to think about “what else” could cause the problem to persist.  In this case, my first reaction would be to say that something is overwriting the camera matrix afterwards.  After all, you are changing things on your end, but the visual result is the same, so it must follow that your changes have either no meaning to the end result or are overwritten.

All you can do from there is keep reading about Irrlicht and keep trying your own experiments.

The secondary point is that “projMatrix = ” is superfluous.  Since I have seen the source code I know that that method modifies itself, and then returns itself.  Then you make a copy of itself into itself.  It’s not necessary to receive the return value from projMatrix.buildProjectionMatrixOrthoRH(); by the time it returns, projMatrix has already been filled with the correct values.

L. Spiro

#19MARS_999  Members   -  Reputation: 1383

Like
0Likes
Like

Posted 20 June 2013 - 01:51 PM

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

I have made some progress, but please look at the link above and read the last two posts.... It seems like I have to use half width to get the object on screen now... and Y is upside down DX upper left 0,0 vs. GL bottom left 0,0

#20JohnnyCode  Members   -  Reputation: 672

Like
1Likes
Like

Posted 20 June 2013 - 05:35 PM

I think you need some clarification. If your view and projection matricies are identities (not set), you get an orthogonal observation and your screen will contain only objects that are in -1 , 1 scope. That is, that if you have object of 4 verticies with values in object space (the object space equals your projection space now) such as 1.0,0.0, it will be placed at vertical center and at right edge of screen, and 0.0,0.0 will be placed at the center, -1.0,1.0 is the upper left corner. Do not confuse this with placing at screen resolution coordinates, 100,100 will place the thing 100 screens to the right up! If you want to place by screen pixel width height, divide by dimensions of screen then. Also realize that ortho camera has its certain scope of view, so if you devide everything by some value, say 1000, then you will be observing 1000.0,-1000.0 square, thus then -1000.0,1000.0 is your upper left corner. You cans still apply some world matricies to the objects. Also finaly, ortho camera may have rotation but this is often not desired, but ortho camera may need translation. So you should set up a view matrix with translation only, and apply that matrix. So in the end you are using only world matrcies per object, view matrix with only translation, and a projection matrix that only scales thing down by a single division. Possibly

Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

PARTNERS