• SDL2 简明教程(三):显示图片


    系列文章目录

    SDL2 简明教程(一):使用 Cmake 和 Conan 构建 SDL2 编程环境

    SDL2 简明教程(二):创建一个空的窗口



    在窗口显示图片

    SDL2 简明教程(二):创建一个空的窗口 中我们已经学会如何创建一个窗口,今天在其基础上更进一步,我们将在窗口上显示一张图片,首先回顾下创建空窗口的代码:

    
    #if defined(__cplusplus)
    extern "C" {
    #endif
    
    #include 
    
    #if defined(__cplusplus)
    };
    #endif
    
    int main(int argc, char *argv[]) {
        bool quit = false;
        SDL_Event event;
    
        SDL_Init(SDL_INIT_VIDEO);
    
        SDL_Window *screen = SDL_CreateWindow("My SDL Empty window",
                                              SDL_WINDOWPOS_UNDEFINED,
                                              SDL_WINDOWPOS_UNDEFINED,
                                              640, 480, 0);
        for (; !quit;) {
            SDL_WaitEvent(&event);
    
            switch (event.type) {
            case SDL_QUIT: {
                quit = true;
                break;
            }
            }
        }
    
        SDL_Quit();
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    接着,创建一个 SDL_Renderer:

    SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
    
    • 1

    SDL_CreateRenderer 创建一个 SDL_Renderer 实例,这个 render 表示绘制的输出设备(通常就是你的显卡)。事实上,它是我们图像的最终目的地,因为我们将按照下面的步骤进行:

    Created with Raphaël 2.3.0 Load image to surface Copy surface to texture Copy texture to render

    SDL_CreateRenderer() 需要三个参数。第一个是我们正在绘制的窗口。第二个参数允许我们选择不同的渲染驱动;在我们的例子中,我们并不关心,我们可以把它设置为 -1,然后得到默认的驱动。最后一个参数允许我们设置 SDL_RendererFlags 来控制渲染的发生方式。我们可以把它设置为 0,默认为硬件渲染。如果这些听起来很混乱,不用担心,就像这里一样使用SDL_CreateRenderer()

    现在我们可以使用 SDL_LoadBMP() 载入一张 BMP 图片,并将其加载到 SDL_Surface 中:

    SDL_Surface * image = SDL_LoadBMP("image.bmp");
    
    • 1

    测试图片大小为 320*240,你可以在代码仓库中的 res 文件夹下找到
    请添加图片描述
    接着,我们需要创建一个 texture(纹理):

    SDL_Texture * texture = SDL_CreateTextureFromSurface(renderer, image);
    
    • 1

    一个 texture 其实就是一块靠近显卡的内存,通过 SDL_CreateTextureFromSurface() 将 surface 映射到 texture 上。Surface 和 texture 的关系如下图:
    在这里插入图片描述
    现在让我们在窗口上显示这个 texture。在 for 循环代码末尾处,添加如下代码:

    SDL_RenderCopy(renderer, texture, NULL, NULL);
    SDL_RenderPresent(renderer);
    
    • 1
    • 2

    SDL_RenderCopy 将 texture 拷贝到 render(输出设备)中;SDL_RenderPresent 将 texture 提交至视频内存,并显示它。

    记得清理我们初始化过的每一个资源,你需要在 SDL_Quit() 前添加如下内容:

    SDL_DestroyTexture(texture);
    SDL_FreeSurface(image);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    
    • 1
    • 2
    • 3
    • 4

    运行你的程序,你会看到窗口中显示了一张图片:
    在这里插入图片描述
    非常神奇!图片真的在窗口中显示出来了,但你会发现这图片似乎不太清晰,这是因为图片大小是 320240 ,但窗口大小是 640480,窗口自动将图片做了拉伸填满了整个窗口。为了让图片看起来不这么模糊,我们可以指定显示区域的位置和大小:

    SDL_Rect dstrect = { 5, 5, 320, 240 };
    SDL_RenderCopy(renderer, texture, NULL, &dstrect);
    
    • 1
    • 2

    SDL_RenderCopy 最后一个参数定义的显示区域,如果它是 NULL 的话,图片将被拉伸填充。

    指定好显示区域后,运行代码,图片将被显示在某个区域而不是平铺在整个窗口:
    在这里插入图片描述

    总结

    在这篇文章中,我们研究了如何创建渲染器、表面和纹理。我们用这些来加载位图并在屏幕上显示它们。我们还看到了将图像复制到窗口的某个区域,和使其填满整个窗口之间的区别。

    本文源码你可以在 sdl2_tutorial 找到。

  • 相关阅读:
    Visual Studio 2022安装教程
    最新数据挖掘赛事方案梳理!
    【无标题】
    Dockerfile安装到项目发布全过程(详解)
    RocksDB 在 vivo 消息推送系统中的实践
    统计分布的 参数估计函数-Matlab命令
    C语言习题练习11--指针
    二十年架构师马士兵老师告诉你:2022年Java架构师到底该如何进阶
    05贪心:买卖股票的最佳时机 II
    密码学基本概念
  • 原文地址:https://blog.csdn.net/weiwei9363/article/details/125900167