【问题标题】:Problems displaying .bmp on SDL2 window in C++在 C++ 中的 SDL2 窗口上显示 .bmp 时出现问题
【发布时间】:2018-09-15 17:06:03
【问题描述】:

第一个问题,我真的需要帮助。所以我在努力学习
C++ 上的 SDL2 api。我正在使用树莓派 3 型号 B 。我首先关注的是 Youtube 上的教程(更具体地说是 CodingMadeEasy) 但现在我正在关注lazyfoo 的教程。我复制了 CME 的代码并尝试显示图像(.bmp),但窗口什么也没有显示 SDL_GetError() 没有报告任何错误。我认为必须
我写的代码有问题,或者我从互联网上下载的图像可能不是 .bmp ,所以我在这里 http://lazyfoo.net/tutorials/SDL/02_getting_an_image_on_the_screen/index.php 访问了lazyfoo 的教程并下载了源代码和 .bmp 文件。但是当我运行它时,我得到了相同的输出:一个空白窗口和 SDL_GetError() 没有在控制台上报告任何内容。 代码如下:

    /*This source code copyrighted by Lazy Foo' Productions 

(2004-2015)
and may not be redistributed without written permission.*/

//Using SDL and standard IO
#include <SDL2/SDL.h>
#include <stdio.h>

//Screen dimension constants
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;

//Starts up SDL and creates window
bool init();

//Loads media
bool loadMedia();

//Frees media and shuts down SDL
void close();

//The window we'll be rendering to
SDL_Window* gWindow = NULL;

//The surface contained by the window
SDL_Surface* gScreenSurface = NULL;

//The image we will load and show on the screen
SDL_Surface* gHelloWorld = NULL;

bool init()
{
    //Initialization flag
    bool success = true;

    //Initialize SDL
    if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
    {
        printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );
        success = false;
    }
    else
    {
        //Create window
        gWindow = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
        if( gWindow == NULL )
        {
            printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() );
            success = false;
        }
        else
        {
            //Get window surface
            gScreenSurface = SDL_GetWindowSurface( gWindow );
        }
    }

    return success;
}

bool loadMedia()
{
    //Loading success flag
    bool success = true;

    //Load splash image
    gHelloWorld = SDL_LoadBMP( "02_getting_an_image_on_the_screen/hello_world.bmp" );
    if( gHelloWorld == NULL )
    {
        printf( "Unable to load image %s! SDL Error: %s\n", "02_getting_an_image_on_the_screen/hello_world.bmp", SDL_GetError() );
        success = false;
    }

    return success;
}

void close()
{
    //Deallocate surface
    SDL_FreeSurface( gHelloWorld );
    gHelloWorld = NULL;

    //Destroy window
    SDL_DestroyWindow( gWindow );
    gWindow = NULL;

    //Quit SDL subsystems
    SDL_Quit();
}

int main( int argc, char* args[] )
{
    //Start up SDL and create window
    if( !init() )
    {
        printf( "Failed to initialize!\n" );
    }
    else
    {
        //Load media
        if( !loadMedia() )
        {
            printf( "Failed to load media!\n" );
        }
        else
        {
            //Apply the image
            SDL_BlitSurface( gHelloWorld, NULL, gScreenSurface, NULL );

            //Update the surface
            SDL_UpdateWindowSurface( gWindow );

            //Wait two seconds
            SDL_Delay( 2000 );
        }
    }

    //Free resources and close SDL
    close();

    return 0;
}

如果您需要 .bmp 文件,请访问上面的链接并下载源代码和文件。它不让我上传它。 这是我得到的输出:Output。这种透明的, 灰色的窗口。我正在使用 gnu c++ 编译器并使用

编译它
g++ 02_getting_an_image_on_the_screen.cpp -w -lSDL2 -o hl

然后得到那个透明的灰色窗口。我猜它是透明的,因为我的终端是这样配置的。为了查看问题出在哪里,我删除了 .bmp 以查看 sdl 是否报告错误,并且确实如此,这意味着它能够在 .bmp 位于正确位置时读取它,只是无法显示它。我在谷歌上搜索了几个小时一无所获。在堆栈溢出时,最接近我的问题是SDL window does not show 我什至尝试轮询事件,以便让系统有机会运行它的事件循环,正如那里所建议的那样,但无论窗口保持打开多长时间,.bmp 都不会出现。 更奇怪的是,这不是我第一次发生。一年前我尝试学习 SDL2,但当时也发生了同样的事情。我使用的是具有 2GB 内存的廉价 Windows 10 笔记本,并且正在使用 code::blocks (mingw 编译器版本),除了窗口不透明,它是白色的,就像你在创建窗口时一样与 sdl 在 Windows 中不显示任何内容。出于某种原因,代码块不允许我将窗口设置为nullptr,说它无法识别它是什么,所以我不得不将其设置为NULL。因此,我认为窗口不显示 .bmp 也是编译器的错。所以我下载了 Microsoft Visual Studio 2015 但结果是一样的:没有图像显示。 那时,我放弃了,但现在我回来了,因为我有一台新机器(rpi model 3 b)和一个新的编译器(gnu c/c++),我认为 SDL 不会再困扰我,但 SDL 不会似乎放弃了。我真的需要帮助。是的,.bmp 位于正确的位置,并且我在代码中包含了它的正确名称。请记住,我已经尝试在 2 台机器、3 个编译器、2 个非常不同的操作系统和 2 个不同的 cpu 架构(armv71 和 x86)上执行此操作,此时它变得令人沮丧。如果 SDL2 允许,我有一些很棒的想法很容易实现。对不起,很长的帖子,任何帮助表示赞赏。谢谢。

【问题讨论】:

  • 1.除非您绝对知道自己在做什么,否则永远不要使用 -w 编译器开关。 2.你的路径说你的图像在子目录中,是吗? 3. 从您的屏幕截图来看,您似乎不是从终端运行程序,那么您希望在哪里看到错误输出? 4.从截图来看,你的窗口根本没有更新(你看到的只是文件管理器和桌面的“背景”),bmp加载不太可能是你的问题的根源;您不会重绘特定事件的事实是。制作事件循环和渲染循环。一次绘制并等待不是一种展示方式。
  • 我总是从终端运行它,但是对于这个截图,我只是执行了输出文件('hl')。不,即使我从终端运行它,我也没有看到任何错误。 @keltar,您能解释一下渲染循环是什么意思吗?我是游戏开发的新手。
  • 在您参考的教程的下一部分中进行了描述。最常见的方法是创建一个在退出条件时中断的循环,并在每次迭代时处理事件并重绘您想要显示的任何内容。
  • 我试过你说的。甚至从教程中下载了源代码和bmp。没用。还是谢谢。
  • 抱歉,我无法读心术。请编辑您的问题以包含您的实际代码,以及此目录中ls -la 的输出,以及程序的完整输出。因为从技术上讲,有问题的代码不需要显示任何内容。此外,这可能是开始使用调试器检查程序流程和变量值的好时机。

标签: c++ sdl-2


【解决方案1】:

您的代码在我的 iMac 上运行良好。我所做的唯一更改如下,所以也许可以尝试进行相同的更改,看看它是否适合你。

首先,有许多不同类型的 BMP 文件,您可能拥有一个在图片查看器应用程序中运行良好的文件,但 SDL 对加载它“不满意”。毫无疑问,请使用 ImageMagick 创建您自己的 BMP 文件,然后您可以确定您有一个好的。我在终端中使用了这个:

convert -size 640x480 gradient:red-cyan image.bmp

其次,在任何 "Integrated Development Environment" 之外运行您的程序,即仅从终端运行并且所有图像都在当前目录中(无路径)并且名称中没有空格。原因是 IDE 可能会对事件循环和屏幕更新造成严重破坏,并且 IDE 通常看起来正在运行一个程序,但实际上正在运行 /some/where/else/Debug/program,这会弄乱您打开文件的路径,例如你的"02_getting_an_image_on_the_screen/hello_world.bmp",这也意味着目录分隔符不会引起问题。

第三,考虑使用pkgconfig 来获取头文件路径和库。例如,在我的 Mac 上,它添加了一个我可能没有意识到的线程安全定义:

pkg-config --cflags --libs sdl2

样本输出

-D_THREAD_SAFE -I/usr/local/include/SDL2 -L/usr/local/lib -lSDL2

所以,为了编译,我使用:

g++ main.cpp $(pkg-config --cflags --libs sdl2) -o main

【讨论】:

  • 感谢您的帮助。我试过了,但输出还是一样: .bmp doesn't show up 。不过,感谢您告诉我有关 ImageMagick 的信息。它真的很好。
  • 也许可以尝试更改 ImageMagick 命令以制作 GIF,看看是否会在 SDL 中加载。
猜你喜欢
  • 1970-01-01
  • 2018-04-23
  • 2022-01-03
  • 2022-01-27
  • 1970-01-01
  • 2022-01-02
  • 2011-01-10
  • 2020-05-20
相关资源
最近更新 更多