SDL 快速了解 - 接口使用
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的初步了解,仅介绍视频、音频、事件和定时器等部分内容。
环境搭建及测试
- Windows环境
下载SDL,先直接下载dll和lib使用(-VC的那个),下载地址:Releases libsdl-org/SDL (github.com)
然后进行环境测试:
注意事项:
- QT路径要纯英文,不能有中文
- 要在 SDL.h 之前定义
#define SDL_MAIN_HANDLED
,原因如下:
- QT会创建两个目录,一个是我们设定的项目名目录,其下的文件是用于调试情况下的,还有一个是以build开头的,其表示的是对应的运行目录,其下的文件是用于运行情况下的。所以我们还需要将 sdl2-vc 文件夹下的lib目录中的.dll动态库同时拷贝到这两个目录中,才能保证运行和编译时的正常运行。> > 4. 其中,.dll动态库有两个,一个是x86、一个是x64,如果x64不行就换x86的,其中C++一直编不过,64位编译器也不行!!!❌>先创建一个qt项目,将 sdl2-vc 文件夹移动到项目目录中,指定include目录路径、添加sdl2.lib路径,即在对应的.pro文件中添加如下部分:
win32 { INCLUDEPATH += $$PWD/SDLl-2.30.5-VC/include LIBS += SDLl-2.30.5-VC/lib/x64/SDL2.lib }
- Linux的参考如下部分
下载SDL源码库,SDL2-2.0.10.tar.gz
解压,然后依次执行命令
./configure make sudo make install.
如果出现"Could not initialize SDL - No available video device (Did you set the DISPLAY variable?)"错误,说明系统中没有安装x11的库文件,因此编译出来的SDL库实际上不能用。下载安装
sudo apt-get install libx11-dev sudo apt-get install xorg-dev
sdl-window显示
相关函数如下:
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 Window代表了一个"窗口"
SDL_Renderer代表了一个"渲染器”
SDL Texture代表了一个"纹理”
SDL Rect一个简单的矩形结构
存储RGB和存储纹理的区别:比如一个从左到右由红色渐变到蓝色的矩形,用存储RGB的话就需要把矩形中每个点的具体颜色值存储下来;而纹理只是一些描述信息,比如记录了矩形的大小、起始颜色、终止颜色等信息,显卡可以通过这些信息推算出矩形块的详细信息。所以相对于存储RGB而已,存储纹理占用的内存要少的多。
sdl-event事件
函数
• SDL_WaitEvent(): 等待一个事件
• SDL_PushEvent(): 发送一个事件
• SDL_PumpEvents(): 将硬件设备产生的事件放入事件队列,用于读取事件,在调用该函数之前,必须调用SDL_PumpEvents搜集键盘等事件
• SDL_PeepEvents(): 从事件队列提取一个事件
数据结构
• SDL_Event: 代表一个事件
sdl-多线程
SDL线程创建:SDL_CreateThread
SDL线程等待:SDL_WaitThead
SDL互斥锁:SDL_CreateMutex
/SDL_DestroyMutex
SDL锁定互斥:SDL_LockMutex
/SDL_UnlockMutex
SDL条件变量(信号量):SDL_CreateCond
/``SDL_DestoryCond SDL条件变量(信号量)等待/通知:
SDL_CondWait/
SDL_CondSingal`
sdl-视频播放流程
大致流程如图所示,其中要区分好窗口、渲染、纹理。纹理就是用于渲染的图像数据,暂且认为纹理就是我们所要加载图像的载体。而渲染是用来加载和显示纹理,窗口就是用来被渲染的。而加载视频其实就是将视频作为纹理被渲染器渲染。
特别的,视频可以看作是一组图片,每刷新一次就会换到下一张图片,如果一直不刷新也就会一直卡在第一张图片上。而渲染器在渲染时,就是渲染的这一张张图片,也就是说本质上纹理还是图片。所以我们可以通过SDL_Delay的方式来实现刷新率。
图片非原创,原图出处:音视频八股文(5)–SDL音视频渲染实战。
sdl-播放音频
大体流程为,
- 初始化SDL和音频系统:
- 使用
SDL_Init
初始化SDL库- 调用
SDL_OpenAudio
来打开音频设备,并设置音频格式、缓冲区大小和回调函数等。- 设置音频回调函数:
- 在
SDL_AudioSpec
结构体中提供一个callback函数,这个函数将在音频缓冲区需要数据时被SDL库调用。- 在回调函数中,通常会使用
SDL_MixAudio
或其他音频处理逻辑来生成或修改音频数据,然后将数据写入缓冲区中。- 启动音频播放:
- 调用
SDL_PauseAudio(0)
设置开始播放音频。这并不直接导致声音输出,而是让音频系统准备就绪,等待回调函数填充缓冲区。- 播放结束,退出
需要注意的是,SDL_PauseAudio(0)确实会准备音频系统以开始播放,但是真正产生声音的步骤是在回调函数中,通过SDL_MixAudio或其他方式将音频数据写入缓冲区,然后音频设备就会根据缓冲区里的内容自动播放。如果缓冲区为空或未被填充,即使SDL_PauseAudio(0)被调用,也不会有声音输出。而回调函数是在SDL创建了的新线程下循环运行的,不需要我们手动控制。