这里我们使用到了SDL的扩展库sdl_image,只需要注意五点即可。
需要加载头文件
#include
初始化
int imgFlags = IMG_INIT_PNG;
if( !( IMG_Init( imgFlags ) & imgFlags ) )
{
printf( "SDL_image could not initialize! SDL_image Error: %s\n", IMG_GetError() );
}
加载图片
入参是文件路径,返回SDL_Surface指针。SDL_Surface数据类型,可以理解为存储的在内存中的2D的图像数据。
SDL_Surface* loadedSurface = IMG_Load( path );
请不要忘记使用SDL_FreeSurface,释放SDL_Surface指针,
SDL_FreeSurface(loadedSurface);
关闭IMG
IMG_Quit();
至此,图片加载就算是完成了。
非硬件加速大体的绘制流程如下:
定义窗口宽度高度都为400。使用全局的宏变量并不是一个良好的编程习惯,不过好在我们这个例子很简单,我这里把它声明为全局变量。
const int WIDTH = 400;
const int HEIGHT = 400;
因为要绘制视频,这里我们初始化时,使用SDL_INIT_VIDEO类型。
//Initialize SDL
if( SDL_Init( SDL_INIT_VIDEO ) != 0 )
{
printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );
}
接下来,我们通过SDL_CreateWindow获得了SDL_Window类型的变量window。SDL_Window可以理解为我们可见的窗口。
SDL_Window* window = SDL_CreateWindow( "SDL", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, SDL_WINDOW_SHOWN );
有了窗口以后,我们就需要获取窗口表面,才能在其上进行绘制,并改变我们看到的窗口。
通过SDL_GetWindowSurface获得了当前屏幕的SDL_Surface类型的变量screenSurface。
SDL_Surface* screenSurface = SDL_GetWindowSurface( window );
使用SDL_FillRect将screenSurface填充为白色(R:0xFF, G:0xFF, B:0xFF)。
//Fill the surface white
SDL_FillRect( screenSurface, NULL, SDL_MapRGB( screenSurface->format, 0xFF, 0x00, 0x00 ) );
在这个动作之后,还记得我们使用IMG_Load,加载图片生成的SDL_Surface* loadedSurface吗?我们需要将这个SDL_Surface数据渲染到screenSurface上。这里使用SDL_BlitSurface()函数。
SDL_BlitSurface(loadedSurface, NULL, screenSurface, NULL);
调用SDL_UpdateWindowSurface进行更新,否则窗口并不会立刻显示。
//Update the surface
SDL_UpdateWindowSurface( window );
给出完整代码如下:
#include
#include
#include
const int WIDTH = 400;
const int HEIGHT = 400;
const char* path = "test.png";
int main(int argc, char* argv[])
{
//Initialize SDL
if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
{
printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );
}
//Init IMG
int imgFlags = IMG_INIT_PNG;
if( !( IMG_Init( imgFlags ) & imgFlags ) )
{
printf( "SDL_image could not initialize! SDL_image Error: %s\n", IMG_GetError() );
}
SDL_Surface* loadedSurface = IMG_Load(path);
SDL_Window* window = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, SDL_WINDOW_SHOWN );
if( window == NULL )
{
printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() );
}else{
SDL_Surface* screenSurface = SDL_GetWindowSurface( window );
SDL_Event test_event;
int isQuit = 0;
while (!isQuit) {
SDL_PollEvent(&test_event);
switch (test_event.type) {
case SDL_QUIT:
isQuit = 1;
printf("We got a quit event.\n");
break;
default:
break;
}
//Fill the surface white
SDL_FillRect( screenSurface, NULL, SDL_MapRGB( screenSurface->format, 0xFF, 0x00, 0x00 ) );
SDL_BlitSurface(loadedSurface, NULL, screenSurface, NULL);
//Update the surface
SDL_UpdateWindowSurface( window );
}
}
SDL_FreeSurface(loadedSurface);
SDL_DestroyWindow( window );
IMG_Quit();
SDL_Quit();
return 0;
}
编译:
gcc sdl_show.c `pkg-config --cflags --libs sdl2 sdl2_image` -o sdl_show
运行:
./sdl_show
输出:一个窗口,显示我们加载的图片,需要注意的是,图片没有经过缩放,和窗口不匹配。点击左上角x,程序退出,日志输出:
We got a quit event.
[1]. Introduction to SDL 2.0
[2]. Beginning Game Programming v2.0
[3]. SDL介绍
[4]. SDL_image Documentation