Unified D3D and OpenGL coordinate system

Source: Internet
Author: User

Author: Nang Lanhai (Http://blog.csdn.net/you_lan_hai)


The difference between DirectX 3D and OpenGL coordinate system brings us a lot of trouble and makes the novice of cross-platform programming confused. Recently in a cross-platform game, carefully looking at the matrix of the two, found that there is no big difference, the D3D left-handed matrix passed to OpenGL shader can work perfectly.

Let's talk about some conceptual differences:

(1) Different coordinate systems

D3D left-hand coordinate system, OpenGL right-hand coordinate

(2) different row order of matrices

D3D Line first, OpenGL column first. These two differences directly lead to the inverse of the coordinate transformation order and the matrix multiplication order. If it is scaled first, then rotated, and finally translated, the corresponding matrix is S, R, T, then the final matrix of D3D is M = S * r * T,opengl m = T * R * S

(3) the Z-value range of the reduction space is different

D3D is [0, 1],opengl is [-1, 1]


On the surface, the two matrices differ greatly, but they are not.

1. Hand coordinate system

For a graphics device, the device coordinate system is left-handed, that is, the z-axis is pointing to the screen, and the greater the Z value indicates the farther away from the line of sight. Therefore, OpenGL's right-hand system, when it enters the cut space, is converted to a left-handed system. This means that within the rendering pipeline, the coordinate system is uniform. Whether it is the left-hand coordinate system matrix or the right-hand coordinate system matrix, as long as the transition to the cut space point is the left-hand system.


2. Matrix row Order

The row matrix and the column matrix, logically one is another transpose, but in the physical storage structure is exactly the same. such as a translation transformation (x, Y, z):


It is important to note that matrix multiplication does not care whether the matrix is a row or column matrix, and is multiplied by the row of the first matrix by the column of the second matrix. For the column matrix, this is the bad place, in order to ensure the validity of the multiplication meaning, the coordinate transformation order is the same as the matrix multiplication order exactly opposite.

Also note that in shader, OpenGL's matrix multiplication rules are different from D3D. Rule by matrix multiplication (first matrix row * Second matrix column):

D3D matrix multiplication: Ma (0 1 2 3) * MB (0 4 8 12)

OpenGL matrix multiplication: Ma (0 4 8) * MB (0 1 2 3)

Therefore, for OpenGL shader, the transformation order and matrix multiplication order are still reversed. If we can transpose the matrix of incoming OpenGL shader, then the shader matrix multiplication of OpenGL will be exactly the same as D3D shader.


3. Modify the projection matrix

Since OpenGL's cut-space Z-value range is [-1, 1] Unlike D3D's [0, 1], we cannot simply use the D3D projection matrix and must redefine the D3D projection matrix.

void Matrix::p erspectiveProjectionLH2 (float FoV, float aspectratio,
        float nearplane, float farplane)
{
        Float h = (1.0f/tanf (FOV * 0.5f));
        float w = h/aspectratio;

        float A = (Farplane + nearplane)/(Farplane-nearplane);
        Float B = -2.0f * Farplane * Nearplane/(Farplane-nearplane);
        
        M[0][0] = W; M[0][1] = 0; M[0][2] = 0; M[0][3] = 0;
        M[1][0] = 0; M[1][1] = h; M[1][2] = 0; M[1][3] = 0;
        M[2][0] = 0; M[2][1] = 0; M[2][2] = A; M[2][3] = 1;
        M[3][0] = 0; M[3][1] = 0; M[3][2] = b; M[3][3] = 0;
}


4. Summary

It is convenient to use the left-handed transform to unify two platforms. Summarize the steps to modify the OpenGL rendering pipeline:

(1) in the C + + layer Unified use left-handed coordinate system transformation;

(2) Modify the projection matrix to fit the z-coordinate range of the cut space [-1, 1];

(3) When the matrix is passed into the shader, the Matrix's transpose matrix is introduced;

(4) In the shader layer, the uniform use of left-handed coordinate system transformation.

If you do not want to modify the transformations in the shader, just do (1) and (2) suffice.


5. Read more

Derivation of projection matrix http://blog.csdn.net/popy007/article/details/4091967

Bridging the gap between OpenGL and D3D http://www.cppblog.com/topjackhjj/articles/157038.html


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.