【FFmpeg】SDL 音视频开发 ② ( SDL 视频显示函数 | 设置渲染器目标纹理 | 设置渲染器颜色 | 清除渲染器 | 渲染器绘制矩形 | 纹理拷贝 | 窗口中显示渲染纹理 )

2024-06-13 13:47:25 浏览数 (1)

文章目录

  • 一、SDL 视频显示函数
    • 1、SDL 的 渲染器 和 纹理 之间的关系
    • 2、SDL_SetRenderTarget 函数 - 设置渲染器目标纹理
    • 3、SDL_SetRenderDrawColor 函数 - 设置渲染器颜色
    • 4、SDL_RenderClear 函数 - 清除渲染器
    • 5、SDL_RenderDrawRect 函数 - 渲染器绘制矩形
    • 6、SDL_RenderCopy 函数 - 纹理拷贝
    • 7、SDL_RenderPresent 函数 - 窗口中显示渲染纹理
  • 二、代码示例 - 移动元素绘制
    • 1、完整代码示例
    • 2、执行结果

博客源码下载 : https://download.csdn.net/download/han1202012/89421317

SDL 代码执行效果如下 :

在这里插入图片描述在这里插入图片描述

一、SDL 视频显示函数


1、SDL 的 渲染器 和 纹理 之间的关系

渲染器 SDL_Renderer 负责将 图像数据 绘制到 渲染目标 上 , 渲染目标通常是

  • 窗口 SDL_Window : 就是 SDL 中创建的 Windows 窗口 或 对话框 ;
  • 纹理 SDL_Texture : 下面详细解释 ;

纹理 SDL_Texture 是 SDL 中用于 存储图像数据 的 结构体类型 , 该结构体对象存储的是 图像的描述信息 , 不是具体的像素数据 ;

  • 如 : 纹理的背景颜色是白色 , 纹理图像的绝对地址是 “D:/image.png” , 纹理中在 (100, 100) 位置绘制了一个 100 x100 大小的矩形 , 这是描述信息 ,
    • 不会存储具体的像素 如 : 第一行第一列是白色像素点 , 第一行第二列是白色像素点 ;

渲染器 SDL_Renderer 工作流程 : 一般情况下 , 渲染器会 先将 绘制内容 渲染到 纹理 SDL_Texture 中 , 在 纹理背景颜色 或 背景图片 的基础上 , 绘制 文字 / 形状 / 图片 等内容 , 然后再将 渲染好的 纹理 SDL_Texture 绘制到窗口中 ;

可以这么理解 , 先在内存中的一张虚拟画布上作画 , 然后将画好的内容一次性绘制到窗口中 ;

2、SDL_SetRenderTarget 函数 - 设置渲染器目标纹理

SDL_SetRenderTarget 函数 的 作用是 设置 SDL_Renderer 渲染器 的 渲染目标纹理 , 渲染就是绘图 , 向目标纹理中渲染就是在 SDL_Texture 纹理中绘图 ;

SDL_SetRenderTarget 函数原型如下 :

代码语言:javascript复制
int SDL_SetRenderTarget(SDL_Renderer* renderer, SDL_Texture* texture);
  • renderer 参数 : 指向 SDL_Renderer 渲染器对象的指针 , 这个渲染器就是要在 SDL_Texture 纹理中绘图的主体 ;
  • texture 参数 : 指向 SDL_Texture 纹理对象的指针 , 在该纹理中进行绘图 ; 如果要在渲染器关联的窗口中绘图 , 传递 NULL 即可 ;
  • 返回值 : 如果 为 SDL_Renderer 渲染器 设置 要渲染的 目标纹理 SDL_Texture 成功 , 返回 0 ; 如果设置过程中发生错误 , 则返回 -1 ; 使用 SDL_GetError 函数可获取报错信息 ;

代码示例 : 先创建 SDL_Window 窗口对象 , 然后根据 窗口对象 创建 SDL_Renderer 渲染器对象 , 最后 根据渲染对象 创建 SDL_Texture 纹理对象 ;

创建了渲染器对象 和 纹理对象后 , 再为 渲染器 设置要渲染的 目标纹理 , 在最后 调用 SDL_SetRenderTarget 为 渲染器设置 目标纹理 ;

代码语言:javascript复制
    // 创建 SDL Window 窗口对象
    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);

3、SDL_SetRenderDrawColor 函数 - 设置渲染器颜色

SDL_SetRenderDrawColor 函数 用于设置 使用渲染器 进行绘图时 , 要绘制的 颜色 , 设置了该颜色后 , 之后渲染器绘制 线条 / 矩形 / 多边形 / 文字 时 , 使用该颜色作为默认绘图的颜色 ;

SDL_SetRenderDrawColor 函数原型 :

代码语言:javascript复制
int SDL_SetRenderDrawColor(SDL_Renderer* renderer, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
  • renderer 参数 : 指向 SDL_Renderer 渲染器对象 的指针 , 这是要使用指定颜色值进行绘图的渲染器 ;
  • r 参数 : 三原色中的红色 Red 分量的值 , 取值范围 0 ~ 255 ;
  • g 参数 : 三原色中的绿色 Green 分量的值 , 取值范围 0 ~ 255 ;
  • b 参数 : 三原色中的蓝色 Blue 分量的值 , 取值范围 0 ~ 255 ;
  • a 参数 : 透明度分量的值取值范围 0 ~ 255 , 0 表示完全透明 , 255 完全不透明 ;
  • 返回值 : 如果 为 SDL_Renderer 渲染器 设置 RGBA 颜色 成功 , 返回 0 ; 如果设置过程中发生错误 , 则返回 -1 ; 使用 SDL_GetError 函数可获取报错信息 ;

代码示例 : 该函数是为 SDL_Renderer 渲染器设置颜色值 , 只要 渲染器对象 创建之后 , 就可以设置 , 也可以多次设置修改颜色值 ;

代码语言:javascript复制
    // 创建 SDL_Renderer 渲染器对象
    SDL_Renderer *renderer = SDL_CreateRenderer(
                window, -1, 0);
                
    // 设置红色背景, 后面四个参数分别是 RGBA
    SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);

4、SDL_RenderClear 函数 - 清除渲染器

SDL_RenderClear 函数 的 作用是 清除 与 渲染器 的 目标纹理 内容 , 使用指定颜色值渲染 目标纹理 ;

在之前调用 SDL_SetRenderDrawColor 函数为渲染器设置了一个颜色值 , 调用 SDL_RenderClear 函数 清除渲染器时 , 就会使用该颜色值 铺满 SDL_Texture 纹理画面 ;

SDL_RenderClear 函数原型 :

代码语言:javascript复制
int SDL_RenderClear(SDL_Renderer* renderer);
  • renderer 参数 : 指向 SDL_Renderer 渲染器对象 的指针 , 这是要清除该渲染器对象 渲染绘制 的 SDL_Texture 纹理画面 ;
  • 返回值 : 如果 为 SDL_Renderer 渲染器 清除纹理画面内容 成功 , 返回 0 ; 如果设置过程中发生错误 , 则返回 -1 , 使用 SDL_GetError 函数可获取报错信息 ;

代码示例 : 下面的代码中提前为渲染器设置了 不透明红色 颜色值 , 在清除渲染器时就会使用红色铺满 该渲染器 渲染的 目标纹理对象 ;

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

5、SDL_RenderDrawRect 函数 - 渲染器绘制矩形

SDL_RenderDrawRect 函数 用于在 目标纹理对象 上绘制一个矩形边框 , 注意 : 只绘制边缘 , 不填充颜色 ;

SDL_RenderDrawRect 函数原型 :

代码语言:javascript复制
int SDL_RenderDrawRect(SDL_Renderer* renderer, const SDL_Rect* rect);
  • renderer 参数 : 指向 SDL_Renderer 渲染器对象 的指针 , 该渲染器对象 被设置了 渲染绘制 的 SDL_Texture 纹理画面 , 矩形就在该纹理上进行绘制 ;
  • rect 参数 : 指向 SDL_Rect 结构的指针 , 该结构体中封装了 矩形的 左上角坐标位置 和 宽高 , 单位都是像素 ;
  • 返回值 : 如果 为 SDL_Renderer 渲染器 绘制矩形 成功 , 返回 0 ; 如果设置过程中发生错误 , 则返回 -1 , 使用 SDL_GetError 函数可获取报错信息 ;

SDL_Rect 是矩形结构 , 该结构体内容如下 : int x, y 是 矩形左上角的 x 和 y 坐标 , int w, h 是 矩形的宽度和高度 , 单位都是像素 ;

代码语言:javascript复制
typedef struct SDL_Rect {  
    int x, y;          // 矩形左上角的 x 和 y 坐标  
    int w, h;          // 矩形的宽度和高度  
} SDL_Rect;

代码示例 : 下面的代码中 , 为 renderer 渲染器 设置目标纹理为 texture 纹理 , 绘制的内容在 texture 纹理上 , 在该纹理上绘制一个红色矩形 , 矩形的左上角坐标位置是 (100, 100) , 矩形的宽高大小为 100x100 像素大小 , 最后调用 SDL_RenderDrawRect 函数 , 将 红色矩形 绘制到 渲染器渲染 的 目标纹理 中 ;

代码语言:javascript复制
	// 为 渲染器 设置 纹理
	SDL_SetRenderTarget(renderer, texture);
	// 设置渲染器颜色值为红色, 后面四个参数分别是 RGBA
	SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
        
    // 在 (100, 100) 位置绘制 100x100 像素大小的矩形
    SDL_Rect rect;
    rect.x = 100;
    rect.y = 100;
    rect.w = 100;
    rect.h = 100;

    // 渲染器绘制矩形
    SDL_RenderDrawRect(renderer, &rect);

6、SDL_RenderCopy 函数 - 纹理拷贝

SDL_RenderCopy 函数 的 作用是 将 SDL_Texture 纹理画面 ( 被复制 ) 复制到 SDL_Renderer 渲染器 的 SDL_Texture 目标纹理 ( 被赋值 ) 中 ;

SDL_RenderCopy 函数原型 :

代码语言:javascript复制
int SDL_RenderCopy(
	SDL_Renderer* renderer, 
	SDL_Texture* texture, 
	const SDL_Rect* srcrect, 
	const SDL_Rect* dstrect);
  • renderer 参数 : 指向 SDL_Renderer 渲染器对象 的指针 , 这是目标渲染器 , 渲染器是用于绘制到窗口或表面的上下文 ;
  • texture 参数 : 指向 SDL_Texture 纹理对象的指针 , 这是要复制的纹理 , 纹理中是对图像的描述数据 , 不是像素数据 ;
  • srcrect 参数 : 指向 SDL_Rect 矩形对象的指针 , 源矩形 , 被复制的 SDL_Texture* texture 参数中的纹理画面上 , 要复制哪些区域 , 使用该矩形指定 ; 如果该参数为 NULL , 则复制整个 SDL_Texture 纹理对象 ;
  • dstrect 参数 : 指向 SDL_Rect 矩形对象的指针 , 目标矩形 , 要绘制到的 SDL_Renderer* renderer 参数 绑定的 渲染目标纹理 上的位置和大小 ;

代码示例 : 下面的代码中 , 现在 texture 纹理中 , 绘制了一个矩形 , 然后将 渲染器 的 渲染目标纹理 设置为窗口 , 最后将 绘制了矩形的 纹理对象 拷贝到 渲染窗口纹理的 渲染器中 ;

代码语言:javascript复制
	// 为 渲染器 设置 纹理
	SDL_SetRenderTarget(renderer, texture);
	// 设置渲染器颜色值为红色, 后面四个参数分别是 RGBA
	SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
        
    // 在 (100, 100) 位置绘制 100x100 像素大小的矩形
    SDL_Rect rect;
    rect.x = 100;
    rect.y = 100;
    rect.w = 100;
    rect.h = 100;

    // 渲染器绘制矩形
    SDL_RenderDrawRect(renderer, &rect);

	// 设置渲染目标为窗口
	SDL_SetRenderTarget(renderer, NULL);
	// 拷贝纹理到 目标纹理 为 窗口 的 渲染器 中
	// 这个渲染器 就是 原来绘制 被拷贝纹理的渲染器
	SDL_RenderCopy(renderer, texture, NULL, NULL);

7、SDL_RenderPresent 函数 - 窗口中显示渲染纹理

SDL_RenderPresent 函数 的 作用是 将渲染器上 渲染绘制 的图像 显示到 窗口 中 ;

调用该函数前 , 务必确认 , 渲染器的目标纹理就是窗口 , 已经调用了 SDL_SetRenderTarget(renderer, NULL); 方法 , 第二个参数设置 NULL , 就是将目标纹理设置为窗口 ;

SDL_RenderPresent 函数原型 :

代码语言:javascript复制
void SDL_RenderPresent(SDL_Renderer* renderer);
  • renderer 参数 : 指向 SDL_Renderer 渲染器对象 的指针 , 这是与窗口绑定的 SDL_Renderer 渲染器 , 并将目标 渲染纹理 设置为了 NULL , 也就是在窗口中渲染 ;
  • 该函数没有返回值 ;

代码示例 : 前两行代码就是上一个章节复制纹理的代码 , 将另外一个纹理复制到渲染器的目标纹理中 , 渲染器的目标纹理 就是窗口 , 再调用 SDL_RenderPresent 函数 , 将窗口中渲染的图像绘制出来 ;

代码语言:javascript复制
	// 设置渲染目标为窗口
	SDL_SetRenderTarget(renderer, NULL);
	// 拷贝纹理到 目标纹理 为 窗口 的 渲染器 中
	// 这个渲染器 就是 原来绘制 被拷贝纹理的渲染器
	SDL_RenderCopy(renderer, texture, NULL, NULL);
	// 输出渲染器渲染内容
    SDL_RenderPresent(renderer);

二、代码示例 - 移动元素绘制


1、完整代码示例

博客源码下载 : https://download.csdn.net/download/han1202012/89421317 , 完整代码可以在这里下载 ;

完整代码示例 :

代码语言: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);


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

    int count = 0;

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

        // 渲染矩形数据计算
        rect.x  = count;
        if(rect.x >= 700) {
            rect.x = 0;
        }
        /*rect.y  = count;
        if(rect.y >= 500) {
            rect.y = 0;
        }*/


        // 渲染器绘制矩形
        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);

        // 延迟 0.05 秒
        SDL_Delay(50);

        // 循环次数自增 1
        count  ;
    }

    // 销毁纹理
    SDL_DestroyTexture(texture);
    // 销毁渲染器
    SDL_DestroyRenderer(renderer);
    // 销毁窗口
    SDL_DestroyWindow(window);

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

    return 0;
}

2、执行结果

执行结果 : 执行后 , 在 窗口 中绘制了 SDL_Rect 矩形 , 该矩形移动时 , 出现了

在这里插入图片描述在这里插入图片描述

0 人点赞