Ошибка просмотра проекции LWJGL?

Итак, я не знаю, как объяснить проблему, которая у меня сейчас слишком хорошо, но я знаю, что она включает в себя матрицы модель / вид / проекция для рисования куба. Я импортировал куб из blender, и теперь я пытаюсь создать систему камер для просмотра под разными углами. Сначала я применил масштабирование, вращение и перевод к кубу, отправил эту матрицу в мой класс вершинных шейдеров, и куб появился там, где должен, с правильным размером, и вращается в любом направлении, которое я ему даю. Следующим шагом была настройка вида с камеры, поэтому я умножил текущие мировые координаты куба на матрицу вида, чтобы я мог перемещать "камеру" и смотреть с разных сторон. Так что теперь у меня есть координаты камеры, и все выглядит так, как должно. Куб все еще вращается, и когда я меняю "камеру", куб вращается в нужном направлении. Итак, наконец, когда я добавляю матрицу проекции в шейдер, все выглядит так, как будто оно работает... изначально. Тем не менее, я замечаю, что куб больше не выглядит правильным. Теперь я могу вращать / перемещать камеру, но куб выглядит измененным так, что некоторые грани не имеют квадратной формы. Теперь странно то, что, если я подойду очень близко к кубу, это почти так, как будто все цвета снаружи идут внутрь, и вы можете увидеть идеальную форму куба. Вот ссылка на то, что он делает, потому что это, вероятно, действительно трудно понять: http://youtu.be/QHY7ZVADeiQ. Ниже приведен код, который я использую для преобразования куба (ModelTransformation), код класса камеры и настройки моего вершинного шейдера. Любые идеи очень приветствуются. И я прошу прощения за огромные блоки кода.

Класс ModelTransformation:

package engine;

import org.lwjgl.util.vector.Matrix4f;
import org.lwjgl.util.vector.Vector3f;

public class ModelTransformation {  
private static Matrix4f identity;
private static Matrix4f scaleMatrix;
private static Matrix4f rotationMatrix;
private static Matrix4f translationMatrix;

public ModelTransformation(){   
    scaleMatrix = new Matrix4f();
    rotationMatrix = new Matrix4f();
    translationMatrix = new Matrix4f();
}

public Matrix4f getScaleMatrix(){
    return scaleMatrix;
}

public void setScaleMatrix(Vector3f axis){
    Matrix4f.setIdentity(scaleMatrix);
    Matrix4f.scale(axis, scaleMatrix, scaleMatrix);
}

public Matrix4f getRotationMatrix(){
    return rotationMatrix;
}

public void setRotationMatrix(Vector3f amount){
    Matrix4f.setIdentity(rotationMatrix);
    if(amount.x == 0 && amount.y == 0 && amount.z == 0)
        return;
    else{
        Matrix4f.rotate(amount.z, new Vector3f (0, 0, 1), rotationMatrix, rotationMatrix);
        Matrix4f.rotate(amount.y, new Vector3f (0, 1, 0), rotationMatrix, rotationMatrix);
        Matrix4f.rotate(amount.x, new Vector3f (1, 0, 0), rotationMatrix, rotationMatrix);
    }
}

public Matrix4f getTranslationMatrix(){
    return translationMatrix;
}

public void setTranslationMatrix(Vector3f axis) {
    Matrix4f.setIdentity(translationMatrix);
    Matrix4f.translate(axis, translationMatrix, translationMatrix);
}

public Matrix4f getTransformationMatrix() {
    return Matrix4f.mul(translationMatrix, Matrix4f.mul(rotationMatrix, scaleMatrix, null), null);
}
}

Класс камеры:

package engine;

import org.lwjgl.input.Keyboard;
import org.lwjgl.util.vector.Matrix4f;
import org.lwjgl.util.vector.Vector3f;

public class Camera {
private float fov;
private float aspect;
private float zNear;
private float zFar;

private Vector3f position;
private Vector3f rotation;

private Vector3f xAxis;
private Vector3f yAxis;
private Vector3f zAxis;

private Matrix4f viewMatrix;
private Matrix4f viewTranslationMatrix;
private Matrix4f viewRotationMatrix;
private Matrix4f projectionMatrix;

public Camera(float fov, float aspect, float zNear, float zFar){
    this.fov = fov;
    this.aspect = aspect;
    this.zNear = zNear;
    this.zFar = zFar;

    position = new Vector3f(0, 0, 0);
    rotation = new Vector3f(0, 0, 0);

    xAxis = new Vector3f(1, 0, 0);
    yAxis = new Vector3f(0, 1, 0);
    zAxis = new Vector3f(0, 0, 1);

    viewMatrix = new Matrix4f();
    viewTranslationMatrix = new Matrix4f();
    viewRotationMatrix = new Matrix4f();

    projectionMatrix = new Matrix4f();
}

public Matrix4f getViewMatrix(){
    viewMatrix.setIdentity();

    rotateCamera();
    translateCamera();
    viewMatrix = Matrix4f.mul(viewRotationMatrix, viewTranslationMatrix, null);

    return viewMatrix;
}

public void rotateCamera(){
    viewRotationMatrix.setIdentity();
    Matrix4f.rotate((float) Math.toRadians(rotation.x), xAxis, viewRotationMatrix, viewRotationMatrix);
    Matrix4f.rotate((float) Math.toRadians(rotation.y), yAxis, viewRotationMatrix, viewRotationMatrix);
    Matrix4f.rotate((float) Math.toRadians(rotation.z), zAxis, viewRotationMatrix, viewRotationMatrix);
}

public void translateCamera(){
    viewTranslationMatrix.setIdentity();
    Matrix4f.translate(position, viewTranslationMatrix, viewTranslationMatrix);

}

public Matrix4f getProjectionMatrix(){
    projectionMatrix.setIdentity();
    float tanFOV = (float)Math.tan(Math.toRadians(fov / 2));
    float zRange = (zFar - zNear);

    projectionMatrix.m00 = ((1 / tanFOV) / aspect); projectionMatrix.m10 = 0;                       projectionMatrix.m20 = 0;                           projectionMatrix.m30 = 0;
    projectionMatrix.m01 = 0;                       projectionMatrix.m11 = ((1 / tanFOV));          projectionMatrix.m21 = 0;                           projectionMatrix.m31 = 0;
    projectionMatrix.m02 = 0;                       projectionMatrix.m12 = 0;                       projectionMatrix.m22 = -((zFar + zNear) / zRange);  projectionMatrix.m32 = -((2 * zFar * zNear) / zRange);
    projectionMatrix.m03 = 0;                       projectionMatrix.m13 = 0;                       projectionMatrix.m23 = -1;                          projectionMatrix.m33 = 0;


    return projectionMatrix;
}

public void input() {
    if (Input.isKeyDown(Keyboard.KEY_UP))
        addRotation(-1f, 0, 0);

    if (Input.isKeyDown(Keyboard.KEY_DOWN))
        addRotation(1f, 0, 0);

    if (Input.isKeyDown(Keyboard.KEY_LEFT))
        addRotation(0, -1f, 0);

    if (Input.isKeyDown(Keyboard.KEY_RIGHT))
        addRotation(0, 1f, 0);

    if (Input.isKeyDown(Keyboard.KEY_W))
        move(0.01f, 1);

    if (Input.isKeyDown(Keyboard.KEY_S))
        move(-0.01f, 1);

    if (Input.isKeyDown(Keyboard.KEY_A))
        move(0.01f, 0);

    if (Input.isKeyDown(Keyboard.KEY_D))
        move(-0.01f, 0);

    if(Input.isKeyDown(Keyboard.KEY_SPACE))
        position.y -= 0.01f;

    if(Input.isKeyDown(Keyboard.KEY_LSHIFT))
        position.y += 0.01f;
}

private void addRotation(float rx, float ry, float rz) {
    rotation.x += rx;
    rotation.y += ry;
    rotation.z += rz;
}   

public void move(float amount, float direction){
    position.z += amount * Math.sin(Math.toRadians(rotation.y + 90 * direction));
    position.x += amount * Math.cos(Math.toRadians(rotation.y + 90 * direction));
}
}

Вершинный шейдер:

#version 430

in vec3 position;

out vec4 color;

uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;

void main(){
vec4 worldCoord = modelMatrix * vec4(position.xyz, 1.0);
vec4 cameraCoord = viewMatrix * worldCoord;
vec4 homogeneousCoord = projectionMatrix * cameraCoord;

color = vec4(clamp(position, 0.0, 1.0), 1.0);

gl_Position =  homogeneousCoord;
}

Изменить: Добавлено еще несколько классов, которые могут помочь, и добавлено больше тегов

Класс RenderUtility:

public class RenderUtility {
//clearScreen - clears the screen with the color buffer bit and depth buffer bit
//then loads the identity projection matrix
public static void clearScreen(){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
}

//Determines how the game is going to run 
public static void initilizeGraphics(){
    glMatrixMode(GL_PROJECTION);
    glClearColor(0, 0, 0, 0);

    glFrontFace(GL_CW);
    glCullFace(GL_BACK);
    glEnable(GL_CULL_FACE);
    glEnable(GL_DEPTH_TEST);

    glEnable(GL_FRAMEBUFFER_SRGB);

}

//getOpenGLVersion - returns the currently used version of OpenGL
public static String getOpenGLVersion(){
    return glGetString(GL_VERSION);
}
}

Класс игры:

public class Game {
private static ShaderProgram program;
private static Model model2;
private static ModelTransformation transformation;
private static Camera camera;
private static Transformation transform;
private static float temp = 0.0f;

// Game - creates the program for the shaders
// Creates the entities necessary for the game
public Game() {
    camera = new Camera(70, Window.getWidth()/Window.getHeight(), 0.001f, 100f);
    program = new ShaderProgram();
    program.addVertexShaderFrom("rsc/shaders/shader.vertex");
    program.addFragmentShaderFrom("rsc/shaders/shader.fragment");
    program.linkAndValidateProgram();

    program.addUniform("modelMatrix");
    program.addUniform("viewMatrix");
    program.addUniform("projectionMatrix");

    transform = new Transformation();

    transformation = new ModelTransformation();
    model2 = new Model("rsc/box3.obj");
}

// render - renders all items used in the game
// This is where shaders are implemented
public void render() {

    program.useShaders();

    program.setUniform("viewMatrix", camera.getViewMatrix());
    program.setUniform("modelMatrix", transformation.getTransformationMatrix());
    program.setUniform("projectionMatrix", camera.getProjectionMatrix());

    model2.draw();

    program.stopUsingShaders();

}

// input - takes input from keyboard/mouse and do something useful
public static void input(List<Integer> currentKeys, List<Integer> currentMouseButtons, Vector2f mouseLocation) {
    // TODO: Add what each input button/key should accomplish
    camera.input();
}

// update - updates values using the time difference between frames
public void update(double deltaTime) {
    temp += deltaTime;
    float sinTemp = 90 * (float)Math.sin(Math.toRadians(temp));
    float cosTemp = (float)Math.cos(Math.toRadians(temp));

    transformation.setTranslationMatrix(new Vector3f(0f, 0f, -3));
    transformation.setRotationMatrix(new Vector3f(sinTemp, 0, sinTemp));
    transformation.setScaleMatrix(new Vector3f(1f, 1f, 1f));

}

}

1 ответ

Итак, я нашел ошибку. Я пытался отбросить заднюю грань куба, хотя на самом деле я отбрасывал переднюю часть. Вот почему куб выглядит супер триповым.

Другие вопросы по тегам