创建纹理

有三个 API 可以用来创建纹理:

  • SDL_CreateTexture 参数少,使用方便,适用于创建简单的纹理
  • SDL_CreateTextureFromSurface

    适用于从已有图像数据创建纹理
  • SDL_CreateTextureWithProperties 可以指定各种属性,功能强大,用起来也比较复杂,适用于另外两个 API 无法满足需求的情况

实际上前两个 API 内部都是通过调用 SDL_CreateTextureWithProperties 实现纹理创建的。这也是 SDL API 设计的特点,对于常用操作有简洁的 API 实现,同时也有使用复杂但是功能更灵活强大的 API 提供。

这里我们准备创建一个最小的四种颜色的纹理,像素尺寸 2x2,也就是总计只有 4 个像素。首先使用数组定义图像数据:

uint8_t pixels[4 * 2 * 2] = {
0, 0, 255, 255, // b, g, r, a
0, 255, 0, 255, //
255, 0, 0, 255, //
0, 255, 255, 255 //
};

SDL 对像素格式的定义是按照从高位到低位的颜色命名的,所以上面的数据对应的格式是 SDL_PIXELFORMAT_ARGB8888

由于已经有像素数据,所以我们可以从图像数据创建 Surface 然后调用 SDL_CreateTextureFromSurface 从 Surface 创建纹理:

SDL_Surface* surface = SDL_CreateSurfaceFrom(pixels, 2, 2, 4 * 2, SDL_PIXELFORMAT_ARGB8888);
if (!surface) {
SDL_Log("Create surface failed: %s", SDL_GetError());
return -1;
} SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
if (!texture) {
SDL_Log("Create texture failed: %s", SDL_GetError());
return -1;
}

图像混合模式选择 None 也就是忽略透明通道,缩放模式选择临近点插值:

SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_NONE);
SDL_SetTextureScaleMode(texture, SDL_SCALEMODE_NEAREST);

渲染纹理

渲染纹理使用的 API 是 SDL_RenderTexture,可以通过参数指定渲染纹理的矩形区域,也可以指定目标矩形区域。这里我们选择渲染整个纹理到目标中心附近宽高各为窗口一般的矩形区域:

// 计算目标矩形
int width = 0;
int height = 0;
SDL_GetRenderOutputSize(renderer, &width, &height);
SDL_FRect dst_rect{};
dst_rect.w = width * 0.5f;
dst_rect.h = height * 0.5f;
dst_rect.x = (width - dst_rect.w) * 0.5f;
dst_rect.y = (height - dst_rect.h) * 0.5f; // 渲染
SDL_SetRenderDrawColor(renderer, 16, 0, 16, 255);
SDL_RenderClear(renderer);
SDL_RenderTexture(renderer, texture, nullptr, &dst_rect);
SDL_RenderPresent(renderer);

渲染效果如下:

图中每种颜色对应的是最初的 2x2 图像中的一个像素,因为前面我们选择的缩放模式是临近点插值。实际图像处理中使用更多的是双线性插值,我们可以修改前面的代码看下效果:

SDL_SetTextureScaleMode(texture, SDL_SCALEMODE_LINEAR);

渲染效果:

纹理格式

可以使用如下代码查询当前渲染器支持的纹理格式:

void PrintSupportedTextureFormats(SDL_Renderer* renderer)
{
SDL_PixelFormatEnum* texture_format = static_cast<SDL_PixelFormatEnum*>(SDL_GetProperty(
SDL_GetRendererProperties(renderer), SDL_PROP_RENDERER_TEXTURE_FORMATS_POINTER, nullptr));
int index = 0;
while (texture_format && *texture_format != SDL_PIXELFORMAT_UNKNOWN) {
SDL_Log("Texture format[%d]: %s", index, SDL_GetPixelFormatName(*texture_format));
++texture_format;
++index;
}
}

使用不同的图形引擎创建渲染器时支持的纹理格式也不相同,下面是在一台 Windows 11 系统笔记本上的测试结果:

Format direct3d11 direct3d12 direct3d(9) opengl opengles2 vulkan software
SDL_PIXELFORMAT_ARGB8888 Y Y Y Y Y Y Y
SDL_PIXELFORMAT_ABGR8888 - - - Y Y - -
SDL_PIXELFORMAT_XRGB8888 Y Y - Y Y Y Y
SDL_PIXELFORMAT_XBGR8888 - - - Y Y - -
SDL_PIXELFORMAT_XBGR2101010 Y Y - - - Y -
SDL_PIXELFORMAT_RGBA64_FLOAT Y Y - - - Y -
SDL_PIXELFORMAT_YV12 Y Y Y Y Y Y -
SDL_PIXELFORMAT_IYUV Y Y Y Y Y Y -
SDL_PIXELFORMAT_NV12 Y Y - Y Y Y -
SDL_PIXELFORMAT_NV21 Y Y - Y Y Y -
SDL_PIXELFORMAT_P010 Y Y - - - Y -

可以看到 SDL_PIXELFORMAT_ARGB8888 格式被包括软件实现在内的所有图形引擎支持,这正是我们前面选择使用该格式创建纹理的原因,可以方便的选择各个图形引擎进行测试。

SDL3 入门(5):纹理渲染的更多相关文章

  1. CSharpGL(8)使用3D纹理渲染体数据 (Volume Rendering) 初探

    CSharpGL(8)使用3D纹理渲染体数据 (Volume Rendering) 初探 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码 ...

  2. SDL 开发实战(五): SDL 纹理渲染

    本文我们讲一下如何使用SDL_Texture将视频纹理渲染出来. 1. SDL 视频渲染相关对象 SDL 视频渲染主要涉及到四个对象:SDL_Window.SDL_Render.SDL_Texture ...

  3. DXVA2解码数据用texture纹理渲染

    FFmpeg DXVA2解码得到的数据使用surface来承载的,surface限制很多,如果能用纹理来渲染的话,那我们就可以充分开发D3D,比如可以用坐标变换来实现电子放大的功能,还可以用坐标变换来 ...

  4. 转 cocos2d-x 优化(纹理渲染优化、资源缓存、内存优化)

    概述 包括以下5种优化:引擎底层优化.纹理优化.渲染优化.资源缓存.内存优化   引擎优化 2.0版本比1.0版本在算法上有所优化,效率更高.2.0版本使用OpenGl ES 2.0图形库,1.0版本 ...

  5. 入职第一天:前端leader手把手教我入门Vue服务器端渲染(SSR)

    继前段时间西安电面之后顺利拿到了OFFER,今天(5月2号)是我入职第一天,在简短的内部培训了一上午后,前端leader让我先了解下什么是vue的服务器端渲染(SSR). SSR,英文全称叫 Serv ...

  6. IOS 中openGL使用教程3(openGL ES 入门篇 | 纹理贴图(texture)使用)

    在这篇文章中,我们将学习如何在openGL中使用纹理贴图. penGL中纹理可以分为1D,2D和3D纹理,我们在绑定纹理对象的时候需要指定纹理的种类.由于本文将以一张图片为例,因此我们为我们的纹理对象 ...

  7. [WebGL入门]四,渲染准备

    注意:文章翻译http://wgld.org/,原作者杉本雅広(doxas),文章中假设有我的额外说明,我会加上[lufy:].另外.鄙人webgl研究还不够深入,一些专业词语,假设翻译有误,欢迎大家 ...

  8. 【JAVASCRIPT】React入门学习-文本渲染

    摘要 react 学习包括几个部分: 文本渲染 JSX 语法 组件化思想 数据流 文本渲染 1. 纯文本渲染 <!DOCTYPE html> <html> <head&g ...

  9. D3D三层Texture纹理经像素着色器实现渲染YUV420P

    简单记录一下这两天用Texture实现渲染YUV420P的一些要点. 在视频播放的过程中,有的时候解码出来的数据是YUV420P的.表面(surface)通过设置参数是可以渲染YUV420P的,但Te ...

  10. 什么是渲染目标(render target)&& 渲染到纹理(Render To Texture, RTT)详解

    渲染到纹理(Render To Texture, RTT)详解 RTT是现在很多特效里面都会用到的一项很基本的技术,实现起来很简单,也很重要.但是让人不解的是网上搜索了半天只找到很少的文章说这个事儿, ...

随机推荐

  1. Python 数据降级(重采样)

    在数据处理中,经常有高频数据转成低频,秒级数据转成分钟.小时数据等.我们将讨论以下方法: 使用 Pandas 的 resample 方法: 示例:将天数据转化成月数据. 代码示例: import pa ...

  2. 实战SQL优化(以MySQL深分页为例)

    1 准备表结构 CREATE TABLE `student` ( `id` int NOT NULL AUTO_INCREMENT, `user_no` varchar(50) CHARACTER S ...

  3. vivo 制品管理在 CICD 落地实践

    作者:vivo 互联网效能平台团队 - Chen Lingling 在DevOps实践中,制品管理是一个重要的组成部分,它可以帮助团队快速交付高质量.高可靠性的软件,本文将介绍在 DevOps 领域, ...

  4. C语言——函数基本知识

    什么是函数 函数的定义 函数就是程序中独立的功能.(简单来说就是把代码打包成整体,起个名字,方便以后使用) 函数的使用 定义函数的格式 格式: 返回值类型 函数名(形参1,形参2,...) { 函数体 ...

  5. 第一次至第三次PTAJava大作业分析

    (1)前言: 三次题目集的知识点: 正则表达式(Regular Expression,简称Regex或RegExp)是一个强大的文本处理工具,用于匹配.查找和替换字符串.以下是正则表达式的主要知识点总 ...

  6. vuex做购物车功能

    先创建一个cart组件 <template> <div> <ListItem></ListItem> </div> </templat ...

  7. git基础命令 gitHub

               git 和 gitHub             git : 本地项目版本管理工具             gitHub : 相当于一个有很多功能的百度云盘,存储本地项目版本,管 ...

  8. Vue学习:21.mixins混入

    在Vue中,mixins(混入)是一种用于分发Vue组件中可复用功能的灵活机制.它们允许你抽取组件中的共享功能,如数据.计算属性.方法.生命周期钩子等,并将其作为单独的模块复用到多个组件中.这种方式有 ...

  9. 项目管理--PMBOK 读书笔记(13)【项目相关方管理】

    1.相关方分矩阵 工具与技术 核查表 又叫检查表,计数表,收集属性数据,解决问题.   焦点小组&访谈: 特点:慢,焦点小组是一对多,访谈时多对多.   抽样统计&控制图: 控制图反应 ...

  10. springboot之日志配置-logback

    springboot之日志配置-logback 1.为什么使用logback logback是springboot默认集成的,是基于Sl4J的日志框架. logback的内核重写了,使得在某些关键路径 ...