You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言3D软件渲染器光栅化故障排查求助

3D软件渲染器扫描线光栅化问题

问题现象

  • 渲染绿色和蓝色两个立方体时,在立方体相同Y坐标范围内出现大量多余的绿色、蓝色水平线,立方体主体着色正常但线条异常
  • 若这些水平线延伸至屏幕顶部或底部,渲染器会直接崩溃
  • 移动鼠标时线条会出现闪烁,但程序并未处理鼠标输入

补充信息

渲染器采用弱透视投影(Weak Perspective Projection),基于Raylib框架实现窗口与绘图。已尝试调整线条绘制逻辑、数组存储方式及数组大小,问题未解决。
编辑补充:通过calloc动态分配buf_x0和buf_x1后,全域闪烁细线问题有所改善,但出现了与立方体等高的粗线,蓝色立方体右侧还存在异常细线。且已确认输入的多边形与顶点无问题——使用Raylib内置三角形绘制函数可正常显示。

相关代码

FillInPolygon函数

void FillInPolygon(struct Triangle triangle, const int WINDOWHEIGHT, Color color) {
    int buf_x0[WINDOWHEIGHT],buf_x1[WINDOWHEIGHT];      //These arrays will store the X start and X end of the lines
    LineDrawerForBuffer(buf_x0, buf_x1, triangle.v0.xProj, triangle.v0.yProj, triangle.v1.xProj, triangle.v1.yProj);    //Line drawer will get the edges of the triangle
    LineDrawerForBuffer(buf_x0, buf_x1, triangle.v1.xProj, triangle.v1.yProj, triangle.v2.xProj, triangle.v2.yProj);
    LineDrawerForBuffer(buf_x0, buf_x1, triangle.v2.xProj, triangle.v2.yProj, triangle.v0.xProj, triangle.v0.yProj);
    int Ay = triangle.v0.yProj;     //Y position of where the first vertex of the triangle is in 2d space
    int By = triangle.v1.yProj;     //Y position of the second
    int Cy = triangle.v2.yProj;     //Y position of the third
    for (int y=Min(Ay,By,Cy);y<=Max(Ay,By,Cy);y++)
        DrawLine(buf_x0[y], y, buf_x1[y], y, color);        //Draws a horizontal line between the X start and X end of the lines
}

LineDrawerForBuffer函数

void LineDrawerForBuffer(int *buf_x0, int *buf_x1, int x1, int y1, int x2, int y2) {
    //Modified version of Bresenham's Line Drawing Algorithm, this one is capable of drawing lines in all directions
    int y = y1;
    int x = x1;
    int dx = Abs(x2-x1);
    int dy = Abs(y2-y1);
    int s1 = Sign(x2-x1);
    int s2 = Sign(y2-y1);
    bool interchange;
    if (dy > dx) {
        int t = dx;
        dx = dy;
        dy = t;
        interchange = true;
    }
    else {
        interchange = false;
    }
    int e = 2*dy-dx;
    int a = 2*dy;
    int b = 2*dy-2*dx;
    if ((dy < 0 && !interchange) || (dx < 0 && interchange)) {
        buf_x0[y] = x;
    }
    else if ((dy > 0 && !interchange) || (dx > 0 && interchange)) {
        buf_x1[y] = x;
    }
    else if ((dy == 0 && !interchange) || (dx == 0 && interchange)) {
        buf_x0[y] = x;
        buf_x1[y] = x;
    }
    for (int i = 0; i<dx; i++) {
        if (e < 0) {
            if (interchange) y = y + s2;
            else             x = x + s1;
            e = e + a;
        }
        else {
            y = y + s2;
            x = x + s1;
            e = e + b;
        }
        if ((dy < 0 && !interchange) || (dx < 0 && interchange)) {
            buf_x0[y] = x;
        }
        else if ((dy > 0 && !interchange) || (dx > 0 && interchange)) {
            buf_x1[y] = x;
        }
        else if ((dy == 0 && !interchange) || (dx == 0 && interchange)) {
            buf_x0[y] = x;
            buf_x1[y] = x;
        }
    }
}

内容的提问来源于stack exchange,提问作者Maxim Ricardo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 04:53:24