LVGL模拟器搭建指南:VS2022+SDL2环境配置与踩坑实录
发布时间:2026/9/28 14:13:28来源:尧图网络
上个月给一个 STM32 仪表的项目选 UI 方案板子还在打样想着先把界面原型跑起来。以前用 Keil 调 LVGL每次改完布局都要重新编译、烧录、插线、看屏十分钟起步改三次我就受不了了。于是打开 Visual Studio 2022 想搭一个 LVGL 模拟器原以为半小时的活结果折腾了差不多两个晚上中间踩到一个非常经典的坑打开社区模拟器工程VS2022 直接报无法找到 Visual Studio 2010 的生成工具(平台工具集 v100)。这篇文章把我最后的顺利路径记下来以 LVGL 9.x SDL2 VS2022 Community 为组合从环境配置讲到模拟器真正跑起来。适合平时在 Keil 里被移植折腾得头疼的同学也适合嵌入式 UI 想先在 PC 上调好再搬回单片机的人。顺手会把 v8 和 v9 的差异点标出来毕竟现在网上一搜一半教程还是 v8 的 API直接抄到 v9 上编译过不去这是大多数人卡住的原因。1. 为什么要把 LVGL 跑在 PC 上模拟器到底解决了什么问题1.1 嵌入式 UI 调试的效率瓶颈只要你在单片机上调过 LVGL一定经历过这个循环改一个坐标改一个字号改一个容器间距然后编译、下载、上电、截图、发现不对、再改。如果用的是 STM32F103 这类主频不高的芯片编译一次两分钟每次迭代都像在等锅烧水。模拟器把这个问题直接拍扁了。在 PC 上跑 LVGL改完代码后按一下 F5几秒钟就能看到界面效果。它实际起到的作用就是 UI 原型验证你可以在硬件回来之前把布局、配色、交互、动画、字体渲染全部调完最后再把稳定的代码原样搬回单片机只需要改显示驱动和输入驱动两个接口UI 层代码一行都不用动。另外LVGL 自带几十个控件和 demo 工程你可以在 PC 上直接看官方示例长什么样比自己对着文档猜率高太多了。1.2 模拟器到底模拟了什么很多人第一次接触 LVGL 模拟器会有个误会以为它是虚拟机或者 QEMU 这类东西。其实不是。LVGL 本身是纯 C 写的软件渲染库不绑定硬件平台所以它根本不关心你运行在什么设备上只要有三个东西就能跑一个能往屏幕上刷像素的显示接口一个能提供触摸、按键或鼠标输入的输入接口一个周期性触发它刷新画面的主循环PC 模拟器用 SDL2 这个跨平台多媒体库来充当上面三个角色。SDL2 开一个窗口创建一块纹理LVGL 把画好的像素丢进这块纹理窗口显示鼠标的坐标和按键状态被包装成 LVGL 的指针输入设备。所以本质上你在 PC 上做的不是模拟嵌入式环境而是把 LVGL 也当成一个普通 Windows 程序跑起来了。这也是它为什么移植起来特别快的原因——LVGL 官方所有 UI 代码都是跨平台可编译的。1.3 这套方案适合谁这个流程最适合两类人一类是平时用 Keil、IAR 等集成开发环境做单片机开发代码本身很熟练但不太熟悉 VS 工程配置的工程师。另一类是想快速验证界面设计、但又不想买开发板的 UI 爱好者。如果你已经在 STM32 上成功跑过 LVGL只是想找个更快的方式调 UI那这篇你直接照着做就行20 分钟内能见到窗口。2. 动手前的准备组件、源码和 SDL2 怎么选才不踩雷2.1 VS2022 安装时候最容易漏的一项VS2022 社区版是免费的官网直接下载。安装时如果你只想写 Python 或者 C#默认勾选就够了但要用 LVGL 模拟器必须勾选使用 C 的桌面开发这个工作负载。这个工作负载包含了 MSVC 编译器、Windows SDK、C CMake 工具等一整套东西。不勾选的话之后创建 C 空项目都会失败更别提编译了。另外说一句VS Installer 的单个组件页面里我有看到过 v100 这样的老工具集选项但我强烈不建议你去装。这个后面讲 v100 报错的时候会细说。2.2 LVGL 源码选 9.x 还是 8.x打开 LVGL 的 GitHub 官方仓库默认分支已经是 9.x 了。我的建议是直接用 9.x 的最新 release比如 v9.2 以上因为 9.x 的 API 比 v8 清晰很多而且官方 demo 更丰富。但有一点你必须清楚网上大量教程、博客、入门视频都是基于 v8.x 写的里面的 API 名字跟 v9 对不上抄到 v9 编译必然报错。如果你时间紧张又想跟着某个 v8 的教程一步步走那也可以切到release/v8.4分支拉代码。但如果你是一个新项目我真心建议直接学 v9不要再接触老 API 了。老 API 里的lv_disp_drv_register、lv_disp_draw_buf_init在 v9 里已经完全换成了新的对象式创建方式。我后文的代码全部基于 v9但我会在每个关键节点注明 v8 对应的写法让你在任何一版源码上都能调通。2.3 SDL2 下载选 VC 版而不是 MinGW 版SDL2 的下载地址是 libsdl.org进 download 页面找SDL2-devel-2.30.x-VC.zip这个压缩包注意一定是 VC 后缀不是 MinGW 后缀。原因很简单Visual Studio 的 C/C 编译器和 MinGW 的编译器不是一家人生成的 .lib 导入库格式不兼容。用 VC 版的 SDL2 库VS2022 才能直接链接拿 MinGW 版硬链最后会甩出一堆 LNK2019 无法解析的外部符号浪费时间。解压之后你会看到 include、lib、cmake、bin 四个目录记住这个结构后面配置的时候会用到。Win 实际使用中可以只保留 include、lib 和 bin其余可以删掉。2.4 不要直接下老模拟器工程自建工程反而更快GitHub 上搜lv_sim_visual_studio能找到不少社区维护的模拟器工程社区版的好处是下载下来直接打开省去配置过程。但问题在于这些工程很多停留在 VS2015、VS2017 时代甚至有 VS2010 时代的旧工程文件里面写死了平台工具集 v100 或 v110。你用 VS2022 打开第一眼看到的就是最开头那个报错。所以我的建议是走一条更稳的路自己在 VS2022 里新建一个空 C 项目手动把 LVGL 源码加进来手动配置 SDL2 路径。前期多花 10 分钟但每一步你都知道为什么出了问题也知道去哪里排查比对着一个黑盒旧工程瞎试好多了。3. 手搓一个最小 VS2022 工程目录、配置和入口代码3.1 把 LVGL 源码放进工程在项目根目录下建一个deps文件夹把下载好的 LVGL 仓库整个放进去。注意我是把整个仓库放进去不是只复制 src。因为 demo 目录里也有 .c 文件头文件路径也依赖固定的目录层级弄错了后面找头文件很麻烦。然后在解决方案资源管理器里右键源文件 → 添加 → 现有项进入 LVGL 目录把src目录下所有 .c 文件都选上。VS 允许一次多选具体操作是进入lvgl/src文件夹CtrlA 全选点击添加。接着把demos目录下的 .c 文件也加进来。如果你想自己写 main.c那就再添加一个新文件作为入口。如果你以后要用 git可以把 deps 下的 LVGL 作为 submodule 管理但这篇文章不展开。3.2 lv_conf.h 模板处理LVGL 的所有配置都集中在lv_conf.h这个文件里。V9 的源码包中不会直接提供一个可以编译用的lv_conf.h而是给了一个lv_conf.h.in模板或者在某些版本里叫lv_conf_template.h。你需要做的是把这个模板复制一份重命名为lv_conf.h放到一个你能在工程里引用的位置。我是直接放在项目根目录下的config文件夹里和 deps 平级。打开lv_conf.h之后有几个开关你需要现在就看一眼LV_COLOR_DEPTH建议先设 32模拟器显示效果最接近真彩。真机如果是 16 位屏后面再改回来。LV_USE_DEMO_WIDGETS如果你想用官方控件 demo 验证画面把它改为 1。LV_USE_LOG调试阶段改为 1会输出 LVGL 内部日志。LV_FONT_MONTSERRAT_14等字体开关默认开启的就够用中文字库后面会说。然后关键一步在 VS 的预处理器定义里加LV_CONF_INCLUDE_SIMPLE1这样 LVGL 内部头文件做#include lv_conf.h时编译器的附加包含目录能找到你的配置文件。如果你不想用简单模式也可以通过LV_CONF_PATH直接指定lv_conf.h的绝对路径但简单模式最方便。3.3 包含目录、库目录和附加依赖项这部分是 VS 配置里最核心的。右键项目 → 属性确保左上角配置是所有配置平台是x6432/64 位问题我会单独说。C/C → 常规 → 附加包含目录添加deps/lvgl deps/SDL2-2.30.x/include config注意第一项加的是deps/lvgl而不是deps/lvgl/src因为很多源码里的头文件是#include lvgl/lvgl.h这种带一层目录的写法所以必须把 lvgl 根目录加进去。链接器 → 常规 → 附加库目录添加deps/SDL2-2.30.x/lib/x64链接器 → 输入 → 附加依赖项添加SDL2.lib SDL2main.lib这里SDL2main.lib很重要它负责把你写的main函数包装成 Windows 程序真正的入口。没有它链接阶段大概率报 LNK2019 无法解析的外部符号 main。3.4 x64 还是 x86一次到位别混VS2022 新建的项目默认可能是 x86 或者 Any CPU而 SDL2 的库目录里分 x86 和 x64 两个文件夹如果你下载的 SDL2 包是 VC 版它的 lib 目录下面会有 x86 和 x64 两个子目录。我在项目配置里选的是 x64。如果你用 x86那链接器的附加库目录就要改成deps/SDL2/lib/x86不能混。混了之后会报 LNK1112模块计算机类型x86与目标计算机类型x64冲突。还有一点VS 顶部解决方案平台下拉框如果显示的是Debug Win32记得打开配置管理器新建一个 x64 平台然后把前面所有配置都切到 x64 再编译。3.5 必须加的预处理器定义在 C/C → 预处理器 → 预处理器定义里除了默认的WIN32、_DEBUG这些再加这几个_ENABLE_EXTENDED_ALIGNED_STORAGE LV_CONF_INCLUDE_SIMPLE1_ENABLE_EXTENDED_ALIGNED_STORAGE这个名字看起来莫名其妙但你不用它编译 LVGL 的某些 C 头文件时会报一串跟std::aligned_storage相关的错误。这是 VS 2019 之后对 C17 标准调整导致的老教程没提是因为当年编译器版本不一样。另外建议加一个NOMINMAX可以避免 Windows.h 里的min/max宏干扰 LVGL 的代码逻辑这个坑比较隐蔽但加上没坏处。3.6 C 语言标准在 C/C → 语言 → C 语言标准里选ISO C17 标准 (/std:c17)。LVGL 本身是 C 代码VS 会用 C 编译器编译 .c 文件但这个选项会影响包含进来的某些 Windows 头文件和 SDL 头文件的解析方式C17 兼容性最好。3.7 把 SDL2.dll 带到生成目录如果编译通过了运行时报由于找不到 SDL2.dll无法继续执行代码那是因为 SDL2 的动态库不在 exe 所在目录。最简单粗暴的办法是手动把deps/SDL2/bin/SDL2.dll复制到x64/Debug或x64/Release目录。但我建议用后期生成事件自动复制右键项目 → 属性 → 生成事件 → 后期生成事件命令行填xcopy /y $(ProjectDir)deps\SDL2\bin\SDL2.dll $(OutDir)这样每次编译完都会自动把 dll 拷到输出目录省得忘记。3.8 最简可用代码骨架配置好之后先写一个最简代码确认环境通不通。新建 main.cpp注意 VS 会按扩展名决定编译方式.cpp文件可以编译 C 代码没问题。#include SDL.h #include lvgl/lvgl.h #define HOR_RES 800 #define VER_RES 480 int main(int argc, char* argv[]) { SDL_Init(SDL_INIT_VIDEO); SDL_Window* win SDL_CreateWindow( LVGL Simulator, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, HOR_RES, VER_RES, SDL_WINDOW_SHOWN); SDL_Renderer* renderer SDL_CreateRenderer(win, -1, 0); SDL_Texture* texture SDL_CreateTexture( renderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, HOR_RES, VER_RES); lv_init(); lv_display_t* disp lv_display_create(HOR_RES, VER_RES); lv_display_set_resolution(disp, HOR_RES, VER_RES); lv_obj_t* label lv_label_create(lv_screen_active()); lv_label_set_text(label, Hello LVGL VS2022); lv_obj_center(label); while (1) { SDL_Event e; while (SDL_PollEvent(e)) { if (e.type SDL_QUIT) return 0; } lv_timer_handler(); SDL_Delay(5); } }这个代码还没有写 flush 回调所以窗口会出现但画面上不会正常显示 LVGL 内容。这一步只是验证编译、链接和 SDL 初始化都正常。等第五章把 flush 和输入补上画面才会真正亮起来。如果你走到这一步编译还有错误先别急第四章把最常见的报错一次列清楚。4. 编译失败日志逐条看v100 工具集、LNK2019 和其他运行期地雷4.1 平台工具集 v100 报错的两个解决路径开头已经提到了这个报错用旧工程打开时VS2022 显示无法找到 Visual Studio 2010 的生成工具(平台工具集 v100)。原理是这样的VS 的每个 C 项目文件.vcxproj里都记录了当年创建这个工程时用的编译工具版本叫平台工具集。VS2010 对应 v100VS2012 对应 v110VS2022 对应的是 v143。VS 只会默认安装当前版本的工具集不会自动带老版本所以用 VS2022 打开写着 v100 的工程它就找不到对应的编译器了。解决办法有两个一是改工程属性右键项目 → 属性 → 常规 → 平台工具集从 v100 改成 Visual Studio 2022 (v143)。如果改了之后还提示 Windows SDK 版本问题再把常规里的 Windows SDK 版本改成10.0最新已安装版本。二是去 VS Installer 里勾选MSVC v100 生成工具组件。但我不推荐理由很简单v100 是 VS2010 时代的编译器对 C99/C11 的支持远不如现代编译器LVGL 源码里有些写法它在标准模式下未必支持。而且为跑一个 demo 去装十年前的工具集没有任何收益。如果你是自己新建的工程正常不会遇到这个报错。所以我一直强调宁可前期多花十分钟自己配工程也不要贪快直接下老工程。4.2 LNK2019无法解析的外部符号 main / SDL_main这个报错有两种常见形态一种是LNK2019 无法解析的外部符号 main。原因通常是你没有链接SDL2main.lib同时工程设置成了 Windows 子系统。Windows 子系统希望找到一个 WinMain 作为入口但你写的是 main对不上。解决方法是去附加依赖项里加上 SDL2main.lib或者把链接器 → 系统 → 子系统改成控制台。另一种形态是无法解析的外部符号 SDL_main。这通常是因为你链接了 SDL2main.lib但自己的 main 函数写成了int main()参数列表不完整。SDL2 的入口包装机制要求你必须写标准签名int main(int argc, char* argv[])如果项目里已经有别人写好的main函数并且你重新定义了main也会出现奇怪冲突。所以自建工程时一定要保证项目里只有一个 main。4.3 _ENABLE_EXTENDED_ALIGNED_STORAGE 缺失导致的报错如果你直接下载官方 LVGL 的某个 demo 工程在 VS2022 上编译有很大概率遇到类似error C2338: static_assert failed: std::aligned_storageLen, Align::value或者一堆指向type_traits的模板错误。这个问题的根源是 MSVC 的 STL 在 C17 模式下对std::aligned_storage增加了新的对齐校验而某些库代码比如 LVGL 或者你引用的 C 封装还在用旧式的对齐方式。解决办法就是在预处理器定义里加_ENABLE_EXTENDED_ALIGNED_STORAGE1。这个宏是微软官方提供的兼容开关看到它别慌加了就完事。4.4 LNK111232 位库链接到了 64 位目标如果你在 x64 平台下附加库目录却指向 SDL2 的 x86 版本VS 链接时会报 LNK1112。反过来也一样。检查路径是不是真的指向了SDL2/lib/x64并且解决方案平台是 x64这个错误就消失了。有一个小技巧在链接器的命令行页面里加上/VERBOSE:LIB可以看到当前实际链接了哪些 .lib 文件能帮你核对路径。4.5 运行报错找不到 SDL2.dll编译链接都过了点运行弹窗说缺 dll。这个问题前面讲过把 SDL2.dll 复制到输出目录或者配置后期生成事件自动拷贝。多说一句如果你把 SDL2.dll 复制过去了还是报找不到很可能你打开的是旧版本 SDL2 而项目链接的是新版本 SDL2.lib或者 dll 放错到了 Release 目录而你在跑 Debug。建议看输出窗口里 exe 的完整路径在哪里再对照 dll 是否在同一个目录。4.6 画面花屏或颜色错乱LV_COLOR_DEPTH 和 SDL 像素格式不一致这个坑非常隐蔽因为它不会导致编译报错只有画面颜色诡异文字变成紫色背景变成绿色之类。原因是 LVGL 输出的像素格式和 SDL 纹理期望的像素格式不匹配。LVGL 根据LV_COLOR_DEPTH决定每个像素是 16 位 RGB565 还是 32 位 ARGB8888而 SDL 纹理创建时也需要指定SDL_PIXELFORMAT_RGB565或SDL_PIXELFORMAT_ARGB8888。如果你的LV_COLOR_DEPTH是 32但 SDL 纹理创建时用 RGB565画面就会花。经验做法是两个地方统一按条件编译#if LV_COLOR_DEPTH 16 SDL_PixelFormatEnum fmt SDL_PIXELFORMAT_RGB565; #else SDL_PixelFormatEnum fmt SDL_PIXELFORMAT_ARGB8888; #endif这样改了 LV_COLOR_DEPTH 之后SDL 这边自动跟随不会再花屏。4.7 编译错误满天飞但其实是头文件路径不对还有一种情况是代码看起来没问题但 VS 报一堆找不到lvgl.h、找不到SDL.h的错误。这种基本都是附加包含目录没有写对。VS 不会自动感知你项目里某个文件夹里有 lvgl你必须在附加包含目录里把deps/lvgl、deps/SDL2/include、config三个路径都加进去。路径最好用相对路径以$(ProjectDir)开头方便换电脑后还能编译。5. 让 UI 真正亮起来显示缓冲、触摸输入与主循环的配合5.1 初始化顺序为什么这么重要只要你接触过图形库就会发现初始化顺序永远是最容易出事的地方。LVGL 模拟器和真实 LCD 驱动的初始化顺序逻辑是一样的先准备好显示硬件再初始化 UI 系统。具体来说SDL 窗口、渲染器、纹理必须在lv_init()之前创建好。为什么因为 LVGL 一旦开始跑第一帧就有可能调用你注册的 flush 回调而 flush 回调里要用到 SDL 纹理。如果纹理还没创建回调就是空指针解引用程序直接崩溃。推荐的初始化顺序SDL_Init(SDL_INIT_VIDEO)创建 SDL 窗口、渲染器、纹理lv_init()创建 LVGL 显示设备设置缓冲区和 flush 回调创建 LVGL 输入设备设置鼠标读取回调加载界面代码demo 或你自己的 UI进入主循环5.2 显示缓冲区的设置逻辑LVGL 是一个局部刷新图形库它不需要把整个屏幕的像素都保存下来它只维护一个较小的绘制缓冲区每次只画画面变化的部分然后通过 flush 回调把这块区域的像素推给显示驱动。lv_display_set_buffers就是干这个的。它接收两个缓冲区指针一个用于绘制一个用于交替刷新即双缓冲机制。缓冲区的大小决定了每帧最大绘制面积。PC 上内存充裕开个800 * 100像素的缓冲区就够用了static lv_color_t buf1[HOR_RES * 100]; static lv_color_t buf2[HOR_RES * 100]; lv_display_set_buffers(disp, buf1, buf2, sizeof(buf1), LV_DISPLAY_RENDER_MODE_PARTIAL);注意buf1和buf2必须是静态或全局的不能是局部数组。栈空间默认只有 1MB而800 * 100 * sizeof(lv_color_t)在 32 位颜色下大约是 320KB两个就是 640KB放栈上必然溢出。如果你换成 16 位颜色一个缓冲区就是 160KB两个 320KB栈还是有可能爆所以一律放静态区最稳。LV_DISPLAY_RENDER_MODE_PARTIAL表示渲染部分区域缓冲区只需要覆盖屏幕的一部分即可。如果缓冲区尺寸等于全屏也可以设为LV_DISPLAY_RENDER_MODE_FULL但在模拟器里没必要。5.3 flush 回调到底做了什么flush 回调是 LVGL 与显示驱动之间的唯一桥梁。每次 LVGL 完成一块区域的绘制就把这块区域的像素数据和坐标范围通过回调传给你你需要把像素数据送出去显示。在模拟器里这个动作分为三步static void lvgl_flush_cb(lv_display_t* display, const lv_area_t* area, uint8_t* px_map) { int w lv_display_get_horizontal_resolution(display); int h lv_display_get_vertical_resolution(display); SDL_UpdateTexture(sdl_texture, NULL, px_map, w * sizeof(lv_color_t)); SDL_RenderClear(sdl_renderer); SDL_RenderCopy(sdl_renderer, sdl_texture, NULL, NULL); SDL_RenderPresent(sdl_renderer); lv_display_flush_ready(display); }第一步SDL_UpdateTexture把 LVGL 像素数据拷贝到 SDL 纹理里。第二步SDL_RenderClear清空渲染器SDL_RenderCopy把纹理绘制到渲染器上SDL_RenderPresent把画面真正送到窗口。第三步极其关键调用lv_display_flush_ready(display)告诉 LVGL 这块区域已经刷完了。如果你漏了第三步LVGL 会认为显示驱动还没有准备好接收下一块数据画面就会卡在某一帧上看起来像死机。这是所有 LVGL 移植中最高频的错误没有之一。我在 v8 时代犯过这个错当时现象是程序不崩但屏幕刷一两屏就再也不动了。查了好久才发现是lv_disp_flush_ready没调用。V9 里这个函数改名成了lv_display_flush_ready原理完全一样。5.4 鼠标输入把 SDL 事件翻译成 LVGL 指针事件模拟器里鼠标就是触摸屏。创建一个 LVGL 输入设备然后提供一个读取回调。LVGL 的主循环会周期性地调用这个回调看看有没有新的输入事件。static void mouse_read_cb(lv_indev_t* indev, lv_indev_data_t* data) { int x 0, y 0; Uint32 buttons SDL_GetMouseState(x, y); >lv_indev_t* mouse lv_indev_create(); lv_indev_set_type(mouse, LV_INDEV_TYPE_POINTER); lv_indev_set_read_cb(mouse, mouse_read_cb);注意 v8 时代创建输入设备是用lv_indev_drv_register()加一个lv_indev_drv_t结构体v9 改成了对象式创建。如果你照着 v8 教程抄到这里编译会报错这不代表你的配置有问题只是 API 变了。5.5 主循环别让 SDL 事件阻塞 LVGL主循环是整个模拟器的心脏。大多数人对图形库主循环的理解是处理事件但 LVGL 这种非阻塞式 UI 库要求事件处理和 UI 刷新交替进行bool running true; while (running) { SDL_Event e; while (SDL_PollEvent(e)) { if (e.type SDL_QUIT) running false; } lv_timer_handler(); SDL_Delay(5); }SDL_PollEvent是非阻塞的它会尽可能多地取事件取完就返回。处理完事件后调用lv_timer_handler()LVGL 内部的定时器、动画、重绘都在这个调用里被触发。最后SDL_Delay(5)把帧率控制在 200 FPS 以内避免空转把 CPU 吃满。千万不要用SDL_WaitEvent去替代SDL_PollEvent。那样的话只要鼠标不动、没有任何事件主循环就阻塞住了LVGL 的动画和刷新也跟着停掉画面会卡死。5.6 完整可运行代码把前面这些片段组合起来就是一个完整的 VS2022 LVGL9 SDL2 模拟器。我贴一个可以直接编译运行的版本#include SDL.h #include lvgl/lvgl.h #include lvgl/demos/lv_demos.h #define HOR_RES 800 #define VER_RES 480 static SDL_Window* sdl_window; static SDL_Renderer* sdl_renderer; static SDL_Texture* sdl_texture; static lv_color_t buf1[HOR_RES * 100]; static lv_color_t buf2[HOR_RES * 100]; static void lvgl_flush_cb(lv_display_t* display, const lv_area_t* area, uint8_t* px_map) { int w lv_display_get_horizontal_resolution(display); int h lv_display_get_vertical_resolution(display); SDL_UpdateTexture(sdl_texture, NULL, px_map, w * sizeof(lv_color_t)); SDL_RenderClear(sdl_renderer); SDL_RenderCopy(sdl_renderer, sdl_texture, NULL, NULL); SDL_RenderPresent(sdl_renderer); lv_display_flush_ready(display); } static void mouse_read_cb(lv_indev_t* indev, lv_indev_data_t* data) { int x 0, y 0; Uint32 buttons SDL_GetMouseState(x, y); >
网站建设高端定制企业官网