• SDL 开发实战(二):SDL 2.0 核心 API 解析


    在上一篇文章 SDL 开发实战(一):SDL介绍及开发环境配置 中,我们配置好了SDL的开发环境,并成功运行了SDL的Hello World 代码。但是可能大部分人还是读不太明白具体Hello Wold的代码的意义。下面我们来根据SDL的使用思路来讲解一下SDL核心API,各位可以将此文结合上一篇文章,我们写的HelloWorld代码进行理解和思考。

    基本的SDL的使用思路,基本分为三部分:初始化 ---> 循环渲染 ---> 销毁释放资源。

    SDL 初始化相关方法 :

    • SDL_Init(): 初始化SDL
    • SDL_CreateWindow(): 创建窗口(Window)
    • SDL_CreateRenderer(): 基于窗口创建渲染器(Render)
    • SDL_CreateTexture(): 创建纹理(Texture)

    SDL 渲染数据相关方法:

    • SDL_UpdateTexture(): 设置纹理的数据。 
    • SDL_RenderCopy(): 纹理复制给渲染器。 
    • SDL_RenderPresent(): 显示。

    SDL 销毁释放资源相关方法:

    • SDL_DestroyTexture(tex) : 释放纹理资源
    • SDL_DestroyRenderer(ren) : 释放渲染器
    • SDL_DestroyWindow(win)  :  释放窗口 
    • SDL_Quit() :  关闭所有SDL子系统

    下面我们就按照这个顺序对核心的API进行讲解。

    一、初始化函数 SDL_Init() 

    该初始化函数可以确定希望激活的子系统。函数原型如下:

    int SDLCALL SDL_Init(Uint32 flags)

    其中Uint32 flags参数为要启动的子系统的flag值,具体可以传入的内容如下:

    • SDL_INIT_TIMER:定时器
    • SDL_INIT_AUDIO:音频
    • SDL_INIT_VIDEO:视频
    • SDL_INIT_JOYSTICK:摇杆
    • SDL_INIT_HAPTIC:触摸屏
    • SDL_INIT_GAMECONTROLLER:游戏控制器
    • SDL_INIT_EVENTS:事件
    • SDL_INIT_NOPARACHUTE:不捕获关键信号(这个不理解)
    • SDL_INIT_EVERYTHING:包含上述所有选项

    SDL_Init() 的实现位于SDL.c中。定义如下:

    int SDL_Init(Uint32 flags)  {
        return SDL_InitSubSystem(flags);
    }

    调用的代码只有这一句,但是我们能很清楚的了解到,SDL_Init(Uint32 flags)所做的操作就是启动SDL系统下指定的子系统。再结合我们上面的Hello World代码,我们可以知道,我们要初始化的是Video子系统。

    二、创建窗口 SDL_CreateWindow()

    SDL_Window结构体定义了一个SDL2中的窗口。而SDL_CreateWindow()方法就是用于创建一个窗口。函数的原型如下:

    SDL_Window * SDLCALL SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags);

    下面解释一下各个参数的含义:

    • title :窗口标题
    • x :窗口位置x坐标。也可以设置为SDL_WINDOWPOS_CENTERED或SDL_WINDOWPOS_UNDEFINED。
    • y :窗口位置y坐标。同上。
    • w :窗口的宽
    • h :窗口的高
    • flags :支持窗口的状态属性的标识。包括了窗口的是否最大化、最小化,能否调整边界等等属性。

     返回创建完成的窗口的ID。如果创建失败则返回0。

    结合我们Hello World代码,可以知道,我们要展示的窗口的标题为 “Hello World”,窗口的坐标为x = 100, y = 100, 窗口的宽度为640,高度为480,窗口的状态属性为SDL_WINDOW_SHOWN,即展示窗口。

    三、创建渲染器 SDL_CreateRenderer()

    SDL中使用SDL_CreateRenderer()基于窗口创建渲染器。SDL_CreateRenderer()函数的原型如下:

    SDL_Renderer * SDLCALL SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags);

    下面解释一下各个参数的含义:

    • window : 渲染的目标窗口。
    • index :打算初始化的渲染设备的索引。设置“-1”则初始化默认的渲染设备。
    • flags :支持以下值(位于SDL_RendererFlags定义中)SDL_RENDERER_SOFTWARE -> 使用软件渲染;SDL_RENDERER_ACCELERATED -> 使用硬件加速;SDL_RENDERER_PRESENTVSYNC -> 和显示器的刷新率同步

    返回创建完成的渲染器的ID。如果创建失败则返回NULL。

    结合我们的HelloWorld代码,可以知道,我们要渲染的目标窗口是第二节我们创建的窗口,索引值为默认的渲染设备,设置的渲染属性为 “使用硬件加速 + 和选时期的刷新率同步”。

    四、创建纹理 SDL_CreateTexture()

    SDL使用SDL_CreateTexture()基于渲染器创建纹理。SDL_CreateTexture()函数的原型如下:

    SDL_Texture * SDLCALL SDL_CreateTexture(SDL_Renderer * renderer, Uint32 format, int access, int w, int h);

    下面解释一下各个参数的含义:

    • renderer:目标渲染器。
    • format :纹理的格式。后面会详述。
    • access :可以取以下值(定义位于SDL_TextureAccess中) SDL_TEXTUREACCESS_STATIC -> 变化极少 ;  SDL_TEXTUREACCESS_STREAMING :变化频繁;
    • w :纹理的宽
    • h :纹理的高

    这个函数创建成功则返回纹理的ID,失败返回0。

    五、更新纹理 SDL_UpdateTexture()

    SDL使用SDL_UpdateTexture()更新纹理的像素数据。SDL_UpdateTexture()函数的原型如下:

    int SDLCALL SDL_UpdateTexture(SDL_Texture * texture, const SDL_Rect * rect, const void *pixels, int pitch);

    下面解释一下各个参数的含义:

    • texture:目标纹理。
    • rect:更新像素的矩形区域。设置为NULL的时候更新整个区域。
    • pixels:像素数据。
    • pitch:一行像素数据的字节数。

    这个函数更新纹理成功的话返回0,失败的话返回-1。

    六、复制纹理到渲染目标 SDL_RenderCopy()

    SDL使用SDL_RenderCopy()将纹理数据复制给渲染目标。SDL_RenderCopy()函数的原型如下:

    int SDLCALL SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_Rect * dstrect);

    下面解释一下各个参数的含义:

    • renderer:渲染目标。
    • texture:输入纹理。
    • srcrect:选择输入纹理的一块矩形区域作为输入。设置为NULL的时候整个纹理作为输入。
    • dstrect:选择渲染目标的一块矩形区域作为输出。设置为NULL的时候整个渲染目标作为输出。

    这个函数执行成功的话返回0,失败的话返回-1。

    七、显示画面 SDL_RenderPresent()

    SDL使用SDL_RenderPresent()显示画面。SDL_RenderPresent()函数的原型如下:

    void SDLCALL SDL_RenderPresent(SDL_Renderer * renderer);

    其中参数 renderer 用于指定渲染器。

    八、SDL 核心 API 使用流程

    介绍完了SDL的核心API,将这些API串联调用的流程步骤如下:

    1. 初始化:SDL_Init()
    2. 创建SDL_Window:SDL_CreateWindow()
    3. 创建SDL_Render:SDL_CreateRenderer()
    4. 创建SDL_Texture:SDL_CreateTexture()
    5. 更新SDL_Texture:SDL_UpdateTexture()
    6. 渲染SDL_Texture:SDL_RenderCopy()
    7. 显示:SDL_RenderPresent()
    8. 返回步骤4继续执行 
  • 相关阅读:
    基于 Javassist 和 Javaagent 实现动态切面
    基于SpringBoot搭建应用开发框架(二) —— 登录认证
    服务器集成环境搭建
    多租户个性化服务路由
    基于SpringBoot搭建应用开发框架(一) —— 基础架构
    Redis 学习(三) —— 事务、消息发布订阅
    Redis 学习(二) —— 数据类型及操作
    Redis 学习(一) —— 安装、通用key操作命令
    用FastDFS一步步搭建文件管理系统
    在Intellij IDEA中使用Debug
  • 原文地址:https://www.cnblogs.com/renhui/p/10455017.html
Copyright © 2020-2023  润新知