在上一篇文章 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继续执行

SDL 开发实战(二):SDL 2.0 核心 API 解析的更多相关文章

  1. SDL 开发实战(三):使用 SDL 绘制基本图形

    在上文 SDL 开发实战(二):SDL 2.0 核心 API 解析 我们讲解了SDL最核心的API,并结合Hello World代码了解了SDL渲染画面的基本原理. 本文我们来讲一下,如何使用SDL的 ...

  2. SDL 开发实战(一):SDL介绍及开发环境配置

    一.什么是SDL? SDL是 “Simple DirectMedia Layer”的缩写,SDL是一个开源的跨平台的多媒体库,封装了复杂的音视频底层操作,简化了音视频处理的难度. SDL使用C语言写成 ...

  3. SDL开发笔记(二):音频基础介绍、使用SDL播放音频

    若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...

  4. SDL 开发实战(五): SDL 纹理渲染

    本文我们讲一下如何使用SDL_Texture将视频纹理渲染出来. 1. SDL 视频渲染相关对象 SDL 视频渲染主要涉及到四个对象:SDL_Window.SDL_Render.SDL_Texture ...

  5. SDL 开发实战(七): SDL 多线程与锁机制

    为什么要用多线程?在音视频领域主要是实现音视频同步.实现了音视频同步,我们的播放器就基本上合格了. 这里我们将讲解一下SDL的多线程与锁机制. 多线程的好处主要是能使程序更加充分利用硬件(主要是CPU ...

  6. SDL 开发实战(四): SDL 事件处理

    在前面学习SDL的例子运行时,我们发现我们的窗口只停留了几秒,但是如果设置更长时间显然也有其他的弊端. 那么有没有一种好的办法可以解决这个问题呢?例如:能不能让窗口一直显示,直到检测到用户用鼠标点击关 ...

  7. Java开发学习(二十七)----SpringMVC之Rest风格解析及快速开发

    一.REST简介 REST(Representational State Transfer),表现形式状态转换,它是一种软件架构风格 当我们想表示一个网络资源的时候,可以使用两种方式: 传统风格资源描 ...

  8. Android事件总线(二)EventBus3.0源码解析

    1.构造函数 当我们要调用EventBus的功能时,比如注册或者发送事件,总会调用EventBus.getDefault()来获取EventBus实例: public static EventBus ...

  9. SDL 开发实战(七): 使用 SDL 实现 PCM播放器

    在上文,我们做了YUV播放器,这样我们就入门了SDL播放视频.下面我们来做一个PCM播放,即使用SDL播放PCM数据. 下面说明一下使用SDL播放PCM音频的基本流程,主要分为两大部分:初始化SDL. ...

随机推荐

  1. TypeError: can only concatenate str (not "int") to str解决方式

    使用format函数解决问题 for page in range(1,pagebox+1): url = "https://www.dd373.com/s/rbg22w-x9kjbs-wwf ...

  2. WPF使用第三方字体(TTF字体)

    1.下载第三方字体文件,将以TTF结尾的文件复制到项目中 2.在App.xaml中或者你需要的地方添加资源的定义 <Application.Resources> <FontFamil ...

  3. James Munkres Topology: Sec 22 Exer 3

    Exercise 22.3 Let \(\pi_1: \mathbb{R} \times \mathbb{R} \rightarrow \mathbb{R}\) be projection on th ...

  4. Codeforces 258D Little Elephant and Broken Sorting (看题解) 概率dp

    Little Elephant and Broken Sorting 怎么感觉这个状态好难想到啊.. dp[ i ][ j ]表示第 i 个数字比第 j 个数字大的概率.转移好像比较显然. #incl ...

  5. UOJ#346. 【清华集训2017】某位歌姬的故事 动态规划

    原文链接www.cnblogs.com/zhouzhendong/p/UOJ346.html 题解 首先按照 $m_i$ 的大小排个序. 如果某一个区间和一个 m 值比他小的区间有交,那么显然可以将这 ...

  6. 蓝桥杯 黄金连分数(BigDecimal的使用)

    标题: 黄金连分数 黄金分割数0.61803... 是个无理数,这个常数十分重要,在许多工程问题中会出现.有时需要把这个数字求得很精确. 对于某些精密工程,常数的精度很重要.也许你听说过哈勃太空望远镜 ...

  7. hdu4811-Ball(2013ACM/ICPC亚洲区南京站现场赛)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4811 题目描述: Problem Description Jenny likes balls. He ...

  8. vue笔记-条件渲染

    条件渲染 1:指令v-if单独使用和结合v-else //单独使用 <h1 v-if="ok">Yes</h1> //组合使用 <h1 v-if=&q ...

  9. 安装es6编译babel

    1.它的安装命令如下. 全局安装 :$ npm install --global babel-cli项目下安装: $ npm install -g babel-cli --save-dev 2.配置. ...

  10. 多项式与三角函数求导——BUAA OO 第一单元作业总结

    第一次作业 需求简要说明 针对符合规定的多项式表达式输出其符合格式规定的导函数多项式,格式错误输出WRONG FORMAT! 带符号整数 支持前导0的带符号整数,符号可省略,如: +02.-16> ...