SDL 图片软拉伸
参考自:https://blog.csdn.net/qq_31024569/article/details/78128166
直到现在我们的代码都仅仅是按原生大小显示图片而已。因为我们一次展示一张图像,这样做没什么问题。但当你制作游戏的时候,这样做会导致不必要的减速(needless slowdown)。现在我们将要把图像转为更加优化的格式以加快速度。
SDL2有一个新特性叫做软拉伸,它允许你将图像缩放到不同的大小。在这篇教程中我们会把一张只有窗口一半尺寸的图像拉伸到整个窗口大小。
当你每次加载位图的时候,基本上它都会以24位的格式加载因为大部分位图都是24位。但这只是大部分,现在的显示器默认的都不是24位。如果我们把24位的图像投射到32位的图像上,SDL就会在每一次投射的时候对它进行转化。
所以我们要做的就是在图像被加载的时候对其以与屏幕相同的格式进行转化来保证投射的过程中不再发生转化的工作。使用SDL_ConvertSurface()函数可以很轻松地完成这个工作。因为我们要做的就仅仅是传入想要转化的surface和格式给这个函数。
很重要的一点是SDL_ConvertSurface()以新的格式返回原来的surface。原来已经加载过的图像在这个调用之后仍然在内存之中。这意味着我们得把原来已经加载的surface释放掉,否则内存中就会有两份相同的图像。(其中一个还是不会用到的)
在图像被加载并完成转换之后,将最终优化过的图像返回。
SDL2有新的专用的函数来把图像以不同的尺寸投射到屏幕——SDL_BlitScaled(),就像之前投射图像那样,SDL_BlitScaled()需要接收一个源surface以投射到目标surface上。它同样要接收定义了将要投射到的位置和尺寸的SDL_Rect作为参数。
所以如果我们想要把比窗口尺寸小的图像拉伸到窗口尺寸大小,你就把要投射的尺寸设定为窗口的尺寸。
完整代码如下:
#include <SDL2/SDL.h>
#include <stdio.h>
#include <string>
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
bool init();
bool loadMedia();
void close();
SDL_Surface* loadSurface( std::string path );
SDL_Window* gWindow = NULL;
//The surface contained by the window
SDL_Surface* gScreenSurface = NULL;
SDL_Surface* gStretchedSurface = NULL;
{
//Initialization flag
bool success = true;
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 );
}
}
}
{
//Loading success flag
bool success = true;
gStretchedSurface = loadSurface( "stretch.bmp" );
if( gStretchedSurface == NULL )
{
printf( "Failed to load stretching image!\n" );
success = false;
}
}
{
//Free loaded image
SDL_FreeSurface( gStretchedSurface );
gStretchedSurface = NULL;
SDL_DestroyWindow( gWindow );
gWindow = NULL;
SDL_Quit();
}
{
//The final optimized image
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() );
}
else
{
//Convert surface to screen format
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() );
}
SDL_FreeSurface( loadedSurface );
}
}
{
//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
{
//Main loop flag
bool quit = false;
SDL_Event e;
while( !quit )
{
//Handle events on queue
while( SDL_PollEvent( &e ) != 0 )
{
//User requests quit
if( e.type == SDL_QUIT )
{
quit = true;
}
}
SDL_Rect stretchRect;
stretchRect.x = 0;
stretchRect.y = 0;
stretchRect.w = SCREEN_WIDTH;
stretchRect.h = SCREEN_HEIGHT;
SDL_BlitScaled( gStretchedSurface, NULL, gScreenSurface, &stretchRect );
//Update the surface
SDL_UpdateWindowSurface( gWindow );
}
}
}
close();
}
浙公网安备 33010602011771号