创建纹理

有三个 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. 4G EPS 中的 User Plane

    目录 文章目录 目录 前文列表 用户平面 EPS UP 中的 GTP-U F-TEID 的组成 UE IP 数据包在 GTP-U Tunnel 上的封装流程 GTP-U 与 EPS Bearer MM ...

  2. ansible自定义模板部署apache服务

    使用Ansible来部署Apache服务是一个很好的选择,因为它可以自动化部署过程,确保所有的服务器上都有相同的配置.以下是一个简单的步骤指南,展示如何使用Ansible来部署Apache服务: 1 ...

  3. pageOffice插件 springboot实现服务器上Word文档在线打开编辑保存

    需求: 在oa系统上,想实现在线,服务器上doc,docx文档,在web打开,编辑.编辑后,可以再同步保存到服务器端. 开发环境: java springboot,thymeleaf 服务器环境: 无 ...

  4. Python:global、local与nonlocal变量

    1 local和global变量 先来看一个最简单的Python程序例子: import numpy as np n = 2 def func(a): b = 1 return a + b print ...

  5. webapi创建WCF WebService+WCF WebService远程服务调用

    首先需要引入soapcore包 这个包提供了所需的类和soap终结点中间件. 引入这个这个包之后,我们需要定义提供的服务. 这里我写了一个用于查询省份面积的服务. 省份信息服务 /// <sum ...

  6. YiShaAdmin:一款基于.NET Core Web + Bootstrap的企业级快速开发框架

    前言 今天大姚给大家分享一款基于.NET Core Web + Bootstrap的企业级快速后台开发框架.权限管理系统,代码简单易懂.界面简洁美观(基于MIT License开源,免费可商用):Yi ...

  7. django中的多表关联

    一.三种关联情况 二.ORM的正向操作和反向操作 1.正向操作: 一个模型中定义了一个外键,通过该模型对该外键操作的操作叫做正向操作. 2.反向操作: 被外键所关联的模型,通过该模型对外键所在模型的操 ...

  8. Opencv笔记(12)傅里叶变换

    在之前了解的OpenCV为我们实现的图像变换,这些本质上是从图像到输出图像的映射,即输入仍是一幅图像.本章的傅里叶变换,输出数组的值在含义上和原图像的强度值大不相同,是输入图像的频域表示. cv::d ...

  9. 如何使用Node.js、TypeScript和Express实现RESTful API服务

    Node.js是一个基于 Chrome V8 引擎的 JavaScript 运行环境.Node.js 使用了一个事件驱动.非阻塞式 I/O 的模型,使其轻量又高效.Express是一个保持最小规模的灵 ...

  10. DevOps全面综述:从概念到实践

    这篇文章详尽介绍了DevOps的背景.核心实践.工具和技术,探讨了团队协作.文化建设及组织变革,旨在帮助企业高效实现持续交付和创新. 关注作者,分享互联网架构.云服务技术的全维度知识.作者拥有10+年 ...