简体   繁体   English

LWJGL投影矩阵-什么都不会发生

[英]LWJGL Projection Matrix - Nothing Happens

Currently, I'm attempting to create a Camera class in LWJGL, but I've been running into a problem with the projection matrix. 当前,我正在尝试在LWJGL中创建Camera类,但是我一直在遇到投影矩阵问题。 For some reason, when I try to multiply the vertices by the projection matrix, nothing at all appears on screen. 由于某些原因,当我尝试将顶点乘以投影矩阵时,屏幕上什么也没有出现。

Camera class 相机类

public class Camera {

private Vector3f position, rotation;
private Matrix4f view;

private final Vector3f xAxis, yAxis, zAxis;

private float fov, aspect, zNear, zFar;
private Matrix4f projection;

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

    projection = createPerspectiveProjection(fov, aspect, zNear, zFar);

    position = new Vector3f();
    rotation = new Vector3f();
    view = new Matrix4f();
    view.setIdentity();

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

public void addRotation(float x, float y, float z){
    rotation.x += x;
    rotation.y += y;
    rotation.z += z;

    apply();
}

public void move(float x, float y, float z){
    position.x += x;
    position.y += y;
    position.z += z;

    apply();
}

public Matrix4f getView(){
    return view;
}

public Matrix4f getProjection(){
    return projection;
}

private void apply(){
    view.setIdentity();

    view.rotate(rotation.x, xAxis);
    view.rotate(rotation.y, yAxis);
    view.rotate(rotation.z, zAxis);

    view.translate(position);
}

private Matrix4f createPerspectiveProjection(float fov, float aspect, float zNear, float zFar){
    Matrix4f mat = new Matrix4f();

    float yScale = (float) (1 / (Math.tan(Math.toRadians(fov / 2))));
    float xScale = yScale / aspect;
    float frustrumLength = zFar - zNear;

    mat.m00 = xScale;
    mat.m11 = yScale;
    mat.m22 = -((zFar + zNear) / frustrumLength);
    mat.m23 = -1;
    mat.m32  = -((2 * zFar * zNear) / frustrumLength);
    mat.m33 = 0;

    return mat;
}

}

Main class 主班

public class Game implements Runnable {

public static final int WIDTH = 800;
public static final int HEIGHT = 600;

public static final DisplayMode dm = new DisplayMode(WIDTH, HEIGHT);

int vaoID;

ShaderProgram program;
Camera camera;

Model model;

public Game(){
    new Thread(this).start();
}

public void run(){
    init();

    while(true){
        if(Display.isCloseRequested())
            break;

        update(Timer.getElapsedTime());

        render();

        Display.sync(60);
        Display.update();
    }

    Display.destroy();
}

public void init(){
    try{
        Display.setTitle("Ludum Dare!");
        Display.setDisplayMode(dm);
        Display.create();
    }catch(LWJGLException e){
        e.printStackTrace();
        System.exit(1);
    }

    Timer.start();

    camera = new Camera(60.0f, WIDTH / HEIGHT, 0.1f, 100.0f);

    program = new ShaderProgram("res/shader/defaultshader.vert", "res/shader/defaultshader.frag");

    glClearColor(0.0f, 0.0f, 0.4f, 0.0f);

    vaoID = glGenVertexArrays();
    glBindVertexArray(vaoID);

    model = new Model(new float[] {
        -1, -1, 1,
        1, -1, 1,
        0, 1, 1
    });
}

public void update(float delta){

}

public void render(){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    program.bind();

    program.setUniform("model_matrix", model.getModel());
    program.setUniform("view_matrix", camera.getView());
    program.setUniform("projection_matrix", camera.getProjection());

    model.render();

    program.unbind();
}

public static void main(String[] args){
    new Game();
}

}

Vertex Shader 顶点着色器

#version 330 core

layout(location = 0) in vec3 vertex_modelspace;

uniform mat4 model_matrix;
uniform mat4 view_matrix;
uniform mat4 projection_matrix;

void main(){
    mat4 modelviewprojection_matrix = projection_matrix * view_matrix * model_matrix;
    vec4 vertex = vec4(vertex_modelspace, 1.0);

    gl_Position = modelviewprojection_matrix * vertex;
}

ShaderProgram class ShaderProgram类

public class ShaderProgram {

private int vertexShaderID, fragmentShaderID;
private int programID;

public ShaderProgram(String vertPath, String fragPath){
    programID = glCreateProgram();

    vertexShaderID = attachShader(vertPath, GL_VERTEX_SHADER);
    fragmentShaderID = attachShader(fragPath, GL_FRAGMENT_SHADER);
    link();
}

private int attachShader(String path, int type){
    StringBuilder shaderSource = new StringBuilder();

    try{
        BufferedReader reader = new BufferedReader(new FileReader(new File(path)));
        String line;

        while((line = reader.readLine()) != null){
            shaderSource.append(line).append("\n");
        }

        reader.close();
    }catch(IOException e){
        e.printStackTrace();
        System.out.println("Error reading from shader " + path);
        System.exit(1);
    }

    System.out.println("Compiling shader " + path);
    int id = glCreateShader(type);
    glShaderSource(id, shaderSource);
    glCompileShader(id);

    if(glGetShaderi(id, GL_COMPILE_STATUS) == GL_FALSE){
        System.out.println(glGetShaderInfoLog(id, 1000));
        System.exit(1);
    }

    return id;
}

private void link(){
    System.out.println("Linking program...");
    glAttachShader(programID, vertexShaderID);
    glAttachShader(programID, fragmentShaderID);
    glLinkProgram(programID);
}

public void bind(){
    glUseProgram(programID);
}

public void unbind(){
    glUseProgram(0);
}

public void setUniform(String name, Matrix4f value){
    FloatBuffer matrix = BufferUtils.createFloatBuffer(16);
    value.store(matrix); matrix.flip();
    glUniformMatrix4(glGetUniformLocation(programID, name), false, matrix);
}

}

When I run this, the VBO that I create (A triangle) doesn't appear, but when I leave the projection matrix out of the multiplication in the vertex shader, it runs just fine. 运行此命令时,不会显示我创建的VBO(三角形),但是当我将投影矩阵放在顶点着色器中的乘法运算之外时,它运行良好。 Am I missing something? 我想念什么吗?

I'm making the assumption that model.getModel() will return the identity matrix (just like your view matrix is identity). 我假设model.getModel()将返回单位矩阵(就像您的视图矩阵是单位)。 In that case, you have the following situation: You draw a triangle in the plane z=1.0. 在这种情况下,您将遇到以下情况:在平面z = 1.0中绘制一个三角形。 If you use identity as projection matrix also, you directly draw in clip space, and the trianlge will be on the far plane, so it is visible. 如果还将身份用作投影矩阵,则可以直接在剪辑空间中绘制,并且三角形将位于远平面上,因此可见。

However, your createPerspectiveProjection function seems to be written with the standard OpenGL conventions in mind, so it is almost like what glFrustum() . 但是,您的createPerspectiveProjection函数似乎是在考虑标准OpenGL约定的情况下编写的,因此它几乎类似于glFrustum() (Your code is missing the parts which are labeled A and B in that manpage, so you are limited to a symmetric frustum, but that is fine in most cases.) The conventions used for this matrix were that the camera is looking into the -z direction, and the zNear and zFar parameters are actually maped such that a point at z_eye=-zNear is projected to the near plane ( z_ndc=-1 ), and a point at z_eye=-zFar is projected to the far plane ( z_ndc=1 ). (您的代码缺少该手册页中标记为A和B的部分,因此您只能使用对称的平截头体,但这在大多数情况下还可以。)用于此矩阵的约定是照相机正在查看-实际映射z方向和zNearzFar参数,以便将z_eye=-zNear处的点投影到近平面( z_ndc=-1 ),将z_eye=-zFar处的点投影到远平面( z_ndc=1 )。 So your triangle at z=1 is just behind the camera, if you apply that projection matrix. 因此,如果应用该投影矩阵,则z = 1处的三角形正好在相机后面。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM