在上一篇文章中我們已經(jīng)利用 SDL 的日志接口實現(xiàn)了簡單的字符串輸出,實際上是解決了開發(fā)環(huán)境搭建問題,接下來我們將在已有代碼的基礎(chǔ)上繼續(xù)開發(fā),實現(xiàn)第一個窗口的創(chuàng)建和背景色繪制。 初始化 首先設(shè)置日志輸出級別: SDL_SetLogPriorities(SDL_LOG_PRIORITY_VERBOSE
在上一篇文章中,我們利用SDL的日志接口實現(xiàn)了簡單的字符串輸出,解決了開發(fā)環(huán)境搭建問題。接下來,我們將在已有代碼的基礎(chǔ)上繼續(xù)開發(fā),實現(xiàn)第一個窗口的創(chuàng)建和背景色繪制。
SDL_SetLogPriorities(SDL_LOG_PRIORITY_VERBOSE);
由于仍處于開發(fā)階段,我們將輸出日志級別設(shè)置為最低的VERBOSE。這樣可以使所有的日志都輸出,有助于觀察SDL的運行情況。當(dāng)出現(xiàn)錯誤時,可以獲得盡可能詳細(xì)的出錯信息,有助于快速定位問題。
接下來,初始化SDL庫,參數(shù)
SDL_INIT_VIDEO
指定初始化的子系統(tǒng)為視頻系統(tǒng):
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
SDL_Log("SDL_Init failed: %s", SDL_GetError());
return -1;
}
實際上,這一步可以省略,因為在調(diào)用SDL API時其內(nèi)部會自行檢查和初始化所需使用的子系統(tǒng)。比如接下來要使用的
SDL_CreateWindow
函數(shù),內(nèi)部有這樣的代碼:
if (!_this) {
/* Initialize the video system if needed */
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
return NULL;
}
...
}
其中
_this
是視頻子系統(tǒng)初始化完成后設(shè)置的全局變量。雖然不是必須的,但我們?nèi)匀唤ㄗh調(diào)用
SDL_Init
對主要用到的子系統(tǒng)進行顯式初始化。這樣做有兩個目的:清晰完整地展示出執(zhí)行過程,有助于理解代碼;如果執(zhí)行失敗,可以在第一時間定位出錯位置,提高排障效率。
SDL_Window* window = SDL_CreateWindow("Hello, SDL3!", 800, 600, SDL_WINDOW_RESIZABLE);
if (!window) {
SDL_Log("Could not create a window: %s", SDL_GetError());
return -1;
}
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
創(chuàng)建和窗口關(guān)聯(lián)的渲染器:
SDL_Renderer* renderer = SDL_CreateRenderer(window, nullptr);
if (!renderer) {
SDL_Log("Create renderer failed: %s", SDL_GetError());
return -1;
}
所有圖形圖像都是通過渲染器繪制到窗口。以背景色繪制為例,代碼如下:
SDL_SetRenderDrawColor(renderer, 16, 0, 16, 255);
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
這里使用的背景色是RGB(16, 0, 16)。這種顏色值常見于曾經(jīng)使用DirectDraw渲染視頻的老手們。但這里只是為了和SDL窗口默認(rèn)的黑色區(qū)分,便于觀察渲染結(jié)果,沒有其他特殊效果。
SDL_PollEvent
類似Win32 API中的PeekMessage,無論隊列中有無事件都會立即返回;區(qū)別只是返回值不同。
SDL_WaitEvent
類似Win32 API中的WaitMessage,如果隊列中沒有事件會阻塞等待,直到收到第一個事件才返回。
我們使用第二種方式實現(xiàn)事件循環(huán):
SDL_Event event{};
bool keep_going = true;
while (keep_going) {
SDL_WaitEvent(&event);
switch (event.type) {
case SDL_EVENT_QUIT: {
keep_going = false;
break;
}
case SDL_EVENT_KEY_DOWN: {
keep_going = keep_going && (event.key.keysym.sym != SDLK_ESCAPE);
break;
}
case SDL_EVENT_WINDOW_EXPOSED: {
SDL_SetRenderDrawColor(renderer, 16, 0, 16, 255);
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
break;
}
}
}
SDL_EVENT_QUIT
表示點擊了關(guān)閉窗口按鈕,所以收到該事件后跳出循環(huán);
SDL_EVENT_KEY_DOWN
表示鍵盤按下事件。這里我們實現(xiàn)了按下'Esc'鍵退出的功能;
SDL_EVENT_WINDOW_EXPOSED
表示需要對窗口進行重繪,所以我們將繪制背景色的代碼放在這個事件中執(zhí)行。
可以在while循環(huán)中增加一行日志來觀察收到了哪些事件:
SDL_Log("Event: %d", event.type);
注意上面這個事件循環(huán)的寫法和大多數(shù)SDL的示例不同。實際上,在這里我們是把SDL當(dāng)作一個正經(jīng)的窗口系統(tǒng)在使用,而不是當(dāng)作一個游戲引擎。兩者一個重要的區(qū)別是使用游戲引擎時一般是按照固定幀率持續(xù)進行窗口重繪,而一般的GUI軟件使用窗口系統(tǒng)時只進行必要的重繪,以最大程度節(jié)省CPU和GPU的使用。視頻雖然也有幀率的概念,但采用的是第二種方式,只在視頻幀刷新時執(zhí)行重繪。
#include
#include
int main(int argc, char* argv[])
{
SDL_SetLogPriorities(SDL_LOG_PRIORITY_VERBOSE);
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
SDL_Log("SDL_Init failed: %s", SDL_GetError());
return -1;
}
SDL_Window* window =
SDL_CreateWindow("Hello, SDL3!", 800, 600, SDL_WINDOW_RESIZABLE);
if (!window) {
SDL_Log("Could not create a window: %s", SDL_GetError());
return -1;
}
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
SDL_Renderer* renderer = SDL_CreateRenderer(window, nullptr);
if (!renderer) {
SDL_Log("Create renderer failed: %s", SDL_GetError());
return -1;
}
SDL_Event event{};
bool keep_going = true;
while (keep_going) {
SDL_WaitEvent(&event);
switch (event.type) {
case SDL_EVENT_QUIT: {
keep_going = false;
break;
}
case SDL_EVENT_KEY_DOWN: {
keep_going = keep_going && (event.key.keysym.sym != SDLK_ESCAPE);
break;
}
case SDL_EVENT_WINDOW_EXPOSED: {
SDL_SetRenderDrawColor(renderer, 16, 0, 16, 255);
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
break;
}
}
SDL_Log("Event: %d", event.type);
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
輸出效果如圖:
小編推薦閱讀機器學(xué)習(xí):神經(jīng)網(wǎng)絡(luò)構(gòu)建(下)
閱讀華為Mate品牌盛典:HarmonyOS NEXT加持下游戲性能得到充分釋放
閱讀實現(xiàn)對象集合與DataTable的相互轉(zhuǎn)換
閱讀算法與數(shù)據(jù)結(jié)構(gòu) 1 - 模擬
閱讀5. Spring Cloud OpenFeign 聲明式 WebService 客戶端的超詳細(xì)使用
閱讀Java代理模式:靜態(tài)代理和動態(tài)代理的對比分析
閱讀Win11筆記本“自動管理應(yīng)用的顏色”顯示規(guī)則
閱讀本站所有軟件,都由網(wǎng)友上傳,如有侵犯你的版權(quán),請發(fā)郵件[email protected]
湘ICP備2022002427號-10 湘公網(wǎng)安備:43070202000427號© 2013~2025 haote.com 好特網(wǎng)