如何使用OpenGL的帧缓冲区为三角形着色

时间:2019-09-13 05:37:19

标签: c++ opengl visual-c++ glfw rasterizing

在不使用GLUT或其他OpenGL函数的情况下,我需要为用户单击三次后渲染的三角形递增颜色。我现在的主要问题是为三角形着色。

我的代码的第一个for循环颜色正确地插值到三角形的一半,顶点之间有一条斜线。

但是我的第二个for循环有时会渲染一条比顶点大的斜线,或者渲染一个矩形。

我注意到,当顶点0的y大于顶点2的y时,颜色具有斜率;当顶点0的y小于顶点2的y时,着色为矩形。

顶点按x0

void triangle_color(int vertex0[5], int vertex1[5], int vertex2[5])
{
    // initialize yBottom and yTop for intersecting lines
    double yB = vertex0[1];         // yB <- y0
    double yT = vertex0[1];         // yT <- y0

    double R0 = vertex0[2];     double R1 = vertex1[2];     double R2 = vertex2[2];
    double G0 = vertex0[3];     double G1 = vertex1[3];     double G2 = vertex2[3];
    double B0 = vertex0[4];     double B1 = vertex1[4];     double B2 = vertex2[4];

    double RB = R0;             double GB = G0;             double BB = B0;
    double RT = R0;             double GT = G0;             double BT = B0;

    double R = 0.0;             double G = 0.0;             double B = 0.0;

    // if x0 = x1 or x1 = x2 then first half of algorithm is skipped
    if (vertex0[0] != vertex1[0] || vertex1[0] != vertex2[0]) {
        // find yB and yT using L0,1 and L0,2
        yB = yB + ((vertex1[1] - vertex0[1]) / (vertex1[0] - vertex0[0]));
        yT = yT + ((vertex2[1] - vertex0[1]) / (vertex2[0] - vertex0[0]));

        RB = RB + ((R1 - R0) / (vertex1[0] - vertex0[0]));
        RT = RT + ((R2 - R0) / (vertex2[0] - vertex0[0]));

        GB = GB + ((G1 - G0) / (vertex1[0] - vertex0[0]));
        GT = GT + ((G2 - G0) / (vertex2[0] - vertex0[0]));

        BB = BB + ((B1 - B0) / (vertex1[0] - vertex0[0]));
        BT = BT + ((B2 - B0) / (vertex2[0] - vertex0[0]));

        // for column x, x0 to x1 -1
        for (int x = vertex0[0]; x <= (vertex1[0] - 1); x++)        // span of line
        {
            R = RB + ((RT - RB) / (yT - yB)) * ((ceil(yB)) - yB);
            G = GB + ((GT - GB) / (yT - yB)) * ((ceil(yB)) - yB);
            B = BB + ((BT - BB) / (yT - yB)) * ((ceil(yB)) - yB);

            // fill in pixels from yB to yT; from bottom to top, fill column
            for (int y = (int)ceil(yB); y <= (int)floor(yT); y++)
            {
                // fill in by column
                frame_buffer[HEIGHT - y][x][0] = R;
                frame_buffer[HEIGHT - y][x][1] = G;
                frame_buffer[HEIGHT - y][x][2] = B;

                R = R + ((RT - RB) / (yT - yB));
                G = G + ((GT - GB) / (yT - yB));
                B = B + ((BT - BB) / (yT - yB));
            }

            yB = yB + ((vertex1[1] - vertex0[1]) / (vertex1[0] - vertex0[0]));
            yT = yT + ((vertex2[1] - vertex0[1]) / (vertex2[0] - vertex0[0]));

            RB = RB + ((R1 - R0) / (vertex1[0] - vertex0[0]));
            RT = RT + ((R2 - R0) / (vertex2[0] - vertex0[0]));

            GB = GB + ((G1 - G0) / (vertex1[0] - vertex0[0]));
            GT = GT + ((G2 - G0) / (vertex2[0] - vertex0[0]));

            BB = BB + ((B1 - B0) / (vertex1[0] - vertex0[0]));
            BT = BT + ((B2 - B0) / (vertex2[0] - vertex0[0]));
        }

        // second loop
        // reinitialize yB for second half of triangle
        double second_yB = vertex1[1];          // yB <- y1
        double second_RB = R1;      double second_GB = G1;      double second_BB = B1;

        // algorithms for second half, for columns from x1 to x2 using L1,2 and L0,2
        second_yB = second_yB + ((vertex2[1] - vertex1[1]) / (vertex2[0] - vertex1[0]));

        second_RB = second_RB + ((R2 - R1) / (vertex2[0] - vertex1[0]));
        RT = RT + ((R2 - R0) / (vertex2[0] - vertex0[0]));

        second_GB = second_GB + ((G2 - G1) / (vertex2[0] - vertex1[0]));
        GT = GT + ((G2 - G0) / (vertex2[0] - vertex0[0]));

        second_BB = second_BB + ((B2 - B1) / (vertex2[0] - vertex1[0]));
        BT = BT + ((B2 - B0) / (vertex2[0] - vertex0[0]));

        for (int x2 = vertex1[0]; x2 <= vertex2[0]; x2++)
        {
            double second_R = second_RB + ((RT - second_RB) / (yT - second_yB)) * ((ceil(second_yB)) - second_yB);
            double second_G = second_GB + ((RT - second_GB) / (yT - second_yB)) * ((ceil(second_yB)) - second_yB);
            double second_B = second_BB + ((RT - second_BB) / (yT - second_yB)) * ((ceil(second_yB)) - second_yB);

            for (int y2 = (int)ceil(second_yB); y2 <= (int)floor(yT); y2++)
            {
                frame_buffer[HEIGHT - y2][x2][0] = second_R;
                frame_buffer[HEIGHT - y2][x2][1] = second_G;
                frame_buffer[HEIGHT - y2][x2][2] = second_B;

                second_R = second_RB + ((RT - second_RB) / (yT - second_yB));
                second_G = second_GB + ((RT - second_GB) / (yT - second_yB));
                second_B = second_BB + ((RT - second_BB) / (yT - second_yB));
            }

            second_yB = second_yB + ((vertex2[1] - vertex1[1]) / (vertex2[0] - vertex1[0]));
            yT = yT + ((vertex2[1] - vertex0[1]) / (vertex2[0] - vertex0[0]));

            second_RB = second_RB + ((R2 - R1) / (vertex2[0] - vertex1[0]));
            RT = RT + ((R2 - R0) / (vertex2[0] - vertex0[0]));

            second_GB = second_GB + ((G2 - G1) / (vertex2[0] - vertex1[0]));
            GT = GT + ((G2 - G0) / (vertex2[0] - vertex0[0]));

            second_BB = second_BB + ((B2 - B1) / (vertex2[0] - vertex1[0]));
            BT = BT + ((B2 - B0) / (vertex2[0] - vertex0[0]));
        }
    }

我目前收到此输出,其中显示了一些情况: https://i.ibb.co/3Y29NH9/output.png

请告知。预先谢谢你!

0 个答案:

没有答案