How to adapt DirectX-style world/view/projection m

2019-06-02 23:26发布

I have an application which uses DirectX, and hence a left-handed world-coordinate systen, a view which looks down positive z and a projection which projects into the unit cube but with z from 0..1.

I'm porting this application to OpenGL, and OpenGL has a different coordinate system etc. In particular, it's right-handed, the view looks down along negative z, and the projection is into the real unit cube.

What is the easiest way to adapt the DirectX matrices to OpenGL? The world-space change seems to be easy, just by flipping the x-axis, but I'm not entirely sure how to change the view/projection. I can modify all of the matrices individually before multiplying them together and sending them off to my shader. If possible, I would like to stick with the DirectX based coordinate system as far down the pipeline as possible (i.e. I don't want to change where I place my objects, how I compute my view frustum, etc. -- ideally, I'll only apply some modification to the matrices right before handing them over to my shaders.)

3条回答
相关推荐>>
2楼-- · 2019-06-03 00:04

The answer is: There's no need to flip anything, only to tweak the depth range. OpenGL has -1..1, and DX has 0..1. You can use the DX matrices just as before, and only multiply a scale/bias matrix at the end on top of the projection matrix to scale the depth values from 0..1 to -1..1.

查看更多
We Are One
3楼-- · 2019-06-03 00:05

There is an age-old extension for OpenGL exactly for that: GL_ARB_TRANSPOSE_MATRIX. It transposes matrices on GPU and should be available on every video card.

查看更多
Ridiculous、
4楼-- · 2019-06-03 00:18

Not tested or anything, just out of the top of my head :

oglProj = transpose(dxProj)
glScalef (1., 1., -1.);  // invert z
glScalef(0.5, 0.5, 1); // from [-1,1] to [-0.5, 0.5]
glTranslatef(0.5, 0.5, 0) // from [-0.5, 0.5] to [0,1]

oglView = transpose(dxView)
glScalef (1., 1., -1.);  // invert z

oglModel = transpose(dwModel)
glScalef (1., 1., -1.);  // invert z

oglModelView = oglView * oglModel
查看更多
登录 后发表回答