0

我在 youtube 上关注 javidx9 的关于制作 3D 图形引擎的教程(我是在 java 中做的,而不是 C++,但我非常接近他的步骤),我正处于我们移动立方体的地方远离“相机”以便更好地看到它(35:49,如果你好奇的话),但是一旦我添加了相关的代码行并运行它,什么都没有出现。当我把它们拿走时,它又回来了,我不知道发生了什么。代码如下,对不起,它有点长而且可能写得不好(使用 Graphics2D 进行显示):

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Main {

    static Frame frame;
    static double FOV = Math.PI / 2;
    static int w = 400;
    static int h = 400;
    static double a = h / w;
    static double f = 1 / Math.tan(FOV / 2);
    static double zFar = 1000;
    static double zNear = 0.1;
    static double q = zFar / (zFar - zNear);
    static double[][] matProj = new double[4][4];

    public static void main(String[] args) {
    
        frame = new Frame();

    }

    static void draw() {
    
        Mesh cubeMesh = new Mesh();

        //south
        cubeMesh.addTri(0, 0, 0, 0, 1, 0, 1, 1, 0);
        cubeMesh.addTri(0, 0, 0, 1, 1, 0, 1, 0, 0);
    
        //east
        cubeMesh.addTri(1, 0, 0, 1, 1, 0, 1, 1, 1);
        cubeMesh.addTri(1, 0, 0, 1, 1, 1, 1, 0, 1);
    
        //north
        cubeMesh.addTri(1, 0, 1, 1, 1, 1, 0, 1, 1);
        cubeMesh.addTri(1, 0, 1, 0, 1, 1, 0, 0, 1);
    
        //west
        cubeMesh.addTri(0, 0, 1, 0, 1, 1, 0, 1, 0);
        cubeMesh.addTri(0, 0, 1, 0, 1, 0, 0, 0, 0);
    
        //top
        cubeMesh.addTri(0, 1, 0, 0, 1, 1, 1, 1, 1);
        cubeMesh.addTri(0, 1, 0, 1, 1, 1, 1, 1, 0);
    
        //bottom
        cubeMesh.addTri(1, 0, 1, 0, 0, 1, 0, 0, 0);
        cubeMesh.addTri(1, 0, 1, 0, 0, 0, 1, 0, 0);
    
        matProj[0][0] = a * f;
        matProj[1][1] = f;
        matProj[2][2] = q;
        matProj[3][2] = -1 * q * zNear;
        matProj[2][3] = 1;
        matProj[3][3] = 0;
    
        frame.graphics.g2D.setColor(Color.WHITE);
        frame.graphics.g2D.setStroke(new BasicStroke(2));
    
        for(TrianglePoints i : cubeMesh.triangles) {
        
            TrianglePoints translated = i;
        
            translated.p1[2] = i.p1[2] + 3; //when I comment out these lines, it works, but then of course the cube isn't translated
            translated.p2[2] = i.p2[2] + 3;
            translated.p3[2] = i.p3[2] + 3;
        
            int[] xPoints = {(int) MultiplyMatrixVector(translated.p1, matProj)[0], (int) MultiplyMatrixVector(translated.p2, matProj)[0], (int) MultiplyMatrixVector(translated.p3, matProj)[0]};
            int[] yPoints = {(int) MultiplyMatrixVector(translated.p1, matProj)[1], (int) MultiplyMatrixVector(translated.p2, matProj)[1], (int) MultiplyMatrixVector(translated.p3, matProj)[1]};
        
            for(int j = 0; j < xPoints.length; j++) {
                xPoints[j] += 1;
                xPoints[j] *= (0.5 * w);
                yPoints[j] += 1;
                yPoints[j] *= (0.5 * w);
            }
        
            frame.graphics.g2D.drawPolygon(xPoints, yPoints, 3);
        
         }
    }

    private static double[] MultiplyMatrixVector(double[] i, double[][] m) {
    
        double[] o = new double[3];
    
        o[0] = i[0] * m[0][0] + i[1] * m[1][0] + i[2] * m[2][0] + m[3][0];
        o[1] = i[0] * m[0][1] + i[1] * m[1][1] + i[2] * m[2][1] + m[3][1];
        o[2] = i[0] * m[0][2] + i[1] * m[1][2] + i[2] * m[2][2] + m[3][2];
        double w = i[0] * m[0][3] + i[1] * m[1][3] + i[2] * m[2][3] + m[3][3];
    
        if(w != 0) {    //I think this might be where the issue is, when I translate it w won't be 0, but I don't know how that would make it not work, I have to divide by w here.
            o[0] /= w;
            o[1] /= w;
            o[2] /= w;
        }
    
        return o;
    
    }

}

class Frame extends JFrame {

    private static final long serialVersionUID = 1L;
    GraphicsC graphics = new GraphicsC();

    Frame(){
    
        this.setSize(Main.w, Main.h);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.add(graphics);
        this.setVisible(true);
    
    }

}

class GraphicsC extends JPanel {

    private static final long serialVersionUID = 1L;
    Graphics2D g2D;

    public void paintComponent(Graphics g) {
    
        super.paintComponent(g);
        this.setBackground(Color.BLACK);
    
        g2D = (Graphics2D) g;
    
        Main.draw();
    
    }

}

class TrianglePoints {

    double[] p1 = new double[3];
    double[] p2 = new double[3];
    double[] p3 = new double[3];

    TrianglePoints(double[] p1, double[] p2, double[] p3) {
        this.p1 = p1;
        this.p2 = p2;
        this.p3 = p3;
    }

}

class Mesh {

    List<TrianglePoints> triangles = new ArrayList<TrianglePoints>();

    void addTri(double a, double b, double c, double d, double e, double f, double g, double h, double i) {
        double[] p1 = {a, b, c};
        double[] p2 = {d, e, f};
        double[] p3 = {g, h, i};
        triangles.add(new TrianglePoints(p1, p2, p3));
    }

}
4

1 回答 1

0

我高度怀疑你的问题是在 C++ 中,做(时间戳

triTranslated = tri;

实际上会复制三角形,而您的代码仅获得参考,因此您的三角形以每次渲染 3 个单位的速度漂移,可能在您看到任何东西之前就消失在视野之外。

于 2021-02-09T23:52:35.357 回答