LWJGL投影矩阵-什么都不会发生 [英] LWJGL Projection Matrix - Nothing Happens

查看:225
本文介绍了LWJGL投影矩阵-什么都不会发生的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当前,我正在尝试在LWJGL中创建Camera类,但是我一直遇到投影矩阵问题.由于某些原因,当我尝试将顶点乘以投影矩阵时,屏幕上什么也没有出现.

Currently, I'm attempting to create a Camera class in LWJGL, but I've been running into a problem with the projection matrix. For some reason, when I try to multiply the vertices by the projection matrix, nothing at all appears on screen.

相机类别

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;
}

}

主班

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();
}

}

顶点着色器

#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类

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);
}

}

运行此命令时,不会显示我创建的VBO(三角形),但是当我将投影矩阵放在顶点着色器中的乘法运算之外时,它运行良好.我想念什么吗?

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. Am I missing something?

推荐答案

我假设model.getModel()将返回单位矩阵(就像您的视图矩阵是单位).在这种情况下,您将遇到以下情况:在平面z = 1.0中绘制一个三角形.如果还使用标识作为投影矩阵,则可以直接在剪辑空间中绘制,并且三角形将位于远平面上,因此它是可见的.

I'm making the assumption that model.getModel() will return the identity matrix (just like your view matrix is identity). In that case, you have the following situation: You draw a triangle in the plane 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.

但是,您的createPerspectiveProjection函数似乎是在考虑标准OpenGL约定的情况下编写的,因此几乎就像

However, your createPerspectiveProjection function seems to be written with the standard OpenGL conventions in mind, so it is almost like what 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). So your triangle at z=1 is just behind the camera, if you apply that projection matrix.

这篇关于LWJGL投影矩阵-什么都不会发生的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆