LWJGL投影查看错误?

时间:2014-01-11 08:11:10

标签: opengl shader lwjgl perspectivecamera

所以,我真的不知道如何解释我目前所拥有的问题,但我知道它涉及用于绘制立方体的模型/视图/投影矩阵。我从搅拌机导入了一个立方体,现在我正在尝试创建一个从不同角度查看的摄像系统。我首先将缩放,旋转和平移应用到立方体,将此矩阵发送到我的顶点着色器类,并且立方体出现在它应该的位置,具有正确的大小,并且在我给它的任何方向上旋转。下一步是设置摄像机视图,所以我将立方体的当前世界坐标乘以视图矩阵,这样我就可以移动“摄像机”并从不同方向看。所以现在我有相机坐标,一切看起来都应该如此。立方体仍在旋转,当我改变“相机”时,立方体按照应该的方向旋转。最后,当我将投影矩阵添加到着色器时,一切看起来都有效......最初。但是,我注意到立方体似乎不再正确。我现在可以旋转/移动相机,但是立方体看起来变形,使得一些面不是方形的。现在奇怪的是,如果我真的接近立方体,那就好像外面的所有颜色都在里面,你可以看到一个完美的立方体形状。以下是它正在做的事情的链接,因为这可能很难理解: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 个答案:

答案 0 :(得分:0)

所以我发现了错误。我试图剔除立方体的背面,实际上我正在剔除前面。这就是为什么立方体看起来非常好看。