SDL入门教程——(一)Hello World

本文详细介绍了SDL库的基础使用,包括初始化、创建窗口、显示图片等关键步骤,并对比了SDL1.2与SDL2的不同之处,适合初学者快速入门。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SDL入门

其实像SDL、FFMPEG、Opencv 我都是从入门到放弃,我不知道入了几次门了都,用的时候就Google,用完就忘,每次都需要重新搜索关键字。所以后面我的学习过程我都要记录一下,包括我看别人的文章我也要记录下来,有时候记得在哪里看过就是找不到然后就是想用就是不会简直是一个while(true),废话不多说,开始SDL的入门记录吧。

Hello World

配置链接库什么的我就不写了,因为无数遍重复已经死死记住了。直接上代码,我参考了bilibili的一个Up主的视频1

#include <iostream>
#include "SDL2/include/SDL.h"

const int screen_width = 800;
const int screen_height = 600;
int main(int, char**)
{
	SDL_Init(SDL_INIT_VIDEO);
    SDL_Window *window = SDL_CreateWindow("YourGame", 
    									  SDL_WINDOWPOS_UNDEFINED, 
    									  SDL_WINDOWPOS_UNDEFINED, 
    									  screen_width, screen_height, 
    									  SDL_WINDOW_SHOWN);
    SDL_Surface *surface = SDL_GetWindowSurface(window);
    SDL_Surface* blackground_surface = SDL_LoadBMP("Hello.bmp");
    SDL_BlitSurface(blackground_surface, NULL, surface, NULL);
    SDL_UpdateWindowSurface(window);
    SDL_Delay(3000);
    SDL_DestroyWindow(window);
    SDL_Quit();
    return 0;
}

因为SDL输出文字是需要扩展功能,SDL本身是没有设计文字的功能,所以Hello World就先输出图片吧。后面我用到字体时我再补充吧。有兴趣的可以参考:SDL显示图像和文字2

上面代码可以看出几点:

  1. SDL初始化和SDL退出:
    SDL_Init(SDL_INIT_VIDEO);
    
    SDL_Quit();
    
  2. 创建Window和销毁窗口:
    SDL_Window *window = SDL_CreateWindow("YourGame", 
    									  SDL_WINDOWPOS_UNDEFINED, 
    									  SDL_WINDOWPOS_UNDEFINED, 
    									  screen_width, screen_height, 
    									  SDL_WINDOW_SHOWN);
    
    SDL_DestroyWindow(window);
    
  3. 让窗口显示图片:
    SDL_Surface *surface = SDL_GetWindowSurface(window);
    SDL_Surface* blackground_surface = SDL_LoadBMP("Hello.bmp");
    SDL_BlitSurface(blackground_surface, NULL, surface, NULL);
    SDL_UpdateWindowSurface(window)
    
  4. 让窗口停留3秒:SDL_Delay(3000);
各个函数参数的意义3 (在左侧搜索框输入自己要搜索的函数,入门可以跳过这段):

在这里插入图片描述
初始化函数SDL_Init参数的意义: (initialize the SDL library)

ValueDescription
SDL_INIT_TIMERtimer subsystem
SDL_INIT_AUDIOaudio subsystem
SDL_INIT_VIDEOvideo subsystem; automatically initializes the events subsystem
SDL_INIT_JOYSTICKjoystick subsystem; automatically initializes the events subsystem
SDL_INIT_HAPTIChaptic (force feedback) subsystem
SDL_INIT_GAMECONTROLLERcontroller subsystem; automatically initializes the joystick subsystem
SDL_INIT_EVENTSevents subsystem
SDL_INIT_EVERYTHINGall of the above subsystems
SDL_INIT_NOPARACHUTEcompatibility; this flag is ignored

创建函数SDL_CreateWindow参数的意义: (create a window)

ParameterDescription
titlethe title of the window, in UTF-8 encoding
xthe x position of the window, SDL_WINDOWPOS_CENTERED, or SDL_WINDOWPOS_UNDEFINED
ythe y position of the window, SDL_WINDOWPOS_CENTERED, or SDL_WINDOWPOS_UNDEFINED
wthe width of the window, in screen coordinates
hthe height of the window, in screen coordinates
flags0, or one or more SDL_WindowFlags OR’d together; see Remarks for details
Value of flagsDescription
SDL_WINDOW_FULLSCREENfullscreen window
SDL_WINDOW_FULLSCREEN_DESKTOPfullscreen window at the current desktop resolution
SDL_WINDOW_OPENGLwindow usable with OpenGL context
SDL_WINDOW_VULKANwindow usable with a Vulkan instance
SDL_WINDOW_HIDDENwindow is not visible
SDL_WINDOW_BORDERLESSno window decoration
SDL_WINDOW_RESIZABLEwindow can be resized
SDL_WINDOW_MINIMIZEDwindow is minimized
SDL_WINDOW_MAXIMIZEDwindow is maximized
SDL_WINDOW_INPUT_GRABBEDwindow has grabbed input focus
SDL_WINDOW_ALLOW_HIGHDPIwindow should be created in high-DPI mode if supported (>= SDL 2.0.1)

拷贝绘制函数SDL_BlitSurface参数的意义: (copy surface to destination surface)

ParameterDescription
srcthe SDL_Surface structure to be copied from
srcrectthe SDL_Rect structure representing the rectangle to be copied, or NULL to copy the entire surface
dstthe SDL_Surface structure that is the blit target
dstrectthe SDL_Rect structure representing the rectangle that is copied into

SDL 官方的 Hello world4

if (SDL_Init(SDL_INIT_VIDEO) != 0){
	std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl;
	return 1;
}
SDL_Window *win = SDL_CreateWindow("Hello World!", 100, 100, 640, 480, SDL_WINDOW_SHOWN);
if (win == nullptr){
	std::cout << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
	SDL_Quit();
	return 1;
}
SDL_Renderer *ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (ren == nullptr){
	SDL_DestroyWindow(win);
	std::cout << "SDL_CreateRenderer Error: " << SDL_GetError() << std::endl;
	SDL_Quit();
	return 1;
}
std::string imagePath = getResourcePath("Lesson1") + "hello.bmp";
SDL_Surface *bmp = SDL_LoadBMP(imagePath.c_str());
if (bmp == nullptr){
	SDL_DestroyRenderer(ren);
	SDL_DestroyWindow(win);
	std::cout << "SDL_LoadBMP Error: " << SDL_GetError() << std::endl;
	SDL_Quit();
	return 1;
}
SDL_Texture *tex = SDL_CreateTextureFromSurface(ren, bmp);
SDL_FreeSurface(bmp);
if (tex == nullptr){
	SDL_DestroyRenderer(ren);
	SDL_DestroyWindow(win);
	std::cout << "SDL_CreateTextureFromSurface Error: " << SDL_GetError() << std::endl;
	SDL_Quit();
	return 1;
}
//A sleepy rendering loop, wait for 3 seconds and render and present the screen each time
for (int i = 0; i < 3; ++i){
	//First clear the renderer
	SDL_RenderClear(ren);
	//Draw the texture
	SDL_RenderCopy(ren, tex, NULL, NULL);
	//Update the screen
	SDL_RenderPresent(ren);
	//Take a quick break after all that hard work
	SDL_Delay(1000);
}
SDL_DestroyTexture(tex);
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
SDL_Quit();

官方的Hello world中和我参考Bilibili Up主的Hello world 有很多不一样的地方,主要突出在错误判断和SDL2和SDL1.2的函数调用。Renderer、Texture 是SDL2新引入的方法,这个在Bilibili Up主后面的视频中也有提到。鉴于本篇文章主题为SDL Hello World,我意在将Hello world 写完整,让其他人入手时可以分清楚你参考的文章是使用的SDL2还是SDL1.2。

关于错误判断的写法风格,我个人觉得这类写法偏向C的风格,这里没有批评与鼓励这种方式,我认为这类写法可以视学习阶段,和开发程度来自己把控这个,学习阶段我不建议过分的进行错误判断,主要目的是以程序跑通可用为主,小型项目也不应该过分关注错误判断,只有在大一点的项目中可以使用这种方式来进行安全检查,毕竟当If分支增多时,进行Code coverage会导致整个coverage下降,到时想提高可不是一件容易的事情。

SDL2 Hello world 中新语法:

  1. 使用Renderer 来绑定 Window 进行渲染:
    SDL_Renderer *ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    SDL_DestroyRenderer(ren);
    
  2. 用Texture来使Surface对Renderer 进行纹理表述:
    SDL_Surface *bmp = SDL_LoadBMP(imagePath.c_str());
    SDL_Texture *tex = SDL_CreateTextureFromSurface(ren, bmp);
    SDL_FreeSurface(bmp);
    
  3. 对Renderer进行Copy以及显示:
    SDL_RenderClear(ren);
    SDL_RenderCopy(ren, tex, NULL, NULL);
    SDL_RenderPresent(ren);
    

创建函数SDL_CreateRenderer参数的意义: (create a texture from an existing surface)

ParameterDescription
windowthe window where rendering is displayed
indexthe index of the rendering driver to initialize, or -1 to initialize the first one supporting the requested flags
flags0, or one or more SDL_RendererFlags OR’d together; see Remarks for details
Value of flagsDescription
SDL_RENDERER_SOFTWAREthe renderer is a software fallback
SDL_RENDERER_ACCELERATEDthe renderer uses hardware acceleration
SDL_RENDERER_PRESENTVSYNCpresent is synchronized with the refresh rate
SDL_RENDERER_TARGETTEXTUREthe renderer supports rendering to texture

创建函数SDL_CreateTextureFromSurface参数的意义: (create a texture from an existing surface)

ParameterDescription
rendererthe rendering context
surfacethe SDL_Surface structure containing pixel data used to fill the texture

在看SDL_CreateTextureFromSurface函数的官方文档时,看到官方的例子里使用SDL_CreateRGBSurface创建surface,所以我再列举一下Surface的创建方法:

Function NameDescription
SDL_ConvertSurfacecopy an existing surface into a new one that is optimized for blitting to a surface of a specified pixel format.
SDL_ConvertSurfaceFormatcopy an existing surface to a new surface of the specified format.
SDL_CreateRGBSurfaceallocate a new RGB surface.
SDL_CreateRGBSurfaceFromallocate a new RGB surface with existing pixel data.
SDL_CreateRGBSurfaceWithFormatallocate an RGB surface.
SDL_GetWindowSurfaceget the SDL surface associated with the window.
SDL_LoadBMPload a surface from a BMP file.
SDL_LoadBMP_RWload a BMP image from a seekable SDL data stream (memory or file).

上面的方法主要集中在SDL_video.hSDL_surface.h两个文件中,其中我加粗部分函数需要与函数SDL_FreeSurface成对出现。


  1. [正月点灯笼] SDL图形编程入门 :https://space.bilibili.com/24014925/channel/detail?cid=12629 ↩︎

  2. [skywalker_leo] SDL显示图像和文字 :https://blog.csdn.net/skywalker_leo/article/details/42776377 ↩︎

  3. [SDL官方文档] :https://wiki.libsdl.org ↩︎

  4. [SDL官方教程] :https://www.willusher.io/sdl2%20tutorials/2013/08/17/lesson-1-hello-world ↩︎

SDL是Simple DirectMedia Layer(简易直控媒体层)的缩写。它是个跨平台的多媒体库,以用于直接控制底层的多媒体硬件的接口。这些多媒体功能包括了音频、键盘和鼠标(事件)、游戏摇杆等。当然,最为重要的是提供了2D图形帧缓冲(framebuffer)的接口,以及为OpenGL与各种操作系统之间提供了统的标准接口以实现3D图形。从这些属性我们可以看出,SDL基本上可以认为是为以电脑游戏为核心开发的多媒体库。 SDL支持主流的操作系统,包括Windows和Linux。在官方的介绍中,我们可以找到它所支持的其他平台。(SDL supports Linux, Windows, Windows CE, BeOS, MacOS, Mac OS X, FreeBSD, NetBSD, OpenBSD, BSD/OS, Solaris, IRIX, and QNX. )。SDL本身从C语言开发,并且能很好的在C++等高级语言中使用。在官方可以看到SDL所支持的语言很多。(Including Ada, C#, Eiffel, Erlang, Euphoria, Guile, Haskell, Java, Lisp, Lua, ML, Objective C, Pascal, Perl, PHP, Pike, Pliant, Python, Ruby, Smalltalk, and Tcl. ) SDL在GNU LGPL version 2下发布,这意味着你可以免费的使用。并且可以免费的用于商业软件的制作(只要你直接使用SDL的动态链接库,Windows下的SDL.dll)。如果你将SDL库编译进了自己的二进制代码中,你需要指明你所使用的SDL库的版本以及包括你自己修改的源代码,并说明这些代码的原始出处。这是很宽松的法律,你可以用如此强大的多媒体库完全合法的免费开发商业游戏。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值