SDL2学习笔记 - 绘制文字,帧数检测和可视区域

开发环境 ：MacOS
参考链接 ：陈云老师的 SDL2 教程
注 ：学习笔记

绘制文字

文字的绘制，需要搞一个字库，我的建议是用思源体，或者 B 站大佬oooooohmygosh团队做的得意体，两者都是开源免费的。
我们还需要下载SDL2_image库：
使用 brew 下载 brew install sdl2_image
然后brew info sdl2_image查看下位置。
最后配置一下 CMake

Copy
cmake_minimum_required(VERSION 3.23.2)
project(DrewText C)

set(CMAKE_C_STANDARD 11)

# SDL2
set(SDL_DIR /usr/local/Cellar/sdl2/2.26.0)
include_directories(${SDL_DIR}/include/SDL2)
link_directories(${SDL_DIR}/lib/)
# SDL2_image
set(SDL2_image /usr/local/Cellar/sdl2_image/2.6.2)
include_directories(${SDL2_image}/include/)
link_directories(${SDL2_image}/lib/)
# SDL2_ttf
set(SDL2_ttf /usr/local/Cellar/sdl2_ttf/2.20.1)
include_directories(${SDL2_ttf}/include/)
link_directories(${SDL2_ttf}/lib/)

link_libraries(SDL2)
link_libraries(SDL2_image)
link_libraries(SDL2_ttf)

# 把可执行文件移出来,防止找不到资源(ttf/image)
set(EXECUTABLE_OUTPUT_PATH ../)
add_executable(DrewText main.c)

先在main里打开字体

Copy
/* 打开字体 */
font = TTF_OpenFont("字体文件地址", FONT_SIZE);
if (font==NULL) {
SDL_Log("Can not open font");
}

别忘了释放

Copy
...
/* 释放字体 */
TTF_CloseFont(font);
...

然后写一个draw函数渲染字体

Copy
void draw(SDL_Surface * screen, SDL_Window * win) {
// 文字渲染
/* 字体颜色 */
SDL_Color color = {225, 0, 0, 255}; // RGBA
/* 渲染文字 */
SDL_Surface * text = TTF_RenderUTF8_Blended(font, "东雪莲我真的好喜欢你啊", color); //字体 内容 字体(前景)颜色
/* 显示到主屏幕 */
// 矩形框
SDL_Rect text_src = {0, 0, text->w, text->h};
// 渲染到
SDL_BlitSurface(text, &text_src, screen, &text_src);

// 更新主屏幕
SDL_UpdateWindowSurface(win);
}

然后运行就好啦

关于帧数检测

首先，什么是帧数？
帧率（英语：frame rate）是用于测量显示帧数的度量。测量单位为 “每秒显示帧数”（frame per second，FPS）或 “赫兹”，一般来说 FPS 用于描述视频、电子绘图或游戏每秒播放多少帧。 -- 维基百科

所以实现起来也很简单，我们只需要知道本次渲染开始时的时间，减去结束时的时间，就可以得到现在的帧数。

所以我们需要在程序主循环开始是设定一个值，SDL2 为我们提供了SDL_GetTicks()函数使我们可以简单的知道程序开始时的时间

Copy
/* 帧率：获取毫秒值 */
long begin = SDL_GetTicks();

然后在结束时时间减去开始时间

Copy
/* 帧率：当前值 */
long current = SDL_GetTicks();
/* 现在每一帧花费的时间 */
long cost = current - begin;

我们也可以锁定帧数，让帧数维持在一个较为稳定的值

Copy
// 设定帧数
#define FRAMERATE 60
...
/* 每帧应该的时间 */
long frame = 1000/FRAMERATE;

/* 计算该休眠的时间维持帧数 */
long delay = frame - cost;
/* 如果delay是负就不休眠维持帧数 */
if (delay > 0) {
SDL_Delay(delay);
}
/* 在系统资源足够的情况下能够保持一个足够的帧频，不够咱也没办法 */

关于可视区域

设置可视区域可以让所有东西都被有条件的限制显示
比如：我想要所有的东西都显示在x=10, y=50，300*300 的矩阵里，就可以这样写

Copy
// 目标框参数
struct SDL_Rect viewport = {10, 50, 300, 300};
// renderer是渲染器
SDL_RenderSetViewport(renderer, &viewport);

你会发现所有用 renderer 渲染器渲染的东西都跑到了目标框里。