本篇介绍如何使用 SDL2
(
Simple DirectMedia 2
)库。
它是一个(相对)易于使用的库,可以在不依赖于特定于操作的功能的情况下添加多媒体功能。
步骤:
1.
初始化
sdl
2.
窗口
SDL_Window,
3.
表面
SDL_Surface,
4.
绘制
SDL_XXX
5.
退出(清理)
初始化
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();
// 创建一个窗口
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图片
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;
}
// 纹理与渲染
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;
}