当前位置: 首页 > news >正文

【音视频】SDL窗口显示

SDL视频显示函数简介

  • SDL_Init(): 初始化SDL系统
  • SDL_CreateWindow():创建窗口SDL_Window
  • SDL_CreateRenderer():创建渲染器SDL_Renderer
  • SDL_CreateTexture():创建纹理SDL_Texture
  • SDL_UpdateTexture(): 设置纹理的数据
  • SDL_RenderCopy():将纹理的数据拷贝给渲染器
  • SDL_RenderPresent():显示
  • SDL_Delay(): 工具函数,用于延时
  • SDL_Quit(): 退出SDL系统

SDL数据结构简介

  • SDL_Window 代表了一个“窗口”
  • SDL_Renderer 代表了一个“渲染器”
  • SDL_Texture 代表了一个“纹理”
  • SDL_Rect 一个简单的矩形结构
存储RGB和存储纹理的区别:

比如一个从左到右由红色渐变到蓝色的矩形,用存储RGB的话就需要把矩形中每个点的具体颜色值存储下来;而纹理只是一些描述信息,比如记
录了矩形的大小、起始颜色、终止颜色等信息,显卡可以通过这些信息推算出矩形块的详细信息。

所以相对于存储RGB而已,存储纹理占用的内存要少的多。

SDL子系统(subsystem):

SDL将功能分成下列数个子系统(subsystem):

  • SDL_INIT_TIMER:定时器
  • SDL_INIT_AUDIO:音频
  • SDL_INIT_VIDEO:视频
  • SDL_INIT_JOYSTICK:摇杆
  • SDL_INIT_HAPTIC:触摸屏
  • SDL_INIT_GAMECONTROLLER:游戏控制器
  • SDL_INIT_EVENTS:事件
  • SDL_INIT_EVERYTHING:包含上述所有选项
  • SDL_INIT_TIMER:定时器
  • SDL_INIT_AUDIO:音频
  • SDL_INIT_VIDEO:视频
  • SDL_INIT_JOYSTICK:摇杆
  • SDL_INIT_HAPTIC:触摸屏
  • SDL_INIT_GAMECONTROLLER:游戏控制器
  • SDL_INIT_EVENTS:事件
  • SDL_INIT_EVERYTHING:包含上述所有选项

实现效果

在这里插入图片描述

实现流程

引入头文件

这个头文件是SDL的核心

#include <SDL.h>

需要取消main的宏,因为在SDL.h中定义了:

#define main  SDL_main

因此,需要取消这个宏,因为我们下面用到的main是作为主函数使用

开启SDL视频模块功能

核心模块有很多,这里就用到视频这一块,因此开启这个即可

SDL_Init(SDL_INIT_VIDEO);//初始化函数,可以确定希望激活的子系统

创建一个窗口

这里可以指定窗口的标题、窗口的出现位置,SDL_WINDOWPOS_UNDEFINED表示默认在窗口中心,设置的窗口大小为640x480

同时:

  • SDL_WINDOW_OPENGL:启用 OpenGL 支持,便于复杂图形渲染
  • SDL_WINDOW_RESIZABLE:允许用户调整窗口大小
SDL_Window *window = NULL;
window = SDL_CreateWindow("SDL-Window",SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,640,480,SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);// 创建窗口

创建失败返回0

if (!window){return -1;
}

创建一个渲染器

创建一个渲染器,用于渲染纹理。这里将这个渲染器与窗口进行绑定。

  • -1表示选择默认渲染驱动,如 Direct3D、OpenGL
  • 0表示使用软件渲染,也可以改为SDL_RENDERER_ACCELERATED使用硬件渲染
SDL_Renderer *renderer = NULL;
renderer = SDL_CreateRenderer(window, -1, 0);//基于窗口创建渲染器

创建失败返回0

if (!render){return -1;
}

创建一个纹理

创建一个纹理,用于渲染器的输入,并将这个纹理绑定在之前创建的渲染器上。

  • SDL_PIXELFORMAT_RGBA8888:32 位像素格式,包含透明通道(A)
  • SDL_TEXTUREACCESS_TARGET:指定纹理为渲染目标,支持离屏绘制
SDL_Texture *texture = NULL;
texture = SDL_CreateTexture(renderer,SDL_PIXELFORMAT_RGBA8888,SDL_TEXTUREACCESS_TARGET,640,480); //创建纹理

创建失败返回0

if (!renderer)
{return -1;
}

创建一个矩形

创建一个矩形,设置矩形的大小

SDL_Rect rect; // 长方形,原点在左上角
rect.w = 50;    //方块大小
rect.h = 50;

开始绘制

我们这里绘制300帧后结束

   int show_count = 0;while (run){rect.x = rand() % 600;rect.y = rand() % 400;SDL_SetRenderTarget(renderer, texture); // 设置渲染目标为纹理SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); // 纹理背景为宏色SDL_RenderClear(renderer); //清屏SDL_RenderDrawRect(renderer, &rect); //绘制一个长方形SDL_SetRenderDrawColor(renderer, 0, 255, 255, 255); //长方形为白色SDL_RenderFillRect(renderer, &rect);SDL_SetRenderTarget(renderer, NULL); //恢复默认,渲染目标为窗口SDL_RenderCopy(renderer, texture, NULL, NULL); //拷贝纹理到CPUSDL_RenderPresent(renderer); //输出到目标窗口上SDL_Delay(300);if(show_count++ > 30){run = 0;        // 不跑了}}
  • 设置矩形的出现位置在窗口的随机位置
rect.x = rand() % 600;
rect.y = rand() % 400;
  • 设置渲染目标为纹理,并且设置纹理的背景颜色为红色,每一帧都需要清屏
SDL_SetRenderTarget(renderer, texture); // 设置渲染目标为纹理
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); // 纹理背景为黑色
SDL_RenderClear(renderer); //清屏
  • 绘制矩形,设置矩形的颜色为白色
SDL_RenderDrawRect(renderer, &rect); //绘制一个长方形
SDL_SetRenderDrawColor(renderer, 0, 255, 255, 255); //长方形为白色
SDL_RenderFillRect(renderer, &rect);
  • 渲染器解绑纹理
SDL_SetRenderTarget(renderer, NULL); //恢复默认,渲染目标为窗口
  • 拷贝纹理到CPU,并且呈现在窗口上
SDL_RenderCopy(renderer, texture, NULL, NULL); //拷贝纹理到CPU
SDL_RenderPresent(renderer); //输出到目标窗口上
  • 延迟300ms,防止速度过快
SDL_Delay(300);

释放内存

程序结束的时候需要释放相关内存,比如窗口、渲染器、纹理等内存

SDL_DestroyTexture(texture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);

最后,执行退出释放所有的SDL子系统资源

SDL_Quit();

整体代码

main.c

#include <stdio.h>
#include <SDL.h>
#undef main
int main()
{int run = 1;SDL_Window *window = NULL;SDL_Renderer *renderer = NULL;SDL_Texture *texture = NULL;SDL_Rect rect; // 长方形,原点在左上角rect.w = 50;    //方块大小rect.h = 50;SDL_Init(SDL_INIT_VIDEO);//初始化函数,可以确定希望激活的子系统window = SDL_CreateWindow("SDL-Window",SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,640,480,SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);// 创建窗口if (!window){return -1;}renderer = SDL_CreateRenderer(window, -1, 0);//基于窗口创建渲染器if (!renderer){return -1;}texture = SDL_CreateTexture(renderer,SDL_PIXELFORMAT_RGBA8888,SDL_TEXTUREACCESS_TARGET,640,480); //创建纹理if (!texture){return -1;}int show_count = 0;while (run){rect.x = rand() % 600;rect.y = rand() % 400;SDL_SetRenderTarget(renderer, texture); // 设置渲染目标为纹理SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); // 纹理背景为红色SDL_RenderClear(renderer); //清屏SDL_RenderDrawRect(renderer, &rect); //绘制一个长方形SDL_SetRenderDrawColor(renderer, 0, 255, 255, 255); //长方形为白色SDL_RenderFillRect(renderer, &rect);SDL_SetRenderTarget(renderer, NULL); //恢复默认,渲染目标为窗口SDL_RenderCopy(renderer, texture, NULL, NULL); //拷贝纹理到CPUSDL_RenderPresent(renderer); //输出到目标窗口上SDL_Delay(300);if(show_count++ > 30){run = 0;        // 不跑了}}SDL_DestroyTexture(texture);SDL_DestroyRenderer(renderer);SDL_DestroyWindow(window); //销毁窗口SDL_Quit();return 0;
}

更多资料:https://github.com/0voice

http://www.xdnf.cn/news/171235.html

相关文章:

  • DIFY教程第一集:安装Dify配置环境
  • 广度优先搜索(BFS)算法详解
  • 23种设计模式-行为型模式之命令模式(Java版本)
  • 鸿蒙系统应用开发全栈指南
  • HarmonyOS Next~鸿蒙系统流畅性技术解析:预加载与原生架构的协同进化
  • 神经编译革命:如何用脑机接口直接编程量子计算机?
  • 用Function Calling让GPT查询数据库(含示例)
  • 【Git】初始Git及入门命令行
  • 03.使用spring-ai玩转MCP
  • IdeaVim 配置与使用指南
  • 【Part 2安卓原生360°VR播放器开发实战】第二节|基于等距圆柱投影方式实现全景视频渲染
  • 位置差在坐标系间的相互转换
  • C++类和对象(上)
  • Spark SQL开发实战:从IDEA环境搭建到UDF/UDAF自定义函数实现
  • 《TVM模式匹配实战:从DFPatternNode到DFPattern的高级用法》
  • OceanBase数据库-学习笔记2-C#/C++程序如何访问
  • C++如何使用调试器(如GDB、LLDB)进行程序调试保姆级教程(2万字长文)
  • 使用 Autofac 实现依赖注入
  • 嵌入式软件--stm32 DAY 4 中断系统
  • Linux日志处理命令多管道实战应用
  • Python爬虫实战:获取网yi云音乐飙升榜的歌曲数据并作分析,为歌单推荐做参考
  • Spark SQL核心概念与编程实战:从DataFrame到DataSet的结构化数据处理
  • 《一键式江湖:Docker Compose中间件部署108式》开篇:告别“配置地狱”,从此笑傲云原生武林!》
  • python+adafruit_pca9685 测试舵机存储当前角度
  • 知识体系_数据量纲化处理方式
  • PWN基础-利用格式化字符串漏洞泄露canary结合栈溢出getshell
  • 神经网络笔记 - 神经网络
  • 东田数码科技前端面经
  • 运算符分为哪几类?哪些运算符常用作判断?简述运算符的优先级
  • 电池的寿命