当前位置: 首页 > 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

相关文章:

  • Vue.js 核心特性解析:响应式原理与组合式API实践
  • IDEA 连接 Oracle 数据库
  • 《代码整洁之道》第7章 错误处理 - 笔记
  • SQLMesh 测试自动化:提升数据工程效率
  • 决策树随机深林
  • 国标GB28181视频平台EasyCVR助力打造太阳能供电远程视频监控系统
  • 高并发架构设计之缓存
  • 数模学习:二,MATLAB的基本语法使用
  • 安卓APP开发项目源码
  • Tauri打包时出现WixTools以及NSIS报错
  • 基于ArcGIS的洪水灾害普查、风险评估及淹没制图技术研究​
  • SpringBoot配置RestTemplate并理解单例模式详解
  • 硬盘损坏数据恢复后对python程序的影响
  • 【创新实训个人博客】multi-agent调研(2)
  • Ubuntu下MySQL的安装
  • LLM应用于自动驾驶方向相关论文整理(大模型在自动驾驶方向的相关研究)
  • IP地址如何切换到国内别的省份?一步步指导
  • 于键值(KV)的表
  • MyBatis DTD [Element type “if“ must be declared]
  • vue+neo4j+flask 音乐知识图谱推荐系统
  • 国家发改委答澎湃:将指导限购城市针对长期摇号家庭和无车家庭等重点群体定向增发购车指标
  • 人社部:就业政策储备充足,将会根据形势变化及时推出
  • 加拿大今日大选:房价、印度移民和特朗普,年轻人在焦虑什么?
  • 影子调查|23岁男子驾照拟注销背后的“被精神病”疑云
  • 今年3月全国查处违反中央八项规定精神问题16994起
  • 辽宁省信访局副局长于江调任辽宁省监狱管理局局长