SDL中文论坛

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 6181|回复: 0
打印 上一主题 下一主题

[SDL] SDL_CreateTexture

[复制链接]

149

主题

331

帖子

2445

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2445
跳转到指定楼层
楼主
发表于 2016-7-6 13:57:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 ancientcc 于 2016-7-6 15:25 编辑

在渲染器内创建纹理。

语法
  1. SDL_Texture* SDL_CreateTexture(SDL_Renderer* renderer, Uint32 format, int access, int w, int h)
复制代码


参数
renderer纹理要归属的渲染器
format像素格式,SDL_PixelFormatenum中的枚举值
access访问方法,SDL_TextureAccess中的枚举值。更多见注释中“支持的access值”
w像素单位的纹理宽度
h像素单位的纹理高度


返回值
如果成功创建,返回指向该纹理的指针,否则NULL。可能失败的原因:1)没有激活的上下文;2)不支持的像素格式;3)指定的宽度或高度超出范围。可调用SDL_GetError获得更多错误信息。

范例
  1. <Example>
复制代码


注释
支持的access值
SDL_TEXTUREACCESS_STATIC很少修改,不能上锁。修改指的是调用SDL_UpdateTexture修改像素数据
SDL_TEXTUREACCESS_STREAMING经常修改,能上锁。修改概念等同SDL_TEXTUREACCESS_STATIC
SDL_TEXTUREACCESS_TARGET可作为复制时的目标纹理。复制操作指SDL_RenderCopy、SDL_RenderCopyEx


缩放方式(scaleMode)
调用该函数前,可设置SDL_HINT_RENDER_SCALE_QUALITY选择希望的缩放方式。以下表格描述了选择到某个值时的条件。
使用它的条件
GL_NEAREST没有设置SDL_HINT_RENDER_SCALE_QUALITY,或空,或是nearest
GL_LINEAR除以上之外


纹理链表
渲染器用开环双向链表(SDL_Texture* textures)来存储内中纹理。纹理一旦创建,就会被加入链表,删除则从链表中移除。新建纹理被加到链表头部。

执行逻辑
  • 申请一块SDL_Texture大小的内存。
  • 检查format是否是渲染器能支持的格式。opengl es2支持的第一种式是SDL_PIXELFORMAT_ARGB8888。
  • 调用CreateTexture,opengs es2时对应的是GLES2_CreateTexture。接下描述该函数逻辑。
    • 根据像素格式得到format、type。对SDL_PIXELFORMAT_ARGB8888,它们的值分别是format=GL_RGBA,type = GL_UNSIGNED_BYTE。
    • 创建要挂接到该纹理的私有结构GLES2_TextureData,填充该结构。
      字段语义实例
      texture_typeGL_TEXTURE_2D固定是GL_TEXTURE_2D
      pixel_format来自上面计算出的formatGL_RGBA
      pixel_type来自上面计算出的typeGL_UNSIGNED_BYTE
      yuv根据格式判断,是IYUV、YV12置1,否则0
      nv12根据格式判断,是NV12、NV21置1,否则0
    • access==SDL_TEXTUREACCESS_STREAMING,会分配个blob用于存储图像数据,pixel_data指向这个数据块。
    • 初始化该纹理,以下是涉及到的opengl api
      1. glGenTextures(1, &data->texture);
      2. glActiveTexture(GL_TEXTURE0);  // 激活GL_TEXTURE0纹理单元,以便后续的gl调用是这个活动单元。
      3. glBindTexture(data->texture_type, data.texture);
      4. glTexParameteri(data->texture_type, GL_TEXTURE_MIN_FILTER, scaleMode); // 如何计算scaleMode见上面的缩放方式
      5. glTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, scaleMode);
      6. glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
      7. glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
      8. glTexImage2D(data->texture_type, 0, format, texture->w, texture->h, 0, format, type, NULL);  // 加载图像数据。像素字段置的是NULL,此时并没有真正上传数据。
      复制代码

    • access==SDL_TEXTUREACCESS_TARGET,会创建帧缓冲区对象fbo。 要注意的是,并不是一个纹理就会创建一个fbo,而是根据尺寸,多少种尺才对应多少个fbo,正因为这个原因,在SDL_DestroyTexture时不执行删除fbo,而是要等到SDL_DestroyRenderer时一并删除。创建fbo会调用以下gl api。
      1. glGenFramebuffers(1, &result->FBO);
      复制代码




相关类、函数
SDL_CreateTextureFromSurface
SDL_DestroyTexture
SDL_QueryTexture
SDL_UpdateTexture
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|丽谷软件|libsdl.cn

GMT+8, 2025-5-2 05:14 , Processed in 0.049124 second(s), 19 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表