|
本帖最后由 ancientcc 于 2016-7-6 15:25 编辑
在渲染器内创建纹理。
语法
- 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获得更多错误信息。
范例
注释
支持的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_type | GL_TEXTURE_2D | 固定是GL_TEXTURE_2D | pixel_format | 来自上面计算出的format | GL_RGBA | pixel_type | 来自上面计算出的type | GL_UNSIGNED_BYTE | yuv | 根据格式判断,是IYUV、YV12置1,否则0 | | nv12 | 根据格式判断,是NV12、NV21置1,否则0 | |
- access==SDL_TEXTUREACCESS_STREAMING,会分配个blob用于存储图像数据,pixel_data指向这个数据块。
- 初始化该纹理,以下是涉及到的opengl api
- glGenTextures(1, &data->texture);
- glActiveTexture(GL_TEXTURE0); // 激活GL_TEXTURE0纹理单元,以便后续的gl调用是这个活动单元。
- glBindTexture(data->texture_type, data.texture);
- glTexParameteri(data->texture_type, GL_TEXTURE_MIN_FILTER, scaleMode); // 如何计算scaleMode见上面的缩放方式
- glTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, scaleMode);
- glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- 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。
- glGenFramebuffers(1, &result->FBO);
复制代码
相关类、函数
SDL_CreateTextureFromSurface
SDL_DestroyTexture
SDL_QueryTexture
SDL_UpdateTexture |
|