開發環境:MacOS
參考連結:陳雲老師的 SDL2 教程
註:學習筆記
繪製文字#
文字的繪製,需要搞一個字庫,我的建議是用思源體,或者 B 站大佬oooooohmygosh團隊做的得意體,兩者都是開源免費的。
我們還需要下載SDL2_image
庫:
使用 brew 下載brew install sdl2_image
然後brew info sdl2_image
查看下位置。
最後配置一下 CMake
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
裡打開字體
/* 打開字體 */
font = TTF_OpenFont("字體文件地址", FONT_SIZE);
if (font==NULL) {
SDL_Log("Can not open font");
}
別忘了釋放
...
/* 釋放字體 */
TTF_CloseFont(font);
...
然後寫一個draw
函數渲染字體
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()
函數使我們可以簡單的知道程式開始時的時間
/* 幀率:獲取毫秒值 */
long begin = SDL_GetTicks();
然後在結束時時間減去開始時間
/* 幀率:當前值 */
long current = SDL_GetTicks();
/* 現在每一幀花費的時間 */
long cost = current - begin;
我們也可以鎖定幀數,讓幀數維持在一個較為穩定的值
// 設定幀數
#define FRAMERATE 60
...
/* 每幀應該的時間 */
long frame = 1000/FRAMERATE;
/* 計算該休眠的時間維持幀數 */
long delay = frame - cost;
/* 如果delay是負就不休眠維持幀數 */
if (delay > 0) {
SDL_Delay(delay);
}
/* 在系統資源足夠的情況下能夠保持一個足夠的幀頻,不夠咱也沒辦法 */
關於可視區域#
設置可視區域可以讓所有東西都被有條件的限制顯示
比如:我想要所有的東西都顯示在x=10
,y=50
,300*300 的矩陣裡,就可以這樣寫
// 目標框參數
struct SDL_Rect viewport = {10, 50, 300, 300};
// renderer是渲染器
SDL_RenderSetViewport(renderer, &viewport);
你會發現所有用 renderer 渲染器渲染的東西都跑到了目標框裡。