SDL初步学习

SDL视频播放学习记录

SDL标准库组成

SDL_image—支持时下流行的图像格式:BMP、PPM、XPM、 PCX、GIF、JPEG、PNG、TGA。

SDL_mixer—更多的声音输出函数以及更多的声音格式支持。

SDL_net—网络支持。

SDL_ttf—TrueType字体渲染支持。

SDL_rtf—简单的RTF渲染支持。

SDL子系统

SDL将功能分成下列数个子系统(subsystem):

Video(图像)—图像控制以及线程(thread)和事件管理(event)

Audio(声音)—声音控制

Joystick(摇杆)—游戏摇杆控制

CD-ROM(光盘驱动器)—光盘媒体控制

Window Management(视窗管理)-与视窗程序设计集成

Event(事件驱动)-处理事件驱动

SDL渲染流程

**初始化:
SDL_Init(): 初始化SDL。
SDL_CreateWindow(): 创建窗口(Window)。
SDL_CreateRenderer(): 基于窗口创建渲染器(Render)。
SDL_CreateTexture(): 创建纹理(Texture)。
循环渲染数据:
SDL_UpdateTexture(): 设置纹理的数据。
SDL_RenderCopy(): 纹理复制给渲染器。
SDL_RenderPresent(): 显示。**


SDL初始化

fun:初始化函数
param:

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_VideoDevice)

Err: SDL_SetError()
int SDLCALL SDL_Init(Uint32 flags)

(关于初始化流程的小说明)

1.判断传入的Flag与子系统内的宏定义,决定是否初始化子系统

2.调用函数SDL_PrivateShouldInitSubsystem()检查每个子系统是否需要初始化

3.每个初始化后调用函数SDL_PrivateSubsystemRefCountIncr(),增加子系统的引用计数

4.下表列出各个子系统的初始化函数

子系统名称函数
AUDIO(音频)SDL_AudioInit()
VIDEO(视频)SDL_VideoInit()
TIMERS(定时器)SDL_TicksInit(),SDL_TimerInit()
EVENTS(事件)SDL_StartEventLoop()
JOYSTICK(摇杆)SDL_GameControllerInit()
HAPTIC(触摸屏)SDL_HapticInit()

子系统初始化(如视频)
1.使用结构体VideoBootStrap创建SDL_VideoDevice
(SDL中有一个VideoBootStrap类型的静态数组bootstrap。用于存储SDL支持的视频驱动程序。多平台支持)
2.根据平台选择创建函数,如:windows ——WIN_CreateDevice()
3.创建对象SDL_VideoDevice
4.根据创建的设备执行VideoInit()(Win_VideoInit())
期中包含三个函数WIN_InitModes(),WIN_InitKeyboard(),WIN_InitMouse(),分别用于获得系统中的显示设备信息,初始化键盘,鼠标


SDL创建窗口

fun:创建一个SDL_Window,指定播放窗口
param:

title :窗口标题
x :窗口位置x坐标。也可以设置为SDL_WINDOWPOS_CENTERED或SDL_WINDOWPOS_UNDEFINED。
y :窗口位置y坐标。同上。
w :窗口的宽
h :窗口的高
flags :支持下列标识。包括了窗口的是否最大化、最小化,能否调整边界等等属性。
::SDL_WINDOW_FULLSCREEN,
::SDL_WINDOW_OPENGL,
::SDL_WINDOW_HIDDEN,
::SDL_WINDOW_BORDERLESS,
::SDL_WINDOW_RESIZABLE,
::SDL_WINDOW_MAXIMIZED,
::SDL_WINDOW_MINIMIZED,
::SDL_WINDOW_INPUT_GRABBED,
::SDL_WINDOW_ALLOW_HIGHDPI.

return: 返回创建完成的窗口的ID。如果创建失败则返回0。
SDL_Window * SDLCALL SDL_CreateWindow(const char *title,int x, int y, int w, int h, Uint32 flags);

(关于创建窗口的内部流程小说明)
  1. 进行一些保证平台兼容性的工作。

  2. 调用SDL_calloc()为SDL_Window结构体分配一块内存。同时设置一些基本属性,例如窗口的宽高,位置等等。

  3. 调用VideoDevice的CreateWindow()方法创建窗口。 ->win32的API,创建时进行优化,如:AdjustWindowRectEx(),SetWindowData()
    (SDL中有一个SDL_VideoDevice类型的静态全局变量_this。SDL调用视频驱动的功能都是通过调用该指针完成的。)

  4. 完成一些收尾工作,如设置标题,全屏窗口,rec。


创建SDL_Render

fun:创建一个SDL_Render渲染器
param:

window : 渲染的目标窗口。
index :打算初始化的渲染设备的索引。设置“-1”则初始化默认的渲染设备。
flags :支持以下值(位于SDL_RendererFlags定义中)
SDL_RENDERER_SOFTWARE :使用软件渲染
SDL_RENDERER_ACCELERATED :使用硬件加速
SDL_RENDERER_PRESENTVSYNC:和显示器的刷新率同步
SDL_RENDERER_TARGETTEXTURE :SDL_SetRenderTarget ()函数使用标签,对应须将目标Target添加SDL_TEXTUREACCESS_TARGET标签

return:返回创建完成的渲染器的ID。如果创建失败则返回NULL。
SDL_Renderer * SDLCALL SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags);

(关于创建渲染器的小说明)
  1. 创建基本函数:调用SDL_RenderDriver的CreateRenderer()方法。

    struct SDL_RenderDriver
    {
    SDL_Renderer (*CreateRenderer) (SDL_Window window, Uint32 flags);
    /* Info about the renderer capabilities */
    SDL_RendererInfo info;
    };
    (在SDL中有一个全局的SDL_RenderDriver类型的静态数组render_drivers,其中存储了SDL支持的所有渲染器。如:Direct3D,OpenGl,软件渲染器驱动程序SW_RenderDriver)


2.(例如D3D)为SDL_Renderer分配内存
  1. 加载Direct3D(9)
    加载Direct3D通过函数D3D_LoadDLL()完成。调用该函数可以得到一个IDirect3D9类型的接口(创建Microsoft Direct3D 目标和配置环境的应用方法类)。

  2. 渲染器接口函数赋值
    SDL_Render结构体中有一系列的函数指针,包含了有关渲染器的各种功能。SDL通过调用这些函数指针就可以调用渲染器相应的功能。这是SDL支持多种渲染器的一个重要特点。

  3. 创建Device
    创建Direct3D的Device通过IDirect3D9_CreateDevice()函数来实现。

  4. 设置渲染状态
    设置渲染状态在函数D3D_InitRenderState(D3D_RenderData *data)中完成。

  5. 创建Shader
    创建Shader通过函数IDirect3DDevice9_CreatePixelShader()完成。


创建SDL_Texture

fun:基于渲染器创建一个纹理
param:

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

return:创建成功则返回纹理的ID,失败返回0。
SDL_Texture * SDL_CreateTexture(SDL_Renderer * renderer, Uint32 format, int access, int w, int h)

(关于纹理创建的小说明)
  1. 检查输入参数的合理性。例如像素格式是否支持,宽和高是否小于等于0等等。

  2. 新建一个SDL_Texture。调用SDL_calloc()(实际上就是calloc())为新建的SDL_Texture分配内存。

  3. 调用SDL_Render的CreateTexture()方法创建纹理。这一步是整个函数的核心。

    D3D_CreateTexture()
    IDirect3DDevice9_CreateTexture();
    GL_CreateTexture ()
    创建纹理:glGenTextures(),glBindTexture()
    设置参数:glTexParameteri()
    SW_CreateTexture ()
    SDL_CreateRGBSurface() ————(创建Surface)


更新纹理

fun:SDL使用SDL_UpdateTexture()设置纹理的像素数据。
param:

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

return:成功的话返回0,失败的话返回-1。
int SDLCALL SDL_UpdateTexture(SDL_Texture * texture, const SDL_Rect * rect, const void *pixels, int pitch);

(关于更新纹理的小说明)
  1. 检查输入参数的合理性。例如像素格式是否支持,宽和高是否小于等于0等等。
  2. 如果是一些特殊的格式,进行一定的处理:
    a) 如果输入的像素数据是YUV格式的,则会调用SDL_UpdateTextureYUV()进行处理。
    b) 如果输入的像素数据的像素格式不是渲染器支持的格式,则会调用SDL_UpdateTextureNative()进行处理。
  3. 调用SDL_Render的UpdateTexture()方法更新纹理。这一步是整个函数的核心。
    4.渲染器更新纹理细则
    (Direct 3D——D3D_UpdateTexture())
    static int D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, const void *pixels, int pitch)
    D3D函数调用D3D_UpdateTextureInternal()进行纹理更新,
    该函数首先调用IDirect3DTexture9_LockRect()锁定纹理,然后使用SDL_memcpy()将新的像素数据拷贝至纹理(SDL_memcpy()实际上就是memcpy()), 最后使用IDirect3DTexture9_UnlockRect()解锁纹理。
    (Software渲染器)
    SW_UpdateTexture()

更新渲染器

fun:将纹理数据复制给渲染器
param:

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

return:成功的话返回0,失败的话返回-1。
int SDLCALL SDL_RenderCopy(SDL_Renderer * renderer,SDL_Texture * texture,const SDL_Rect * srcrect,const SDL_Rect * dstrect);

(关于更新渲染器的小说明)
  1. 检查输入参数的合理性。
  2. 调用SDL_Render的RenderCopy ()方法复制纹理到渲染目标。这一步是整个函数的核心。
  3. (Direct3D更新细则)——D3D_RenderCopy()
    D3D_ActivateRenderer():激活渲染器。其内部使用Direct3D的API函数IDirect3DDevice9_BeginScene()开始一个D3D的场景。
    D3D_SetBlendMode():设置渲染器状态。其内部使用Direct3D的API函数IDirect3DDevice9_SetRenderState()设置渲染器的状态。
    D3D_UpdateTextureScaleMode():设置纹理采样方式。其内部调用使用Direct3D的API函数IDirect3DDevice9_SetSamplerState()设置D3D的纹理采样方式。
    IDirect3DDevice9_SetTexture():Direct3D的API,用于设置当前启用的纹理。
    IDirect3DDevice9_SetPixelShader():Direct3D的API,用于设置使用的像素着色器。
    IDirect3DDevice9_DrawPrimitiveUP():Direct3D的API,用于渲染。
    上述几个函数中,前3个函数是SDL中的函数,后3个函数是Direct3D的API。
  4. (Software)——SW_RenderCopy()

显示

fun:显示画面
param:

SDL_Renderer 渲染器

void SDL_RenderPresent(SDL_Renderer * renderer)

(关于显示的刷新的显示小说明)

(SDL_RenderPresent()调用SDL_Render的RenderPresent()方法显示图像。)
(Direct3D)–D3D_RenderPresent()
该函数调用了2个最关键Direct3D的API:
IDirect3DDevice9_EndScene():结束一个场景。
IDirect3DDevice9_Present():显示。
(Software)–SW_RenderPresent()
函数调用顺序示意:本函数->SDL_UpdateWindowSurface()->DL_UpdateWindowSurfaceRects()->(SDL_VideoDevice) UpdateWindowFramebuffer()->(Windows视频驱动) WIN_UpdateWindowFramebuffer()->BitBlt()
(之后对该函数进行详细的分析)

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值