I've decided to use JOGL for my project. But here is the problem with setting perspective. Simple code:
System.out.println("BEFORE:");
projectionMatrix.identity();
projectionMatrix.setPerspective(fovy, aspect, zNear, zFar);
System.out.println(projectionMatrix);
System.out.println("AFTER:");
projectionMatrix.identity();
projectionMatrix.m00 =
(float)(1.0 / (aspect*Math.tan(viewAngle)));
projectionMatrix.m11 =
(float)(1.0 / Math.tan(viewAngle));
projectionMatrix.m22 =
(float)((-zNear-zFar) / (zNear-zFar));
projectionMatrix.m33 = 0.0f;
projectionMatrix.m23 =
(float)((2*zFar*zNear) / (zNear-zFar));
projectionMatrix.m32 = 1.0f;
System.out.println(projectionMatrix);
Output:
BEFORE:
2.414E+0 0.000E+0 0.000E+0 0.000E+0
0.000E+0 2.414E+0 0.000E+0 0.000E+0
0.000E+0 0.000E+0 -1.000E+0 -2.000E-2
0.000E+0 0.000E+0 -1.000E+0 0.000E+0
AFTER:
1.000E+0 0.000E+0 0.000E+0 0.000E+0
0.000E+0 1.000E+0 0.000E+0 0.000E+0
0.000E+0 0.000E+0 1.000E+0 1.000E+0
0.000E+0 0.000E+0 -2.000E-2 0.000E+0
As you can see, matrices are different. Their (jogl) code:
public Matrix4f setPerspective(float fovy, float aspect, float zNear, float zFar) {
float h = (float) Math.tan(fovy * 0.5f) * zNear;
float w = h * aspect;
m00 = zNear / w;
m01 = 0.0f;
m02 = 0.0f;
m03 = 0.0f;
m10 = 0.0f;
m11 = zNear / h;
m12 = 0.0f;
m13 = 0.0f;
m20 = 0.0f;
m21 = 0.0f;
m22 = -(zFar + zNear) / (zFar - zNear);
m23 = -1.0f;
m30 = 0.0f;
m31 = 0.0f;
m32 = -2.0f * zFar * zNear / (zFar - zNear);
m33 = 0.0f;
return this;
}
Gives different from mine. Program works fine with my version of code. How do I use their library?
Another problem: simple by switching from javax.vecmath.Matrix4f to org.joml.Matrix4f rotation becomes broken (rotate around wrong axis and around a point that is slightly off camera).
First, update jogl, second use
FloatUtil.makePerspective(final float[] m, final int m_off, final boolean initM, final float fovy_rad, final float aspect, final float zNear, final float zFar)
float[] m
is the matrix you need to submit. This offers you flexibility, that means if you want use pools, you can. Otherwise just passnew float[16]
and catch the return result