最近学习 ffmpeg 例程,发现里面常用 SDL 库,进行开发。故最近找了个教程学习了一下,下面对学习的做个小结。
1. 第一大坑: main 函数必须写成下面的形式,不然会报错。
int main(int argc, char* argv[])
应该是 SDL.h 对其进行了一些操作。看源码看到下面这两句,应该就是声明了 int main(int argc, char* argv[]),所以必须实现这个函数,不然就会报错。
#define main SDL_main
extern SDLMAIN_DECLSPEC int SDL_main(int argc, char *argv[]);
2. 对 SDL 进行初始化,最好只初始你需要的功能,这样之后的代码能够自检,你后面的代码是不是有问题,或者把有问题的代码规避掉。
SDL_Init(SDL_INIT_VIDEO);
3.创建一个窗口,使用 SDL 主要是进行图像化展示,所以需要创建一个窗口进行展示。
SDL_CreateWindow("Hello world", 100, 100, 640 ,480, SDL_WINDOW_SHOWN);
第一个参数是窗口的名字,之后的四个参数分别是 窗口的左上角坐标和窗口的大小,最后一个参数是显示的模式(正常显示、最大化、最小化和全屏展示等)。
4.显示图片,有两种方式,一种是 CPU渲染、一种是GPU渲染
CPU 渲染
获得窗口的 surface 、获得图片的 surface 、将图片 surface 数据拷贝到窗口 surface 、更新窗口的 surface。
gScreenSurface = SDL_GetWindowSurface(gWindow);
gHelloWorld = SDL_LoadBMP(path.c_str());
SDL_BlitSurface(gHelloWorld, NULL, gScreenSurface, NULL);
SDL_UpdateWindowSurface(gWindow);
GPU渲染
获得窗口画布、获得图片的 surface、通过 surface 创建纹理、将纹理拷贝到备用缓冲区、交换前和后缓冲区显示图片
SDL_Renderer* ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
SDL_Surface* bmp = SDL_LoadBMP("../Resource/hello.bmp");
SDL_Texture* tex = SDL_CreateTextureFromSurface(ren, bmp);
SDL_RenderCopy(ren, tex, NULL, NULL);
SDL_RenderPresent(ren);
5. 人机交互,信息的获取
SDL 可以获取鼠标、键盘、窗口本身和其他一些交互设备的输入。
使用下面函数,获取消息队列中的信息。
SDL_PollEvent(&e);
e.type == SDL_QUIT // 退出事件
e.type == SDL_KEYDOWN // 键盘事件
e->type == SDL_MOUSEMOTION || e->type == SDL_MOUSEBUTTONDOWN || e->type == SDL_MOUSEBUTTONUP//鼠标事件
通过 cpp e.key.keysym.sym
获取按下的按钮。例如 cpp SDLK_UP、 SDLK_DOWN
通过cpp SDL_GetMouseState(&x, &y);
获得鼠标的位置
6.缩放拷贝 surface
SDL_BlitScaled
7.加载除 bmp 的其他类型的图片,可以使用外部库如 SDL_image
此处也有一个坑,最新的 2.0.5 的 SDL_image 与 SDL 不兼容会报错,下载使用 2.0.4 的就好了。从下面的网站找就好了。
SDL_image 下载地址
首先初始化图片的格式,如PNG。之后使用这个库加载图片,考虑兼容问题,还将加载的 surface的格式转换为与 屏幕 surface 相同的格式。
int imgFlags = IMG_INIT_PNG;
if (!(IMG_Init(imgFlags) & imgFlags))
SDL_Surface* loadedSurface = IMG_Load(path.c_str());
optimizedSurface = SDL_ConvertSurface(loadedSurface, gScreenSurface->format, 0);
8.绘制集合图形
SDL_SetRenderDrawColor(gRenderer, 0xFF, 0xFF, 0xFF, 0xFF); // 设置颜色
SDL_RenderClear(gRenderer);// 清除屏幕
SDL_RenderFillRect(gRenderer, &fillRect);//实心矩形
SDL_RenderDrawRect(gRenderer, &outlineRect);//空心矩形
SDL_RenderDrawLine(gRenderer, 0, SCREEN_HEIGHT / 2, SCREEN_WIDTH, SCREEN_HEIGHT / 2); // 线
SDL_RenderDrawPoint(gRenderer, SCREEN_WIDTH / 2, i); // 点
9.设置视角
SDL_RenderSetViewport(gRenderer, &topLeftViewport);
10.设置裁剪
SDL_RenderCopy(gRenderer, mTexture, clip, &renderQuad);
11.设置图片叠加方式
alpha 为0,为前面的图片完全透明,可以看见后面的图片。
SDL_SetTextureBlendMode(mTexture, SDL_BLENDMODE_BLEND);
SDL_SetTextureAlphaMod(mTexture, alpha);
12.旋转和镜像
SDL_RenderCopyEx(gRenderer, mTexture, clip, &renderQuad, angle, center, flip);
13.获得时间
得到的是程序开始运行到现在的时间
SDL_GetTicks();