三角形分成 上線兩個,以中間高度的點爲準,橫切一刀.然後橫着向上,或者向下進行一條一條畫線填充
爲了更加清晰顯示 填充過程,我把上半三角形的條紋每間隔2 像素畫一條橫線,
void fillTriangle(ImVec2 t0, ImVec2 t1, ImVec2 t2, TGAImage& image, TGAColor color)
{
//根據 點的y座標 從上到下排序
if (t0.y < t1.y)
{
std::swap(t0, t1);
}
if (t0.y < t2.y)
{
std::swap(t0, t2);
}
if (t1.y < t2.y)
{
std::swap(t1, t2);
}
if (t1.y == t2.y)
{
fillUpTriangle(t0, t1, t2, image, color);
}
else if (t1.y == t0.y)
{
fillDownTriangle(t2, t1, t0, image, color);
}
else
{
//直線表達 兩點式
ImVec2 t4;
t4.y = t1.y;
t4.x = (t0.x - t2.x) / (t0.y - t2.y) * (t4.y - t2.y) + t2.x;
fillUpTriangle(t0, t1, t4, image, color);
fillDownTriangle(t2, t1, t4, image, color);
line(t1, t4, image, white);
}
}
void fillUpTriangle(ImVec2 t0, ImVec2 t1, ImVec2 t2, TGAImage& image, TGAColor color)
{
for (int i = 0; i < (t0.y - t1.y); i += 3)
{
ImVec2 p1, p2;
p1.y = p2.y = t1.y + i;
p1.x = (t0.x - t1.x) / (t0.y - t1.y) * (p1.y - t1.y) + t1.x;
p2.x = (t0.x - t2.x) / (t0.y - t2.y) * (p2.y - t2.y) + t2.x;
line(p1, p2, image, color);
}
}
void fillDownTriangle(ImVec2 t0, ImVec2 t1, ImVec2 t2, TGAImage& image, TGAColor color)
{
for (int i = 0; i < (t1.y - t0.y); i++)
{
ImVec2 p1, p2;
p1.y = p2.y = t1.y - i;
p1.x = (t0.x - t1.x) / (t0.y - t1.y) * (p1.y - t1.y) + t1.x;
p2.x = (t0.x - t2.x) / (t0.y - t2.y) * (p2.y - t2.y) + t2.x;
line(p1, p2, image, color);
}
}
畫圖的最基本的代碼框架來自於開源庫
最基本軟渲染的框架https://github.com/ssloy/tinyrenderer