大家好! 这是SDL 2中的第四节课。我决定将这两节课合并为一个,因为在最初的时候它们很小。 但是可以在
这里和
这里找到它们。 好,让我们开始上课。
首先,我们将决定我们将做什么。 今天,我们将学习如何上传另一个扩展程序(不是BMP)的图像,即:PNG。 以其他格式重做图像,以加快工作速度并调整图像大小。 我们将使用此图像:
安装方式
因此,首先我们学习如何下载PNG。 标准SDL 2功能集不会加载非BMP格式的图像。 要下载其他格式,您需要安装扩展程序。
以下是说明:
窗户您可以转到此
页面并从“
开发库”部分下载ZIP或TAR.GZ归档。 解压缩并将它们放入编译器的文件夹中。
的Linux如果您的系统使用Debian,则需要输入以下命令:
apt-cache search libsdl2-image apt-get install libsdl2-image-dev
如果使用“ Yellowdog Updater,Modified”,则输入以下命令:
yum search SDL2_image-devel yum SDL2_image-devel
编写代码
设置
SDL_image之后,我们开始编写代码。 首先,与往常一样,连接库,设置窗口大小并创建3个全局变量。
#include <SDL2/SDL.h> #include <SDL2/SDL_image.h> #include <iostream> const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; SDL_Window *win = NULL; SDL_Surface *scr = NULL; SDL_Surface *flower = NULL;
请注意,我单独连接了
SDL_image.h ,因为它是一个单独的库。
接下来,我们编写3个众所周知的函数,像往常一样在其中添加和更改某些内容。
初始化() bool init() { if (SDL_Init(SDL_INIT_VIDEO) != 0) { std::cout << "Can't init video: " << SDL_GetError() << std::endl; return false; } int flags = IMG_INIT_PNG; if ( !( IMG_Init( flags ) & flags ) ) { std::cout << "Can't init image: " << IMG_GetError() << std::endl; return false; } win = SDL_CreateWindow(" PNG", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); if (win == NULL) { std::cout << "Can't create window: " << SDL_GetError() << std::endl; return false; } scr = SDL_GetWindowSurface(win); return true; }
在这里,我们添加了SDL_image模块的初始化。 要初始化它,首先创建一个
int变量,我们有
flags ,然后将要用于初始化的所有标志保存在那里。
所有标志列表SDL_INIT_PNG-初始化PNG图像下载器;
SDL_INIT_JPG-初始化JPG图像下载器;
SDL_INIT_TIF-初始化TIF图像下载器;
接下来,我们编写此条件:
if ( !( IMG_Init( flags ) & flags ) )
IMG_Init()函数返回它能够初始化的标志。 如果她返回了这些标志,但是我们想要的那个标志丢失了,我们将返回一个错误。 很简单 另外,请注意,我使用
IMG_GetError而不是
SDL_GetError ,因为我们正在寻找
SDL_image模块而不是
SDL函数的错误。
我还想指出,我决定使用
布尔类型
返回 a-这是一种更合理的方法。
让我们继续编写程序,编写
Load()函数,在其中加载PNG图像并进行转换。
负荷 bool load() { flower = IMG_Load("flower.png"); if (flower == NULL) { std::cout << "Can't load: " << IMG_GetError() << std::endl; return false; } flower = SDL_ConvertSurface(flower, scr->format, NULL); if (flower == NULL) { std::cout << "Can't convert: " << SDL_GetError() << std::endl; return false; } return true; }
在这里,我们使用新的
IMG_Load函数上传图像。
它的功能与
SDL_LoadBMP的功能相同,并且结果相同-它返回
SDL_Surface类的实例。 为了在加载期间发现错误,我们还使用了
IMG_GetError 。
现在该转换了。 首先,一点理论。 很少有人知道,但是在下载图像时,它以24位格式下载,大多数现代显示器都是32位格式。 每次我们在屏幕上显示图像时,都会首先重做32位格式。 对于简单程序,这无关紧要,但是在创建某种大型项目时,它将极大地影响性能,因此我们会采用它,在下载图像的阶段,我们将以显示格式重新制作它们。
SDL_ConvertSurface函数将有所帮助。 它包含3个值:我们要设置格式的表面,我们要设置格式的表面以及标志。 我们要格式化
花朵图像,将其传递给第一个参数。 第二个参数是窗口表面的格式,我们将不使用标志。 此函数返回表面的副本,我们立即将其分配给
flower 。 为了发现错误,我们采用
SDL_GetError()函数,
因为我们已经在使用曲面,它们来自
SDL ,而不是来自
SDL_image 。
接下来,我们编写Quit函数,仅向其中添加一个函数。
退出 void quit() { SDL_FreeSurface(flower); SDL_FreeSurface(scr); SDL_DestroyWindow(win); SDL_Quit(); IMG_Quit(); }
我们添加了
IMG_Quit以
取消初始化SDL_image模块。
主要的
现在,最简单的事情仍然存在-
主要功能。
int main (int argc, char ** args) { if (!init()) { system("pause"); quit(); return 1; } if (!load()) { system("pause"); quit(); return 1; }
首先,请初始化并创建所需的所有内容,然后上传必要的文件。 我们不会在这里停止。
SDL_Rect bg_flower; bg_flower.w = SCREEN_WIDTH; bg_flower.h = SCREEN_HEIGHT; bg_flower.x = 0; bg_flower.y = 0;
之后,创建一个类
SDL_Rect的对象。 我们将需要它来拉伸图像。 如果您注意到,花朵图像比窗口大小小4倍(变薄2倍,变小2倍),我们需要将其拉伸到窗口大小。 因此,在矩形的宽度
bg_flower中,写入窗口宽度的值,并在高度中输入窗口的高度。 将坐标设置为0,以便图像显示在左上角。
要显示调整大小的图像,有一项特殊功能。 看起来像这样:
SDL_BlitScaled(flower, NULL, scr, &bg_flower);
它有4个含义。 第一个是我们要显示的图像,第二个是我们要从该图像切出的矩形(如果要拍摄整个图像,我们将其写为NULL),第三个是要在其上显示图像的表面,第四个是相同的矩形,尺寸以及我们用来拉伸或压缩并显示图像的坐标。
接下来,只需更新屏幕表面,设置延迟,退出并返回0。
SDL_UpdateWindowSurface(win); SDL_Delay(2000); quit(); return 0; };
这是我们程序结束的地方。 为了编译这个奇迹,您需要添加-lSDL2_image作为另一个编译选项。
至此,我们将今天结束。 这是我们得到的代码:
#include <SDL2/SDL.h> #include <SDL2/SDL_image.h> #include <iostream> const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; SDL_Window *win = NULL; SDL_Surface *scr = NULL; SDL_Surface *flower = NULL; bool init() { if (SDL_Init(SDL_INIT_VIDEO) != 0) { std::cout << "Can't init video: " << SDL_GetError() << std::endl; return false; } int flags = IMG_INIT_PNG; if ( !( IMG_Init( flags ) & flags ) ) { std::cout << "Can't init image: " << IMG_GetError() << std::endl; return false; } win = SDL_CreateWindow(" PNG", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); if (win == NULL) { std::cout << "Can't create window: " << SDL_GetError() << std::endl; return false; } scr = SDL_GetWindowSurface(win); return true; } bool load() { flower = IMG_Load("flower.png"); if (flower == NULL) { std::cout << "Can't load: " << IMG_GetError() << std::endl; return false; } flower = SDL_ConvertSurface(flower, scr->format, NULL); if (flower == NULL) { std::cout << "Can't convert: " << SDL_GetError() << std::endl; return false; } return true; } void quit() { SDL_FreeSurface(flower); SDL_FreeSurface(scr); SDL_DestroyWindow(win); SDL_Quit(); IMG_Quit(); } int main (int argc, char ** args) { if (!init()) { system("pause"); quit(); return 1; } if (!load()) { system("pause"); quit(); return 1; } SDL_Rect bg_flower; bg_flower.w = SCREEN_WIDTH; bg_flower.h = SCREEN_HEIGHT; bg_flower.x = 0; bg_flower.y = 0; SDL_BlitScaled(flower, NULL, scr, &bg_flower); SDL_UpdateWindowSurface(win); SDL_Delay(2000); quit(); return 0; };
再见!
<<上一课|| 下一课
>>