SDL窗口不显示

SDL window does not show

本文关键字:显示 窗口 SDL      更新时间:2023-10-16

这是我的代码:

#include <iostream>
#include <SDL2/SDL.h>
int main(int argc, const char * argv[]) {
SDL_Init(SDL_INIT_VIDEO);
SDL_Window *_window;
_window = SDL_CreateWindow("Game Engine", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 700, 500, SDL_WINDOW_RESIZABLE);
SDL_Delay(20000);
SDL_DestroyWindow(_window);
SDL_Quit();
return 0;
}

我在Xcode工作。我已经下载了SDL2并将库导入到项目构建阶段。我已经测试了SDL2是否正常工作。

问题是窗户永远不会出现。我只是得到了一个"旋转的mac轮子",然后程序在延迟后退出。我已经确定窗户没有藏在什么地方。

想法?

您必须给系统一个运行其事件循环的机会。

最简单的方法是自己对事件进行投票:

SDL_Event e;
bool quit = false;
while (!quit){
    while (SDL_PollEvent(&e)){
        if (e.type == SDL_QUIT){
            quit = true;
        }
        if (e.type == SDL_KEYDOWN){
            quit = true;
        }
        if (e.type == SDL_MOUSEBUTTONDOWN){
            quit = true;
        }
    }
}

而不是等待循环

---附录

既然这个答案仍然对人们有帮助,也许我也可以添加更多的信息来说明为什么它有效,而不仅仅是发布解决方案。

当在Mac上(实际上Windows也是如此)程序启动时,它只从"主线程"开始。这是用于设置UI内容的线程。"main thead"与其他线程的不同之处在于它附带了一个事件处理系统。这个系统捕捉鼠标移动、按键、按钮点击等事件,然后将这些事件排队,并让代码对其做出响应。Mac(和Windows)上的所有UI都依赖于这个事件泵的存在和运行。这就是为什么如果你在代码中做任何与UI相关的事情,你需要确保你没有在不同的线程上。

现在,在代码中初始化窗口和UI,然后执行SDL_Delay。这只是阻塞了线程并使其停止20秒,所以什么也没做。由于您在主线程上执行此操作,因此即使是对包含事件的队列的处理也会被阻止。在Mac上,它显示为旋转的macwheel。

所以我发布的解决方案实际上一直在轮询事件并处理它们。通过这种方式,你实际上也处于"空闲"状态,但当事件发布(如鼠标点击和按键)时,线程将再次唤醒,并进行处理。

您必须加载位图图像,或者在窗口上显示一些内容,Xcode才能开始显示窗口。

#include <SDL2/SDL.h>
#include <iostream>
using namespace std;
int main() {
    SDL_Window * window = nullptr;
    SDL_Surface * window_surface = nullptr;
    SDL_Surface * image_surface = nullptr;
    SDL_Init(SDL_INIT_VIDEO);
    window = SDL_CreateWindow("Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_SHOWN);
    window_surface = SDL_GetWindowSurface(window);
    image_surface = SDL_LoadBMP("image.bmp");
    SDL_BlitSurface(image_surface, NULL, window_surface, NULL);
    SDL_UpdateWindowSurface(window);
    SDL_Delay(5000);
    SDL_DestroyWindow(window);
    SDL_FreeSurface(image_surface);
    SDL_Quit();
}

在创建窗口之前,需要使用SDL_Init(SDL_INIT_VIDEO)初始化SDL。

请删除sdl_delay()并用下面提到的代码替换它。我没有任何理由,但我自己尝试了一下,它起到了的作用

bool isquit = false;
SDL_Event event;
while (!isquit) {
    if (SDL_PollEvent( & event)) {
        if (event.type == SDL_QUIT) {
            isquit = true;
        }
    }
}