Java ZBuffer与自制渲染引擎的问题

Java ZBuffer与自制渲染引擎的问题,java,swing,graphics,3d,rendering,Java,Swing,Graphics,3d,Rendering,我的渲染引擎中的zbuffer有问题。我白手起家地写了这篇文章,之前没有太多关于3D图形的知识。在没有zbuffer的情况下,转换可以完美地工作。但是,当缓冲区启用时,它不会以正确的顺序绘制 下面是它的实现方式 场景类有一个渲染方法,JFrame在需要更新时调用该方法。Render清除zbuffer,然后将命令传递给场景的形状。Renderable是一个接口。代码如下: public void render(Graphics2D g2, int pitch, int yaw, int roll)

我的渲染引擎中的zbuffer有问题。我白手起家地写了这篇文章,之前没有太多关于3D图形的知识。在没有zbuffer的情况下,转换可以完美地工作。但是,当缓冲区启用时,它不会以正确的顺序绘制

下面是它的实现方式

场景类有一个渲染方法,JFrame在需要更新时调用该方法。Render清除zbuffer,然后将命令传递给场景的形状。Renderable是一个接口。代码如下:

public void render(Graphics2D g2, int pitch, int yaw, int roll) 
{
    for(double[] d : buffer)
        Arrays.fill(d, Double.NEGATIVE_INFINITY);
    for(Renderable shape : shapes)
        shape.render(image, pitch, yaw, roll, buffer);
    g2.drawImage(image, null, null);
    for(int x = 0; x < 512; x++)
        for(int y = 0; y < 512; y++)
            image.setRGB(x, y, 0); //Clear buffered image
}

private Renderable[] shapes;
private double[][] buffer = new double[512][512];
private BufferedImage image = new BufferedImage(512, 512, BufferedImage.TYPE_INT_ARGB);
public void渲染(图形2D g2、整数俯仰、整数偏航、整数滚动)
{
for(双[]d:缓冲区)
数组填充(d,双负无穷大);
用于(可渲染形状:形状)
渲染(图像、俯仰、偏航、滚动、缓冲);
g2.drawImage(图像,空,空);
对于(int x=0;x<512;x++)
对于(int y=0;y<512;y++)
setRGB(x,y,0);//清除缓冲图像
}
私有可渲染形状;
专用双精度[]缓冲区=新双精度[512][512];
private BufferedImage image=new BufferedImage(512,512,BufferedImage.TYPE_INT_ARGB);
以下是Triangle3D中渲染方法的代码(实现可渲染)

public void渲染(buffereImage图像、int-pitch、int-yaw、int-roll、double[][]缓冲区、布尔显示边框)
{
三角形3D旋转=(三角形3D)getRotated(俯仰、偏航、横摇);
旋转、平移(256、256、0);
多边形路径=新多边形();
addPoint(rotated.getFirst().getFirst().intValue(),rotated.getFirst().getSecond().intValue());
addPoint(rotated.getSecond().getFirst().intValue(),rotated.getSecond().getSecond().intValue());
addPoint(rotated.getThird().getFirst().intValue(),rotated.getThird().getSecond().intValue());
矩形边界=path.getBounds();
int minY=Math.max(Math.min(bounds.y,511),0);
int maxY=Math.max(Math.min(bounds.y+bounds.height,511),0);
int minX=Math.max(Math.min(bounds.x,511),0);
int maxX=Math.max(Math.min(bounds.x+bounds.width,511),0);

for(int y=minY;ygetZ()返回未旋转三角形的Z值。使其旋转。getZ()相反

为什么
Triangle3D
绘制到一个新的图像,它在需要的地方着色,然后绘制到
g2
,而不是只接收一个它在需要的地方着色的图像,然后渲染循环绘制到
g2
?如果你可以cate 1图像并绘制一次。我不清楚
z
计算是如何工作的。它似乎是根据旋转来编写的(我猜
getFirst()
getSecond()
等是3x3旋转矩阵的元素)-在哪里考虑平移?(我不知道你是否遇到过这样一个事实,OpenGL使用4x4矩阵,它允许旋转和平移一起传递,称为齐次表示法,因为这两种表示法并不不同)将参数从g2更改为缓冲图像将有助于提高效率。感谢您的建议!Triangle3D和Point3D扩展了一个三元组类,该类仅包含3个数据,并允许访问和变异。我发现这样做比编写getX()、getY()、getZ()更容易,等等。这就是getFirst Third的来源。Z计算来自平面方程:ax+by+cz=d。简单的3D几何。转换尚未实现。我计划在坐标点上进行转换,而不是4x4倾斜。如果在完整的代码链接中运行JAR,您将看到旋转工作。我关心的是ab输出z缓冲区不工作。
public void render(BufferedImage image, int pitch, int yaw, int roll, double[][] buffer, boolean showBorders)
{
    Triangle3D rotated = (Triangle3D) getRotated(pitch, yaw, roll);
    rotated.translate(256, 256, 0);
    Polygon path = new Polygon();
    path.addPoint(rotated.getFirst().getFirst().intValue(), rotated.getFirst().getSecond().intValue());
    path.addPoint(rotated.getSecond().getFirst().intValue(), rotated.getSecond().getSecond().intValue());
    path.addPoint(rotated.getThird().getFirst().intValue(), rotated.getThird().getSecond().intValue());

    Rectangle bounds = path.getBounds();
    int minY = Math.max(Math.min(bounds.y, 511), 0);
    int maxY = Math.max(Math.min(bounds.y + bounds.height, 511), 0);
    int minX = Math.max(Math.min(bounds.x, 511), 0);
    int maxX = Math.max(Math.min(bounds.x + bounds.width, 511), 0);

    for (int y = minY; y <= maxY; y++) 
        for (int x = minX; x <= maxX; x++)
            if(path.contains(x, y) && buffer[x][y] < getZ(x, y))
            {
                image.setRGB(x, y, color.getRGB());
                buffer[x][y] = getZ(x, y);
            }
}

public double getZ(int x, int y)
{
    double a = getFirst().getFirst();
    double b = getFirst().getSecond();
    double c = getFirst().getThird();

    double d = getSecond().getFirst();
    double e = getSecond().getSecond();
    double f = getSecond().getThird();

    double g = getThird().getFirst();
    double h = getThird().getSecond();
    double w = getThird().getThird();

    double v1a = d - a;
    double v1b = e - b;
    double v1c = f - c;
    double v2a = g - a;
    double v2b = h - b;
    double v2c = w - c;

    double i = v1b * v2c - v1c * v2b;
    double j = v1c * v2a - v1a * v2c;
    double k = v1a * v2b - v1b * v2a;

    double o = (a * i) + (b * j) + (c * k);

    return ((o - (x * i) - (y * j)) / k);
}