Chapter 31 · 基础图元

多边形与自定义 Mesh

当内置图元不够用时,用多边形(任意 N 边形)或自定义 Mesh(顶点+索引)绘制任意形状。

31

概念

  • 多边形:传入 N 个顶点(xge_vec2_t 数组),引擎自动三角化并填充。支持凸/凹多边形。
  • 自定义 Mesh:传入顶点数组(位置+颜色)+ 索引数组,直接提交三角形列表。最底层的绘制方式。
  • 顶点颜色:Mesh 的每个顶点可携带独立颜色,实现渐变效果。

API 速查

函数 / 类型说明
void xgeShapePolygonFill(const xge_vec2_t* pPoints, int iCount, uint32_t iColor)填充多边形
void xgeShapePolygonFillPx(const xge_vec2_t* pPoints, int iCount, uint32_t iColor)填充多边形(像素坐标)
int xgeShapeMeshFill(const xge_shape_vertex_t* pVertices, int iVertexCount, const uint32_t* pIndices, int iIndexCount)自定义 Mesh 填充
int xgeShapeMeshFillPx(const xge_shape_vertex_t* pVertices, int iVertexCount, const uint32_t* pIndices, int iIndexCount)自定义 Mesh(像素坐标)
xge_shape_vertex_t { float fX, fY; uint32_t iColor; }Mesh 顶点结构

编译本章示例

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

示例 1:正五边形

// 生成正五边形顶点
xge_vec2_t pts[5];
float cx = 400, cy = 300, r = 100;
for (int i = 0; i < 5; i++) {
    float a = -3.14159265f/2 + i * 2*3.14159265f/5;
    pts[i].fX = cx + r * cosf(a);
    pts[i].fY = cy + r * sinf(a);
}
xgeShapePolygonFill(pts, 5, 0x4FD8C2FF);

示例 2:五角星

// 五角星 = 10 个交替顶点(外圈 + 内圈)
xge_vec2_t star[10];
for (int i = 0; i < 10; i++) {
    float a = -3.14159265f/2 + i * 3.14159265f/5;
    float rad = (i%2==0) ? 120.0f : 50.0f;
    star[i].fX = 400 + rad * cosf(a);
    star[i].fY = 300 + rad * sinf(a);
}
xgeShapePolygonFill(star, 10, 0xFFB454FF);

示例 3:顶点色渐变 Mesh

// 两个三角形组成矩形,顶点色从红渐变到蓝
xge_shape_vertex_t verts[4] = {
    { 100, 400, 0xFF0000FF },  // 左上 红
    { 300, 400, 0x0000FFFF },  // 右上 蓝
    { 300, 500, 0x0000FFFF },  // 右下 蓝
    { 100, 500, 0xFF0000FF },  // 左下 红
};
uint32_t indices[] = { 0,1,2, 0,2,3 };  // 两个三角形

xgeShapeMeshFill(verts, 4, indices, 6);

完整代码

将以下代码保存为 ch31_main.c,编译后运行即可看到多边形与顶点色 Mesh 效果:

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

static int onFrame(void* pUser) {
    (void)pUser;
    xgeClear(0x081114FF);

    // 正五边形
    xge_vec2_t penta[5];
    for (int i = 0; i < 5; i++) {
        float a = -3.14159265f/2 + i * 2*3.14159265f/5;
        penta[i].fX = 200 + 90 * cosf(a);
        penta[i].fY = 180 + 90 * sinf(a);
    }
    xgeShapePolygonFill(penta, 5, 0x4FD8C2FF);

    // 五角星(10 个交替顶点)
    xge_vec2_t star[10];
    for (int i = 0; i < 10; i++) {
        float a = -3.14159265f/2 + i * 3.14159265f/5;
        float rad = (i % 2 == 0) ? 110.0f : 45.0f;
        star[i].fX = 550 + rad * cosf(a);
        star[i].fY = 180 + rad * sinf(a);
    }
    xgeShapePolygonFill(star, 10, 0xFFB454FF);

    // 顶点色渐变 Mesh(红→蓝)
    xge_shape_vertex_t verts[4] = {
        { 150, 380, 0xFF0000FF },
        { 400, 380, 0x0000FFFF },
        { 400, 520, 0x0000FFFF },
        { 150, 520, 0xFF0000FF },
    };
    uint32_t indices[] = { 0,1,2, 0,2,3 };
    xgeShapeMeshFill(verts, 4, indices, 6);

    return XGE_OK;
}

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

代码讲解

  • 正多边形生成:用三角函数在圆周上均匀取 N 个点,传入 xgeShapePolygonFill 即可绘制任意正多边形。
  • 五角星:外圈/内圈交替取 10 个顶点,形成凹多边形,引擎自动三角化。
  • Mesh 顶点色:每个 xge_shape_vertex_t 携带独立颜色,GPU 在三角形内部线性插值,实现平滑渐变。
  • 索引数组:每 3 个索引构成一个三角形,两个三角形拼成矩形。

要点与陷阱

  • 多边形自动三角化:引擎内部对多边形做三角剖分,支持凹多边形。
  • 顶点数 ≥ 3:少于 3 个顶点不绘制。
  • Mesh 索引数必须是 3 的倍数:每 3 个索引构成一个三角形。
  • Mesh 返回值:返回 0 表示成功,非 0 表示参数错误。
  • 顶点色插值:Mesh 的颜色在三角形内部线性插值,可实现平滑渐变。
  • 自相交多边形:自相交的多边形结果未定义,应避免。

进阶练习

  1. 用多边形绘制一个正 N 边形(N 从 3 到 12 递增展示)。
  2. 用 Mesh 顶点色实现一个彩虹渐变三角形。
  3. 实现一个可拖拽顶点的多边形编辑器(结合鼠标输入)。
多边形与自定义 Mesh效果
图:多边形与自定义 Mesh渲染效果