前言
一直想着要接触一下SDL, 毕竟网上很多FFmpeg的demo都是使用SDL进行显示的,如果弄好了SDL,肯定后面跑音视频的demo,就更为简单了。所以,今天早上一大早,开始搞一下这个东西。搞好搞去,查来查去,发现,还是依然没有一个比较完整的教程,感觉就是自己跑通了就好了,也不会去讲一些细节问题。这就很恼火了,明明很简单的一个东西,搞的这么麻烦。废话不多说,开始。
正文
一、环境
我这边的环境是:
win11
VS2019
这个环境可以注意一下,估计用VS2022啥的应该也没啥问题,但用低版本的话,我就不太清楚了。
二、SDL简介
SDL是 “Simple DirectMedia Layer”的缩写,SDL是一个开源的跨平台的多媒体库,封装了复杂的音视频底层操作,简化了音视频处理的难度。
SDL使用C语言写成,提供了数种控制图像、声音、输出入的函数,可以开发出跨多个平台(Linux、Windows、Mac OS X等)的应用软件。目前多用于开发游戏、模拟器、媒体播放器等多媒体应用领域。
1. SDL 库分类
SDL库分为 Video、Audio、CD-ROM、Joystick 和 Timer 等若干子系统,除此之外,还有一些单独的官方扩充函数库。
这些库由官方网站提供,并包含在官方文档中,共同组成了SDL的“标准库”:
- SDL_image : 支持时下流行的图像格式,如BMP、PPM、XPM、 PCX、GIF、JPEG、PNG、TGA。
- SDL_mixer:更多的声音输出函数以及更多的声音格式支持。
- SDL_net:网络支持。
- SDL_ttf:TrueType字体渲染支持。
- SDL_rtf:简单的RTF渲染支持。
2. SDL 子系统分类
SDL 按照功能可以分成下列数个子系统(subsystem):
- Video(图像): 图像控制以及线程(thread)和事件管理(event)。
- Audio(声音): 声音控制
- Joystick(摇杆): 游戏摇杆控制
- CD-ROM(光盘驱动器): 光盘媒体控制
- Window Management(视窗管理): 与视窗程序设计集成
- Event(事件驱动):处理事件驱动
这部分就是抄一下其他兄弟的了,参考这篇[SDL 开发实战(一):SDL介绍及开发环境配置 ](https://www.cnblogs.com/renhui/p/10449936.html)
三、SDL下载
SDL官网:http://www.libsdl.org/index.php
https://github.com/libsdl-org/SDL/releases/tag/release-2.30.3
可下载这个:
四、VS2019 + SDL
1、打开VS2019
2、新建一个C++空项目
3、建完之后,这个样子
4、记得在源文件那增加一个cpp文件
5、重点来了,引入头文件和库
6、引入头文件:
7、点击项目->右键->属性
8、将头文件添加到这个里面:双击进去添加
9、引如库文件:将库文件目录放入
10、引如依赖项:先找到属性–>链接器–> 输入—> 附加依赖项,添加附加依赖项:SDL2.lib;SDL2main.lib;
环境到这里就配置结束了。
五、引如测试代码
//#include "pch.h"
#include <iostream>
extern "C" {
#include "SDL.h"
}
int main(int argc, char* argv[])
{
if (SDL_Init(SDL_INIT_VIDEO)) {
std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl;
return 1;
}
SDL_Window* win = SDL_CreateWindow("Hello World!", 100, 100, 640, 480, SDL_WINDOW_SHOWN);
if (win == nullptr) {
std::cout << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
return 1;
}
SDL_Renderer* ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (ren == nullptr) {
SDL_DestroyWindow(win);
std::cout << "SDL_CreateRender Error: " << SDL_GetError() << std::endl;
SDL_Quit();
return 1;
}
std::string imagePath = "3.bmp";
SDL_Surface* bmp = SDL_LoadBMP(imagePath.c_str());
if (bmp == nullptr) {
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
std::cout << "SDL_LoadBMP Error: " << SDL_GetError() << std::endl;
SDL_Quit();
return 1;
}
SDL_Texture* tex = SDL_CreateTextureFromSurface(ren, bmp);
SDL_FreeSurface(bmp);
if (tex == nullptr) {
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
std::cout << "SDL_CreateTextureFromSurface Error: " << SDL_GetError() << std::endl;
SDL_Quit();
return 1;
}
for (int i = 0; i < 3; ++i) {
SDL_RenderClear(ren);
SDL_RenderCopy(ren, tex, NULL, NULL);
SDL_RenderPresent(ren);
SDL_Delay(1000);
}
SDL_DestroyTexture(tex);
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
SDL_Quit();
// Return
return 0;
}
这个是一个显示bmp图片的程序。
注意,bmp图片要放在这个目录:
也就是要放在test.cpp同级目录,而不是在可执行文件的那个目录,如果放在那个目录,会显示无法找到对应的bmp图片。注意格式一定要原本是bmp格式,否则应该是会报错的。
刚才试了一下,用qt也是可以的。
注意,qt的话,要用MSVC2019 或是其他的,MinGw好像是用不了的
如果遇到什么问题,可以直接留言讨论
想看视频的可以看看这个:C/C++编程技术】零基础上手SDL图形库!思路分析 + 代码演示
相关的文件以及环境在这里:SDL显示yuv视频以及库文件都在里面