乐趣区

关于ffmpeg:SDL开发笔记三使用SDL渲染窗口颜色和图片

若该文为原创文章,未经容许不得转载
原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/108602694

红瘦子 (红模拟) 的博文大全:开发技术汇合(蕴含 Qt 实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬联合等等)继续更新中…(点击传送门)

Qt 开发专栏:三方库开发技术(点击传送门)

上一篇:《SDL 开发笔记(二):音频根底介绍、应用 SDL 播放音频》
下一篇:敬请期待

前言

  对于 Qt 利用来说,为了更大的跨平台通用性,应用 SDL 播放音频,同样也风行应用 SDL 渲染视频,基本上很大一部分市面上的 sdk 播放器都是基于 sdl 的,传入窗口句柄应用 sdl 渲染。

Demo

  循环渲染色彩:
  

  按键渲染色彩:
  
  按键渲染图片:
  

SDL 渲染流程解析

  根本流程如下:
  

步骤一:初始化子系统

  SDL_Init()初始化视频零碎,其余多余的零碎不必初始化。

步骤二:创立窗口

  SDL_CreateWindow()创立 windows 窗口,设置一些罕用属性。

步骤三:创立渲染器(与窗口绑定)

  SDL_CreateRenderer()创立渲染器,该渲染器创立时曾经与显示的窗口进行了绑定。

步骤四:渲染色彩 / 渲染图片步骤

  本篇有 3 个 demo,别离为渲染了简略的色彩,同构按键工夫渲染不同的色彩,通过按键渲染不同的图片。
  渲染简略的色彩:设置渲染色彩 -> 清空 -> 渲染

// 步骤四:开始渲染 - 渲染简略的色彩
for(int index = 0; index < 100000; index++)
{
    SDL_SetRenderDrawColor(pSDLRenderer, 
                           index/255%255, 
                           index/10%255, 
                           index/20%255, 
                           128);
    SDL_RenderClear(pSDLRenderer);
    SDL_RenderPresent(pSDLRenderer);

    SDL_PollEvent(&event);
}

  按键渲染简略的色彩:设置渲染色彩 -> 清空 -> 渲染 -> 按键不同的色彩

// 步骤四:开始渲染 - 渲染简答的色彩,承受按键输出 0~9 对应不同的色彩,// 对键盘事件进行解决
bool out = false;
int r = 0;
int g = 0;
int b = 0;
while(true)
{SDL_SetRenderDrawColor(pSDLRenderer, r, g, b, 255);
    SDL_RenderClear(pSDLRenderer);
    SDL_RenderPresent(pSDLRenderer);
    SDL_PollEvent(&event);
    switch (event.type)
    {
    case SDL_KEYDOWN:
        switch (event.key.keysym.sym)
        {
        case SDLK_ESCAPE:
            out = true;
            break;
        case SDLK_1:
            r = 255; g = 0; b = 0;
            break;
        case SDLK_2:
            r = 0; g = 255; b = 0;
            break;
        case SDLK_3:
            r = 0; g = 0; b = 255;
            break;
        case SDLK_4:
            r = 255; g = 255; b = 0;
            break;
        case SDLK_5:
            r = 0; g = 255; b = 255;
            break;
        case SDLK_6:
            r = 255; g = 0; b = 255;
            break;
        case SDLK_7:
            r = 255; g = 255; b = 255;
            break;
        case SDLK_8:
            r = 255; g = 140; b = 0;
            break;
        case SDLK_9:
            r = 0; g = 191; b = 255;
            break;
        case SDLK_0:
            r = 255; g = 215; b = 0;
            break;
        default:
            break;
        }
        break;
    case SDL_QUIT:
        out = true;
        break;
    default:
        break;
    }
    if(out)
    {break;}
}

  渲染图片:加载图片 -> 创立纹理 -> 清空 -> 复制纹理到渲染 -> 渲染。

// 步骤四:开始渲染 - 渲染 bmp 图片,1- 2 两张图片
SDL_Surface *pSDLSurface = 0;
SDL_Texture *pSDLTexture = 0;
SDL_Surface *pSDLSurface2 = 0;
SDL_Texture *pSDLTexture2 = 0;

SDL_Texture *pSDLTextureTemp = 0;       // 用于长期寄存

bool out = false;
pSDLSurface = SDL_LoadBMP("testBMP/1.bmp");
pSDLTexture = SDL_CreateTextureFromSurface(pSDLRenderer, pSDLSurface);
pSDLSurface2 = SDL_LoadBMP("testBMP/2.bmp");
pSDLTexture2 = SDL_CreateTextureFromSurface(pSDLRenderer, pSDLSurface2);

pSDLTextureTemp = pSDLTexture;
while(true)
{

    // 清空渲染器
    SDL_RenderClear(pSDLRenderer);
    // 将问题 copy 到渲染器上
    SDL_RenderCopy(pSDLRenderer, pSDLTextureTemp, 0, 0);
    // 显示渲染器内容
    SDL_RenderPresent(pSDLRenderer);
    // 事件处理
    SDL_PollEvent(&event);

    switch (event.type)
    {
    case SDL_KEYDOWN:
        switch (event.key.keysym.sym)
        {
        case SDLK_ESCAPE:
            out = true;
            break;
        case SDLK_1:
            pSDLTextureTemp = pSDLTexture;
            break;
        case SDLK_2:
            pSDLTextureTemp = pSDLTexture2;
            break;
        default:
            break;
        }
        break;
    case SDL_QUIT:
        out = true;
        break;
    default:
        break;
    }
    if(out)
    {break;}
} 

步骤五:销毁渲染器

  SDL_DestroyRenderer();

步骤六:销毁窗口

  SDL_DestroyWindow();

步骤七:退出 SDL 零碎

  SDL_Quit();

SDL 渲染相干变量

SDL_Window

  用于标识窗口。

SDL_Renderer

  示意出现状态的构造。

typedef struct SDL_Surface
{
    Uint32 flags;               /**< Read-only */
    SDL_PixelFormat *format;    /**< Read-only */
    int w, h;                   /**< Read-only */
    int pitch;                  /**< Read-only */
    void *pixels;               /**< Read-write */

    /** Application data associated with the surface */
    void *userdata;             /**< Read-write */

    /** information needed for surfaces requiring locks */
    int locked;                 /**< Read-only */
    void *lock_data;            /**< Read-only */

    /** clipping information */
    SDL_Rect clip_rect;         /**< Read-only */

    /** info for fast blit mapping to other surfaces */
    struct SDL_BlitMap *map;    /**< Private */

    /** Reference count -- used when freeing surface */
    int refcount;               /**< Read-mostly */
} SDL_Surface;

SDL_Event

  SDL 的事件系统结构体,博大精深,当前趣味能够认真钻研,按键次要用到了其 type,而后键值用到的是其 key.keysym.sym。

switch (event.type)
{
case SDL_KEYDOWN:
    switch (event.key.keysym.sym)
    {
    case SDLK_ESCAPE:
        out = true;
        break;
    default:
        ;
    }
}

SDL_Surface

  在软件 blitting 中应用的像素汇合, 此构造应被视为只读,但像素除外,如果不为空,则蕴含外表的原始像素数据。

typedef struct SDL_Surface
{
    Uint32 flags;               /**< Read-only */
    SDL_PixelFormat *format;    /**< Read-only */
    int w, h;                   /**< Read-only */
    int pitch;                  /**< Read-only */
    void *pixels;               /**< Read-write */

    /** Application data associated with the surface */
    void *userdata;             /**< Read-write */

    /** information needed for surfaces requiring locks */
    int locked;                 /**< Read-only */
    void *lock_data;            /**< Read-only */

    /** clipping information */
    SDL_Rect clip_rect;         /**< Read-only */

    /** info for fast blit mapping to other surfaces */
    struct SDL_BlitMap *map;    /**< Private */

    /** Reference count -- used when freeing surface */
    int refcount;               /**< Read-mostly */
} SDL_Surface;

SDL_Texture

  纹理,像素数据的一种高效的特定示意。

SDL 渲染相干函数原型

SDL_Init()

int SDLCALL SDL_Init(Uint32 flags);

  应用此函数初始化 SDL 库,必须在应用大多数其余 SDL 函数之前调用它,初始化的时候尽量做到“够用就好”,而不要用 SDL_INIT_EVERYTHING。会呈现一些不可预知的问题。

  • 参数一:输出初始化的设施

  

SDL_CreateWindow()

SDL_Window * SDL_CreateWindow(const char *title,
                              int x,
                              int y,
                              int w,
                              int h,
                              Uint32 flags);

  应用指定的地位、尺寸和标记创立一个窗口。
  后面 5 个参数都是罕用的,第六个参数是窗口的属性,如是否可扭转大小等等.

SDL_CreateRenderer()

SDL_Renderer * SDL_CreateRenderer(SDL_Window * window,
                                  int index,
                                  Uint32 flags);

  为窗口创立二维渲染上下文,参数一为咱们之前须要渲染的窗口。

SDL_SetRenderDrawColor()

int SDLCALL SDL_SetRenderDrawColor(SDL_Renderer * renderer,
                                   Uint8 r,
                                   Uint8 g,
                                   Uint8 b,
                                   Uint8 a);

  设置用于绘图操作的色彩(矩形、直线和革除)。

SDL_RenderClear()

int SDL_RenderClear(SDL_Renderer * renderer);

  应用绘图色彩革除以后渲染指标。

SDL_RenderPresent()

void SDL_RenderPresent(SDL_Renderer * renderer);

  应用已执行的渲染更新屏幕。

SDL_PollEvent()

int SDL_PollEvent(SDL_Event * event);

  以后挂起事件的轮询。

SDL_LoadBMP()

#define SDL_LoadBMP(file)   SDL_LoadBMP_RW(SDL_RWFromFile(file, "rb"), 1)
SDL_Surface * SDL_LoadBMP_RW(SDL_RWops * src,
                             int freesrc);

  从可查找的 SDL 数据流(内存或文件)加载外表数据。

SDL_CreateTextureFromSurface()

SDL_Texture * SDL_CreateTextureFromSurface(SDL_Renderer * renderer,
                                           SDL_Surface * surface);

  从现有外表创立纹理。

  • 参数一:绑定窗口的渲染器。
  • 参数二:加载文件后的外表数据(加载的图片)。

SDL_RenderCopy()

int SDL_RenderCopy(SDL_Renderer * renderer,
                   SDL_Texture * texture,
                   const SDL_Rect * srcrect,
                   const SDL_Rect * dstrect);

  将纹理的一部分复制到以后渲染指标。

  • 参数一:应该复制纹理局部的渲染器。
  • 参数二:源纹理
  • 参数三:指向源矩形的指针,设置为 0 则全副。
  • 参数四:指向指标矩形的指针,设置为 0 则全副。

SDL_DestroyRenderer()

void SDL_DestroyRenderer(SDL_Renderer * renderer);

  销毁渲染器。

SDL_DestroyWindow()

void SDL_DestroyWindow(SDL_Window * window);

  销毁窗口。

SDL_Quit()

void SDL_Quit(void);

  此函数用于革除所有初始化的子系统。在所有退出条件后调用它。

本文章博客地址:https://blog.csdn.net/qq21497936/article/details/108602694

Demo 源码

void SDLManager::testRenderWindow()
{
    int ret = 0;
    SDL_Window *pSDLWindow = 0;
    SDL_Renderer *pSDLRenderer = 0;
    SDL_Event event;

    // 步骤一:初始化视频子系统
    ret = SDL_Init(SDL_INIT_VIDEO);
    if(ret)
    {
        LOG << "Failed";
        return;
    }
    // 步骤二:创立窗口,反对 opengl、大小可变
    pSDLWindow = SDL_CreateWindow("SDL Widget", 
                                   0, 
                                   0, 
                                   800,
                                    480, 
                                   SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
    if(!pSDLWindow)
    {
        LOG << "Failed";
        return;
    }
    // 步骤三:基于窗口创立渲染器
    pSDLRenderer = SDL_CreateRenderer(pSDLWindow, -1, 0);
    if(!pSDLRenderer)
    {
        LOG << "Failed";
        return;
    }

#if 0
    // 步骤四:开始渲染 - 渲染简略的色彩
    for(int index = 0; index < 100000; index++)
    {
        SDL_SetRenderDrawColor(pSDLRenderer,
                               index/255%255, 
                               index/10%255, 
                               index/20%255, 128);
        SDL_RenderClear(pSDLRenderer);
        SDL_RenderPresent(pSDLRenderer);

        SDL_PollEvent(&event);
    }
#endif

#if 0
    // 步骤四:开始渲染 - 渲染简答的色彩,承受按键输出 0~9 对应不同的色彩,// 对键盘事件进行解决
    bool out = false;
    int r = 0;
    int g = 0;
    int b = 0;
    while(true)
    {SDL_SetRenderDrawColor(pSDLRenderer, r, g, b, 255);
        SDL_RenderClear(pSDLRenderer);
        SDL_RenderPresent(pSDLRenderer);
        SDL_PollEvent(&event);
        switch (event.type)
        {
        case SDL_KEYDOWN:
            switch (event.key.keysym.sym)
            {
            case SDLK_ESCAPE:
                out = true;
                break;
            case SDLK_1:
                r = 255; g = 0; b = 0;
                break;
            case SDLK_2:
                r = 0; g = 255; b = 0;
                break;
            case SDLK_3:
                r = 0; g = 0; b = 255;
                break;
            case SDLK_4:
                r = 255; g = 255; b = 0;
                break;
            case SDLK_5:
                r = 0; g = 255; b = 255;
                break;
            case SDLK_6:
                r = 255; g = 0; b = 255;
                break;
            case SDLK_7:
                r = 255; g = 255; b = 255;
                break;
            case SDLK_8:
                r = 255; g = 140; b = 0;
                break;
            case SDLK_9:
                r = 0; g = 191; b = 255;
                break;
            case SDLK_0:
                r = 255; g = 215; b = 0;
                break;
            default:
                break;
            }
            break;
        case SDL_QUIT:
            out = true;
            break;
        default:
            break;
        }
        if(out)
        {break;}
    }
#endif

#if 1
    // 步骤四:开始渲染 - 渲染 bmp 图片,1- 2 两张图片
    SDL_Surface *pSDLSurface = 0;
    SDL_Texture *pSDLTexture = 0;
    SDL_Surface *pSDLSurface2 = 0;
    SDL_Texture *pSDLTexture2 = 0;

    SDL_Texture *pSDLTextureTemp = 0;       // 用于长期寄存

    bool out = false;
    pSDLSurface = SDL_LoadBMP("testBMP/1.bmp");
    pSDLTexture = SDL_CreateTextureFromSurface(pSDLRenderer, pSDLSurface);
    pSDLSurface2 = SDL_LoadBMP("testBMP/2.bmp");
    pSDLTexture2 = SDL_CreateTextureFromSurface(pSDLRenderer, pSDLSurface2);

    pSDLTextureTemp = pSDLTexture;
    while(true)
    {

        // 清空渲染器
        SDL_RenderClear(pSDLRenderer);
        // 将问题 copy 到渲染器上
        SDL_RenderCopy(pSDLRenderer, pSDLTextureTemp, 0, 0);
        // 显示渲染器内容
        SDL_RenderPresent(pSDLRenderer);
        // 事件处理
        SDL_PollEvent(&event);

        switch (event.type)
        {
        case SDL_KEYDOWN:
            switch (event.key.keysym.sym)
            {
            case SDLK_ESCAPE:
                out = true;
                break;
            case SDLK_1:
                pSDLTextureTemp = pSDLTexture;
                break;
            case SDLK_2:
                pSDLTextureTemp = pSDLTexture2;
                break;
            default:
                break;
            }
            break;
        case SDL_QUIT:
            out = true;
            break;
        default:
            break;
        }
        if(out)
        {break;}
    }
#endif
    // 步骤五:销毁渲染器
    SDL_DestroyRenderer(pSDLRenderer);
    // 步骤六:销毁窗口
    SDL_DestroyWindow(pSDLWindow);
    // 步骤七:退出 SDL
    SDL_Quit();}

工程模板:对应版本号 v1.2.0

  对应版本号 v1.2.0:按键渲染色彩和 BMP 图片

上一篇:《SDL 开发笔记(二):音频根底介绍、应用 SDL 播放音频》
下一篇:敬请期待

原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/108602694

退出移动版