美文网首页FFmpeg音视频直播技术OpenGL渲染
「SDL第五篇」彻底理解纹理(Texture)

「SDL第五篇」彻底理解纹理(Texture)

作者: 音视频直播技术专家 | 来源:发表于2018-04-10 00:17 被阅读243次

    前言

    这是SDL系列文章的第五篇,本文将彻底让你理解什么是纹理。并带你深入探讨SDL的几个重要概念SDL_Window、SDL_Render、SDL_Surface 与 SDL_Texture。在文章的最后向你展示SDL如何通过SDL_Texture进行渲染。

    对于前面系列文章感兴趣的同学可以通过下面的链接查看:

    另外,我在慕课网分享了音视频免费入门课程,有兴趣的同学可以去学习更多的音视频知识。

    SDL_Surface vs SDL_Texture

    在SDL系列文章的第二篇里,我详细的介绍了SDL 渲染的工作原理。即在SDL_Render对象中有一个视频缓冲区,该缓冲区我们称之为SDL_Surface,它是按照像素存放图像的。我们一般把真彩色的像素称为RGB24数据。也就是说,每一个像素由24位组成,每8位代表一种颜色,像素的最终颜色是由RGB三种颜色混合而成的。

    SDL_Texture 与SDL_Surface相似,也是一种缓冲区。只不过它存放的不是真正的像素数据,而是存放的图像的描述信息。当渲染纹理时,SDL以这些描述信息为数据,底层通过OpenGL、D3D 或 Metal操作GPU,最终绘制出与SDL_Surface一样的图形,且效率更高(因为它是GPU硬件计算的)。

    看了以上的介绍,是不是对纹理有了一个清楚的认识了?

    介绍完 SDL_Surface 和 SDL_Texture后,我们再看下SDL_Window 与 SDL_Render。

    SDL_Window 与 SDL_Render

    SDL_Window代表的是窗口的逻辑概念,它是存放在主内存中的一个对象。所以当我们调用SDL API 创建窗口后,它并不会被显示出来。

    SDL_Render 是渲染器,它也是主存中的一个对象。对Render操作时实际上分为两个阶段:

    一、渲染阶段。在该阶段,用户可以画各种图形渲染到SDL_Surface或SDL_Texture 中;

    二、显示阶段。参SDL_Texture为数据,通过OpenGL操作GPU,最终将 SDL_Surfce 或SDL_Texture中的数据输出到显示器上。

    通过上面的介绍,我们就将 SDL_Window、SDL_Render、SDL_Surface与 SDL_Texture之间的关系梳理清楚了,下面我们来看一下如何使用 SDL_Texture。

    使用SDL_Texture

    SDL提供了非常好用的操作SDL_Texture的方法,下面我们来重点介绍一下使用SDL_Texute的基本步骤。

    • 创建一个 SDL_Texture。

    • 渲染 Texture

    • Destory Texture

    API详细介绍

    • 创建 SDL_Texture

      SDL_Texture* SDL_CreateTexture(SDL_Renderer* renderer,
                                   Uint32        format,
                                   int           access,
                                   int           w,
                                   int           h)
      
      • format: 指明像素格式,可以是YUV,也可以是RGB
      • access: 指明Texture的类型。可以是 Stream(视频),也可以是Target一般的类型。
    • 渲染

      int SDL_RenderCopy(SDL_Renderer*   renderer,
                       SDL_Texture*    texture,
                       const SDL_Rect* srcrect,
                       const SDL_Rect* dstrect)
      
      • srcrect: 指定 Texture 中要渲染的一部分。如果将 Texture全部输出,可以设置它为 NULL。
      • dstrect: 指定输出的空间大小。
    • 销毁Texture

      void SDL_DestroyTexture(SDL_Texture* texture)
      

    例子

    下面这个例子非常简单,我这里就不做特别的说明了。对这个程序看不懂的同学可以看我之前的几篇 SDL 的相关文章。

    #include "SDL.h"
    
    /* Moving Rectangle */
    int main(int argc, char *argv[])
    {
            SDL_Window *window;
            SDL_Renderer *renderer;
            SDL_Texture *texture;
            SDL_Event event;
            SDL_Rect r;
    
            if (SDL_Init(SDL_INIT_VIDEO) < 0) {
                    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s", SDL_GetError());
                    return 3;
            }
    
            window = SDL_CreateWindow("SDL_CreateTexture",
                            SDL_WINDOWPOS_UNDEFINED,
                            SDL_WINDOWPOS_UNDEFINED,
                            1024, 768,
                            SDL_WINDOW_RESIZABLE);
    
            r.w = 100;
            r.h = 50;
    
            renderer = SDL_CreateRenderer(window, -1, 0);
    
            texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, 1024, 768);
    
            while (1) {
                    SDL_PollEvent(&event);
                    if(event.type == SDL_QUIT)
                            break;
                    r.x=rand()%500;
                    r.y=rand()%500;
    
                    SDL_SetRenderTarget(renderer, texture);
                    SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0x00);
                    SDL_RenderClear(renderer);
                    SDL_RenderDrawRect(renderer,&r);
                    SDL_SetRenderDrawColor(renderer, 0xFF, 0x00, 0x00, 0x00);
                    SDL_RenderFillRect(renderer, &r);
                    SDL_SetRenderTarget(renderer, NULL);
                    SDL_RenderCopy(renderer, texture, NULL, NULL);
                    SDL_RenderPresent(renderer);
            }
            SDL_DestroyRenderer(renderer);
            SDL_Quit();
            return 0;
    }
    

    小结

    本文重点介绍了 SDL_Window、SDL_Render、SDL_Surface以及SDL_Texture之间的关系。搞清楚它们之前的关系对于理解 SDL 渲染起着至关重要的作用。

    大家一定要仔细的理解文章中所讲的内容,在我后序的文章中,尤其是后面介绍 播放器 相关内容时,都要用到现在所讲的这些内容。

    希望本文能对你有所帮助,谢谢!

    隆重推荐

    音视频免费入门课

    相关文章

      网友评论

        本文标题:「SDL第五篇」彻底理解纹理(Texture)

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