cancel
Showing results for 
Search instead for 
Did you mean: 

Orthographic matrix is upside-down in OpenGL

jherico
Adventurer
I'm trying to work on a couple of examples showing the use of the orthographic projection matrix to render elements to the screen. Yes, I know that elements that are fixed to the orientation of the Rift are frowned upon, but they're a) invaluable for debugging and b) justified if you're recreating an actual helmet based HUD, like an Iron Man style interface. Anyway...

My test application uses the output of the of the ovrMatrix4f_Projection() method (with the rightHanded parameter set to true, since I'm working in GL), uses a scale of (1, 1) and a distance of 0.8. I then draw a quad from (-0.5, -0.5) to (0.5, 0.5) with a primary color in each corner and white in the upper left.

At first I had issues with not seeing anything at all, until I realized my geometry was there, but being eliminated by face-culling. When I turned off face-culling I discovered that my simple quad had been flipped 180 degrees on the X axis, so that the white corner was in the lower left.

I'm assuming that this is another issue where the SDK isn't taking into account OpenGL vs DirectX conventions.
Brad Davis - Developer for High Fidelity Co-author of Oculus Rift in Action
4 REPLIES 4

vrdaveb
Oculus Staff
"jherico" wrote:
I'm trying to work on a couple of examples showing the use of the orthographic projection matrix to render elements to the screen.

Sure, it also makes sense for a number of cases. If you render the same thing to both eyes, it will appear on a plane that is infinitely far away.

"jherico" wrote:
At first I had issues with not seeing anything at all, until I realized my geometry was there, but being eliminated by face-culling.

I assume you're using SDK 0.3.2. If so, we shouldn't be interfering with your culling state. If you're using GL_BACK and drawing the quad in counter-clockwise order our projection matrix shouldn't be causing the quad to get culled. Let me know if we are missing something there.

"jherico" wrote:
When I turned off face-culling I discovered that my simple quad had been flipped 180 degrees on the X axis, so that the white corner was in the lower left.

Can you try adding the following code to OVR::CAPI::GL::DistortionRenderer::SubmitEye(..), just after the call to ovrHmd_GetRenderScaleAndOffset(..)?
			eachEye[eyeId].UVScaleOffset[0].y = -eachEye[eyeId].UVScaleOffset[0].y;
eachEye[eyeId].UVScaleOffset[1].y = 1.0f - eachEye[eyeId].UVScaleOffset[1].y;

jherico
Adventurer
"vrdaveb" wrote:
"jherico" wrote:
I'm trying to work on a couple of examples showing the use of the orthographic projection matrix to render elements to the screen.

Sure, it also makes sense for a number of cases. If you render the same thing to both eyes, it will appear on a plane that is infinitely far away.


Actually, my reading of the Ortho function is that the items rendered while using the projection will appear at a fixed distance away, specified as one of the parameters. Indeed, if I pass in 0.2 to the orthoDistance parameter, the two rendered squares are pushed in towards the center, as if i were looking at a small paper held uncomfortably close to my face. The larger the orthoDistance value, the closer the two squares are to being perfectly centered in my eye view. This is more or less what I expect.

"vrdaveb" wrote:
"jherico" wrote:
At first I had issues with not seeing anything at all, until I realized my geometry was there, but being eliminated by face-culling.

I assume you're using SDK 0.3.2. If so, we shouldn't be interfering with your culling state. If you're using GL_BACK and drawing the quad in counter-clockwise order our projection matrix shouldn't be causing the quad to get culled. Let me know if we are missing something there.


The quad is rendered CCW, as is the rest of my geometry. The remainder of my rendering works fine, which jibes with the projection matrix being rotated so that it's facing the wrong way. I'll double check when I get home that rendering the quad with the normal projection matrix works properly.

"vrdaveb" wrote:
"jherico" wrote:
When I turned off face-culling I discovered that my simple quad had been flipped 180 degrees on the X axis, so that the white corner was in the lower left.

Can you try adding the following code to OVR::CAPI::GL::DistortionRenderer::SubmitEye(..), just after the call to ovrHmd_GetRenderScaleAndOffset(..)?
			eachEye[eyeId].UVScaleOffset[0].y = -eachEye[eyeId].UVScaleOffset[0].y;
eachEye[eyeId].UVScaleOffset[1].y = 1.0f - eachEye[eyeId].UVScaleOffset[1].y;


I'll give it a shot when I get home, but wouldn't that impact the rest of my rendering as well? I'll also push the full example to my github repository on a branch so you can examine the whole thing if you so desire.
Brad Davis - Developer for High Fidelity Co-author of Oculus Rift in Action

vrdaveb
Oculus Staff
It looks like the ovrMatrix4f_OrthoSubProjection(..) uses Y=down, resulting in a left-handed coordinate system that flipped the winding of your quad. I'll see about adding a "right-handed" option. For now, can you render your quad clockwise and upside-down? Alternatively you could flip the sign of the following line:

    ortho.M[1][1] = -projection.M[1][1] * orthoScale.y;       // Note sign flip (text rendering uses Y=down).

jherico
Adventurer
"vrdaveb" wrote:
It looks like the ovrMatrix4f_OrthoSubProjection(..) uses Y=down, resulting in a left-handed coordinate system that flipped the winding of your quad. I'll see about adding a "right-handed" option. For now, can you render your quad clockwise and upside-down? Alternatively you could flip the sign of the following line:

    ortho.M[1][1] = -projection.M[1][1] * orthoScale.y;       // Note sign flip (text rendering uses Y=down).


Yeah, doing this in my code fixes it:


pr.top()[1][1] = -pr.top()[1][1];


IMO, it's a mistake to assume that the caller is going to be using the ortho matrix only for text rendering, or that they'll necessarily require text rendering to use +Y = down.

In particular, in my text rendering code I like to target an ortho-graphic matrix with bounds of [-1,1] with Y pointing up, and then use the modelview matrix to provide relative positioning and scaling of the text within those bounds.

It would also be nice if you could define the ortho matrix in terms of the FOV it would cover, rather than the somewhat vaguely named 'scale' parameter. I'm not quite sure what exactly scale is supposed to do. For that matter, it would be nice if I could simply specify the orthoDistance and have the Oculus SDK automatically produce a matrix where 1 unit was still 1 meter (at least at the center of the FOV).
Brad Davis - Developer for High Fidelity Co-author of Oculus Rift in Action
Still need help?

Did this answer your question? If it didn’t, use our search to find other topics or create your own and other members of the community will help out.

If you need an agent to help with your Meta device, please contact our store support team here.

Having trouble with a Facebook or Instagram account? The best place to go for help with those accounts is the Facebook Help Center or the Instagram Help Center. This community can't help with those accounts.

Check out some popular posts here:

Getting Help from the Meta Quest Community

Tips and Tricks: Charging your Meta Quest Headset

Tips and Tricks: Help with Pairing your Meta Quest

Trouble With Facebook/Instagram Accounts?