本篇介绍如何使用 SDL2 ( Simple DirectMedia 2 )库。
它是一个(相对)易于使用的库,可以在不依赖于特定于操作的功能的情况下添加多媒体功能。
步骤:
- 初始化 sdl
2. 窗口 SDL_Window,
3. 表面 SDL_Surface,
4. 绘制 SDL_XXX - 退出(清理)
初始化 SDL
在做任何其他事情之前,您必须将 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();
// 创建一个窗口
cpp
int main_CreateWindow() {
// Pointers to our window and surface
/// 1.原理流程架构
/// 2.数据结构+API
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-Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 360, 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, 0, 0));
// 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;
}
// 显示BMP图片
cpp
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
int main_ShowBMPImage()
{
//The window we'll be rendering to
SDL_Window* gWindow = NULL;
//The surface contained by the window
SDL_Surface* gScreenSurface = NULL;
//The image we will load and show on the screen
SDL_Surface* gHelloWorld = NULL;
//首先初始化 初始化SD视频子系统
if (SDL_Init(SDL_INIT_VIDEO)<0)
{
printf("Window could not be created! SDL_Error: %s\n", SDL_GetError());
return false;
}
//创建窗口
gWindow = SDL_CreateWindow("SHOW BMP",//窗口标题
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());
return false;
}
//Use this function to get the SDL surface associated with the window.
//获取窗口对应的surface
gScreenSurface = SDL_GetWindowSurface(gWindow);
//加载图片
gHelloWorld = SDL_LoadBMP("./images/Hello_World.bmp");//加载图片
if (gHelloWorld == NULL)
{
printf("Unable to load image %s! SDL Error: %s\n", "Hello_World.bmp", SDL_GetError());
return false;
}
//Use this function to perform a fast surface copy to a destination surface.
//surface的快速复制
//下面函数的参数分别为: SDL_Surface* src ,const SDL_Rect* srcrect , SDL_Surface* dst , SDL_Rect* dstrect
SDL_BlitSurface(gHelloWorld, NULL, gScreenSurface, NULL);
SDL_UpdateWindowSurface(gWindow);//更新显示copy the window surface to the screen
SDL_Delay(2000);//延时2000毫秒,2s后自动关闭
//释放内存
SDL_FreeSurface(gHelloWorld);//释放空间
gHelloWorld = NULL;
SDL_DestroyWindow(gWindow);//销毁窗口
gWindow = NULL;
SDL_Quit();//退出SDL
return 0;
}
// 纹理与渲染
cpp
int main_Render_Texture_demo()
{
SDL_Window *window;
SDL_Renderer *renderer;
SDL_Texture *texture;
SDL_Event event;
SDL_Rect r;
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s", SDL_GetError());
return 3;
}
window = SDL_CreateWindow("SDL_CreateTexture",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
1024, 768,
SDL_WINDOW_RESIZABLE);
r.w = 100;
r.h = 100;
/// render---->window
renderer = SDL_CreateRenderer(window, -1, 0);
/// texture-->render
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, 1024, 768);
// 跳来跳去的方块
while (1) {
SDL_PollEvent(&event);
if (event.type == SDL_QUIT)
break;
r.x = rand() % 500;
r.y = rand() % 500;
SDL_SetRenderTarget(renderer, texture);
SDL_SetRenderDrawColor(renderer, 0x88, 0x88, 0x88, 0x00);
/// 将上一次render中的内容清空
SDL_RenderClear(renderer);
SDL_RenderDrawRect(renderer, &r);
SDL_SetRenderDrawColor(renderer, 0x00, 0xFF, 0x00, 0x00);
SDL_RenderFillRect(renderer, &r);
SDL_SetRenderTarget(renderer, NULL);
/// core: 复制内容
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
SDL_Delay(1000);
}
/// 清理、释放
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}