<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[MCU 上纯软件实现 OpenGL]]></title><description><![CDATA[<p dir="auto"><strong>在 ESP32 上移植 OpenGL 实现（一）</strong></p>
<p dir="auto">看 @FrostMiku 最近一直在玩 ESP32，而且看起来真的很有趣，所以就求了个链接买了一块板子自己玩。咱也很想玩玩嵌入式嘛。不过 ESP32 的板子倒是真便宜，基本都在二三十左右。我这块由于带了个 TFT 屏，所以稍贵，价格是 38。到手之后发现屏幕虽然不大，但是分辨率有 135×240，所以整体显示效果还是很清晰的。正好最近在学 OpenGL，于是就觉得移植一个 OpenGL 实现玩玩。</p>
<p dir="auto">选择实现<br />
我还没自己实现 OpenGL 的功力，所以还是用别人吧。大致找到了如下实现：</p>
<ul>
<li>
<p dir="auto">Google 的 SwiftShader。其实原本不是 Google 的，前身是 TransGaming 的开源项目 swShader（后转为闭源），不过后来由 Google 接盘再开源的。SwiftShader 实现了 Vulkan、OpenGL ES、D3D 9，并且运行效率很不错。不过 SwiftShader 大量使用多线程，显然不适合 ESP32。</p>
</li>
<li>
<p dir="auto">Mesa。Mesa 大概是最被广泛使用的 OpenGL/Vulkan 的软件实现了，Mesa 的运行销量也相当不错。但是 Mesa 过于庞大，移植难度非常大。<br />
Vincent（ogles）。Vincent 实现了 OpenGL ES 1.1，由 C++ 编写，本身就是为嵌入式打造的。不过我简单浏览了下，为了优化，Vincent 的很多逻辑都是直接内嵌汇编的，和平台关系过于紧密，移植起来还是有难度的。</p>
</li>
<li>
<p dir="auto">TinyGL。TinyGL 是 Fabrice Bellard 开发的 OpenGL 1.1 子集。Fabrice 不用多说，是神仙级程序员。TinyGL 是他开发的一个轻量级 C 语言的 OpenGL 软件实现。TinyGL 的一大优点是，本身实现是纯 C 的，没有用到任何汇编内嵌，而且编译结果按官方说明只有 40K，非常适合移植。<br />
经过评估，我最后选择了 TinyGL 的一个分支实现 PicoGL。PicoGL 基于 TinyGL 4.0，增加了直接写 Linux Framebuffer 的 backend、使用 Makefile 组织项目、增加了定点数运算支持。</p>
</li>
</ul>
<p dir="auto">再开发：RepicoGL<br />
不过对于移植来说，PicoGL 还是有很多问题的。首先就是 PicoGL 增加的 backend 是写 Linux Framebuffer 的，然而 ESP32 并不是 Embed Linux，所以要新编写一个直接写入内存 Framebuffer 的后端。其次就是改用更现代的 CMake 来控制编译流程。另外，我在试验过程中发现，现有的 X11 backend 的支持实际上是有问题的，最终的渲染结果会显示两份并且颜色也不对。而且，似乎内部渲染修改为 RGB24 时也无法给出正确的输出（默认是 RGB565）。</p>
<p dir="auto">因此，我在 PicoGL 的基础上又重新开发了一个 backend。不过这个 backend 由于其特殊性，需要兼容各种不同的输入，所以原有的接口是无法满足开发需求的，因此还需要扩充若干函数。另外，由于我的开发环境是 Arduino，因此还需要为 C++ 的兼容做一些处理。</p>
<p dir="auto">另外，SDL 的 backend 还是可用的，因此可以用作图形程序的调试。不过 SDL 目前 backend 默认使用的 bbp 为 8（在 tk.c 里可以调整）。</p>
<p dir="auto">由于各处都有代码改动，所以干脆就另开一个 RepicoGL 项目好啦。代码整理完毕后，我应该会开一个 repo 上传的，时间大概在近期（咕）。</p>
<p dir="auto">移植<br />
因为实在是没有嵌入式开发经验，所以我选择了 Arduino 进行开发。直接上手 esp-idf 之类的还是有点顶不住。因此需要把 RepicoGL 做成一个库，不过我不咋熟悉 Arduino，所以直接暴力的把所有文件丢到了一起（</p>
<p dir="auto">屏幕显示用的是 TFT_eSPI 这个库。不过直接烧写发现程序运行错误，不断重启。通过 coredump 发现是内部绘制用 zbuffer 的像素 buffer 没有成功分配…… 后来发现，Arduino 的 ESP32 环境下似乎不能一次性分配太大的内存？？？</p>
<p dir="auto">因此只能把屏幕改小，这下是可以绘制了，但是绘制结果的颜色完全偏色…… 后来发现问题出在我传入 Framebuffer 数据的时候用的是 uint8_t，用 bpp8 模式输出，然后两个程序的颜色表不同。换成 uint16_t 使用 RGB565 输出就能正确绘制颜色了。</p>
<p dir="auto">另外参考一处测试（见 Reference），ESP32 的 double 运算性能较差，而且似乎并不是使用 FPU，而是采用软件计算的，因此最好是让程序内部使用 float 进行运算。好在 PicoGL 使用了统一的定点数运算库，所以有一个统一的数据类型来负责计算，全都改为 float 就可以了。修改为 float 之后，输出帧率有了肉眼可见的提升。</p>
<p dir="auto"><img src="/assets/uploads/files/1635393815096-gear.gif" alt="gear.gif" class=" img-responsive img-markdown" width="1280" height="720" /><br />
实际帧率是大于 30 的，不过为了防止 gif 过大所以就进行了压缩。</p>
<p dir="auto">然而由于开不了过大的存储空间，并且 TinyGL 内部是先将材质规格化到 256×256 再进行处理的，要开 256<em>256</em>2 的空间，所以材质暂时没有办法使用。另外还有一个机器人示例，但是由于 glu 和部分函数操作需要开缓存（当然也开不下），所以也没办法绘制所有部分。严格来说，只能画出来这么多：</p>
<p dir="auto"><img src="/assets/uploads/files/1635393832127-robot.gif" alt="robot.gif" class=" img-responsive img-markdown" width="1280" height="720" /><br />
嘛…… 至少也是正确的画出来了。下一步的移植重点（如果有的话）就是对暂时不能运行的函数尝试修正，并且继续整理 RepicoGL 了。</p>
<p dir="auto">目前的代码如下，增加了很多奇怪的调试语句，之后应该会全都去掉的（逃</p>
<p dir="auto">Arduino 库：RepicoGL_arduino_v0.1.zip<br />
齿轮示例：gear_sample.zip</p>
<p dir="auto">如果不能下载，请尝试 “右键”-“链接另存为”。</p>
<p dir="auto">Reference<br />
OpenMoko 的 OpenGL/ES 實做（<a href="http://orzlab.blogspot.com/2007/05/openmokoopengles.html%EF%BC%89" target="_blank" rel="noopener noreferrer nofollow ugc">http://orzlab.blogspot.com/2007/05/openmokoopengles.html）</a><br />
ESP32 floating-point performance（<a href="https://blog.classycode.com/esp32-floating-point-performance-6e9f6f567a69%EF%BC%89" target="_blank" rel="noopener noreferrer nofollow ugc">https://blog.classycode.com/esp32-floating-point-performance-6e9f6f567a69）</a></p>
<p dir="auto">转载： <a href="https://blog.kaaass.net/archives/1340" target="_blank" rel="noopener noreferrer nofollow ugc">https://blog.kaaass.net/archives/1340</a></p>
]]></description><link>https://bbs.aw-ol.com/topic/524/mcu-上纯软件实现-opengl</link><generator>RSS for Node</generator><lastBuildDate>Fri, 17 Jul 2026 12:20:01 GMT</lastBuildDate><atom:link href="https://bbs.aw-ol.com/topic/524.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 28 Oct 2021 04:01:58 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to MCU 上纯软件实现 OpenGL on Thu, 28 Oct 2021 06:20:44 GMT]]></title><description><![CDATA[<p dir="auto">尝试原作者的工程，在M5Stack Fire上跑一下试试：<br />
<img src="/assets/uploads/files/1635401797844-esp32-opengl.jpeg" alt="esp32-opengl.jpeg" class=" img-responsive img-markdown" width="224" height="398" /></p>
<p dir="auto">颜色好像不太对，有一点需要注意点的是<br />
<img src="/assets/uploads/files/1635401850457-6df7ced5-ab78-42bd-a9f3-f7f9a82e3802-image.png" alt="6df7ced5-ab78-42bd-a9f3-f7f9a82e3802-image.png" class=" img-responsive img-markdown" width="800" height="239" /></p>
<p dir="auto"><img src="/assets/uploads/files/1635401862312-c536d127-de8c-4633-8d6d-e535fa267b3e-image.png" alt="c536d127-de8c-4633-8d6d-e535fa267b3e-image.png" class=" img-responsive img-markdown" width="800" height="133" /></p>
<p dir="auto">这里的宽高要对应起来，不然输出的图像会错位，感觉没正常运行是的，别的好像也没有了，这是基于Arduino的工程，TFT_eSPI兼容很多LCD 驱动，还是蛮方便的，传一下完整工程吧，有时间俺也在哪吒上试试。<br />
<a href="/assets/uploads/files/1635402002126-m5fire-opengl.zip">M5Fire-OpenGL.zip</a></p>
<p dir="auto">哦，对了，原作者的Arduino被我改成PIO工程了，PIO更好用点？</p>
]]></description><link>https://bbs.aw-ol.com/post/2414</link><guid isPermaLink="true">https://bbs.aw-ol.com/post/2414</guid><dc:creator><![CDATA[IAMLIUBO]]></dc:creator><pubDate>Thu, 28 Oct 2021 06:20:44 GMT</pubDate></item><item><title><![CDATA[Reply to MCU 上纯软件实现 OpenGL on Thu, 28 Oct 2021 04:18:52 GMT]]></title><description><![CDATA[<p dir="auto"><img src="/assets/uploads/files/1635394727940-img_20211028_121906.jpg" alt="IMG_20211028_121906.jpg" class=" img-responsive img-markdown" width="1822" height="1799" /></p>
<p dir="auto">我用V3s试了一下，只出了一帧，然后段错误了。</p>
]]></description><link>https://bbs.aw-ol.com/post/2413</link><guid isPermaLink="true">https://bbs.aw-ol.com/post/2413</guid><dc:creator><![CDATA[memory]]></dc:creator><pubDate>Thu, 28 Oct 2021 04:18:52 GMT</pubDate></item><item><title><![CDATA[Reply to MCU 上纯软件实现 OpenGL on Thu, 28 Oct 2021 04:14:26 GMT]]></title><description><![CDATA[<p dir="auto">可以移植到D1吗？</p>
]]></description><link>https://bbs.aw-ol.com/post/2412</link><guid isPermaLink="true">https://bbs.aw-ol.com/post/2412</guid><dc:creator><![CDATA[tigger]]></dc:creator><pubDate>Thu, 28 Oct 2021 04:14:26 GMT</pubDate></item></channel></rss>