nuklear的设计与源码分析

本文分析了轻量级图形库nuklear的设计,包括输入部分、GUI部分和渲染部分。nuklear通过一个上下文变量连接各个部分,输入API收集状态,GUI部分构建UI,而渲染部分则将命令推送给后端。文章详细介绍了新建窗口、设置布局和创建小部件的步骤,并提供了相关代码示例。
摘要由CSDN通过智能技术生成

转载自邵晨峰的个人网站

最近在逛Github时发现了一个单文件跨平台零依赖的图形库nuklear,这使我产生了兴趣,一个大约两万行的程序,实现了很不错的效果,更神奇的是它是零依赖的,这意味着可以运用到类似单片机等特殊环境,于是我果断Fork了它开始了学习之路zoollcar/nuklear,下面我们分析下nuklear图形库的源代码

综述

首先看一下官方提供的demo(win gui版),后面会一部分一部分的分析

/* win32 实现细节*/
while (running)
{
    /* 输入部分 */
    /* win32 实现细节 */
    nk_input_begin(ctx);
    /* input 细节 */
    nk_input_end(ctx);

    /* GUI 部分 */
    if (nk_begin(ctx, "Demo", nk_rect(50, 50, 200, 200),
        NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE|
        NK_WINDOW_CLOSABLE|NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE))
    {
        enum {EASY, HARD};
        static int op = EASY;
        static int property = 20;
        /* 固定小部件像素宽度(纵向布局) */
        /* 创建小部件之前使用 nk_layout_xxx 来说明后面的小部件布局 */
        nk_layout_row_static(ctx, 30/* 高度 */, 80/* 元素宽度 */, 1/* 个数 */);
        if (nk_button_label(ctx, "button")){
            /* 点击事件 */
            fprintf(stdout, "button pressed\n");
        }
        /* 小部件横向动态布局(默认是纵向) */
        nk_layout_row_dynamic(ctx, 30, 2);
        if (nk_option_label(ctx, "easy", op == EASY)) op = EASY;
        if (nk_option_label(ctx, "hard", op == HARD)) op = HARD;

        nk_layout_row_dynamic(ctx, 22, 1);
        nk_property_int(ctx, "Compression:", 0, &property, 100, 10, 1);
    }
    nk_end(ctx);
    /* 绘制部分 */
    nk_gdi_render(nk_rgb(30,30,30)); /* win32 gui平台专用渲染 */
}

这里去除了win32实现细节,因为它本身虽然是跨平台的,但并不是所有部分都跨平台 整个程序可以分为输入部分,GUI部分,绘制部分,他们的关系是这样的:

graph TD;
    输入部分--输入信息-->GUI部分;
    GUI部分--绘制命令-->绘制部分;

nuklear 中一个称为上下文的变量会贯穿整个程序,其类型为nk_context,其中记录了这个程序几乎所有的信息,包括输入结构体、整体样式、个个窗口、渲染命令缓冲区,它起着连接 nuklear 所有部分的功能

/* 上下文 */
struct nk_context {
    struct nk_input input; /* 输入 */
    struct nk_style style; /* 样式 */
    struct nk_buffer memory; /* 缓冲区 */
    struct nk_clipboard clip;  /* 剪切板 */
    nk_flags last_widget_state;  /* 最近一个小部件状态 */
    enum nk_button_behavior button_behavior; /* 按钮行为是默认还是被替换的 */
    struct nk_configuration_stacks stacks;
    float delta_time_seconds; /* 时间(秒) */

    /* 其他细节 */

    /* 窗口 */
    int build;
    int use_pool;
    struct nk_pool pool;
    struct nk_window *begin; /* 窗口链表 */
    struct nk_window *end;
    struct nk_window *active; /* 激活窗口 */
    struct nk_window *current; /* 当前窗口 */
    struct nk_page_element *freelist;
    unsigned int count;
    unsigned int seq;
};

输入部分

input API 负

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值