美文网首页
SDL开发笔记(三):使用SDL渲染窗口颜色和图片

SDL开发笔记(三):使用SDL渲染窗口颜色和图片

作者: 红模仿_红胖子 | 来源:发表于2020-09-16 09:55 被阅读0次

    若该文为原创文章,未经允许不得转载

    原博主博客地址:https://blog.csdn.net/qq21497936

    原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062

    本文章博客地址:https://blog.csdn.net/qq21497936/article/details/108602694

    红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中…(点击传送门)

    Qt开发专栏:三方库开发技术(点击传送门)

    上一篇:《SDL开发笔记(二):音频基础介绍、使用SDL播放音频

    下一篇:敬请期待

    前言

      对于Qt应用来说,为了更大的跨平台通用性,使用SDL播放音频,同样也流行使用SDL渲染视频,基本上很大一部分市面上的sdk播放器都是基于sdl的,传入窗口句柄使用sdl渲染。

    Demo

    循环渲染颜色:

    SDL渲染流程解析

    基本流程如下:

    步骤一:初始化子系统

      SDL_Init()初始化视频系统,其他多余的系统不用初始化。

    步骤二:创建窗口

      SDL_CreateWindow()创建windows窗口,设置一些常用属性。

    步骤三:创建渲染器(与窗口绑定)

      SDL_CreateRenderer()创建渲染器,该渲染器创建时已经与显示的窗口进行了绑定。

    步骤四:渲染颜色/渲染图片步骤

    本篇有3个demo,分别为渲染了简单的颜色,同构按键时间渲染不同的颜色,通过按键渲染不同的图片。

    渲染简单的颜色:设置渲染颜色->清空->渲染

    // 步骤四:开始渲染-渲染简单的颜色

    for(int index = 0; index < 100000; index++)

    {

        SDL_SetRenderDrawColor(pSDLRenderer,

                              index/255%255,

                              index/10%255,

                              index/20%255,

                              128);

        SDL_RenderClear(pSDLRenderer);

        SDL_RenderPresent(pSDLRenderer);

        SDL_PollEvent(&event);

    }

      按键渲染简单的颜色:设置渲染颜色->清空->渲染->按键不同的颜色

    // 步骤四:开始渲染-渲染简答的颜色,接受按键输入0~9对应不同的颜色,

    // 对键盘事件进行处理

    bool out = false;

    int r = 0;

    int g = 0;

    int b = 0;

    while(true)

    {

        SDL_SetRenderDrawColor(pSDLRenderer, r, g, b, 255);

        SDL_RenderClear(pSDLRenderer);

        SDL_RenderPresent(pSDLRenderer);

        SDL_PollEvent(&event);

        switch (event.type)

        {

        case SDL_KEYDOWN:

            switch (event.key.keysym.sym)

            {

            case SDLK_ESCAPE:

                out = true;

                break;

            case SDLK_1:

                r = 255; g = 0; b = 0;

                break;

            case SDLK_2:

                r = 0; g = 255; b = 0;

                break;

            case SDLK_3:

                r = 0; g = 0; b = 255;

                break;

            case SDLK_4:

                r = 255; g = 255; b = 0;

                break;

            case SDLK_5:

                r = 0; g = 255; b = 255;

                break;

            case SDLK_6:

                r = 255; g = 0; b = 255;

                break;

            case SDLK_7:

                r = 255; g = 255; b = 255;

                break;

            case SDLK_8:

                r = 255; g = 140; b = 0;

                break;

            case SDLK_9:

                r = 0; g = 191; b = 255;

                break;

            case SDLK_0:

                r = 255; g = 215; b = 0;

                break;

            default:

                break;

            }

            break;

        case SDL_QUIT:

            out = true;

            break;

        default:

            break;

        }

        if(out)

        {

            break;

        }

    }

      渲染图片:加载图片->创建纹理->清空->复制纹理到渲染->渲染。

    // 步骤四:开始渲染-渲染bmp图片,1-2两张图片

    SDL_Surface *pSDLSurface = 0;

    SDL_Texture *pSDLTexture = 0;

    SDL_Surface *pSDLSurface2 = 0;

    SDL_Texture *pSDLTexture2 = 0;

    SDL_Texture *pSDLTextureTemp = 0;      // 用于临时存放

    bool out = false;

    pSDLSurface = SDL_LoadBMP("testBMP/1.bmp");

    pSDLTexture = SDL_CreateTextureFromSurface(pSDLRenderer, pSDLSurface);

    pSDLSurface2 = SDL_LoadBMP("testBMP/2.bmp");

    pSDLTexture2 = SDL_CreateTextureFromSurface(pSDLRenderer, pSDLSurface2);

    pSDLTextureTemp = pSDLTexture;

    while(true)

    {

        // 清空渲染器

        SDL_RenderClear(pSDLRenderer);

        // 将问题copy到渲染器上

        SDL_RenderCopy(pSDLRenderer, pSDLTextureTemp, 0, 0);

        // 显示渲染器内容

        SDL_RenderPresent(pSDLRenderer);

        // 事件处理

        SDL_PollEvent(&event);

        switch (event.type)

        {

        case SDL_KEYDOWN:

            switch (event.key.keysym.sym)

            {

            case SDLK_ESCAPE:

                out = true;

                break;

            case SDLK_1:

                pSDLTextureTemp = pSDLTexture;

                break;

            case SDLK_2:

                pSDLTextureTemp = pSDLTexture2;

                break;

            default:

                break;

            }

            break;

        case SDL_QUIT:

            out = true;

            break;

        default:

            break;

        }

        if(out)

        {

            break;

        }

    }

    步骤五:销毁渲染器

      SDL_DestroyRenderer();

    步骤六:销毁窗口

      SDL_DestroyWindow();

    步骤七:退出SDL系统

      SDL_Quit();

    SDL渲染相关变量

    SDL_Window

      用于标识窗口。

    SDL_Renderer

      表示呈现状态的结构。

    typedef struct SDL_Surface

    {

        Uint32 flags;              /**< Read-only */

        SDL_PixelFormat *format;    /**< Read-only */

        int w, h;                  /**< Read-only */

        int pitch;                  /**< Read-only */

        void *pixels;              /**< Read-write */

        /** Application data associated with the surface */

        void *userdata;            /**< Read-write */

        /** information needed for surfaces requiring locks */

        int locked;                /**< Read-only */

        void *lock_data;            /**< Read-only */

        /** clipping information */

        SDL_Rect clip_rect;        /**< Read-only */

        /** info for fast blit mapping to other surfaces */

        struct SDL_BlitMap *map;    /**< Private */

        /** Reference count -- used when freeing surface */

        int refcount;              /**< Read-mostly */

    } SDL_Surface;

    SDL_Event

      SDL的事件系统结构体,博大精深,以后兴趣可以仔细研究,按键主要用到了其type,然后键值用到的是其key.keysym.sym。

    switch (event.type)

    {

    case SDL_KEYDOWN:

        switch (event.key.keysym.sym)

        {

        case SDLK_ESCAPE:

            out = true;

            break;

        default:

            ;

        }

    }

    SDL_Surface

      在软件blitting中使用的像素集合,此结构应被视为只读,但像素除外,如果不为空,则包含表面的原始像素数据。

    typedef struct SDL_Surface

    {

        Uint32 flags;              /**< Read-only */

        SDL_PixelFormat *format;    /**< Read-only */

        int w, h;                  /**< Read-only */

        int pitch;                  /**< Read-only */

        void *pixels;              /**< Read-write */

        /** Application data associated with the surface */

        void *userdata;            /**< Read-write */

        /** information needed for surfaces requiring locks */

        int locked;                /**< Read-only */

        void *lock_data;            /**< Read-only */

        /** clipping information */

        SDL_Rect clip_rect;        /**< Read-only */

        /** info for fast blit mapping to other surfaces */

        struct SDL_BlitMap *map;    /**< Private */

        /** Reference count -- used when freeing surface */

        int refcount;              /**< Read-mostly */

    } SDL_Surface;

    SDL_Texture

      纹理,像素数据的一种高效的特定表示。

    SDL渲染相关函数原型

    SDL_Init()

    int SDLCALL SDL_Init(Uint32 flags);

      使用此函数初始化SDL库,必须在使用大多数其他SDL函数之前调用它,初始化的时候尽量做到“够用就好”,而不要用SDL_INIT_EVERYTHING。会出现一些不可预知的问题。

    参数一:输入初始化的设备

    SDL_CreateWindow()

    SDL_Window * SDL_CreateWindow(const char *title,

                                  int x,

                                  int y,

                                  int w,

                                  int h,

                                  Uint32 flags);

    使用指定的位置、尺寸和标志创建一个窗口。

    前面5个参数都是常用的,第六个参数是窗口的属性,如是否可改变大小等等.

    SDL_CreateRenderer()

    SDL_Renderer * SDL_CreateRenderer(SDL_Window * window,

                                      int index,

                                      Uint32 flags);

      为窗口创建二维渲染上下文,参数一为我们之前需要渲染的窗口。

    SDL_SetRenderDrawColor()

    int SDLCALL SDL_SetRenderDrawColor(SDL_Renderer * renderer,

                                      Uint8 r,

                                      Uint8 g,

                                      Uint8 b,

                                      Uint8 a);

      设置用于绘图操作的颜色(矩形、直线和清除)。

    SDL_RenderClear()

    int SDL_RenderClear(SDL_Renderer * renderer);

      使用绘图颜色清除当前渲染目标。

    SDL_RenderPresent()

    void SDL_RenderPresent(SDL_Renderer * renderer);

      使用已执行的渲染更新屏幕。

    SDL_PollEvent()

    int SDL_PollEvent(SDL_Event * event);

      当前挂起事件的轮询。

    SDL_LoadBMP()

    #define SDL_LoadBMP(file)  SDL_LoadBMP_RW(SDL_RWFromFile(file, "rb"), 1)

    SDL_Surface * SDL_LoadBMP_RW(SDL_RWops * src,

                                int freesrc);

      从可查找的SDL数据流(内存或文件)加载表面数据。

    SDL_CreateTextureFromSurface()

    SDL_Texture * SDL_CreateTextureFromSurface(SDL_Renderer * renderer,

                                              SDL_Surface * surface);

      从现有表面创建纹理。

    参数一:绑定窗口的渲染器。

    参数二:加载文件后的表面数据(加载的图片)。

    SDL_RenderCopy()

    int SDL_RenderCopy(SDL_Renderer * renderer,

                      SDL_Texture * texture,

                      const SDL_Rect * srcrect,

                      const SDL_Rect * dstrect);

      将纹理的一部分复制到当前渲染目标。

    参数一:应该复制纹理部分的渲染器。

    参数二:源纹理

    参数三:指向源矩形的指针,设置为0则全部。

    参数四:指向目标矩形的指针,设置为0则全部。

    SDL_DestroyRenderer()

    void SDL_DestroyRenderer(SDL_Renderer * renderer);

      销毁渲染器。

    SDL_DestroyWindow()

    void SDL_DestroyWindow(SDL_Window * window);

      销毁窗口。

    SDL_Quit()

    void SDL_Quit(void);

      此函数用于清除所有初始化的子系统。在所有退出条件后调用它。

    本文章博客地址:https://blog.csdn.net/qq21497936/article/details/108602694

    Demo源码

    void SDLManager::testRenderWindow()

    {

        int ret = 0;

        SDL_Window *pSDLWindow = 0;

        SDL_Renderer *pSDLRenderer = 0;

        SDL_Event event;

        // 步骤一:初始化视频子系统

        ret = SDL_Init(SDL_INIT_VIDEO);

        if(ret)

        {

            LOG << "Failed";

            return;

        }

        // 步骤二:创建窗口,支持opengl、大小可变

        pSDLWindow = SDL_CreateWindow("SDL Widget",

                                      0,

                                      0,

                                      800,

                                        480,

                                      SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);

        if(!pSDLWindow)

        {

            LOG << "Failed";

            return;

        }

        // 步骤三:基于窗口创建渲染器

        pSDLRenderer = SDL_CreateRenderer(pSDLWindow, -1, 0);

        if(!pSDLRenderer)

        {

            LOG << "Failed";

            return;

        }

    #if 0

        // 步骤四:开始渲染-渲染简单的颜色

        for(int index = 0; index < 100000; index++)

        {

            SDL_SetRenderDrawColor(pSDLRenderer,

                                  index/255%255,

                                  index/10%255,

                                  index/20%255, 128);

            SDL_RenderClear(pSDLRenderer);

            SDL_RenderPresent(pSDLRenderer);

            SDL_PollEvent(&event);

        }

    #endif

    #if 0

        // 步骤四:开始渲染-渲染简答的颜色,接受按键输入0~9对应不同的颜色,

        // 对键盘事件进行处理

        bool out = false;

        int r = 0;

        int g = 0;

        int b = 0;

        while(true)

        {

            SDL_SetRenderDrawColor(pSDLRenderer, r, g, b, 255);

            SDL_RenderClear(pSDLRenderer);

            SDL_RenderPresent(pSDLRenderer);

            SDL_PollEvent(&event);

            switch (event.type)

            {

            case SDL_KEYDOWN:

                switch (event.key.keysym.sym)

                {

                case SDLK_ESCAPE:

                    out = true;

                    break;

                case SDLK_1:

                    r = 255; g = 0; b = 0;

                    break;

                case SDLK_2:

                    r = 0; g = 255; b = 0;

                    break;

                case SDLK_3:

                    r = 0; g = 0; b = 255;

                    break;

                case SDLK_4:

                    r = 255; g = 255; b = 0;

                    break;

                case SDLK_5:

                    r = 0; g = 255; b = 255;

                    break;

                case SDLK_6:

                    r = 255; g = 0; b = 255;

                    break;

                case SDLK_7:

                    r = 255; g = 255; b = 255;

                    break;

                case SDLK_8:

                    r = 255; g = 140; b = 0;

                    break;

                case SDLK_9:

                    r = 0; g = 191; b = 255;

                    break;

                case SDLK_0:

                    r = 255; g = 215; b = 0;

                    break;

                default:

                    break;

                }

                break;

            case SDL_QUIT:

                out = true;

                break;

            default:

                break;

            }

            if(out)

            {

                break;

            }

        }

    #endif

    #if 1

        // 步骤四:开始渲染-渲染bmp图片,1-2两张图片

        SDL_Surface *pSDLSurface = 0;

        SDL_Texture *pSDLTexture = 0;

        SDL_Surface *pSDLSurface2 = 0;

        SDL_Texture *pSDLTexture2 = 0;

        SDL_Texture *pSDLTextureTemp = 0;      // 用于临时存放

        bool out = false;

        pSDLSurface = SDL_LoadBMP("testBMP/1.bmp");

        pSDLTexture = SDL_CreateTextureFromSurface(pSDLRenderer, pSDLSurface);

        pSDLSurface2 = SDL_LoadBMP("testBMP/2.bmp");

        pSDLTexture2 = SDL_CreateTextureFromSurface(pSDLRenderer, pSDLSurface2);

        pSDLTextureTemp = pSDLTexture;

        while(true)

        {

            // 清空渲染器

            SDL_RenderClear(pSDLRenderer);

            // 将问题copy到渲染器上

            SDL_RenderCopy(pSDLRenderer, pSDLTextureTemp, 0, 0);

            // 显示渲染器内容

            SDL_RenderPresent(pSDLRenderer);

            // 事件处理

            SDL_PollEvent(&event);

            switch (event.type)

            {

            case SDL_KEYDOWN:

                switch (event.key.keysym.sym)

                {

                case SDLK_ESCAPE:

                    out = true;

                    break;

                case SDLK_1:

                    pSDLTextureTemp = pSDLTexture;

                    break;

                case SDLK_2:

                    pSDLTextureTemp = pSDLTexture2;

                    break;

                default:

                    break;

                }

                break;

            case SDL_QUIT:

                out = true;

                break;

            default:

                break;

            }

            if(out)

            {

                break;

            }

        }

    #endif

        // 步骤五:销毁渲染器

        SDL_DestroyRenderer(pSDLRenderer);

        // 步骤六:销毁窗口

        SDL_DestroyWindow(pSDLWindow);

        // 步骤七:退出SDL

        SDL_Quit();

    }

    工程模板:对应版本号v1.2.0

      对应版本号v1.2.0:按键渲染颜色和BMP图片

    上一篇:《SDL开发笔记(二):音频基础介绍、使用SDL播放音频

    下一篇:敬请期待

    原博主博客地址:https://blog.csdn.net/qq21497936

    原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062

    本文章博客地址:https://blog.csdn.net/qq21497936/article/details/108602694

    相关文章

      网友评论

          本文标题:SDL开发笔记(三):使用SDL渲染窗口颜色和图片

          本文链接:https://www.haomeiwen.com/subject/aedcyktx.html