【问题标题】:SDL2 cannot open any BMP filesSDL2 无法打开任何 BMP 文件
【发布时间】:2020-12-05 19:01:27
【问题描述】:

我正在尝试按照lazyfoo 的教程使用SDL2 以适应它,但即使是最基本的大多数程序也无法正常工作。我可以打开一个没有图像的基本空白窗口并保持打开状态,但是一旦我尝试在窗口中打开 BMP 文件,它就会变得很奇怪并且不再起作用。我的代码,最初没有显示错误:

#include <SDL2/SDL.h>
#include <cstdio>

const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;

SDL_Window *newWindow = nullptr;
SDL_Surface *loadedImage = nullptr;
SDL_Surface *screenSurface = nullptr;
bool quit = false;
SDL_Event event;

bool initWindow() {
    bool state = true;

    if (SDL_Init(SDL_INIT_VIDEO) < 0)
    {
        std::puts("Error init");
        state = false;
    }
    else
    {
        newWindow = SDL_CreateWindow("Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
                                     SCREEN_WIDTH,
                                     SCREEN_HEIGHT, SDL_WINDOWEVENT_SHOWN);

        if (nullptr == newWindow)
        {
            std::puts("Error window");
            state = false;
        }
        else
        {
            screenSurface = SDL_GetWindowSurface(newWindow);
        }
    }
    return state;
}

bool loadMedia() {
    bool success = true;

    loadedImage = SDL_LoadBMP("LAND3.BMP");

    if (loadedImage == nullptr)
    {
        printf("Error image %s \n", SDL_GetError());
        success = false;
    }

    return success;
}

void closeWindow() {
    SDL_FreeSurface(loadedImage);
    loadedImage = nullptr;

    SDL_DestroyWindow(newWindow);
    newWindow = nullptr;

    SDL_Quit();
}

int main(int argc, char *args[]) {

    if (!initWindow())
    {
        std::puts("Error init main");
    }
    else
    {
        if (!loadMedia())
        {
            std::puts("Error image main");
        }
        else
        {
            while (!quit)
            {
                if (event.type == SDL_QUIT)
                {
                    quit = true;
                }
                else
                {
                    SDL_BlitSurface(loadedImage, nullptr, screenSurface, nullptr);
                    SDL_UpdateWindowSurface(newWindow);
                }
            }
        }
    }

    closeWindow();

    return 0;
}

运行此程序时,我没有收到任何错误,但 UI 开始表现得很疯狂;分辨率变得非常小(比我设置的 480p 小得多),所有窗口都会调整大小,并且会持续很短的时间。如果我用SDL_Delay(1000) 替换while(!quit) 循环,则此行为的持续时间大约与延迟时间一样长。

最初我怀疑我第一次使用的文件已损坏(我刚刚重命名了现有图片),但后来我下载了一个示例 BMP 文件,但没有任何改变。

使用调试器时,我从loadMedia() 收到一个错误,即无论我使用哪个文件都无法加载该文件。我正在使用 MinGW 和 cLion。

可能是什么问题?

【问题讨论】:

  • “当使用调试器时,我从loadMedia() 收到一个错误,即无法加载文件”——如果失败,该函数将打印出一个 SDL 错误字符串。究竟打印了什么?
  • @AndreasWenzel SDL_GetError() 的文本是“无法打开 LAND3.BMP”。无论我输入什么文件,错误都是一样的,除了照片名称。
  • 您必须将文件放在程序的current working directory 中,或者必须指定文件的绝对路径,例如"C:\\Users\\MyUsername\\Desktop\\LAND3.BMP"
  • @AndreasWenzel 奇怪的是,当我只使用文件名时,它通常可以工作,因为它与 main 位于同一文件夹中。无论如何,它仍然搞砸了我的界面,只是这一次它甚至没有停止。任务管理器也没有帮助,我真的不得不强行关闭 Windows 才能在启动备份时开始更新。 Windows was looking like this 。我想这是我和 SDL 分道扬镳的时候......

标签: c++ sdl-2


【解决方案1】:

常量SDL_WINDOWEVENT_SHOWN 不是函数SDL_CreateWindow 的有效标志。该常量不是作为标志,而是作为event ID。您可能打算改用常量 SDL_WINDOW_SHOWN

常量SDL_WINDOWEVENT_SHOWN 恰好与SDL_WINDOW_FULLSCREEN 具有相同的值(两者都具有1 的值)。因此,您不正确的函数调用

newWindow = SDL_CreateWindow("Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
                                     SCREEN_WIDTH,
                                     SCREEN_HEIGHT, SDL_WINDOWEVENT_SHOWN);

相当于:

newWindow = SDL_CreateWindow("Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
                                     SCREEN_WIDTH,
                                     SCREEN_HEIGHT, SDL_WINDOW_FULLSCREEN);

换句话说,您无意中要求 SDL 以 640*480 全屏模式创建窗口。这可能是您的桌面被调整大小的原因。

找不到该文件的原因可能是因为该文件不在您程序的current working directory 中。您可以确保文件位于该目录中,也可以使用文件的绝对路径,例如"C:\\Users\\MyUsername\\Desktop\\LAND3.BMP"

我怀疑您无法使用任务管理器杀死您的应用程序的问题是 SDL 的错误。这可能是 Microsoft Windows 的设计缺陷。请参阅this link,了解如何让挂起的全屏应用程序更容易访问任务管理器。

【讨论】:

  • 非常感谢!感谢您花时间写一个更详细的答案。
  • @AndreiVicol:我希望我现在已经说服您不要这么快放弃 SDL。 :-) 但是,如果您正在寻找替代品,您可能需要查看SFML。虽然我从未使用过它,但从我阅读的内容来看,主要区别似乎是 SFML 提供了面向对象的 C++ 接口,而 SDL 仅提供了 C 接口。由于您已将您的问题标记为 C++ 而不是 C,因此我认为这值得一提。但是,SFML 的用户群比 SDL 小。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-13
  • 1970-01-01
  • 1970-01-01
  • 2021-01-19
  • 2019-05-31
  • 2019-01-06
  • 1970-01-01
相关资源
最近更新 更多