最优化渲染及软拉伸
最优化渲染及软拉伸
目前为止,我们加载的图片只是屈指可数的,但是游戏呢?别忘了,想用这个来开发的程序游戏居多,就算不是游戏,显示成千上万的图片不过分吧,原始图片直接显示运行太慢了(相对来说),因此,我们需要优化。
别问,问就是恰好,SDL库可以有解决办法。
下面我们来学习把原始图片直接转化为优化格式,这就是最优化渲染,加快运行速度(放心,由于运行太快,同时本教程以一张图片为例,因此你观察不出来的。记住有这个事情就可,等哪天遇见了,得记住还有这个处理办法。)同时,我们的SDL2版本,是该长大了。于是我们有了可以拉伸图片的功能了,这就是软拉伸。
同样的,以中文代码形式讲解,英文代码为已经讲解过的部分,不加以阐述。
在文末划重点。
/*This source code copyrighted by Lazy Foo' Productions (2004-2020)
and may not be redistributed without written permission.*/
//为适应纯C语言,已经在源码基础上做出修改,与大佬开源有部分出入纯属正常
//Using SDL, standard IO, and strings
#include <SDL.h>
#include <stdio.h>
#include <string.h>
#include "struct_type.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();
//Loads individual image
SDL_Surface* loadSurface(char path[]);
//The window we'll be rendering to
SDL_Window* gWindow = NULL;
//The surface contained by the window
SDL_Surface* gScreenSurface = NULL;
//Current displayed image
SDL_Surface* gStretchedSurface = 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 stretching surface
gStretchedSurface = loadSurface("C:\\Users\\Lixin\\Desktop\\stretch.bmp");
if (gStretchedSurface == NULL)
{
printf("Failed to load stretching image!\n");
success = false;
}
return success;
}
void close()
{
//Free loaded image
SDL_FreeSurface(gStretchedSurface);
gStretchedSurface = NULL;
//Destroy window
SDL_DestroyWindow(gWindow);
gWindow = NULL;
//Quit SDL subsystems
SDL_Quit();
}
SDL_Surface* loadSurface(char path[])
{
//The final optimized image
SDL_Surface* optimizedSurface = NULL;
//Load image at specified path
SDL_Surface* loadedSurface = SDL_LoadBMP(path);
if (loadedSurface == NULL)
{
printf("Unable to load image %s! SDL Error: %s\n", path, SDL_GetError());
}
else
{
//转变图片格式,实现加速
optimizedSurface = SDL_ConvertSurface(loadedSurface, gScreenSurface->format, 0);
if (optimizedSurface == NULL)
{
printf("Unable to optimize image %s! SDL Error: %s\n", path, SDL_GetError());
}
//释放老格式图片占用空间,避免内存泄漏
SDL_FreeSurface(loadedSurface);
}
return optimizedSurface;
}
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
{
//Main loop flag
bool quit = false;
//Event handler
SDL_Event e;
//While application is running
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);
}
}
}
//Free resources and close SDL
close();
return 0;
}
- 最优化渲染:查看加载位图时,通常以24位格式加载,因为大多数位图都是24位。默认情况下,大多数(如果不是全部)现代显示器不是24位。如果我们将24位的图像分割到32位图像上,SDL会在每次图像渲染时对其进行转换。因此,当加载图像时,我们要做的是将其转换为与屏幕相同的格式,因此无需在blit上进行转换。这可以通过SDL_ConvertSurface轻松完成。我们所要做的就是传入我们要用屏幕格式转换的表面。请务必注意,SDL_ConvertSurface以新格式返回原始副本。此调用后,原始加载的图像仍在内存中。这意味着我们必须释放原始加载的表面,否则我们将在内存中拥有同一图像的两个副本。加载并转换图像后,我们返回最终的优化图像。
- 图片软拉伸:SDL2新增了一项专用功能,可将图像缩小到不同的大小:SDL_BlitScaled。与之前的blitting 图像一样,SDL_BlitScaled将一个源表面连接到目标表面上。它还会引入目标SDL_Rect,该目标定义了您正在展示的图像的位置和大小。因此,如果我们要展示比屏幕小的图像并使其成为屏幕的大小,则可以将目标宽度(高度设置)为屏幕的宽度(高度)。
疫情退散!!!憋在宿舍写教程,呜呜呜~~~

浙公网安备 33010602011771号