目录
1、SDL介绍
2、实现效果
3、主要函数的作用
4、主要代码
5、完整代码
6、总结
1、SDL介绍
SDL用C编写,可与C ++一起使用,并且可用于其他几种语言,如C#和Python,
支持Windows,Mac OS X,Linux,iOS和Android,是一套开放源代码的跨平台开发库,功能强大,在音视频开发领域经常被使用到。
SDL多用于开发媒体播放器、游戏等多媒体应用领域,不仅支持绘制图片,还支持播放视频、音频,
它的底层实际是封装了opengl,使用gpu渲染,不会占用过多的cpu。
首先需要下载SDL,引入其头文件和库
SDL下载地址:http://www.libsdl.org/
因为我是用vs2015开发,所以下载的是上面这个。
首先在代码中需要引入SDL头文件和库。
#include "SDL.h"
#undef main
#pragma comment(lib,"SDL2.lib")
#pragma comment(lib,"SDL2main.lib")
#pragma comment(lib,"SDL2test.lib")
加上#undef main的目的是为了防止出现以下错误
2、实现效果
3、主要函数的作用
1、SDL_Init(SDL_INIT_EVERYTHING):
表示初始化SDL
2、SDL_CreateWindowFrom((void*)this->winId()):
表示嵌入Qt窗口
3、SDL_GetWindowSurface(_window):
获取与窗口相关联的像素信息
4、SDL_LoadBMP("test.bmp"):
是一个宏,作用是读取一个BMP图片
5、SDL_BlitSurface(_pload, NULL, _pScreens, NULL):
也是一个宏,目的是执行从源像素到目标像素的传输。
6、SDL_UpdateWindowSurface(_window):
将窗口复制到屏幕上
4、主要代码
//初始化void Init() { if (SDL_Init(SDL_INIT_EVERYTHING) < 0) { cout << "SDL_Init failed" << endl; return; } _window = SDL_CreateWindowFrom((void*)this->winId()); if (!_window) { cout << "DL_CreateWindowFrom failed" << endl; return; }}
这里主要是初始化SDL,然后创建SDL绘制窗口。
//绘制图片void timerEvent(QTimerEvent *event){ _pScreens = SDL_GetWindowSurface(_window); if (!_pScreens) { cout << "SDL_GetWindowSurface failed" << endl; } _pload = SDL_LoadBMP("test.bmp"); if (!_pload) { cout << "SDL_LoadBMP failed" << endl; return; } SDL_BlitSurface(_pload, NULL, _pScreens, NULL); if (SDL_UpdateWindowSurface(_window) < 0) { cout << "SDL_UpdateWindowSurface failed" << endl; }}
读取bmp图片,讲图片信息设置到窗口上。
5、完整代码
#pragma once #include #include "ui_testSDL.h"#include #include "SDL.h"#undef main #pragma comment(lib,"SDL2.lib") #pragma comment(lib,"SDL2main.lib")#pragma comment(lib,"SDL2test.lib") #include using namespace std; class testSDL : public QWidget{ Q_OBJECT public: testSDL(QWidget *parent = Q_NULLPTR):_window(nullptr), _pScreens(nullptr),_pload(nullptr) { ui.setupUi(this); Init(); startTimer(50); } ~testSDL() { SDL_FreeSurface(_pload); SDL_DestroyWindow(_window); SDL_Quit(); } void Init() { if (SDL_Init(SDL_INIT_EVERYTHING) < 0) { cout << "SDL_Init failed" << endl; return; } _window = SDL_CreateWindowFrom((void*)this->winId()); if (!_window) { cout << "DL_CreateWindowFrom failed" << endl; return; } } void timerEvent(QTimerEvent *event){ _pScreens = SDL_GetWindowSurface(_window); if (!_pScreens) { cout << "SDL_GetWindowSurface failed" << endl; } _pload = SDL_LoadBMP("test.bmp"); if (!_pload) { cout << "SDL_LoadBMP failed" << endl; return; } SDL_BlitSurface(_pload, NULL, _pScreens, NULL); if (SDL_UpdateWindowSurface(_window) < 0) { cout << "SDL_UpdateWindowSurface failed" << endl; } }private: Ui::testSDLClass ui; SDL_Window *_window; SDL_Surface *_pScreens; SDL_Surface *_pload;};
6、总结
原先是在QPaintEvent中绘制的,但是图片只显示一下就没了,并没有达到效果,原因可能是将sdl绘制嵌入qt后,qt窗口的焦点被sdl抢占的原因。所以这里改用定时器绘制。
其实qt内部提供了QPaint绘制图像,但是qimage显示图像,需要将数据转为rgb格式,这是一个很耗时的操作,而且是在cpu层面做的处理,在4K的电脑显示器,显示图像就很吃力了,如果是视频的连续图像帧,那么会很卡顿,所以选择sdl来做,用gpu渲染。当前qt也有QOpenglWidget,不过使用起来并没有sdl方便。