本节介绍如何使用SDL2(Simple DirectMedia 2)库。它是一个(相对)易于使用的库,可以在不依赖于特定于操作的功能的情况下添加多媒体功能。
SDL提供的内容:
SDL有扩展,提供更多功能 - 网络,更好的音频系统,图像加载等。
在本节中,我将引用SDL提供的许多功能。这些课程的目的是教你如何使用SDL的功能,而不是参数的细节等。因此,每个对SDL对象的引用都将包含指向其SDL文档页面的链接。如果您对函数的参数,返回类型,副作用或结构成员等有疑问,请阅读文档。这将是一个非常宝贵的资源。
文档提示:
使用SDL函数或对象时,您必须(当然)包含其头文件。文件SDL.h将自动包含其他所有内容 - 通常这就是您需要的全部内容。但是,许多函数都是在特定文件中进行原型化。如果您不确定需要包含哪些内容,请查看文档。
此外,如果正确设置编译器,则应该能够使用尖括号(例如#include
在做任何其他事情之前,您必须将SDL整体初始化。正如您所料,SDL_Init()就是这样做的。如果要初始化SDL的所有部分,请传递SDL_INIT_EVERYTHING。
SDL还允许您单独初始化库的特定子集(或子系统)。要指定,请指定SDL_Init()的标志,或使用SDL_InitSubSystem()。如果您计划单独初始化子系统,只需将0传递给SDL_Init()。
SDL_Init( SDL_INIT_EVERYTHING )
您必须创建程序将用于多媒体输入和输出的窗口。从头开始创建Windows应用程序时,必须定义“WinMain”,调用操作系统来获取句柄,创建窗口等等.SDL提供了一个更简单,与平台无关的窗口API。
为了管理窗口,SDL方便地提供结构SDL_Window和SDL_CreateWindow()等功能。
略微切线:您可能会注意到SDL_Window没有文档链接。这是因为结构不透明; 你的程序无法看到“SDL_Window”中实际包含的内容。您只需管理指向SDL_Window的指针即可。
SDL_CreateWindow()执行您期望的操作:它接受指定窗口的名称,大小,位置和选项的参数,并返回指向新SDL_Window结构的指针。有关详细信息,请参阅SDL文档。
SDL_Window *window;
window = SDL_CreateWindow( "窗口名称", 100, 100, 1280, 720, SDL_WINDOW_SHOWN );
大多数SDL函数将在失败时返回特定值。对于返回指针的函数,此值为NULL。因此,您可以轻松检查操作是否成功。
发生任何错误后,函数SDL_GetError()允许您检索描述错误的字符串。
if ( !window ) {
cout << "Error creating window: " << SDL_GetError() << endl;
return 1;
}
创建窗口后,您需要一种绘制方法。SDL将您可以绘制的任何区域(包括加载的图像)抽象为“表面”。(这是为了软件渲染 - 在未来,我们将进入GPU渲染,它不使用表面。)
结构SDL_Surface和诸如SDL_LoadBMP()和SDL_GetWindowSurface()之类的函数提供软件渲染(也称为blitting)API。
正如您所期望的那样,使用SDL_GetWindowSurface()来获取窗口的表面。绘制到此表面后,可以通过调用SDL_UpdateWindowSurface()在窗口中看到结果。
SDL_Surface* winSurface = SDL_GetWindowSurface( window );
// 做绘画
SDL_UpdateWindowSurface( win );
要测试窗口表面是否正常工作,可以用颜色填充它。一个非常简单的方法是使用SDL_FillRect()。要填充整个窗口,只需传递NULL而不是SDL_Rect指针。此外,SDL_FillRect()采用表示颜色的特定格式编号。要获得此格式的颜色,可以使用曲面格式和所需的RGB值调用SDL_MapRGB。
SDL_FillRect( winSurface, NULL, SDL_MapRGB( winSurface->format, 255, 90, 120 ));
一旦程序完成其操作,它必须销毁窗口并释放相关资源。正如您所料,SDL_DestroyWindow()就是这么做的。该功能将关闭窗口,释放相关内存(包括窗口表面)。
SDL_DestroyWindow( window ); win = NULL; winSurface = NULL;
最后,要关闭SDL作为一个整体,请调用SDL_Quit()。这是非常明确的。
SDL_Quit();
代码如下:
#include
#include
// You shouldn't really use this statement, but it's fine for small programs
using namespace std;
// You must include the command line parameters for your main function to be recognized by SDL
int main(int argc, char* args[]) {
// Pointers to our window and surface
SDL_Surface* winSurface = NULL;
SDL_Window* window = NULL;
// Initialize SDL. SDL_Init will return -1 if it fails.
if ( SDL_Init( SDL_INIT_EVERYTHING ) < 0 ) {
cout << "Error initializing SDL: " << SDL_GetError() << endl;
return 1;
}
// Create our window
window = SDL_CreateWindow( "Example", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1280, 720, SDL_WINDOW_SHOWN );
// Make sure creating the window succeeded
if ( !window ) {
cout << "Error creating window: " << SDL_GetError() << endl;
return 1;
}
// Get the surface from the window
winSurface = SDL_GetWindowSurface( window );
// Make sure getting the surface succeeded
if ( !winSurface ) {
cout << "Error getting surface: " << SDL_GetError() << endl;
return 1;
}
// Fill the window with a white rectangle
SDL_FillRect( winSurface, NULL, SDL_MapRGB( winSurface->format, 255, 255, 255 ) );
// Update the window display
SDL_UpdateWindowSurface( window );
//Delay 3s
SDL_Delay(3000);
// Destroy the window. This will also destroy the surface
SDL_DestroyWindow( window );
// Quit SDL
SDL_Quit();
// End the program
return 0;
}
修改Makefile
make编译
结果,显示白色窗口3秒后退出。