ffmpeg-SDL显示BMP

效果图如下

本文主要将我们通过创建窗口、渲染上下文工具、纹理工具、矩形框工具;其需要主要的是:首先我们在显示BMP时,需要先创建好窗口,再使用渲染工具对窗口进行格式刷,使用纹理工具和渲染工具配合进行BMP图片显示,矩形框的作用就是显示BMP图片的大小。

下面小例子就是当鼠标点击时,会通过texture纹理工具,使用渲染拷贝一份纹理显示至window窗口

cpp 复制代码
#include "playthread.h"
#include <SDL2/SDL.h>
#include <QDebug>
#include <QFile>

//#号自动添加双引号""
#define END(judge,SDL_Init) \
    if(judge) \
    {\
        qDebug() << #SDL_Init << "error" << SDL_GetError();\
        goto end;\
    }

playThread::playThread(QObject *parent) : QThread(parent)
{
    //监听线程,线程结束后自动释放线程内存
    connect(this,&playThread::finished,this,&playThread::deleteLater);
}


playThread::~playThread()
{
    disconnect();//?
    requestInterruption();
    quit();
    wait();

    qDebug() << "析构了";
}


void playThread::run()
{
    //创建窗口
    SDL_Window *window = nullptr;

    //渲染上下文
    SDL_Renderer *renderer = nullptr;

    //纹理(直接跟特定驱动程序相关的像素数据)
    SDL_Texture *texture = nullptr;

    //矩形框
    SDL_Rect dstRect = {0,0,50,50};

    //初始化子系统
    END(SDL_Init(SDL_INIT_VIDEO),SDL_Init);

    //创建一个窗口
    //标题-X-Y-width-height
    window = SDL_CreateWindow("SDL修改渲染目标",
                              SDL_WINDOWPOS_UNDEFINED,
                              SDL_WINDOWPOS_UNDEFINED,
                              500,
                              500,
                              SDL_WINDOW_SHOWN);
    END(!window,SDL_CreateWindow);

    //创建渲染上下文--用于渲染图形到窗口
    //这SDL_RENDERER_ACCELERATED -- 个标志告诉 SDL 尝试创建一个使用硬件加速的渲染器
    //SDL_RENDERER_PRESENTVSYNC -- 这个标志使渲染器的呈现操作同步到显示器的垂直同步(VSync)
    renderer = SDL_CreateRenderer(window, -1,
                                  SDL_RENDERER_ACCELERATED |
                                  SDL_RENDERER_PRESENTVSYNC);
    //如果创建失败
    if(!renderer)
    {
        renderer = SDL_CreateRenderer(window,-1,0);
        END(!renderer,SDL_CreateRenderer);
    }

    //创建纹理
    texture = createTexture(renderer);
    END(!texture,SDL_CreateTextureFromSurface);

    //设置渲染目标为windows -- nullptr默认为windows
    END(SDL_SetRenderTarget(renderer,nullptr),SDL_SetRenderTarget);

    //设置绘制颜色(画笔颜色)
    END(SDL_SetRenderDrawColor(renderer,0,0,0,SDL_ALPHA_OPAQUE),SDL_SetRenderDrawColor);

    //用绘制颜色(画笔颜色)清除渲染目标---也就是覆盖
    END(SDL_RenderClear(renderer),SDL_RenderClear);

    //拷贝纹理到渲染目标
    END(SDL_RenderCopy(renderer,texture,nullptr,&dstRect),SDL_rSDL_RenderCopyen);

    //更新所有的渲染操作到屏幕上
    SDL_RenderPresent(renderer);

    //等待退出事件
    while(!isInterruptionRequested())
    {
        SDL_Event event;
        SDL_WaitEvent(&event);
        switch(event.type)
        {
        case SDL_QUIT:
        {
            goto end;
            break;
        }
        case SDL_MOUSEBUTTONUP:
        {
            showClick(event,renderer,texture);
            break;
        }
        }
    }

end:
    SDL_DestroyRenderer(renderer);
    SDL_DestroyTexture(texture);
    SDL_DestroyWindow(window);
    SDL_Quit();//初始化子系统后必须做一个退出操作
}

SDL_Texture *playThread::createTexture(SDL_Renderer *renderer)
{
    //创建一个纹理对象
    SDL_Texture *texture = SDL_CreateTexture(renderer,
                                             SDL_PIXELFORMAT_RGB24,
                                             SDL_TEXTUREACCESS_TARGET,
                                             50,50);
    if(!texture)
    {
        //创建失败
        return nullptr;
    }

    //设置纹理为渲染目标
    if(SDL_SetRenderTarget(renderer,texture))
    {
        return nullptr;
    }

    //设置颜色
    if(SDL_SetRenderDrawColor(renderer,255,255,0,SDL_ALPHA_OPAQUE))
    {
        return nullptr;
    }

    //画图形
    SDL_Rect rect = {0,0,50,50};
    if(SDL_RenderDrawRect(renderer,&rect))
    {
        return nullptr;
    }

    if(SDL_RenderDrawLine(renderer,0,0,50,50))
    {
        return nullptr;
    }

    if(SDL_RenderDrawLine(renderer,50,0,0,50))
    {
        return nullptr;
    }
    return texture;
}

void playThread::showClick(SDL_Event &event, SDL_Renderer *renderer,SDL_Texture *texture)
{
    SDL_MouseButtonEvent btn = event.button;
    int w = 0,h = 0;
    if(SDL_QueryTexture(texture,nullptr,nullptr,&w,&h))
    {
        return;
    }
    int x = btn.x - (w >> 1);
    int y = btn.y - (h >> 1);

    SDL_Rect dstRect = {x,y,w,h};

    //SDL_RenderClear(renderer);

    //赋值纹理到渲染目标
    SDL_RenderCopy(renderer,texture,nullptr,&dstRect);

    //更新渲染操作到屏幕上
    SDL_RenderPresent(renderer);
}
相关推荐
莫等闲-16 小时前
代码随想录一刷记录Day44——leetcode1143.最长公共子序列 53. 最大子序和
数据结构·c++·算法·leetcode·动态规划
承渊政道17 小时前
【动态规划算法】(背包问题经典模型与解题套路)
数据结构·c++·学习·算法·leetcode·动态规划·哈希算法
weixin_4217252617 小时前
2026年C/C++/C#全解析:底层语言的进化与场景抉择,选错直接掉队
c语言·c++·c·编程语言·技术选择
我头发多我先学17 小时前
C++ 红黑树:从规则到实现,手把手带你写一棵红黑树
数据结构·c++·算法
lzh2004091917 小时前
深入学习Linux进程间通信:解析消息队列
linux·c++
水饺编程17 小时前
第5章,[标签 Win32] :设备的尺寸(三)
c语言·c++·windows·visual studio
Cando学算法17 小时前
中位数定理:到所有点的距离之和最小的点就是中位数
c++·算法·学习方法
HZY1618yzh17 小时前
洛谷题解:P16304 [蓝桥杯 2026 省 Java C 组] 抽奖活动
java·c++·算法·蓝桥杯
智者知已应修善业18 小时前
【51单片机从奇数始再转偶数逐一点亮并循环】2023-9-8
c++·经验分享·笔记·算法·51单片机
努力努力再努力wz18 小时前
【MySQL进阶系列】拒绝冗余SQL:带你透彻理解视图的底层逻辑
android·c语言·数据结构·数据库·c++·sql·mysql