SDL2源代码分析4:纹理(SDL_Texture)

SDL_Texture

SDL_Texture结构定义了一个SDL中的纹理。

/**
 * An efficient driver-specific representation of pixel data
 */
struct SDL_Texture;
typedef struct SDL_Texture SDL_Texture;

在源代码工程中可以看到SDL_Texture的定义,位于render\SDL_sysrender.h文件中。它的定义如下。


/* Define the SDL texture structure */
struct SDL_Texture
{
    const void *magic;
    Uint32 format;              /**< The pixel format of the texture */
    int access;                 /**< SDL_TextureAccess */
    int w;                      /**< The width of the texture */
    int h;                      /**< The height of the texture */
    int modMode;                /**< The texture modulation mode */
    SDL_BlendMode blendMode;    /**< The texture blend mode */
    SDL_ScaleMode scaleMode;    /**< The texture scale mode */
    Uint8 r, g, b, a;           /**< Texture modulation values */

    SDL_Renderer *renderer;

    /* Support for formats not supported directly by the renderer */
    SDL_Texture *native;
    SDL_SW_YUVTexture *yuv;
    void *pixels;
    int pitch;
    SDL_Rect locked_rect;
    SDL_Surface *locked_surface;  /**< Locked region exposed as a SDL surface */

    Uint32 last_command_generation; /* last command queue generation this texture was in. */

    void *driverdata;           /**< Driver specific texture representation */

    SDL_Texture *prev;
    SDL_Texture *next;
};

可以看出其中包含了一个“纹理”所具备的各种属性。下面来看看如何创建这个SDL_Texture。

SDL_CreateTexture()

函数简介

使用SDL_CreateTexture()基于渲染器创建一个纹理。SDL_CreateTexture()的原型如下。

SDL_Texture * SDLCALL SDL_CreateTexture(SDL_Renderer * renderer,
                                                        Uint32 format,
                                                        int access, int w,
                                                        int h);

参数的含义如下。

renderer:目标渲染器。

format :纹理的格式。后面会详述。
access :可以取以下值(定义位于SDL_TextureAccess中)

SDL_TEXTUREACCESS_STATIC  :变化极少
SDL_TEXTUREACCESS_STREAMING  :变化频繁
SDL_TEXTUREACCESS_TARGET :暂时没有理解

w :纹理的宽

h :纹理的高

创建成功则返回纹理的ID,失败返回0。

源代码分析

SDL_CreateTexture()的源代码位于render\SDL_render.c中。如下所示。

SDL_Texture *
SDL_CreateTexture(SDL_Renderer * renderer, Uint32 format, int access, int w, int h)
{
    SDL_Texture *texture;
    SDL_bool texture_is_fourcc_and_target;

    CHECK_RENDERER_MAGIC(renderer, NULL);

    if (!format) {
        format = renderer->info.texture_formats[0];
    }
    if (SDL_BYTESPERPIXEL(format) == 0) {
        SDL_SetError("Invalid texture format");
        return NULL;
    }
    if (SDL_ISPIXELFORMAT_INDEXED(format)) {
        SDL_SetError("Palettized textures are not supported");
        return NULL;
    }
    if (w <= 0 || h <= 0) {
        SDL_SetError("Texture dimensions can't be 0");
        return NULL;
    }
    if ((renderer->info.max_texture_width && w > renderer->info.max_texture_width) ||
        (renderer->info.max_texture_height && h > renderer->info.max_texture_height)) {
        SDL_SetError("Texture dimensions are limited to %dx%d", renderer->info.max_texture_width, renderer->info.max_texture_height);
        return NULL;
    }
    texture = (SDL_Texture *) SDL_calloc(1, sizeof(*texture));
    if (!texture) {
        SDL_OutOfMemory();
        return NULL;
    }
    texture->magic = &texture_magic;
    texture->format = format;
    texture->access = access;
    texture->w = w;
    texture->h = h;
    texture->r = 255;
    texture->g = 255;
    texture->b = 255;
    texture->a = 255;
    texture->scaleMode = SDL_GetScaleMode();
    texture->renderer = renderer;
    texture->next = renderer->textures;
    if (renderer->textures) {
        renderer->textures->prev = texture;
    }
    renderer->textures = texture;

    /* FOURCC format cannot be used directly by renderer back-ends for target texture */
    texture_is_fourcc_and_target = (access == SDL_TEXTUREACCESS_TARGET && SDL_ISPIXELFORMAT_FOURCC(texture->format));

    if (texture_is_fourcc_and_target == SDL_FALSE && IsSupportedFormat(renderer, format)) {
        if (renderer->CreateTexture(renderer, texture) < 0) {
            SDL_DestroyTexture(texture);
            return NULL;
        }
    } else {
        int closest_format;

        if (texture_is_fourcc_and_target == SDL_FALSE) {
            closest_format = GetClosestSupportedFormat(renderer, format);
        } else {
            closest_format = renderer->info.texture_formats[0];
        }

        texture->native = SDL_CreateTexture(renderer, closest_format, access, w, h);
        if (!texture->native) {
            SDL_DestroyTexture(texture);
            return NULL;
        }

        /* Swap textures to have texture before texture->native in the list */
        texture->native->next = texture->next;
        if (texture->native->next) {
            texture->native->next->prev = texture->native;
        }
        texture->prev = texture->native->prev;
        if (texture->prev) {
            texture->prev->next = texture;
        }
        texture->native->prev = texture;
        texture->next = texture->native;
        renderer->textures = texture;

        if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
#if SDL_HAVE_YUV
            texture->yuv = SDL_SW_CreateYUVTexture(format, w, h);
#else
            SDL_SetError("SDL not built with YUV support");
#endif
            if (!texture->yuv) {
                SDL_DestroyTexture(texture);
                return NULL;
            }
        } else if (access == SDL_TEXTUREACCESS_STREAMING) {
            /* The pitch is 4 byte aligned */
            texture->pitch = (((w * SDL_BYTESPERPIXEL(format)) + 3) & ~3);
            texture->pixels = SDL_calloc(1, texture->pitch * h);
            if (!texture->pixels) {
                SDL_DestroyTexture(texture);
                return NULL;
            }
        }
    }
    return texture;
}

从源代码中可以看出,SDL_CreateTexture()的大致流程如下。

  1. 检查输入参数的合理性。例如像素格式是否支持,宽和高是否小于等于0等等。

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

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

参考文献

1、https://blog.csdn.net/leixiaohua1020/article/details/40743061

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SDL2/SDL.h: No such file or directory错误通常是因为缺少SDL2库文件。要解决这个问题,可以按照以下步骤进行操作: 1. 确保已经安装了SDL2库及其相关依赖包。可以使用包管理器来安装SDL2库。在Linux上,可以使用以下命令安装SDL2库及其开发包: ``` sudo apt-get install libsdl2-dev ``` 2. 如果已经安装了SDL2库但仍然报错,可以尝试重新安装库文件。可以使用以下命令卸载并重新安装SDL2库: ``` sudo apt-get remove libsdl2-dev sudo apt-get install libsdl2-dev ``` 3. 如果问题仍然存在,可以尝试手动添加SDL2库的路径。可以使用以下命令找到SDL2库的路径: ``` sdl2-config --cflags ``` 将输出的路径添加到编译命令中,例如: ``` gcc -o myprogram myprogram.c -I/path/to/sdl2 ``` 请确保将`/path/to/sdl2`替换为实际的SDL2库路径。 通过以上步骤,您应该能够解决SDL2/SDL.h: No such file or directory错误。希望对您有帮助! <span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [解决SDL/SDL.h: No such file or directory的方法](https://blog.csdn.net/liuqingsongmsdn2014/article/details/112241577)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值