SDL扩展库允许你做一些事情,比如加载BMP以外的图像文件,渲染TTF字体,以及播放音乐。您可以设置SDL_image来加载PNG文件,这可以为您节省大量的磁盘空间。在本教程中,我们将介绍如何安装SDL_image。
SDL本身是一个扩展库,因为它增加了游戏和媒体功能,而这些功能并不是你的C++编译器的标准配置。当你设置扩展库的时候,你会发现它和单独安装SDL几乎是一样的。我们将特别安装SDL_image,但如果你能安装该扩展库,你应该能够安装任何一个扩展库。
您需要做的第一件事是下载SDL_image头文件和二进制文件。您可以在SDL_image网站[1]上找到它们
在设置好SDL_image之后,我们将介绍如何使用SDL创建加载PNG。
现在库已经全部设置好了,让我们加载一些PNG。
//使用SDL、SDL_image、标准IO和字符串。
#include <SDL.h>
#include <SDL_image.h>
#include <stdio.h>
#include <string>
要使用任何 SDL_image 函数或数据类型,我们需要包含 SDL_image 头。对于SDL_ttf,或者SDL_mixer,我们也要做同样的事情。
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
{
//初始化PNG加载
int imgFlags = IMG_INIT_PNG;
if( !( IMG_Init( imgFlags ) & imgFlags ) )
{
printf( "SDL_image could not initialize! SDL_image Error: %s\n", IMG_GetError() );
success = false;
}
else
{
//Get window surface
gScreenSurface = SDL_GetWindowSurface( gWindow );
}
}
}
return success;
}
现在我们使用SDL_image,我们需要初始化它。这里我们想用PNG加载来初始化SDL_image,所以我们将PNG加载标志传递给IMG_Init。IMG_Init返回成功加载的标志。如果返回的标志不包含我们要求的标志,那就意味着出现了错误。
当SDL_image出现错误时,你会用IMG_GetError得到错误字符串,而不是SDL_GetError。
Also:STOP E-MAILING ME TELLING ME THAT THAT CALL TO IMG_Init IS A BUG!STOP E-MAILING ME TELLING ME THAT THAT CALL TO IMG_Init IS A BUG!STOP E-MAILING ME TELLING ME THAT THAT CALL TO IMG_Init IS A BUG!STOP E-MAILING ME TELLING ME THAT THAT CALL TO IMG_Init IS A BUG!STOP E-MAILING ME TELLING ME THAT THAT CALL TO IMG_Init IS A BUG!
不是的,IMG_INIT_PNG是2。如果你用IMG_INIT_PNG初始化,然后得到IMG_INIT_PNG,你得到的是2 & 2,也就是2。2会被评估为true, !否定它,这意味着它会被评估为false ,这将导致SDL_GetWindowSurface行执行。
如果你想从IMG_Init取回4,而你想要的是2,那么4 &2是0,它的值是false,这就被 ! 否定了,它的值是true,这将导致错误打印代码的执行。
如果当你想要2的时候,从IMG_Init中取回6(包括4和2位),6 & 2是2,它的值为true,被 !否定为false,这将导致SDL_GetWindowSurface一行执行。
代码之所以是这样,是因为我们只关心PNG加载位。如果我们得到了,就意味着我们可以继续。在其他情况下,这段代码会有所不同,但我们在这里不处理这个问题。
所以一定要把你的二进制数学学好,不要再发邮件告诉我说调用IMG_Init是个BUG!。说真的,我收到的错误报告中,有25%是这样的。
SDL_Surface* loadSurface( std::string path ){
//The final optimized image
SDL_Surface* optimizedSurface = NULL;
//Load image at specified path
SDL_Surface* loadedSurface = IMG_Load( path.c_str() );
if( loadedSurface == NULL )
{
printf( "Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError() );
}
else
{
//Convert surface to screen format
optimizedSurface = SDL_ConvertSurface( loadedSurface, gScreenSurface->format, 0 );
if( optimizedSurface == NULL )
{
printf( "Unable to optimize image %s! SDL Error: %s\n", path.c_str(), SDL_GetError() );
}
//Get rid of old loaded surface
SDL_FreeSurface( loadedSurface );
}
return optimizedSurface;
}
我们的图像加载功能和以前差不多,只是现在它使用IMG_Load而不是SDL_LoadBMP。IMG_Load 可以加载许多不同类型的格式,你可以在 SDL_image 文档[2]中找到相关信息。和IMG_Init一样,当IMG_Load出现错误时,我们调用IMG_GetError来获取错误字符串。
在 这里[3]下载本教程的媒体和源代码。
[1]
SDL_image网站: https://www.libsdl.org/projects/SDL_image/
[2]
SDL_image 文档: https://www.libsdl.org/projects/SDL_image/docs/index.html
[3]
这里: http://www.lazyfoo.net/tutorials/SDL/06_extension_libraries_and_loading_other_image_formats/06_extension_libraries_and_loading_other_image_formats.zip
[4]
原文链接: http://www.lazyfoo.net/tutorials/SDL/06_extension_libraries_and_loading_other_image_formats/index2.php