SDL学习

Simple DirectMedia Layer 是一个跨平台开发库 ,旨在通过OpenGLDirect3D 提供对音频、键盘、鼠标、操纵杆和图形硬件的低级访问 。它被视频播放软件、模拟器和流行游戏使用,包括Valve的获奖目录和许多Humble Bundle游戏。

SDL正式支持Windows、macOS、Linux、iOS和Android。 对其他平台的支持可以在源代码中找到。SDL是用C编写的,可以在C++中原生运行,并且有几种其他语言的绑定,包括C#和Python。

SDL基本使用方法

  • 初始化/退出API SDL_Init/SDL_Quit()
  • 创建窗口/释放窗口SDL_CreateWindow()/SDL_DestoryWindow()
  • 创建渲染器 SDL_CreateRender()

使用例子

cpp 复制代码
#include <SDL.h>
int main(int argc, char const *argv[])
{
    // 初始化SDL
    SDL_Init(SDL_INIT_VIDEO);
    // 退出SDL
    SDL_Quit();
    return 0;
}

找到SDL2的动态连接库和头文件地址:

cpp 复制代码
// 找到对应的链接库
pkg-config --libs sdl2
-L/usr/local/lib -Wl,-rpath,/usr/local/lib -Wl,--enable-new-dtags -pthread -lSDL2
cpp 复制代码
// 找到对应的头文件
pkg-config --cflags --libs sdl2
-D_REENTRANT -I/usr/local/include/SDL2 -L/usr/local/lib -Wl,-rpath,/usr/local/lib -Wl,--enable-new-dtags -pthread -lSDL2

SDL进行渲染

  • SDL_CreateRender/SDL_DestoryRenderer
  • SDL_RenderClear 清空数据
  • SDL_RenderPresent 把数据推送出去

例子:

cpp 复制代码
#include <SDL.h>
#include <stdio.h>
int main(int argc, char const *argv[])
{
    // 创建窗口
    SDL_Window * window = NULL;
    // 创建对应的渲染
    SDL_Renderer * render = NULL;
    // 初始化SDL
    SDL_Init(SDL_INIT_VIDEO);
    
    // 窗口的具体的创建过程
    window = SDL_CreateWindow("SDL2 window",200,200,480,640,SDL_WINDOW_SHOWN);
    if(window == NULL){
        printf("Couldn't create SDL2 window\n");
        goto __EXIT;
    }
    // 创建对应渲染
    render = SDL_CreateRenderer(window,-1,0 );
    if(!render){
        printf("Couldn't create renderer");
        goto __EXIT_WINDOWS;
    }
    
    //  推送Render
    SDL_SetRenderDrawColor(render,255,255,0,50  );
    // 清空render数据
    SDL_RenderClear(render);
    SDL_RenderPresent(render);
    // 延时延时
    SDL_Delay(3000);
    // 销毁窗口
    SDL_DestroyWindow(window);
__EXIT_WINDOWS:
    // 销毁对应的render
    SDL_DestroyWindow(window);
__EXIT:
    // 退出SDL
    SDL_Quit();
    return 0;
}

编译结果:

SDL事件处理

SDL将所有的事件放在一个对应的事件的队列中 ,所有对事件的操作都是对队列的操作。

事件的类型

  • SDL_WindowEvent : Window窗口相关的事件。
  • SDL_KeyboardEvent : 键盘相关的事件。
  • SDL_MouseMotionEvent : 鼠标移动相关的事件。
  • SDL_QuitEvent : 退出事件。
  • SDL_UserEvent : 用户自定义事件。

事件处理的类型

  • SDL_PollEvent:传统事件的处理方式,以轮询的方式进行处理,事件的处理需要的进行进行事件周期,需要进行等待。
  • SDL_WaitEvent:现代事件的处理方式,监听特定的时间,进行休眠等待,会阻塞
cpp 复制代码
#include <SDL.h>
#include <stdio.h>
int main(int argc, char const *argv[])
{

    int quit = 1;

    // 创建窗口
    SDL_Window * window = NULL;
    // 创建对应的渲染
    SDL_Renderer * render = NULL;
    // 初始化SDL
    SDL_Init(SDL_INIT_VIDEO);
    
    // 窗口的具体的创建过程
    window = SDL_CreateWindow("SDL2 window",200,200,480,640,SDL_WINDOW_SHOWN);
    if(window == NULL){
        printf("Couldn't create SDL2 window\n");
        goto __EXIT;
    }
    // 创建对应渲染
    render = SDL_CreateRenderer(window,-1,0 );
    if(!render){
        printf("Couldn't create renderer");
        goto __EXIT_WINDOWS;
    }
    
    //  推送Render
    SDL_SetRenderDrawColor(render,255,255,0,50  );
    // 清空render数据
    SDL_RenderClear(render);
    SDL_RenderPresent(render);
    // 事件处理
    do{
        SDL_Event event;
        SDL_WaitEvent(&event);
        switch(event.type){
            case SDL_QUIT:
                quit = 0;
                break;
            default:
                SDL_Log("event type is: %d", event.type);

        }
    }while(quit);


    // 销毁窗口
    SDL_DestroyWindow(window);
__EXIT_WINDOWS:
    // 销毁对应的render
    SDL_DestroyWindow(window);
__EXIT:
    // 退出SDL
    SDL_Quit();
    return 0;
}

该例子会打印各种事件类型。

纹理渲染

纹理用于图像信息的表示,占用内存很少,而且计算在的GPU中,之后通过显示。

常用API

  • SDL_CreateTexture():创建纹理 format:对应的数据类型,access:访问类型 Target(常用),Stream(流式)
  • SDL_DestoryTexture():销毁纹理
  • SDL_SetRenderTarget :设置一个纹理作为当前渲染目标。
cpp 复制代码
/**
 * Set a texture as the current rendering target.
 *
 * Before using this function, you should check the
 * `SDL_RENDERER_TARGETTEXTURE` bit in the flags of SDL_RendererInfo to see if
 * render targets are supported.
 *
 * The default render target is the window for which the renderer was created.
 * To stop rendering to a texture and render to the window again, call this
 * function with a NULL `texture`.
 *
 * \param renderer 渲染上下文
 * \param texture 目标纹理,必须使用.
 * \returns 0 on success or a negative error code on failure; call
 *          SDL_GetError() for more information.
 *
 * \since This function is available since SDL 2.0.0.
 *
 * \sa SDL_GetRenderTarget
 */
extern DECLSPEC int SDLCALL SDL_SetRenderTarget(SDL_Renderer *renderer,
                                                SDL_Texture *texture);
  • SDL_RenderClear()
cpp 复制代码
/**
 * 用绘图颜色清除当前渲染目标。
 *
 * This function clears the entire rendering target, ignoring the viewport and
 * the clip rectangle.
 *
 * \param renderer 渲染上下文 
 * \returns 0 on success or a negative error code on failure; call
 *          SDL_GetError() for more information.
 *
 * \since This function is available since SDL 2.0.0.
 *
 * \sa SDL_SetRenderDrawColor
 */
extern DECLSPEC int SDLCALL SDL_RenderClear(SDL_Renderer * renderer);
  • SDL_RenderCopy()拷贝纹理数数据到GPU中,进行计算最终的图像
cpp 复制代码
/**
 * 将纹理的一部分复制到当前渲染目标。 *
 * The texture is blended with the destination based on its blend mode set
 * with SDL_SetTextureBlendMode().
 *
 * The texture color is affected based on its color modulation set by
 * SDL_SetTextureColorMod().
 *
 * The texture alpha is affected based on its alpha modulation set by
 * SDL_SetTextureAlphaMod().
 *
 * \param renderer the rendering context
 * \param texture the source texture
 * \param srcrect the source SDL_Rect structure or NULL for the entire texture
 * \param dstrect the destination SDL_Rect structure or NULL for the entire
 *                rendering target; the texture will be stretched to fill the
 *                given rectangle
 * \returns 0 on success or a negative error code on failure; call
 *          SDL_GetError() for more information.
 *
 * \since This function is available since SDL 2.0.0.
 *
 * \sa SDL_RenderCopyEx
 * \sa SDL_SetTextureAlphaMod
 * \sa SDL_SetTextureBlendMode
 * \sa SDL_SetTextureColorMod
 */
extern DECLSPEC int SDLCALL SDL_RenderCopy(SDL_Renderer * renderer,
                                           SDL_Texture * texture,
                                           const SDL_Rect * srcrect,
                                           const SDL_Rect * dstrect);
  • SDL_RenderPresent() 计算好的图像进行显示
cpp 复制代码
/**
 * 使用自上次调用以来执行的任何渲染更新屏幕。 *
 * SDL's rendering functions operate on a backbuffer; that is, calling a
 * rendering function such as SDL_RenderDrawLine() does not directly put a
 * line on the screen, but rather updates the backbuffer. As such, you compose
 * your entire scene and *present* the composed backbuffer to the screen as a
 * complete picture.
 *
 * Therefore, when using SDL's rendering API, one does all drawing intended
 * for the frame, and then calls this function once per frame to present the
 * final drawing to the user.
 *
 * The backbuffer should be considered invalidated after each present; do not
 * assume that previous contents will exist between frames. You are strongly
 * encouraged to call SDL_RenderClear() to initialize the backbuffer before
 * starting each new frame's drawing, even if you plan to overwrite every
 * pixel.
 *
 * \param renderer the rendering context
 *
 * \since This function is available since SDL 2.0.0.
 *
 * \sa SDL_RenderClear
 * \sa SDL_RenderDrawLine
 * \sa SDL_RenderDrawLines
 * \sa SDL_RenderDrawPoint
 * \sa SDL_RenderDrawPoints
 * \sa SDL_RenderDrawRect
 * \sa SDL_RenderDrawRects
 * \sa SDL_RenderFillRect
 * \sa SDL_RenderFillRects
 * \sa SDL_SetRenderDrawBlendMode
 * \sa SDL_SetRenderDrawColor
 */
extern DECLSPEC void SDLCALL SDL_RenderPresent(SDL_Renderer * renderer);

例子

cpp 复制代码
#include <SDL.h>
#include <stdio.h>
int main(int argc, char const *argv[])
{

    int quit = 1;
    SDL_Event event;
    // 创建窗口
    SDL_Window * window = NULL;
    // 创建对应的渲染
    SDL_Renderer * render = NULL;
    // 创建纹理
    SDL_Texture * texture = NULL;

    SDL_Rect rect;
        rect.w= 30;
        rect.h= 30;

    // 初始化SDL
    SDL_Init(SDL_INIT_VIDEO);
    
    // 窗口的具体的创建过程
    window = SDL_CreateWindow("SDL2 window",200,200,480,640,SDL_WINDOW_SHOWN);
    if(window == NULL){
        printf("Couldn't create SDL2 window\n");
        goto __EXIT;
    }
    // 创建对应渲染
    render = SDL_CreateRenderer(window,-1,0 );
    if(!render){
        printf("Couldn't create renderer");
        goto __EXIT_WINDOWS;
    }
    
    //  推送Render
    SDL_SetRenderDrawColor(render,255,255,0,50  );
    // 清空render数据
    SDL_RenderClear(render);
    
    SDL_RenderPresent(render);

    // 创建初始化纹理
    texture= SDL_CreateTexture(render,SDL_PIXELFORMAT_RGBA8888,SDL_TEXTUREACCESS_TARGET,600,440);


    // 事件处理
    do{
        SDL_PollEvent(&event);
        switch(event.type){
            case SDL_QUIT:
                quit = 0;
                break;
            default:
                SDL_Log("event type is: %d", event.type);

        }
        
        rect.x = rand()%600;
        rect.y = rand()%440;
        SDL_SetRenderTarget(render,texture);
        SDL_SetRenderDrawColor(render,0,0,0,0);
        SDL_RenderClear(render);
       
        SDL_RenderDrawRect(render, &rect);
        SDL_SetRenderDrawColor(render,255,0,0,0);
        SDL_RenderFillRect(render, &rect);

        SDL_SetRenderTarget(render,NULL);
        SDL_RenderCopy(render,texture,NULL,NULL);
        SDL_RenderPresent(render);

    }while(quit);

    // 销毁纹理
    SDL_DestroyTexture(texture);

    // 销毁窗口
    SDL_DestroyWindow(window);
__EXIT_WINDOWS:
    // 销毁对应的render
    SDL_DestroyWindow(window);
__EXIT:
    // 退出SDL
    SDL_Quit();
    return 0;
}

输出的结果为:

相关推荐
cyr___2 小时前
Unity教程(二十四)技能系统 投剑技能(中)技能变种实现
学习·游戏·unity·游戏引擎
上海云盾第一敬业销售5 小时前
手游遇攻击为何要用游戏盾SDK?
游戏
德迅云安全杨德俊7 小时前
应用加速游戏盾的安全作用
网络·安全·游戏·ddos
大梦谁先行11 小时前
Qt写游戏脚本/辅助(仅供参考)
c++·qt·游戏
小木木爸12 小时前
HLS视频切片音频中断问题分析与解决方案
音视频·hls视频切片·音频中断问题
lovep11 天前
CLAP文本-音频基础模型: LEARNING AUDIO CONCEPTS FROM NATURAL LANGUAGE SUPERVISION
音视频·语音识别·多模态模型·音频识别·基础模型
liuhaikang1 天前
【鸿蒙HarmonyOS Next App实战开发】视频提取音频
华为·音视频·harmonyos
棒棒AIT1 天前
mac 苹果电脑 Intel 芯片(Mac X86) 安卓虚拟机 Android模拟器 的救命稻草(下载安装指南)
android·游戏·macos·安卓·mac
Deng9452013141 天前
24点数学游戏(穷举法求解表达式)
游戏·穷举法·递归回溯算法
用户6120414922131 天前
C语言做的井字棋小游戏
c语言·后端·游戏