音视频技术应用(8)-SDL渲染RGB数据到Qt的控件,并能够通过定时器刷新

1. 在VS2019中新建一个Qt Widget Application 项目:

右键项目属性,设置所需要的头文件路径,库文件路径,工作目录等,这里省略。

2. 双击sdlqtrgb.ui 文件,打开设计器,为当前窗口添加一个Label:

添加label: 从左侧的Display Widgets 窗口中拖动一个Label标签到当前的窗口中,然后点击该Label, 在右侧的属性编辑器中设置该Label的宽高分别为400*300,未来SDL 渲染的RGB数据将会直接渲染到这个控件上。

注意objectName栏它的名字,它的名字现在为label

3. 打开 sdlqtrgb.cpp, 添加下列code :

sdlqtrgb.h

复制代码
#pragma once

#include <QtWidgets/QWidget>
#include "ui_sdlqtrgb.h"

class SDLQtRGB : public QWidget
{
    Q_OBJECT

public:
    SDLQtRGB(QWidget *parent = Q_NULLPTR);

    // 重写QT的一个定时器函数,在该函数里执行定时操作
    void timerEvent(QTimerEvent *ev) override;

private:
    Ui::SDLQtRGBClass ui;
};
复制代码

sdlqtrgb.cpp

复制代码
#include "sdlqtrgb.h"

#include <iostream>

#include <sdl/SDL.h>

#pragma comment(lib, "SDL2.lib")

using namespace std;

static int sdl_width = 0;
static int sdl_height = 0;

static SDL_Window* sdl_window = NULL;
static SDL_Renderer* sdl_render = NULL;
static SDL_Texture* sdl_texture = NULL;

static int pixel_size = 4;                  // 材质的像素格式是ARGB8888, 占4字节
static unsigned char* rgb = NULL;

SDLQtRGB::SDLQtRGB(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);

    // 取得label的宽高
    sdl_width = ui.label->width();
    sdl_height = ui.label->height();

    // 1. 初始化SDL
    if (SDL_Init(SDL_INIT_VIDEO))
    {
        cout << SDL_GetError() << endl;
        return;
    }

    // 2. 创建窗口, 这里取得label所对应的窗口句柄
    sdl_window = SDL_CreateWindowFrom((void*)ui.label->winId());
    if (!sdl_window)
    {
        cout << SDL_GetError() << endl;
        return;
    }

    // 3. 创建渲染器
    sdl_render = SDL_CreateRenderer(sdl_window, -1, SDL_RENDERER_ACCELERATED);
    if (!sdl_render)
    {
        cout << SDL_GetError() << endl;
        return;
    }

    // 4. 根据label控件的宽高来创建材质
    sdl_texture = SDL_CreateTexture(sdl_render,
        SDL_PIXELFORMAT_ARGB8888, 
        SDL_TEXTUREACCESS_STREAMING, 
        sdl_width, sdl_height
    );
    if (!sdl_texture)
    {
        cout << SDL_GetError() << endl;
        return;
    }

    // 申请一块内存空间用于存放RGB数据
    rgb = new unsigned char[sdl_width * sdl_height * pixel_size];


    // 每隔10ms调用一次timerEvent函数
    startTimer(10);
}


void SDLQtRGB::timerEvent(QTimerEvent* ev)
{
    static unsigned char tmp = 255;

    tmp--;

    // 动态的更新RGB图像
    for (int j = 0; j < sdl_height; j++)
    {
        int begin = j * sdl_width * pixel_size;
        for (int i = 0; i < sdl_width * pixel_size; i += 4)
        {
            rgb[begin + i] = 0;                     // B
            rgb[begin + i + 1] = tmp;                 // G
            rgb[begin + i + 2] = 0;               // R
            rgb[begin + i + 3] = 0;                 // A
        }
    }

    // 5. 动态更新材质信息
    if (SDL_UpdateTexture(sdl_texture, NULL, rgb, sdl_width * pixel_size))
    {
        cout << SDL_GetError() << endl;
        return;
    }

    // 6. 清理屏幕
    if (SDL_RenderClear(sdl_render))
    {
        cout << SDL_GetError() << endl;
        return;
    }

    // 7. 复制材质到渲染器对象
    SDL_Rect rect;
    rect.x = 0;
    rect.y = 0;
    rect.w = sdl_width;
    rect.h = sdl_height;
    if (SDL_RenderCopy(sdl_render, sdl_texture, NULL, &rect))
    {
        cout << SDL_GetError() << endl;
        return;
    }

    // 8. 执行渲染操作
    SDL_RenderPresent(sdl_render);

}
复制代码

运行:

可以看到,已经成功地把绿色的图像渲染到窗口中label控件所在的位置。

<完>



如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
posted @   夜行过客  阅读(463)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
历史上的今天:
2016-11-16 新浪微博客户端(26)-添加转发评论工具条
点击右上角即可分享
微信分享提示