您的位置:首页 > 编程语言 > C语言/C++

C++ SDL学习之路 2nd —— 第一个显示图片的SDL程序

2017-06-20 21:22 267 查看
哦哈哈,我这个初二的学生又来了,经常关注我博客的知道我在之前翻译了两篇外国的SDL教程,但是教程里面并没有给完整的代码,而且我给的外国原本的源代码也看不懂,所以这里我给大家详细讲一下。

SDL需要配置,具体的配置过程,请看 C++ SDL学习之路 1st ,这里我就不再教如何配置了。

大家请先把以下代码复制到已经配置SDL的项目的cpp中,这些代码中的注释是外国代码中我翻译过来的,并且添加了一些代码:

//使用SDL和标准IO
#include <SDL.h>
#include <stdio.h>

//屏幕尺寸常量
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;

//启动SDL并创建窗口
bool init();
//加载媒体
bool loadMedia();
//释放媒体并关闭SDL
void close();
//我们将要渲染的窗口
SDL_Window* gWindow = NULL;
//窗口所包含的表面
SDL_Surface* gScreenSurface = NULL;
//我们将在屏幕上加载和显示的图像
SDL_Surface* gHelloWorld = NULL;

bool init()
{
//初始化标志
bool success = true;
//初始化SDL
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
printf("SDL不能初始化! SDL错误: %s\n", SDL_GetError());
success = false;
}
else
{
//创建窗口
gWindow = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if (gWindow == NULL)
{
printf("不能创建窗口! SDL错误: %s\n", SDL_GetError());
success = false;
}
else
{
//获取窗口表面
gScreenSurface = SDL_GetWindowSurface(gWindow);
}
}
return success;
}

bool loadMedia()
{
//标志加载成功
bool success = true;
//负载启动图像
gHelloWorld = SDL_LoadBMP("02_getting_an_image_on_the_screen/hello_world.bmp");
if (gHelloWorld == NULL)
{
printf("无法加载图片 %s! SDL错误: %s\n", "02_getting_an_image_on_the_screen/hello_world.bmp", SDL_GetError());
success = false;
}
return success;
}

void close()
{
//释放表面
SDL_FreeSurface(gHelloWorld);
gHelloWorld = NULL;
//销毁窗口
SDL_DestroyWindow(gWindow);
gWindow = NULL;
//退出SDL子系统
SDL_Quit();
}

int main(int argc, char* args[])
{
//启动SDL并创建窗口
if (!init())
{
printf("初始化失败!\n");
}
else
{
//加载媒体
if (!loadMedia())
{
printf("未能加载媒体!\n");
}
else
{
//应用图像
SDL_BlitSurface(gHelloWorld, NULL, gScreenSurface, NULL);
//更新表面
SDL_UpdateWindowSurface(gWindow);
//等待2秒
SDL_Delay(2000);
}
}
//释放资源并关闭SDL
close();
//结束程序
return 0;
}


好,现在我给大家讲一下:

//屏幕尺寸常量
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;


这个也是十分明显了,这里定义了两个整型常量,分别是SDL窗口的宽(SCREEN_WIDTH)和高(SCREEN_HEIGHT)。

//启动SDL并创建窗口
bool init();
//加载媒体
bool loadMedia();
//释放媒体并关闭SDL
void close();


这个是创建了三个函数,会在后面用到的。

//我们将要渲染的窗口
SDL_Window* gWindow = NULL;
//窗口所包含的表面
SDL_Surface* gScreenSurface = NULL;
//我们将在屏幕上加载和显示的图像
SDL_Surface* gHelloWorld = NULL;


这里是定义了三个指针,都是SDL中的指针,这里的 表面 说实话我也不知道什么意思,但是我也就只能翻译成这个样子了。

这三个指针分别指向:

SDL_Window*:要渲染的窗口

SDL_Surface*:窗口所包含的表面

SDL_Surface*:在屏幕上加载和显示的图像

bool init()
{
//初始化标志
bool success = true;
//初始化SDL
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
printf("SDL不能初始化! SDL错误: %s\n", SDL_GetError());
success = false;
}
else
{
//创建窗口
gWindow = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if (gWindow == NULL)
{
printf("不能创建窗口! SDL错误: %s\n", SDL_GetError());
success = false;
}
else
{
//获取窗口表面
gScreenSurface = SDL_GetWindowSurface(gWindow);
}
}
return success;
}


这个函数是用来初始化SDL的,具体每行代码的意义我都在注释中写了。

这个函数是bool型的,是有返回值的,返回值的具体作用会在下面说主函数的时候讲。

例如一开始就让success是true(1,即“是”)

bool success = true;


然后如果gWindow指针指向空(即创建窗口失败),就会让success = false,即下面代码:

if (gWindow == NULL)
{
printf("不能创建窗口! SDL错误: %s\n", SDL_GetError());
success = false;
}


最后的时候又返回success。

return success;


好吧,这个init函数就讲完了,接下来是loadMedia(加载媒体,就是加载图像)函数:

bool loadMedia()
{
//标志加载成功
bool success = true;
//负载启动图像
gHelloWorld = SDL_LoadBMP("02_getting_an_image_on_the_screen/hello_world.bmp");
if (gHelloWorld == NULL)
{
printf("无法加载图片 %s! SDL错误: %s\n", "02_getting_an_image_on_the_screen/hello_world.bmp", SDL_GetError());
success = false;
}
return success;
}


这个跟上一个一样,末尾也是返回success,作用在主函数中体现,后面讲。

这里面有个 负载启动图像 ,说实话,我也不知道这是什么意思,但是其实很明显,gHelloWorld是整个代码一开头定义的一个指针,这里其实是指向一个文件位置。这里指向的是一个图片。

当然如果加载失败gHelloWorld就是指向空,然后就报错了,返回值也是false的了。

void close()
{
//释放表面
SDL_FreeSurface(gHelloWorld);
gHelloWorld = NULL;
//销毁窗口
SDL_DestroyWindow(gWindow);
gWindow = NULL;
//退出SDL子系统
SDL_Quit();
}


这是一个单纯的函数,就是把多行代码整合一下,用处就是关闭SDL窗口,不再多说了,这几行代码就算不理解也可以,这几行代码就是关闭SDL窗口的。

int main(int argc, char* args[])
{
//启动SDL并创建窗口
if (!init())
{
printf("初始化失败!\n");
}
else
{
//加载媒体
if (!loadMedia())
{
printf("未能加载媒体!\n");
}
else
{
//应用图像
SDL_BlitSurface(gHelloWorld, NULL, gScreenSurface, NULL);
//更新表面
SDL_UpdateWindowSurface(gWindow);
//等待2秒
SDL_Delay(2000);
}
}
//释放资源并关闭SDL
close();
//结束程序
return 0;
}


总算到主函数了,这里面一上来就是初始化SDL,其中一上来是

//启动SDL并创建窗口
if (!init())
{
printf("初始化失败!\n");
}


这四行代码就的意思是运行init(初始化)函数,如何返回值(success)是false,那么久报错,紧接如果是返回值是true:

else//如果init返回值不是false
{
//加载媒体
if (!loadMedia())//这里也是运行函数(loadMedia函数),然后判断返回值
{
printf("未能加载媒体!\n");//返回false就报错
}
else//如果返回值不是false
{
//应用图像
SDL_BlitSurface(gHelloWorld, NULL, gScreenSurface, NULL);
//更新表面
SDL_UpdateWindowSurface(gWindow);
//等待2秒
SDL_Delay(2000);//SDL特有的等待,就像Sleep一样
}
}


最后呢就关闭SDL,即:

//释放资源并关闭SDL
close();
//结束程序
return 0;


这就是主函数,是不是十分简单?(而且我都加注释了···)

这就是这个代码的解释了,接下来的编译后还要做以下工作:

1.下载下面的图片,并且命名为hello_world.bmp。

2.在编译生成的exe同文件夹中建立一个文件夹命名为 02_getting_an_image_on_the_screen

3.再把hello_world.bmp放到这个 02_getting_an_image_on_the_screen 文件夹中

4.测试请运行exe,直接编译时是无法加载图片的

5.针对4,如果你的IDE是VS,那么可以把这个 02_getting_an_image_on_the_screen 文件夹(和里面的图片)放到cpp的同文件夹,就可以在编译的时候也加载图片了。



OK,这样运行一下,成功的样子是这样滴:



那么好吧,C++ SDL学习之路 2nd 就结束了,别急着等3rd,毕竟我快期末考试了,而且下一篇是2nd的扩展:SDL中的双缓冲讲解!!!

去睡觉去。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++ sdl教程 sdl2 sdl