Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/384.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用JOML模拟类似OpenGL的模型,在3D投影到2D平面上查看矩阵?_Java_Math_Opengl_3d_Projection Matrix - Fatal编程技术网

Java 如何使用JOML模拟类似OpenGL的模型,在3D投影到2D平面上查看矩阵?

Java 如何使用JOML模拟类似OpenGL的模型,在3D投影到2D平面上查看矩阵?,java,math,opengl,3d,projection-matrix,Java,Math,Opengl,3d,Projection Matrix,在学习了多年OpenGL和线性代数的初级课程后,我最近终于理解了模型、视图和投影矩阵的观点。基本上,模型矩阵将三维模型的顶点坐标转换为三维世界中的顶点坐标(相对于三维世界的原点平移、旋转和缩放模型)。视图矩阵将三维世界的顶点坐标转换为相对于摄影机的顶点坐标(通常仅世界相对于摄影机的平移和旋转),投影矩阵用于将摄影机视图中的顶点坐标计算/转换为二维平面(通常为屏幕)上的投影 我试图在没有OpenGL的情况下,通过使用JOML在2D平面上创建一个3D投影的相机系统,JOML是一个Java数学(主要是

在学习了多年OpenGL和线性代数的初级课程后,我最近终于理解了模型、视图和投影矩阵的观点。基本上,模型矩阵将三维模型的顶点坐标转换为三维世界中的顶点坐标(相对于三维世界的原点平移、旋转和缩放模型)。视图矩阵将三维世界的顶点坐标转换为相对于摄影机的顶点坐标(通常仅世界相对于摄影机的平移和旋转),投影矩阵用于将摄影机视图中的顶点坐标计算/转换为二维平面(通常为屏幕)上的投影

我试图在没有OpenGL的情况下,通过使用JOML在2D平面上创建一个3D投影的相机系统,JOML是一个Java数学(主要是线性代数数学)库,用于OpenGL,常用于轻量级Java游戏库3。我能够在OpenGL中创建一个相机系统,使用上面提到的3个矩阵非常简单。但是,当我使用相同的精确矩阵(以及一些额外的代码以便投影显示在屏幕上)时,我只能在二维平面上进行投影。模型矩阵和视图矩阵似乎对模型在屏幕上的投影方式没有任何影响

下面是我用来在屏幕上投影立方体的代码:

private float theta = 0;

@Override
public void render(Graphics g) {

    Vector3f cube3f[][] = {

        // SOUTH
        { new Vector3f(-0.5f, -0.5f, -0.5f),    new Vector3f(-0.5f,  0.5f, -0.5f),    new Vector3f( 0.5f,  0.5f, -0.5f) },
        { new Vector3f(-0.5f, -0.5f, -0.5f),    new Vector3f( 0.5f,  0.5f, -0.5f),    new Vector3f( 0.5f, -0.5f, -0.5f) },

        // EAST                                                      
        { new Vector3f( 0.5f, -0.5f, -0.5f),    new Vector3f( 0.5f,  0.5f, -0.5f),    new Vector3f( 0.5f,  0.5f,  0.5f) },
        { new Vector3f( 0.5f, -0.5f, -0.5f),    new Vector3f( 0.5f,  0.5f,  0.5f),    new Vector3f( 0.5f, -0.5f,  0.5f) },

        // NORTH                                                     
        { new Vector3f( 0.5f, -0.5f,  0.5f),    new Vector3f( 0.5f,  0.5f,  0.5f),    new Vector3f(-0.5f,  0.5f,  0.5f) },
        { new Vector3f( 0.5f, -0.5f,  0.5f),    new Vector3f(-0.5f,  0.5f,  0.5f),    new Vector3f(-0.5f, -0.5f,  0.5f) },

        // WEST                                                      
        { new Vector3f(-0.5f, -0.5f,  0.5f),    new Vector3f(-0.5f,  0.5f,  0.5f),    new Vector3f(-0.5f,  0.5f, -0.5f) },
        { new Vector3f(-0.5f, -0.5f,  0.5f),    new Vector3f(-0.5f,  0.5f, -0.5f),    new Vector3f(-0.5f, -0.5f, -0.5f) },

        // TOP                                                       
        { new Vector3f(-0.5f,  0.5f, -0.5f),    new Vector3f(-0.5f,  0.5f,  0.5f),    new Vector3f( 0.5f,  0.5f,  0.5f) },
        { new Vector3f(-0.5f,  0.5f, -0.5f),    new Vector3f( 0.5f,  0.5f,  0.5f),    new Vector3f( 0.5f,  0.5f, -0.5f) },

        // BOTTOM                                                    
        { new Vector3f( 0.5f, -0.5f,  0.5f),    new Vector3f(-0.5f, -0.5f,  0.5f),    new Vector3f(-0.5f, -0.5f, -0.5f) },
        { new Vector3f( 0.5f, -0.5f,  0.5f),    new Vector3f(-0.5f, -0.5f, -0.5f),    new Vector3f( 0.5f, -0.5f, -0.5f) },

    };
    
    Vector4f cube4f[][] = new Vector4f[cube3f.length][cube3f[0].length];
    
    for(int i = 0; i < cube3f.length; i++) {
        for(int j = 0; j < cube3f[i].length; j++) {
            
            Matrix4f modelMatrix = new Matrix4f()
                    .rotate((float)Math.toRadians(theta), new Vector3f(0.0f, 1.0f, 0))
                    .rotate((float)Math.toRadians(theta), new Vector3f(1.0f, 0, 0))
                    .translate(new Vector3f(0, 5, 5)); // this is supposed to move the cube up 5 units and away 5 units
            Vector4f tempvec = new Vector4f(cube3f[i][j], 0.0f).mul(modelMatrix);
            Matrix4f viewMatrix = new Matrix4f().translate(new Vector3f(theta, 0, -20)); //this is supposed to translate the camera back 20 units
            tempvec = tempvec.mul(viewMatrix);
            Matrix4f projectionMatrix = new Matrix4f().identity().setPerspective((float)Math.toRadians(70.0f), 1280.0f/720.0f, 0.1f, 1000.0f);
            cube4f[i][j] = tempvec.mul(projectionMatrix);
            
            //following code makes the projection appear inside the screen's borders
            cube4f[i][j].x += 1.0f;
            cube4f[i][j].y += 1.0f;
            cube4f[i][j].x *= 0.5f * 1280.0f;
            cube4f[i][j].y *= 0.5f * 720.0f;
            
        }
    }
    
    Graphics2D g2d = (Graphics2D)g;
    g2d.setBackground(new Color(32, 32, 32, 255));
    g2d.clearRect(0, 0, 1280, 720);
    
    g2d.setColor(Color.WHITE);
    
    for(int i = 0; i < cube4f.length; i++) {
        g2d.drawLine((int)cube4f[i][0].x, (int)cube4f[i][0].y, (int)cube4f[i][1].x, (int)cube4f[i][1].y);
        g2d.drawLine((int)cube4f[i][1].x, (int)cube4f[i][1].y, (int)cube4f[i][2].x, (int)cube4f[i][2].y);
        g2d.drawLine((int)cube4f[i][2].x, (int)cube4f[i][2].y, (int)cube4f[i][0].x, (int)cube4f[i][0].y);
    }
}

@Override
public void update() {
    theta++;
}
private float theta=0;
@凌驾
公共空间渲染(图形g){
向量3f立方f[]]={
//南方
{新向量3F(-0.5f,-0.5f,-0.5f),新向量3F(-0.5f,0.5f,-0.5f),新向量3F(0.5f,0.5f,-0.5f)},
{新向量3F(-0.5f,-0.5f,-0.5f),新向量3F(0.5f,0.5f,-0.5f),新向量3F(0.5f,-0.5f,-0.5f)},
//东边
{新向量3F(0.5f,-0.5f,-0.5f),新向量3F(0.5f,0.5f,-0.5f),新向量3F(0.5f,0.5f,0.5f)},
{新向量3F(0.5f,-0.5f,-0.5f),新向量3F(0.5f,0.5f,0.5f),新向量3F(0.5f,-0.5f,0.5f)},
//北
{新向量3F(0.5f,-0.5f,0.5f),新向量3F(0.5f,0.5f,0.5f),新向量3F(-0.5f,0.5f,0.5f)},
{新向量3F(0.5f,-0.5f,0.5f),新向量3F(-0.5f,0.5f,0.5f),新向量3F(-0.5f,-0.5f,0.5f)},
//西部
{新向量3F(-0.5f,-0.5f,0.5f),新向量3F(-0.5f,0.5f,0.5f),新向量3F(-0.5f,0.5f,-0.5f)},
{新向量3F(-0.5f,-0.5f,0.5f),新向量3F(-0.5f,0.5f,-0.5f),新向量3F(-0.5f,-0.5f)},
//顶
{新向量3F(-0.5f,0.5f,-0.5f),新向量3F(-0.5f,0.5f,0.5f),新向量3F(0.5f,0.5f,0.5f)},
{新向量3F(-0.5f,0.5f,-0.5f),新向量3F(0.5f,0.5f,0.5f),新向量3F(0.5f,0.5f,-0.5f)},
//底部
{新向量3F(0.5f,-0.5f,0.5f),新向量3F(-0.5f,-0.5f,0.5f),新向量3F(-0.5f,-0.5f,-0.5f)},
{新向量3F(0.5f,-0.5f,0.5f),新向量3F(-0.5f,-0.5f,-0.5f),新向量3F(0.5f,-0.5f,-0.5f)},
};
Vector4f cube4f[][]=新的Vector4f[cube3f.length][cube3f[0.length];
对于(int i=0;i
在上面的代码中,立方体应该距离摄影机25个单位(因为立方体距离世界原点5个单位,摄影机在相反方向距离世界20个单位),距离世界右侧5个单位。但我们在下图中看到的情况并非如此:

如图所示;立方体清晰居中,近距离观察

我正试图找到一种解决方案,使我能够在LWJGL3应用程序和3D投影应用程序上保留相同的“OpenGL”基本代码(更准确地说是JOML基本代码)。即使用相同的模型、视图和投影矩阵在两个应用程序上生成相同的投影