Java LWJGL 3中的视图矩阵未显示右侧
我的相机类中的视图矩阵设置正确,带有旋转和负平移,但它将相机移动到其他地方,我似乎找不到我的模型。旋转和平移矩阵起作用是因为平移起作用,而我的模型和投影矩阵也起作用,但当我添加视图矩阵时,它只显示模型的一部分。顺便说一下,我自己上了矩阵数学课 矩阵数学课Java LWJGL 3中的视图矩阵未显示右侧,java,opengl,matrix,lwjgl,Java,Opengl,Matrix,Lwjgl,我的相机类中的视图矩阵设置正确,带有旋转和负平移,但它将相机移动到其他地方,我似乎找不到我的模型。旋转和平移矩阵起作用是因为平移起作用,而我的模型和投影矩阵也起作用,但当我添加视图矩阵时,它只显示模型的一部分。顺便说一下,我自己上了矩阵数学课 矩阵数学课 package engine.maths; public class Matrix4f { private float[][] matrix; public Matrix4f() { matrix = new
package engine.maths;
public class Matrix4f {
private float[][] matrix;
public Matrix4f() {
matrix = new float[4][4];
}
public Matrix4f identity() {
matrix[0][0] = 1; matrix[0][1] = 0; matrix[0][2] = 0; matrix[0][3] = 0;
matrix[1][0] = 0; matrix[1][1] = 1; matrix[1][2] = 0; matrix[1][3] = 0;
matrix[2][0] = 0; matrix[2][1] = 0; matrix[2][2] = 1; matrix[2][3] = 0;
matrix[3][0] = 0; matrix[3][1] = 0; matrix[3][2] = 0; matrix[3][3] = 1;
return this;
}
public Matrix4f translate(Vector3f vector) {
matrix[0][0] = 1; matrix[0][1] = 0; matrix[0][2] = 0; matrix[0][3] = vector.getX();
matrix[1][0] = 0; matrix[1][1] = 1; matrix[1][2] = 0; matrix[1][3] = vector.getY();
matrix[2][0] = 0; matrix[2][1] = 0; matrix[2][2] = 1; matrix[2][3] = vector.getZ();
matrix[3][0] = 0; matrix[3][1] = 0; matrix[3][2] = 0; matrix[3][3] = 1;
return this;
}
public Matrix4f rotate(Vector3f vector) {
Matrix4f rotateX = new Matrix4f();
Matrix4f rotateY = new Matrix4f();
Matrix4f rotateZ = new Matrix4f();
Vector3f rotatedVector = new Vector3f((float) Math.toRadians(vector.getX()), (float) Math.toRadians(vector.getY()), (float) Math.toRadians(vector.getZ()));
rotateZ.matrix[0][0] = (float)Math.cos(rotatedVector.getZ()); rotateZ.matrix[0][1] = -(float)Math.sin(rotatedVector.getZ()); rotateZ.matrix[0][2] = 0; rotateZ.matrix[0][3] = 0;
rotateZ.matrix[1][0] = (float)Math.sin(rotatedVector.getZ()); rotateZ.matrix[1][1] = (float)Math.cos(rotatedVector.getZ()); rotateZ.matrix[1][2] = 0; rotateZ.matrix[1][3] = 0;
rotateZ.matrix[2][0] = 0; rotateZ.matrix[2][1] = 0; rotateZ.matrix[2][2] = 1; rotateZ.matrix[2][3] = 0;
rotateZ.matrix[3][0] = 0; rotateZ.matrix[3][1] = 0; rotateZ.matrix[3][2] = 0; rotateZ.matrix[3][3] = 1;
rotateX.matrix[0][0] = 1; rotateX.matrix[0][1] = 0; rotateX.matrix[0][2] = 0; rotateX.matrix[0][3] = 0;
rotateX.matrix[1][0] = 0; rotateX.matrix[1][1] = (float)Math.cos(rotatedVector.getX()); rotateX.matrix[1][2] = -(float)Math.sin(rotatedVector.getX()); rotateX.matrix[1][3] = 0;
rotateX.matrix[2][0] = 0; rotateX.matrix[2][1] = (float)Math.sin(rotatedVector.getX()); rotateX.matrix[2][2] = (float)Math.cos(rotatedVector.getX()); rotateX.matrix[2][3] = 0;
rotateX.matrix[3][0] = 0; rotateX.matrix[3][1] = 0; rotateX.matrix[3][2] = 0; rotateX.matrix[3][3] = 1;
rotateY.matrix[0][0] = (float)Math.cos(rotatedVector.getY()); rotateY.matrix[0][1] = 0; rotateY.matrix[0][2] = -(float)Math.sin(rotatedVector.getY()); rotateY.matrix[0][3] = 0;
rotateY.matrix[1][0] = 0; rotateY.matrix[1][1] = 1; rotateY.matrix[1][2] = 0; rotateY.matrix[1][3] = 0;
rotateY.matrix[2][0] = (float)Math.sin(rotatedVector.getY()); rotateY.matrix[2][1] = 0; rotateY.matrix[2][2] = (float)Math.cos(rotatedVector.getY()); rotateY.matrix[2][3] = 0;
rotateY.matrix[3][0] = 0; rotateY.matrix[3][1] = 0; rotateY.matrix[3][2] = 0; rotateY.matrix[3][3] = 1;
matrix = rotateZ.mul(rotateY.mul(rotateX)).getMatrix();
return this;
}
public Matrix4f scale(Vector3f vector) {
matrix[0][0] = vector.getX(); matrix[0][1] = 0; matrix[0][2] = 0; matrix[0][3] = 0;
matrix[1][0] = 0; matrix[1][1] = vector.getY(); matrix[1][2] = 0; matrix[1][3] = 0;
matrix[2][0] = 0; matrix[2][1] = 0; matrix[2][2] = vector.getZ(); matrix[2][3] = 0;
matrix[3][0] = 0; matrix[3][1] = 0; matrix[3][2] = 0; matrix[3][3] = 1;
return this;
}
public Matrix4f projection(float fov, float aspectRatio, float zNear, float zFar) {
float tanHalfFOV = (float) Math.tan(Math.toRadians(fov / 2));
float zRange = zNear - zFar;
matrix[0][0] = 1.0f / (tanHalfFOV * aspectRatio); matrix[0][1] = 0; matrix[0][2] = 0; matrix[0][3] = 0;
matrix[1][0] = 0; matrix[1][1] = 1.0f / tanHalfFOV; matrix[1][2] = 0; matrix[1][3] = 0;
matrix[2][0] = 0; matrix[2][1] = 0; matrix[2][2] = (-zNear - zFar) / zRange; matrix[2][3] = 2 * zFar * zNear / zRange;
matrix[3][0] = 0; matrix[3][1] = 0; matrix[3][2] = 1; matrix[3][3] = 0;
return this;
}
public Matrix4f mul(Matrix4f m) {
Matrix4f result = new Matrix4f();
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
result.set(i, j, matrix[i][0] * m.get(0, j) +
matrix[i][1] * m.get(1, j) +
matrix[i][2] * m.get(2, j) +
matrix[i][3] * m.get(3, j));
}
}
return result;
}
public float[][] getMatrix() {
return matrix;
}
public void setMatrix(float[][] matrix) {
this.matrix = matrix;
}
public float get(int x, int y) {
return matrix[x][y];
}
public void set(int x, int y, float value) {
matrix[x][y] = value;
}
public String toString() {
String matrix = "";
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
matrix += (Float.toString(get(i, j)) + ", ");
}
matrix += "\n";
}
return matrix + "";
}
}
package engine.rendering;
import engine.maths.Matrix4f;
import engine.maths.Vector3f;
public class Camera {
private Vector3f position, rotation;
public Camera(Vector3f position, Vector3f rotation) {
this.position = position;
this.rotation = rotation;
}
public Matrix4f getViewMatrix() {
Matrix4f rotationMatrix = new Matrix4f().identity().rotate(rotation);
Vector3f negativePosition = new Vector3f(-position.getX(), -position.getY(), -position.getZ());
Matrix4f translationMatrix = new Matrix4f().identity().translate(negativePosition);
return rotationMatrix.mul(translationMatrix);
}
public void addPosition(float x, float y, float z) {
position.add(new Vector3f(x, y, z));
}
public void addPosition(Vector3f value) {
position.add(value);
}
public void setPosition(float x, float y, float z) {
position = new Vector3f(x, y, z);
}
public void setPosition(Vector3f pos) {
position = pos;
}
public Vector3f getPosition() {
return position;
}
public void addRotation(float x, float y, float z) {
rotation.add(new Vector3f(x, y, z));
}
public void addRotation(Vector3f value) {
rotation.add(value);
}
public void setRotation(float x, float y, float z) {
rotation = new Vector3f(x, y, z);
}
public void setRotation(Vector3f rot) {
rotation = rot;
}
public Vector3f getRotation() {
return rotation;
}
}
package engine.shaders;
import engine.maths.Matrix4f;
public class BasicShader extends Shader {
private static final String VERTEX_FILE = "src/engine/shaders/basicVertexShader.glsl";
private static final String FRAGMENT_FILE = "src/engine/shaders/basicFragmentShader.glsl";
private int tvpMatrixLocation;
private Matrix4f transformationMatrix = new Matrix4f().identity(), projectionMatrix = new Matrix4f().identity(), viewMatrix = new Matrix4f().identity();
public BasicShader() {
super(VERTEX_FILE, FRAGMENT_FILE);
}
@Override
protected void bindAttributes() {
super.bindAttribute(0, "position");
super.bindAttribute(1, "textCoords");
}
@Override
protected void getAllUniforms() {
tvpMatrixLocation = super.getUniform("tvpMatrix");
}
public void useMatrices() {
super.loadMatrixUniform(tvpMatrixLocation, transformationMatrix.mul(projectionMatrix.mul(viewMatrix)));
}
public void loadTransformationMatrix(Matrix4f matrix) {
transformationMatrix = matrix;
}
public void loadProjectionMatrix(Matrix4f matrix) {
projectionMatrix = matrix;
}
public void loadViewMatrix(Matrix4f matrix) {
viewMatrix = matrix;
}
}
加载矩阵类
package engine.maths;
public class Matrix4f {
private float[][] matrix;
public Matrix4f() {
matrix = new float[4][4];
}
public Matrix4f identity() {
matrix[0][0] = 1; matrix[0][1] = 0; matrix[0][2] = 0; matrix[0][3] = 0;
matrix[1][0] = 0; matrix[1][1] = 1; matrix[1][2] = 0; matrix[1][3] = 0;
matrix[2][0] = 0; matrix[2][1] = 0; matrix[2][2] = 1; matrix[2][3] = 0;
matrix[3][0] = 0; matrix[3][1] = 0; matrix[3][2] = 0; matrix[3][3] = 1;
return this;
}
public Matrix4f translate(Vector3f vector) {
matrix[0][0] = 1; matrix[0][1] = 0; matrix[0][2] = 0; matrix[0][3] = vector.getX();
matrix[1][0] = 0; matrix[1][1] = 1; matrix[1][2] = 0; matrix[1][3] = vector.getY();
matrix[2][0] = 0; matrix[2][1] = 0; matrix[2][2] = 1; matrix[2][3] = vector.getZ();
matrix[3][0] = 0; matrix[3][1] = 0; matrix[3][2] = 0; matrix[3][3] = 1;
return this;
}
public Matrix4f rotate(Vector3f vector) {
Matrix4f rotateX = new Matrix4f();
Matrix4f rotateY = new Matrix4f();
Matrix4f rotateZ = new Matrix4f();
Vector3f rotatedVector = new Vector3f((float) Math.toRadians(vector.getX()), (float) Math.toRadians(vector.getY()), (float) Math.toRadians(vector.getZ()));
rotateZ.matrix[0][0] = (float)Math.cos(rotatedVector.getZ()); rotateZ.matrix[0][1] = -(float)Math.sin(rotatedVector.getZ()); rotateZ.matrix[0][2] = 0; rotateZ.matrix[0][3] = 0;
rotateZ.matrix[1][0] = (float)Math.sin(rotatedVector.getZ()); rotateZ.matrix[1][1] = (float)Math.cos(rotatedVector.getZ()); rotateZ.matrix[1][2] = 0; rotateZ.matrix[1][3] = 0;
rotateZ.matrix[2][0] = 0; rotateZ.matrix[2][1] = 0; rotateZ.matrix[2][2] = 1; rotateZ.matrix[2][3] = 0;
rotateZ.matrix[3][0] = 0; rotateZ.matrix[3][1] = 0; rotateZ.matrix[3][2] = 0; rotateZ.matrix[3][3] = 1;
rotateX.matrix[0][0] = 1; rotateX.matrix[0][1] = 0; rotateX.matrix[0][2] = 0; rotateX.matrix[0][3] = 0;
rotateX.matrix[1][0] = 0; rotateX.matrix[1][1] = (float)Math.cos(rotatedVector.getX()); rotateX.matrix[1][2] = -(float)Math.sin(rotatedVector.getX()); rotateX.matrix[1][3] = 0;
rotateX.matrix[2][0] = 0; rotateX.matrix[2][1] = (float)Math.sin(rotatedVector.getX()); rotateX.matrix[2][2] = (float)Math.cos(rotatedVector.getX()); rotateX.matrix[2][3] = 0;
rotateX.matrix[3][0] = 0; rotateX.matrix[3][1] = 0; rotateX.matrix[3][2] = 0; rotateX.matrix[3][3] = 1;
rotateY.matrix[0][0] = (float)Math.cos(rotatedVector.getY()); rotateY.matrix[0][1] = 0; rotateY.matrix[0][2] = -(float)Math.sin(rotatedVector.getY()); rotateY.matrix[0][3] = 0;
rotateY.matrix[1][0] = 0; rotateY.matrix[1][1] = 1; rotateY.matrix[1][2] = 0; rotateY.matrix[1][3] = 0;
rotateY.matrix[2][0] = (float)Math.sin(rotatedVector.getY()); rotateY.matrix[2][1] = 0; rotateY.matrix[2][2] = (float)Math.cos(rotatedVector.getY()); rotateY.matrix[2][3] = 0;
rotateY.matrix[3][0] = 0; rotateY.matrix[3][1] = 0; rotateY.matrix[3][2] = 0; rotateY.matrix[3][3] = 1;
matrix = rotateZ.mul(rotateY.mul(rotateX)).getMatrix();
return this;
}
public Matrix4f scale(Vector3f vector) {
matrix[0][0] = vector.getX(); matrix[0][1] = 0; matrix[0][2] = 0; matrix[0][3] = 0;
matrix[1][0] = 0; matrix[1][1] = vector.getY(); matrix[1][2] = 0; matrix[1][3] = 0;
matrix[2][0] = 0; matrix[2][1] = 0; matrix[2][2] = vector.getZ(); matrix[2][3] = 0;
matrix[3][0] = 0; matrix[3][1] = 0; matrix[3][2] = 0; matrix[3][3] = 1;
return this;
}
public Matrix4f projection(float fov, float aspectRatio, float zNear, float zFar) {
float tanHalfFOV = (float) Math.tan(Math.toRadians(fov / 2));
float zRange = zNear - zFar;
matrix[0][0] = 1.0f / (tanHalfFOV * aspectRatio); matrix[0][1] = 0; matrix[0][2] = 0; matrix[0][3] = 0;
matrix[1][0] = 0; matrix[1][1] = 1.0f / tanHalfFOV; matrix[1][2] = 0; matrix[1][3] = 0;
matrix[2][0] = 0; matrix[2][1] = 0; matrix[2][2] = (-zNear - zFar) / zRange; matrix[2][3] = 2 * zFar * zNear / zRange;
matrix[3][0] = 0; matrix[3][1] = 0; matrix[3][2] = 1; matrix[3][3] = 0;
return this;
}
public Matrix4f mul(Matrix4f m) {
Matrix4f result = new Matrix4f();
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
result.set(i, j, matrix[i][0] * m.get(0, j) +
matrix[i][1] * m.get(1, j) +
matrix[i][2] * m.get(2, j) +
matrix[i][3] * m.get(3, j));
}
}
return result;
}
public float[][] getMatrix() {
return matrix;
}
public void setMatrix(float[][] matrix) {
this.matrix = matrix;
}
public float get(int x, int y) {
return matrix[x][y];
}
public void set(int x, int y, float value) {
matrix[x][y] = value;
}
public String toString() {
String matrix = "";
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
matrix += (Float.toString(get(i, j)) + ", ");
}
matrix += "\n";
}
return matrix + "";
}
}
package engine.rendering;
import engine.maths.Matrix4f;
import engine.maths.Vector3f;
public class Camera {
private Vector3f position, rotation;
public Camera(Vector3f position, Vector3f rotation) {
this.position = position;
this.rotation = rotation;
}
public Matrix4f getViewMatrix() {
Matrix4f rotationMatrix = new Matrix4f().identity().rotate(rotation);
Vector3f negativePosition = new Vector3f(-position.getX(), -position.getY(), -position.getZ());
Matrix4f translationMatrix = new Matrix4f().identity().translate(negativePosition);
return rotationMatrix.mul(translationMatrix);
}
public void addPosition(float x, float y, float z) {
position.add(new Vector3f(x, y, z));
}
public void addPosition(Vector3f value) {
position.add(value);
}
public void setPosition(float x, float y, float z) {
position = new Vector3f(x, y, z);
}
public void setPosition(Vector3f pos) {
position = pos;
}
public Vector3f getPosition() {
return position;
}
public void addRotation(float x, float y, float z) {
rotation.add(new Vector3f(x, y, z));
}
public void addRotation(Vector3f value) {
rotation.add(value);
}
public void setRotation(float x, float y, float z) {
rotation = new Vector3f(x, y, z);
}
public void setRotation(Vector3f rot) {
rotation = rot;
}
public Vector3f getRotation() {
return rotation;
}
}
package engine.shaders;
import engine.maths.Matrix4f;
public class BasicShader extends Shader {
private static final String VERTEX_FILE = "src/engine/shaders/basicVertexShader.glsl";
private static final String FRAGMENT_FILE = "src/engine/shaders/basicFragmentShader.glsl";
private int tvpMatrixLocation;
private Matrix4f transformationMatrix = new Matrix4f().identity(), projectionMatrix = new Matrix4f().identity(), viewMatrix = new Matrix4f().identity();
public BasicShader() {
super(VERTEX_FILE, FRAGMENT_FILE);
}
@Override
protected void bindAttributes() {
super.bindAttribute(0, "position");
super.bindAttribute(1, "textCoords");
}
@Override
protected void getAllUniforms() {
tvpMatrixLocation = super.getUniform("tvpMatrix");
}
public void useMatrices() {
super.loadMatrixUniform(tvpMatrixLocation, transformationMatrix.mul(projectionMatrix.mul(viewMatrix)));
}
public void loadTransformationMatrix(Matrix4f matrix) {
transformationMatrix = matrix;
}
public void loadProjectionMatrix(Matrix4f matrix) {
projectionMatrix = matrix;
}
public void loadViewMatrix(Matrix4f matrix) {
viewMatrix = matrix;
}
}
您的投影矩阵有错误:矩阵[3][2]=1
必须是-1
这是因为OpenGL NDC空间是特殊的,跨产品XxY
提供-Z
而不是Z
令人惊讶的事实是,所有可见对象在视图空间中都必须具有负Z坐标。这没有任何意义:
无论您使用什么约定,也不管
mul()方法的实际乘法顺序是什么。您要么以T*P*V
结束,要么以V*P*T
结束,这两种情况都是不正确的(对于在投影后不应用某些附加转换的典型用例) 是否已验证是否正确添加了矩阵旋转?您必须验证是否使用了正确的度量(弧度/度)。否则,您可以使用像JOML这样的库,它的性能可能更高(不使用2D数组),功能也更完整。@vandench我使用旋转来旋转游戏对象,效果很好。这是关于左手和右手投影矩阵的吗?此外,它也不起作用……因此,根据您的约定,顺序是什么,或者P*V*t
或者t*V*P