2025/12/26大约 2 分钟
上周回顾
- pc端
- 编译了ffmpeg
- rk3566端
- 编译了uboot、kernel、rootfs,并制作了烧录镜像
本周计划
- pc端
- 学会sdl渲染
- 重新掌握QT技能,最好把kvm和dstool的代码分析一边
- rk3566端
- 尝试编译一个支持拓展板上网口的uboot
本周记录
#daily/25/09/29
渲染(显示)RGB
通过qt渲染RGB
具体查看 001test_qt_rgb
void test_qt_rgb::paintEvent(QPaintEvent* event)
{
// 创建一个空的rgb图像
QImage img = QImage(WIDTH, HEIGHT, QImage::Format_RGB888);
// 手动填入rgb数值,rgb是3位一组的,也就是把width会以3为单位等分,不足的补0
auto data = img.bits(); // 获取图像的首地址
for (int h = 0; h < HEIGHT; h++)
{
for (int w = 0; w < WIDTH; w++) // 1个像素点中有RGB,24位,3个字节
{
// *****************计算像素位置*****************
// 之前行的像素点x3,即获取之前行RGB数量总和 + 当前行的像素点*3,即获取当前行RGB的偏移量
int index = h * WIDTH * 3 + w * 3;
data[index] = 255;
data[index+1] = 0;
data[index+2] = 0;
// *****************错误点*****************
//p[w * h] = 255; // 不能这么算,因为这一行的w一直在递增的
}
}
QPainter painter(this);
painter.begin(this);
painter.fillRect(rect(), img);
painter.end();
}
vs跳转到qt源码 #todo
painter.begin(this)的作用
begin() 和 end() 是会自动调用的,所以可以不用显示调用
void test_qt_rgb::paintEvent(QPaintEvent* event)
{
QImage img = QImage(WIDTH, HEIGHT, QImage::Format_RGB888);
auto p = img.bits();
for (int h = 0; h < HEIGHT; h++)
{
for (int w = 0; w < WIDTH; w++)
{
int index = (h * WIDTH + w) * 3;
p[index] = 255; // R
p[index + 1] = 0; // G
p[index + 2] = 0; // B
}
}
QPainter painter(this); // 自动 begin(this)
painter.drawImage(0, 0, img);
// 自动 end() (析构时)
}重用 QPainter 对象
下面这些情况需要显示调用
QPainter painter;
painter.begin(device1);
// 绘制到 device1
painter.end();
painter.begin(device2); // 重用 painter
// 绘制到 device2
painter.end();错误处理
QPainter painter;
if (!painter.begin(device)) {
// 处理绘制失败的情况
return;
}
// 绘制操作
painter.end();精确控制绘制时机
QPainter painter;
painter.begin(device);
// 立即提交绘制
painter.end();
// 其他操作...通过SDL渲染RGB
适合需要高帧率的(25帧以上)
编译SDL
参考资料
源码下载 Release 3.2.22 · libsdl-org/SDL
官方提供了vs编译好的版本 SDL3-devel-3.2.22-VC,可以直接使用
以下是自己编译的过程
cmake提供了图形化的工具
- 勾选安装、注意安装路径、可以设置编译win32版本的
- 生产vs工程后,改用release编译
- 编译后release目录里只有lib,需要手动把
include/sdl中的头文件拷贝
