在上一篇文章中我們已經(jīng)利用 SDL 的日志接口實(shí)現(xiàn)了簡(jiǎn)單的字符串輸出,實(shí)際上是解決了開發(fā)環(huán)境搭建問題,接下來我們將在已有代碼的基礎(chǔ)上繼續(xù)開發(fā),實(shí)現(xiàn)第一個(gè)窗口的創(chuàng)建和背景色繪制。 初始化 首先設(shè)置日志輸出級(jí)別: SDL_SetLogPriorities(SDL_LOG_PRIORITY_VERBOSE
在上一篇文章中,我們利用SDL的日志接口實(shí)現(xiàn)了簡(jiǎn)單的字符串輸出,解決了開發(fā)環(huán)境搭建問題。接下來,我們將在已有代碼的基礎(chǔ)上繼續(xù)開發(fā),實(shí)現(xiàn)第一個(gè)窗口的創(chuàng)建和背景色繪制。
SDL_SetLogPriorities(SDL_LOG_PRIORITY_VERBOSE);
由于仍處于開發(fā)階段,我們將輸出日志級(jí)別設(shè)置為最低的VERBOSE。這樣可以使所有的日志都輸出,有助于觀察SDL的運(yùn)行情況。當(dāng)出現(xiàn)錯(cuò)誤時(shí),可以獲得盡可能詳細(xì)的出錯(cuò)信息,有助于快速定位問題。
接下來,初始化SDL庫(kù),參數(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;
}
實(shí)際上,這一步可以省略,因?yàn)樵谡{(diào)用SDL API時(shí)其內(nèi)部會(huì)自行檢查和初始化所需使用的子系統(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
對(duì)主要用到的子系統(tǒng)進(jìn)行顯式初始化。這樣做有兩個(gè)目的:清晰完整地展示出執(zhí)行過程,有助于理解代碼;如果執(zhí)行失敗,可以在第一時(shí)間定位出錯(cuò)位置,提高排障效率。
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,無論隊(duì)列中有無事件都會(huì)立即返回;區(qū)別只是返回值不同。
SDL_WaitEvent
類似Win32 API中的WaitMessage,如果隊(duì)列中沒有事件會(huì)阻塞等待,直到收到第一個(gè)事件才返回。
我們使用第二種方式實(shí)現(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
表示點(diǎn)擊了關(guān)閉窗口按鈕,所以收到該事件后跳出循環(huán);
SDL_EVENT_KEY_DOWN
表示鍵盤按下事件。這里我們實(shí)現(xiàn)了按下'Esc'鍵退出的功能;
SDL_EVENT_WINDOW_EXPOSED
表示需要對(duì)窗口進(jìn)行重繪,所以我們將繪制背景色的代碼放在這個(gè)事件中執(zhí)行。
可以在while循環(huán)中增加一行日志來觀察收到了哪些事件:
SDL_Log("Event: %d", event.type);
注意上面這個(gè)事件循環(huán)的寫法和大多數(shù)SDL的示例不同。實(shí)際上,在這里我們是把SDL當(dāng)作一個(gè)正經(jīng)的窗口系統(tǒng)在使用,而不是當(dāng)作一個(gè)游戲引擎。兩者一個(gè)重要的區(qū)別是使用游戲引擎時(shí)一般是按照固定幀率持續(xù)進(jìn)行窗口重繪,而一般的GUI軟件使用窗口系統(tǒng)時(shí)只進(jìn)行必要的重繪,以最大程度節(jié)省CPU和GPU的使用。視頻雖然也有幀率的概念,但采用的是第二種方式,只在視頻幀刷新時(shí)執(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;
}
輸出效果如圖:
機(jī)器學(xué)習(xí):神經(jīng)網(wǎng)絡(luò)構(gòu)建(下)
閱讀華為Mate品牌盛典:HarmonyOS NEXT加持下游戲性能得到充分釋放
閱讀實(shí)現(xiàn)對(duì)象集合與DataTable的相互轉(zhuǎn)換
閱讀鴻蒙NEXT元服務(wù):論如何免費(fèi)快速上架作品
閱讀算法與數(shù)據(jù)結(jié)構(gòu) 1 - 模擬
閱讀5. Spring Cloud OpenFeign 聲明式 WebService 客戶端的超詳細(xì)使用
閱讀Java代理模式:靜態(tài)代理和動(dòng)態(tài)代理的對(duì)比分析
閱讀Win11筆記本“自動(dòng)管理應(yīng)用的顏色”顯示規(guī)則
閱讀本站所有軟件,都由網(wǎng)友上傳,如有侵犯你的版權(quán),請(qǐng)發(fā)郵件[email protected]
湘ICP備2022002427號(hào)-10 湘公網(wǎng)安備:43070202000427號(hào)© 2013~2025 haote.com 好特網(wǎng)