SDL2 无法打开任何 BMP 文件
SDL2 cannot open any BMP files
我正在尝试按照 lazyfoo 的教程使用 SDL2 来适应它,但即使是最基本的程序也无法正常工作。我可以打开一个没有图像的基本空白 window 并保持打开状态,但是一旦我尝试在 window 中打开 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 小得多),所有 windows 调整大小,这会持续很短的时间。如果我用 SDL_Delay(1000)
替换 while(!quit)
循环,这种行为的持续时间大约与延迟一样长。
最初我怀疑我第一次使用的文件已损坏(我刚刚重命名了一张现有图片),但后来我下载了一个示例 BMP 文件,但没有任何改变。
当使用调试器时,我收到来自 loadMedia()
的错误消息,指出无法加载文件,无论我使用哪个调试器。我正在使用 MinGW 和 cLion。
可能是什么问题?
常量 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 全屏 模式下创建 window。这可能是您的桌面被调整大小的原因。
找不到文件的原因可能是因为该文件不在您程序的current working directory中。您可以确保文件位于该目录中,也可以使用文件的绝对路径,例如 "C:\Users\MyUsername\Desktop\LAND3.BMP"
.
我怀疑您无法使用任务管理器终止您的应用程序的问题是 SDL 的问题。这可能是 Microsoft Windows 的设计缺陷。请参阅 this link 了解如何使挂起的全屏应用程序更易于访问任务管理器。
我正在尝试按照 lazyfoo 的教程使用 SDL2 来适应它,但即使是最基本的程序也无法正常工作。我可以打开一个没有图像的基本空白 window 并保持打开状态,但是一旦我尝试在 window 中打开 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 小得多),所有 windows 调整大小,这会持续很短的时间。如果我用 SDL_Delay(1000)
替换 while(!quit)
循环,这种行为的持续时间大约与延迟一样长。
最初我怀疑我第一次使用的文件已损坏(我刚刚重命名了一张现有图片),但后来我下载了一个示例 BMP 文件,但没有任何改变。
当使用调试器时,我收到来自 loadMedia()
的错误消息,指出无法加载文件,无论我使用哪个调试器。我正在使用 MinGW 和 cLion。
可能是什么问题?
常量 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 全屏 模式下创建 window。这可能是您的桌面被调整大小的原因。
找不到文件的原因可能是因为该文件不在您程序的current working directory中。您可以确保文件位于该目录中,也可以使用文件的绝对路径,例如 "C:\Users\MyUsername\Desktop\LAND3.BMP"
.
我怀疑您无法使用任务管理器终止您的应用程序的问题是 SDL 的问题。这可能是 Microsoft Windows 的设计缺陷。请参阅 this link 了解如何使挂起的全屏应用程序更易于访问任务管理器。