Chapter 25 · 基础图元

三角形

三角形是 GPU 渲染的基本单元。学习用三个顶点定义三角形,进行填充与描边绘制。

25

API 速查

函数说明
void xgeShapeTriangleFill(xge_vec2_t tA, xge_vec2_t tB, xge_vec2_t tC, uint32_t iColor)填充三角形
void xgeShapeTriangleFillPx(xge_vec2_t tA, xge_vec2_t tB, xge_vec2_t tC, uint32_t iColor)填充三角形(像素坐标)
void xgeShapeTriangleStroke(xge_vec2_t tA, xge_vec2_t tB, xge_vec2_t tC, float fWidth, uint32_t iColor)描边三角形
void xgeShapeTriangleStrokePx(xge_vec2_t tA, xge_vec2_t tB, xge_vec2_t tC, float fWidth, uint32_t iColor)描边三角形(像素坐标)

编译本章示例

gcc -O2 -I. -o ch25.exe ch25_main.c build\xge.lib -lm -lws2_32 -liphlpapi -lgdi32 -luser32 -lshell32 -lopengl32 -lole32 -lwinmm -lavrt
.\ch25.exe

示例 1:基本三角形

xge_vec2_t A = { 400, 100 };  // 顶点
xge_vec2_t B = { 250, 450 };  // 左下
xge_vec2_t C = { 550, 450 };  // 右下

// 填充
xgeShapeTriangleFill(A, B, C, 0x4FD8C2FF);

// 描边(线宽 3)
xgeShapeTriangleStroke(A, B, C, 3.0f, 0xFFB454FF);

示例 2:箭头指示器

// 向右的箭头
float x = 600, y = 300, s = 20;
xge_vec2_t tip   = { x + s, y };
xge_vec2_t top   = { x - s, y - s };
xge_vec2_t bot   = { x - s, y + s };
xgeShapeTriangleFill(tip, top, bot, 0xFF6B5EFF);

示例 3:正三角形网格

// 绘制一排交替三角形(锯齿装饰)
float baseY = 500, h = 30, w = 40;
for (int i = 0; i < 20; i++) {
    float x0 = i * w;
    xge_vec2_t a = { x0, baseY };
    xge_vec2_t b = { x0 + w, baseY };
    xge_vec2_t c = { x0 + w/2, baseY - h };
    uint32_t col = (i%2) ? 0x4FD8C260 : 0xFFB45460;
    xgeShapeTriangleFill(a, b, c, col);
}

完整代码

将以下代码保存为 ch25_main.c,编译后运行即可看到三角形的填充与描边:

#include "xge.h"
#include <math.h>

static int onFrame(void* pUser) {
    (void)pUser;
    double t = xgeTimer();
    xgeClear(0x081114FF);

    // 静态填充三角形
    xgeShapeTriangleFill(150, 400, 300, 150, 450, 400, 0x4FD8C2FF);

    // 旋转三角形
    float cx = 600, cy = 300, r = 100;
    float angle = (float)(t * 1.5);
    float x0 = cx + r * cosf(angle);
    float y0 = cy + r * sinf(angle);
    float x1 = cx + r * cosf(angle + 2.094f);
    float y1 = cy + r * sinf(angle + 2.094f);
    float x2 = cx + r * cosf(angle + 4.189f);
    float y2 = cy + r * sinf(angle + 4.189f);
    xgeShapeTriangleFill(x0, y0, x1, y1, x2, y2, 0xFFB454FF);

    return XGE_OK;
}

int main(void) {
    xge_desc_t d = {0};
    d.iWidth  = 800;
    d.iHeight = 600;
    d.sTitle  = "ch25 - Triangles";
    d.iFlags  = XGE_INIT_VSYNC;
    xgeInit(&d);
    xgeRun(onFrame, NULL);
    xgeUnit();
    return 0;
}

代码讲解

  • xgeShapeTriangleFill(x0,y0, x1,y1, x2,y2, color) 用三个顶点定义三角形并填充。
  • 旋转三角形通过每帧改变顶点角度实现,2.094 = 2π/3(120°)。
  • 三角形是 GPU 渲染的基本单元,所有复杂图形最终都分解为三角形。
  • 顶点顺序影响正面/背面判断(逆时针为正面)。

要点与陷阱

  • 顶点顺序无关:填充三角形不要求顺时针/逆时针顺序。
  • 退化三角形:三点共线时面积为零,不绘制任何内容。
  • 三角形是基础:所有复杂图形(圆、矩形)在 GPU 内部都被分解为三角形。
  • 自定义 Mesh:需要更复杂的三角形网格时,使用 xgeShapeMeshFill(第 31 章)。

进阶练习

  1. 实现一个旋转的三角形(顶点绕中心旋转)。
  2. 用三角形拼出一个五角星(5 个三角形 + 1 个五边形)。
  3. 实现 Delaunay 三角剖分的可视化(随机点 → 三角形网格)。
三角形效果
图:三角形渲染效果