注: 本教程翻译自 lazyfoo的教程,原教程戳这里,可能语言不准确,本翻译仅供参考,建议对比阅读。
直到现在我们的代码都仅仅是按原生大小显示图片而已。因为我们一次展示一张图像,这样做没什么问题。但当你制作游戏的时候,这样做会导致不必要的减速(needless slowdown)。现在我们将要把图像转为更加优化的格式以加快速度。
SDL2有一个新特性叫做软拉伸,它允许你将图像缩放到不同的大小。在这篇教程中我们会把一张只有窗口一半尺寸的图像拉伸到整个窗口大小。
SDL_Surface* loadSurface( std::string path )
{
//用以指向最终优化的图像
SDL_Surface* optimizedSurface = NULL;
//从指定路径加载图像
SDL_Surface* loadedSurface = SDL_LoadBMP( path.c_str() );
if( loadedSurface == NULL )
{
printf( "Unable to load image %s! SDL Error: %s\n", path.c_str(), SDL_GetError() );
}
回到我们的图像加载函数中,我们将要做一些修改以使surface在加载的时候就被转化。在这个函数的开始部分的代码大致和之前的教程中提到的相同。但我们多声明了一个指针来指向最终优化过的图像。
else
{
//按照窗口的格式转化surface
optimizedSurface = SDL_ConvertSurface( loadedSurface, gScreenSurface->format, NULL );
if( optimizedSurface == NULL )
{
printf( "Unable to optimize image %s! SDL Error: %s\n", path.c_str(), SDL_GetError() );
}
//处理已经加载的surface
SDL_FreeSurface( loadedSurface );
}
return optimizedSurface;
}
如果图像在这段代码的起始处被成功加载,我们就把已加载的surface进行优化。
当你每次加载位图的时候,基本上它都会以24位的格式加载因为大部分位图都是24位。但这只是大部分,现在的显示器默认的都不是24位。如果我们把24位的图像投射到32位的图像上,SDL就会在每一次投射的时候对它进行转化。
所以我们要做的就是在图像被加载的时候对其以与屏幕相同的格式进行转化来保证投射的过程中不再发生转化的工作。使用SDL_ConvertSurface()
函数可以很轻松地完成这个工作。因为我们要做的就仅仅是传入想要转化的surface和格式给这个函数。
很重要的一点是SDL_ConvertSurface()
以新的格式返回原来的surface。原来已经加载过的图像在这个调用之后仍然在内存之中。这意味着我们得把原来已经加载的surface释放掉,否则内存中就会有两份相同的图像。(其中一个还是不会用到的)
在图像被加载并完成转换之后,将最终优化过的图像返回。
在这里作者提到:我收到邮件说SDL_ConvertSurface()
的最后一个参数应该是0。NULL就是0。如果你的编译器在这里冒出了一个warning,你可以手动把它改为0。
//应用拉伸过的图像
SDL_Rect stretchRect;
stretchRect.x = 0;
stretchRect.y = 0;
stretchRect.w = SCREEN_WIDTH;
stretchRect.h = SCREEN_HEIGHT;
SDL_BlitScaled( gStretchedSurface, NULL, gScreenSurface, &stretchRect );
SDL2有新的专用的函数来把图像以不同的尺寸投射到屏幕——SDL_BlitScaled()
,就像之前投射图像那样,SDL_BlitScaled()
需要接收一个源surface以投射到目标surface上。它同样要接收定义了将要投射到的位置和尺寸的SDL_Rect作为参数。
所以如果我们想要把比窗口尺寸小的图像拉伸到窗口尺寸大小,你就把要投射的尺寸设定为窗口的尺寸。
下载多媒体文件和源代码请戳原作者链接
注: 本教程翻译自 lazyfoo的教程,原教程戳这里,可能语言不准确,本翻译仅供参考,建议对比阅读。