SDL系列(二)—— 渲染窗口与BMP图片

本篇介绍如何使用 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;
}

  • 23
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值