在不使用GLUT或其他OpenGL函数的情况下,我需要为用户单击三次后渲染的三角形递增颜色。我现在的主要问题是为三角形着色。
我的代码的第一个for循环颜色正确地插值到三角形的一半,顶点之间有一条斜线。
但是我的第二个for循环有时会渲染一条比顶点大的斜线,或者渲染一个矩形。
我注意到,当顶点0的y大于顶点2的y时,颜色具有斜率;当顶点0的y小于顶点2的y时,着色为矩形。
顶点按x0 我目前收到此输出,其中显示了一些情况:
https://i.ibb.co/3Y29NH9/output.png 请告知。预先谢谢你!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]));
}
}