Search code examples
javaopengl-esopengl-es-2.0perspectivecamera

Misunderstanding of multiplyMV - OpenGL ES 2.0


I wrote a simple program using OpenGL ES 2.0 and Java for Android. This program draw a point in a random position on the screen using an ortho projection matrix, view matrix and a model matrix. In the shader I put matrix * position.

All works well, but then I tried, for testing purpose, to calculate the position of the point by myself, so I used multiplyMV and as arguments I put my MVPmatrix (obtained by using multiplyMM before between projection and view and then between the result and the model matrix) and my point (for example 2f, 3.5f, 0f, 1f). The problem is that sometimes the result I get for x and/or y is greater than 1 or smaller than -1, despite the fact that the point is on the screen. But in normalized device coordinates the point must have a range between -1 and 1 in order to be "on screen".

I really don't understand where is my mistake.


Solution

  • The point has to be in normalized device space [-1, 1] (for x, y, z), after the projection matrix is applied.
    But note the point may be a Homogeneous coordinate. This means you have to do a Perspective divide first.

    The projection matrix describes the mapping from 3D points of a scene, to 2D points of the viewport. The projection matrix transforms from view space to the clip space. The coordinates in the clip space are transformed to the normalized device coordinates (NDC) in the range (-1, -1, -1) to (1, 1, 1) by dividing with the w component of the clip coordinates.

    Clip space coordinates are Homogeneous coordinates. In clipspace the clipping of the scene is performed. A point is in clip space if the x, y and z components are in the range defined by the inverted w component and the w component of the homogeneous coordinates of the point:

    -p.w <=  p.x, p.y, p.z  <= p.w.
    

    The clip coordinates are transformed to the normalized evice coordiantes by doing the Perspective divide:

    ndc.xyz = (p.x/p.w, p.y/p.w, p.z/p.w)