Chapter 29 · 基础图元

圆角矩形(基础)

圆角矩形是现代 UI 的核心元素。本章学习统一半径的圆角矩形:填充、描边、一次绘制填充+描边。

29

概念

  • 统一半径:四个角使用相同的圆角半径 fRadius。
  • 三种绘制方式:Fill(仅填充)、Stroke(仅描边)、Draw(填充+描边一次完成)。
  • 半径限制:fRadius 不能超过 min(W,H)/2,超出时自动钳制为胶囊形。

API 速查

函数说明
void xgeShapeRoundRectFill(xge_rect_t tRect, float fRadius, uint32_t iColor)填充圆角矩形
void xgeShapeRoundRectFillPx(xge_rect_t tRect, float fRadius, uint32_t iColor)填充圆角矩形(像素坐标)
void xgeShapeRoundRectStroke(xge_rect_t tRect, float fRadius, float fWidth, uint32_t iColor)描边圆角矩形
void xgeShapeRoundRectStrokePx(xge_rect_t tRect, float fRadius, float fWidth, uint32_t iColor)描边圆角矩形(像素坐标)
void xgeShapeRoundRectDraw(xge_rect_t tRect, float fRadius, uint32_t iFillColor, float fStrokeWidth, uint32_t iStrokeColor)填充+描边一次绘制
void xgeShapeRoundRectDrawPx(xge_rect_t tRect, float fRadius, uint32_t iFillColor, float fStrokeWidth, uint32_t iStrokeColor)填充+描边(像素坐标)

编译本章示例

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

示例 1:卡片背景

// 圆角卡片(半径 12)
xge_rect_t card = { 100, 100, 300, 200 };
xgeShapeRoundRectFill(card, 12.0f, 0x1A2A30FF);

// 描边高亮
xgeShapeRoundRectStroke(card, 12.0f, 1.5f, 0x4FD8C260);

示例 2:Draw 一次完成

// 一次调用同时绘制填充和描边
xge_rect_t btn = { 500, 100, 180, 50 };
xgeShapeRoundRectDraw(btn,
    8.0f,          // 圆角半径
    0x2A3A40FF,    // 填充色
    2.0f,          // 描边宽度
    0xFFB454FF);   // 描边色

示例 3:不同半径对比

float radii[] = { 0, 4, 8, 16, 25 };
for (int i = 0; i < 5; i++) {
    xge_rect_t r = { 80 + i*150, 350, 120, 80 };
    xgeShapeRoundRectFill(r, radii[i], 0x4FD8C2FF);
}

完整代码

将以下代码保存为 ch29_main.c,编译后运行即可看到圆角矩形的填充、描边与 Draw 效果:

#include "xge.h"

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

    // 圆角卡片(填充 + 描边)
    xge_rect_t card = { 80, 80, 300, 200 };
    xgeShapeRoundRectFill(card, 12.0f, 0x1A2A30FF);
    xgeShapeRoundRectStroke(card, 12.0f, 1.5f, 0x4FD8C260);

    // Draw 一次完成填充+描边
    xge_rect_t btn = { 450, 80, 200, 50 };
    xgeShapeRoundRectDraw(btn, 8.0f, 0x2A3A40FF, 2.0f, 0xFFB454FF);

    // 不同半径对比
    float radii[] = { 0, 4, 8, 16, 25 };
    for (int i = 0; i < 5; i++) {
        xge_rect_t r = { 80 + i * 140, 380, 120, 80 };
        xgeShapeRoundRectFill(r, radii[i], 0x4FD8C2FF);
    }

    return XGE_OK;
}

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

代码讲解

  • Fill + Stroke:先填充背景色,再叠加描边,两步完成卡片效果。
  • Draw 一次完成:xgeShapeRoundRectDraw 内部一次提交填充和描边,避免两次绘制间的潜在闪烁。
  • 半径对比:从 0(直角)到 25(接近胶囊),直观展示 fRadius 对形状的影响。
  • 半径钳制:当 fRadius > min(W,H)/2 时,引擎自动钳制为胶囊形。

要点与陷阱

  • Draw ≠ Fill + Stroke:Draw 内部一次提交,避免两次绘制间可能的闪烁。
  • 半径为 0:等价于普通矩形(第 22 章)。
  • 半径 = min(W,H)/2:等价于胶囊形(第 28 章)。
  • 全局模式:可用 xgeShapeRoundRectModeSet 切换渲染算法,详见第 30 章。

进阶练习

  1. 实现一个对话框窗口:圆角矩形背景 + 标题栏 + 关闭按钮。
  2. 用不同半径绘制一组 iOS 风格的应用图标背景。
  3. 实现圆角矩形按钮的 hover 效果:鼠标进入时描边颜色渐变。
圆角矩形(基础)效果
图:圆角矩形(基础)渲染效果