我的相机类中的视图矩阵已正确设置,具有旋转和负平移功能,但是它将相机移动到其他位置,我似乎找不到我的模型。旋转和平移矩阵起作用了,因为平移起作用了,我的模型和投影矩阵也起作用了,但是当我添加视图矩阵时,它仅显示模型的一部分。顺便说一句,做了我自己的矩阵数学课。
矩阵数学类
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;
}
}
答案 0 :(得分:0)
您的投影矩阵有错误:matrix[3][2] = 1
必须为-1
。
这是由于OpenGL NDC空间是特殊的,叉积XxY
给出的是-Z
而不是Z
。
令人惊讶的事实是,所有可见对象在视图空间中都必须具有负Z坐标。
答案 1 :(得分:0)
这没有任何意义:
super.loadMatrixUniform(tvpMatrixLocation, transformationMatrix.mul(projectionMatrix.mul(viewMatrix)));
无论您使用哪种约定以及mul()
方法实际上乘以的顺序。您要么以T*P*V
或V*P*T
结尾,但两者都不正确(对于典型的用例,在投影后不应用其他变换)。