前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【FFmpeg】SDL 音视频开发 ② ( SDL 视频显示函数 | 设置渲染器目标纹理 | 设置渲染器颜色 | 清除渲染器 | 渲染器绘制矩形 | 纹理拷贝 | 窗口中显示渲染纹理 )

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

作者头像
韩曙亮
发布2024-06-13 13:47:25
700
发布2024-06-13 13:47:25
举报
文章目录

  • 一、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 矩形 , 该矩形移动时 , 出现了

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 一、SDL 视频显示函数
    • 1、SDL 的 渲染器 和 纹理 之间的关系
      • 2、SDL_SetRenderTarget 函数 - 设置渲染器目标纹理
        • 3、SDL_SetRenderDrawColor 函数 - 设置渲染器颜色
          • 4、SDL_RenderClear 函数 - 清除渲染器
            • 5、SDL_RenderDrawRect 函数 - 渲染器绘制矩形
              • 6、SDL_RenderCopy 函数 - 纹理拷贝
                • 7、SDL_RenderPresent 函数 - 窗口中显示渲染纹理
                • 二、代码示例 - 移动元素绘制
                  • 1、完整代码示例
                    • 2、执行结果
                    相关产品与服务
                    对象存储
                    对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档