cpp文件:
#include "sdlqtrgb.h"
#include <sdl/SDL.h>
static SDL_Window* sdl_win = NULL;
static SDL_Renderer* sdl_render = NULL;
static SDL_Texture* sdl_texture = NULL;
static int sdl_width = 0;
static int sdl_height = 0;
static unsigned  char* rgb = NULL;
static int pix_size = 4;
void SdlQtRGB::timerEvent(QTimerEvent* ev)
{
    static unsigned char tmp = 255;
    tmp--;
    for (int j = 0; j < sdl_height; j++)
    {
        int b = j * sdl_width * pix_size;
        for (int i = 0; i < sdl_width * pix_size; i += pix_size)
        {
            rgb[b + i] = 0;         //B
            rgb[b + i + 1] = tmp;   //G
            rgb[b + i + 2] = 0;     //R
            rgb[b + i + 3] = 0;     //A
        }
    }
    SDL_UpdateTexture(sdl_texture, NULL, rgb, sdl_width * pix_size);
    SDL_RenderClear(sdl_render);
    SDL_Rect rect;
    rect.x = 0;
    rect.y = 0;
    rect.w = sdl_width;
    rect.h = sdl_height;
    SDL_RenderCopy(sdl_render, sdl_texture, NULL, &rect);
    SDL_RenderPresent(sdl_render);
}
SdlQtRGB::SdlQtRGB(QWidget* parent)
    : QWidget(parent)
{
    ui.setupUi(this);
    sdl_width = ui.label->width();
    sdl_height = ui.label->height();
    //初始化SDL
    SDL_Init(SDL_INIT_VIDEO);
    //创建窗口
    sdl_win = SDL_CreateWindowFrom((void*)ui.label->winId());
    //创建渲染器
    sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_ACCELERATED);
    //创建材质
    sdl_texture = SDL_CreateTexture(sdl_render,
        SDL_PIXELFORMAT_ARGB8888,
        SDL_TEXTUREACCESS_STREAMING,
        sdl_width,
        sdl_height
    );
    rgb = new unsigned char[sdl_width * sdl_height * pix_size];
    startTimer(10);
}
 
1. 前要知识
1.像素
在这个上下文中,像素通常被表示为一组连续的颜色分量值。对于RGB图像来说,每个像素通常由三个分量组成:红色(R)、绿色(G)和蓝色(B)。在某些情况下还可能包含一个Alpha通道(A),像素的颜色分量值以一定的顺序存储在内存中,用一个一维数组存储,你可以想象成BGRABGRABGRABGRA........,一组BGRA就是一个像素点,不同分量的值的配比对应不同的颜色
2.代码中的循环
在这个循环中,每次迭代的单位是像素。换句话说,每次循环迭代处理的是一行中的一个像素。在RGB图像中,一个像素通常由多个字节组成,每个字节对应一个颜色通道(红色、绿色、蓝色和可能的Alpha通道),我们可以想象一张图片有很多行,每一行上有许多像素点(BGRA),比如
BGRABGRABGRABGRABGRA
BGRABGRABGRABGRABGRA
BGRABGRABGRABGRABGRA
BGRABGRABGRABGRABGRA
BGRABGRABGRABGRABGRA
上面是五行 每一行有五个像素点  
2.代码解析
1.定时器函数解析
1.外部循环(行循环):
- 目的:遍历图像的每一行。
 - 变量: 
  
- 
j:当前行的索引,从0开始直到sdl_height - 1。 
 - 
 - 每次迭代: 
  
- 计算当前行在图像数据数组中的起始偏移量 
b:b = j * sdl_width * pix_size。 - 这确保我们处理每一行的像素数据。
 
 - 计算当前行在图像数据数组中的起始偏移量 
 
2.内部循环(像素循环):
- 目的:遍历当前行的每个像素,并设置其RGB值。
 - 变量: 
  
- 
i:当前像素中第一个颜色通道(通常是蓝色)的偏移量,从0开始,每次递增pix_size。 
 - 
 - 每次迭代: 
  
- 对当前像素的每个颜色通道(B、G、R、A),设置相应的值: 
    
- 
rgb[b + i] = 0:将蓝色分量(B)设为0。 - 
rgb[b + i + 1] = tmp:将绿色分量(G)设为tmp的值,它在每次定时器事件中递减,导致逐渐减少的绿色。 - 
rgb[b + i + 2] = 0:将红色分量(R)设为0。 - 
rgb[b + i + 3] = 0:如果存在,将Alpha通道(A)设为0 
 - 
 
 - 对当前像素的每个颜色通道(B、G、R、A),设置相应的值: 
    
 
3.SDL_UpdateTexture(sdl_texture, NULL, rgb, sdl_width * pix_size) 更新纹理数据
- 这一步是将新的图像数据(存储在 
rgb数组中)更新到SDL纹理中。 - 在这个例子中,
SDL_UpdateTexture函数用于更新纹理,使其包含了最新的图像数据。 - 这个函数的参数包括要更新的纹理、更新的矩形区域(如果为NULL,则更新整个纹理)、指向新图像数据的指针,以及新图像数据的行距(通常为图像宽度乘以每个像素的大小)。
 
4.SDL_RenderClear 清空当前渲染器:
- 这一步是清空当前渲染器的内容,准备开始绘制新的内容。
 - 
SDL_RenderClear函数用于清空渲染器,以便在其上绘制新的内容。 
5.SDL_RenderCopy(sdl_render, sdl_texture, NULL, &rect);
- 在这一步中,你首先定义一个矩形区域,然后使用 
SDL_RenderCopy函数将纹理复制到渲染器中。 - 这个矩形区域定义了纹理将要绘制到屏幕上的位置和大小。
 - 
SDL_RenderCopy函数将指定的纹理复制到渲染器中,并根据矩形区域的位置和大小进行调整。 
6.SDL_RenderPresent 更新屏幕显示:
- 这一步是将渲染器中的内容更新到屏幕上,使其可见。
 - 
SDL_RenderPresent函数用于更新屏幕显示,将渲染器中的内容呈现到屏幕上。 
综上所述,这些步骤组成了SDL中绘制图形的基本流程:更新纹理数据、清空渲染器、复制纹理到渲染器中,然后更新屏幕显示。通过这个流程,你可以实现动态更新和显示图形,例如在这个例子中每次定时器事件都会更新屏幕显示,使图像逐渐变化。
2.构造函数解析
- 调用 
SDL_Init函数来初始化SDL库的视频子系统。这是必要的,因为我们将使用SDL来处理图形。 - 调用 
SDL_CreateWindowFrom函数来创建一个SDL窗口,并将其与界面上的label控件关联起来。这样,我们可以在该控件内部显示图形。 - 调用 
SDL_CreateRenderer函数来创建一个SDL渲染器,用于在窗口上进行绘制。参数-1表示选择第一个可用的渲染器,SDL_RENDERER_ACCELERATED表示使用硬件加速。 - 调用 
SDL_CreateTexture函数来创建一个SDL纹理,用于存储图像数据。参数指定了纹理的格式(ARGB8888)、访问方式(STREAMING,表示数据将被频繁更新)、宽度和高度。 - 动态分配了一个大小为 
sdl_width * sdl_height * pix_size字节的内存块,并将指针存储在rgb变量中。这个内存块用于存储图像数据。 - 调用 
startTimer函数,启动一个定时器,每隔10毫秒触发一次定时器事件。定时器事件在之前的代码中已经被重载,用于更新图像数据并刷新屏幕显示。 
构造函数完成了SDL的初始化、窗口、渲染器和纹理的创建,以及图像数据的内存分配和定时器的启动。整个流程为在Qt应用程序中嵌入SDL图形显示提供了基础。
3.运行结果展示

颜色从绿色到黑色再到绿色一直循环,根据循环里的temp变化而变化