前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【FFmpeg】SDL 音视频开发 ① ( SDL 窗口绘制 | SDL 视频显示函数 | SDL_Window 窗口 | SDL_Renderer 渲染器 | SDL_Texture 纹理 )

【FFmpeg】SDL 音视频开发 ① ( SDL 窗口绘制 | SDL 视频显示函数 | SDL_Window 窗口 | SDL_Renderer 渲染器 | SDL_Texture 纹理 )

作者头像
韩曙亮
发布2024-06-09 13:53:20
730
发布2024-06-09 13:53:20
举报

一、SDL 视频显示函数

1、SDL_Init 函数

使用 SDL 开发库 的 功能 之前 , 都要先 初始化 SDL 系统环境 ;

调用 SDL_Init() 函数 , 可以初始化 SDL 系统上下文环境 , 这是进行 SDL 任何操作之前都必须执行的操作 ;

在该函数中传入 不同子系统 对应的 位掩码 , 初始化不同的子系统 ;

函数原型如下 :

代码语言:javascript
复制
int SDL_Init(Uint32 flags);
  • flags 参数 : 是 位掩码 , 表示 子系统标志位 , 可以通过 | 操作符 同时设置多个 子系统 标志位 , 常用的子系统标志位如下 , 不同的 子系统 可实现的功能不同 ;
    • SDL_INIT_VIDEO : 视频子系统 , 可以 实现 创建窗口 , 渲染器 , 纹理 等功能 ;
    • SDL_INIT_AUDIO:音频子系统 , 可进行声音播放 ;
    • SDL_INIT_EVENTS:事件子系统 , 可处理 鼠标 键盘 等事件 ;
    • SDL_INIT_TIMER : 定时器子系统 , 可实现 SDL 定时器 功能 ;
  • 返回值 : 如果 SDL 系统初始化成功 , 则返回 0 ; 如果初始化失败 , 返回负数 ;

子系统标志位 定义在了 SDL.h 头文件中 ,

代码语言:javascript
复制
/**
 *  \name SDL_INIT_*
 *
 *  These are the flags which may be passed to SDL_Init().  You should
 *  specify the subsystems which you will be using in your application.
 *  这些是可以传递给SDL_Init()的标志。您应该指定将在应用程序中使用的子系统。
 */
/* @{ */
#define SDL_INIT_TIMER          0x00000001u
#define SDL_INIT_AUDIO          0x00000010u
#define SDL_INIT_VIDEO          0x00000020u  /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
#define SDL_INIT_JOYSTICK       0x00000200u  /**< SDL_INIT_JOYSTICK implies SDL_INIT_EVENTS */
#define SDL_INIT_HAPTIC         0x00001000u
#define SDL_INIT_GAMECONTROLLER 0x00002000u  /**< SDL_INIT_GAMECONTROLLER implies SDL_INIT_JOYSTICK */
#define SDL_INIT_EVENTS         0x00004000u
#define SDL_INIT_SENSOR         0x00008000u
#define SDL_INIT_NOPARACHUTE    0x00100000u  /**< compatibility; this flag is ignored. */
#define SDL_INIT_EVERYTHING ( \
                SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_EVENTS | \
                SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | SDL_INIT_SENSOR \
            )
/* @} */

代码示例 :

代码语言:javascript
复制
#include <stdio.h>

#include <SDL.h>

int main()
{
	// ...
	
    // 初始化 SDL 环境 , 用于播放视频
    SDL_Init(SDL_INIT_VIDEO);

2、SDL_Quit 函数

SDL_Init 函数 的作用是 初始化 要使用的各个子系统 , 使用完毕后需要退出 , SDL_Quit 函数 就是退出 SDL 系统 时需要调用的函数 ;

SDL_Quit 函数原型如下 : 该函数没有参数 , 也没有返回值 ;

代码语言:javascript
复制
void SDL_Quit(void);

SDL_Quit 函数 用于 关闭 SDL 各个子系统 , 释放所有 SDL 申请的系统资源 , 包括

  • 关闭已打开的 SDL 窗口
  • 释放内存中已加载的图像和音频资源所占用的内存空间
  • 停止所有线程 , 避免应用退出后仍然占用 CPU 资源

如果 SDL 应用程序退出前不调用 SDL_Quit 函数 , 会发生 内存泄漏 / 资源泄漏 等问题 ;

代码示例 :

代码语言:javascript
复制
#include <stdio.h>

#include <SDL.h>

#undef main
int main()
{
    // ... 

    // 初始化 SDL 环境 , 用于播放视频
    SDL_Init(SDL_INIT_VIDEO);

	// ... 

    // 释放系统资源
    SDL_Quit();

    return 0;
}

3、SDL_CreateWindow 函数

SDL_CreateWindow 函数 用于 创建 SDL_Window 窗口 , 该函数的函数原型如下 :

代码语言:javascript
复制
SDL_Window* SDL_CreateWindow(const char* title, int x, int y, int w, int h, Uint32 flags);
  • title 参数 : 窗口标题字符串 ;
  • x , y 参数 : 窗口位置 , 左上角坐标 ; 建议使用 SDL_WINDOWPOS_UNDEFINED 自动设置 , 默认是屏幕中心位置 ;
  • w , h 参数 : 窗口宽高 , 单位像素 ;
  • flags 参数 : 窗口属性标志位 , 这个参数也是 位掩码 , 可使用 | 运算符 进行多个位掩码 组合设置 ;
  • SDL_Window* 返回值 : 返回窗口的引用 ;

代码示例 :

代码语言:javascript
复制
    // 创建 SDL 窗口对象
    SDL_Window *window = NULL;

    // 初始化 SDL 环境 , 用于播放视频
    SDL_Init(SDL_INIT_VIDEO);

    // 创建 SDL Window 窗口对象
    window = SDL_CreateWindow("SDL窗口",
                              SDL_WINDOWPOS_UNDEFINED,
                              SDL_WINDOWPOS_UNDEFINED,
                              800,
                              600,
                              SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);

	// 窗口创建成功 后 进行 渲染 / 事件处理 操作
  
  	// 销毁窗口
    SDL_DestroyWindow(window);   
	// 退出 SDL
    SDL_Quit();  

4、SDL_CreateRenderer 函数

SDL_CreateRenderer 函数 用于创建 渲染器对象 , 渲染器 的作用是 在 SDL_Window 窗口上绘制图像 ;

SDL_CreateRenderer 函数原型如下 :

代码语言:javascript
复制
SDL_Renderer* SDL_CreateRenderer(SDL_Window* window, int index, Uint32 flags);
  • window 参数 : 调用 SDL_CreateWindow 函数创建的 SDL_Window 窗口对象 , 创建 的 渲染器 用于在该窗口中绘制图像 ;
  • index 参数 : 设置 渲染驱动程序的索引 , 设置 -1 表示使用第一个支持指定标志的渲染驱动程序 ;
  • flags 参数 : 一个 或 多个 SDL_RendererFlags 位掩码组合 , 可使用 | 运算符进行或运算组合设置 ;
  • SDL_Renderer* 返回值 : 如果创建渲染器成功 , 则返回新创建的渲染器对象指针 ; 创建失败返回 NULL ;

代码示例 :

代码语言:javascript
复制
    // 创建 SDL 窗口对象
    SDL_Window *window = NULL;

    // 初始化 SDL 环境 , 用于播放视频
    SDL_Init(SDL_INIT_VIDEO);

    // 创建 SDL_Window 窗口对象
    window = SDL_CreateWindow("SDL窗口",
                              SDL_WINDOWPOS_UNDEFINED,
                              SDL_WINDOWPOS_UNDEFINED,
                              800,
                              600,
                              SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);

	// 创建 SDL_Renderer 渲染器
	SDL_Renderer *renderer = SDL_CreateRenderer(
							  window, -1, SDL_RENDERER_ACCELERATED);   

  	// 销毁窗口
    SDL_DestroyWindow(window);   
	// 退出 SDL
    SDL_Quit();  

5、SDL_CreateTexture 函数

SDL_CreateTexture 函数 用于创建 " 纹理 " 对象 SDL_Texture , 渲染器 使用 纹理对象 绘制图像 ;

SDL_CreateTexture 函数原型如下 :

代码语言:javascript
复制
SDL_Texture* SDL_CreateTexture(SDL_Renderer* renderer, Uint32 format, int access, int w, int h);
  • renderer 参数 : 该参数是 指向已经创建的 SDL_Renderer 对象的指针 , 渲染器对象 使用 该纹理 进行图像绘制 ;
  • format 参数 : 设置 纹理 像素格式 ;
  • access 参数 : 设置纹理的访问权限 ;
    • SDL_TEXTUREACCESS_STATIC 是 不会频繁更新的纹理 ;
    • SDL_TEXTUREACCESS_STREAMING 是 频繁更新的纹理 ;
  • w , h 参数 : 设置纹理宽高 , 单位像素 ;
  • SDL_Texture* 参数 : 创建纹理对象成功 , 则返回 SDL_Texture 对象指针 ; 如果创建失败返回 NULL ;

代码示例 :

代码语言:javascript
复制
    // 创建 SDL 窗口对象
    SDL_Window *window = NULL;

    // 初始化 SDL 环境 , 用于播放视频
    SDL_Init(SDL_INIT_VIDEO);

    // 创建 SDL_Window 窗口对象
    window = SDL_CreateWindow("SDL窗口",
                              SDL_WINDOWPOS_UNDEFINED,
                              SDL_WINDOWPOS_UNDEFINED,
                              800,
                              600,
                              SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);

	// 创建 SDL_Renderer 渲染器对象
	SDL_Renderer *renderer = SDL_CreateRenderer(
							  window, -1, SDL_RENDERER_ACCELERATED);  

	// 创建 SDL_Texture 纹理对象
	SDL_Texture* texture = SDL_CreateTexture(
							  renderer, 
							  SDL_PIXELFORMAT_RGBA8888, 
							  SDL_TEXTUREACCESS_STATIC, 800, 600); 

  	// 销毁窗口
    SDL_DestroyWindow(window);   
	// 退出 SDL
    SDL_Quit();  

6、窗口 / 渲染器 / 纹理 关联

窗口 SDL_Window , 使用 SDL_CreateWindow 函数创建 ;

渲染器 SDL_Renderer , 使用 SDL_CreateRenderer 函数创建 ;

纹理 SDL_Texture , 使用 SDL_CreateTexture 函数创建 ;

在 Windows 操作系统中 , 每个应用的窗口都是一个 SDL_Window 对象 ;

在 SDL_Window 窗口 中 , 可以 有多个 SDL_Renderer 渲染器 , 渲染器 可以用于渲染 / 显示 纹理 ; SDL_Renderer 渲染器 是 基于 SDL_Window 窗口对象创建的 ;

每个 SDL_Renderer 渲染器 可以 设置不同的 纹理 SDL_Texture ; SDL_Texture 纹理 是基于 SDL_Renderer 渲染器 对象创建 ;

二、SDL 窗口绘制 - 代码示例


1、SDL 窗口绘制代码

这是在上一篇博客 【FFmpeg】SDL 开发环境搭建 ( SDL 简介 | 下载 SDL 开发库 | 拷贝动态库到 C:\Windows\SysWOW64 目录 | 将 SDL 开发库配置到 Qt 项目 ) 代码的基础上 , 编写的代码 ;

完整代码参考 https://download.csdn.net/download/han1202012/89408757

代码语言:javascript
复制
#include <stdio.h>

#include <SDL.h>

#undef main
int main(int argc, char* argv[])
{
    printf("Hello World!\n");

    // 创建 SDL 窗口对象
    SDL_Window *window = NULL;

    // 初始化 SDL 环境 , 用于播放视频
    SDL_Init(SDL_INIT_VIDEO);

    // 创建 SDL Window 窗口对象
    window = SDL_CreateWindow("SDL窗口",
                              SDL_WINDOWPOS_UNDEFINED,
                              SDL_WINDOWPOS_UNDEFINED,
                              800,
                              600,
                              SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);


    // 创建 SDL_Renderer 渲染器对象
    SDL_Renderer *renderer = SDL_CreateRenderer(
                window, -1, 0);

    // 创建 SDL_Texture 纹理对象
    SDL_Texture* texture = SDL_CreateTexture(
                renderer,
                SDL_PIXELFORMAT_RGBA8888,
                SDL_TEXTUREACCESS_TARGET,
                800, 600);


    // 为 渲染器 设置 纹理
    SDL_SetRenderTarget(renderer, texture);
    // 设置红色背景, 后面四个参数分别是 RGBA
    SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
    // 清除屏幕
    SDL_RenderClear(renderer);

    // 在 (100, 100) 位置绘制 100x100 像素大小的矩形
    SDL_Rect rect;
    rect.x = 100;
    rect.y = 100;
    rect.w = 100;
    rect.h = 100;

    // 渲染器绘制矩形
    SDL_RenderDrawRect(renderer, &rect);
    // 设置绘制矩形颜色为白色 最后四位参数是 RGBA
    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
    // 设置矩形为颜色填充
    SDL_RenderFillRect(renderer, &rect);

    // 设置渲染目标为窗口
    SDL_SetRenderTarget(renderer, NULL);
    // 拷贝纹理到 CPU 中
    SDL_RenderCopy(renderer, texture, NULL, NULL);

    // 输出渲染器渲染内容
    SDL_RenderPresent(renderer);

    // 延迟 3 秒
    SDL_Delay(10000);

    // 关闭窗口
    SDL_DestroyWindow(window);

    // 释放系统资源
    SDL_Quit();

    return 0;
}

2、执行结果

执行结果如下图所示 :

执行后 , 弹出如下窗口 , 窗口背景为红色 , 在 窗口的 (100, 100) 像素位置 绘制了 100x100 像素大小的矩形 ;

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-06-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、SDL 视频显示函数
    • 1、SDL_Init 函数
      • 2、SDL_Quit 函数
        • 3、SDL_CreateWindow 函数
          • 4、SDL_CreateRenderer 函数
            • 5、SDL_CreateTexture 函数
              • 6、窗口 / 渲染器 / 纹理 关联
              • 二、SDL 窗口绘制 - 代码示例
                • 1、SDL 窗口绘制代码
                  • 2、执行结果
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档