创建纹理

有三个 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. 一个免费、时尚、强大的 Windows GitHub 客户端

    前言 今天大姚给大家分享一个.NET开源(MIT License).免费.时尚.功能强大的 Windows GitHub 客户端:FluentHub. 工具功能 多任务标签页. 上下文菜单扩展. 对问 ...

  2. Swoole 源码分析之 Timer 定时器模块

    原文首发链接:Swoole 源码分析之 Timer 定时器模块 大家好,我是码农先森. 引言 Swoole 中的毫秒精度的定时器.底层基于 epoll_wait 和 setitimer 实现,数据结构 ...

  3. HTML——基本标签

    1.标题标签 <h1>标题1</h1> <h2>标题2</h2> <h3>标题3</h3> <h4>标题4</ ...

  4. PaddleOCR在 windows下的webAPI部署方案

    很多小伙伴在使用OCR时都希望能过采用API的方式调用,这样就可以跨端跨平台了.本文将介绍一种基于python的PaddleOCR识方案.喜欢的可以关注公众号,获取更多内容. # 一. windows ...

  5. k8s网络问题以及容器跨宿主机通信原理

    [0]资源配置文件 [root@mcwk8s03 mcwtest]# ls mcwdeploy.yaml [root@mcwk8s03 mcwtest]# cat mcwdeploy.yaml api ...

  6. vue3拉取代码install 报错 npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! While resolving: npm ERR! Found: vue@3.2.31

    先看报错 说明安装的包和现有的包已经冲突了版本不一致 我们先试一下npm install @vue/cli -- force然后再试一下npm install @vue/cli --legacy-pe ...

  7. 小程序的文件结构及配置 小程序配置 app.json

    程序包含一个描述整体程序的 app 和多个描述各自页面的 page. 一个小程序主体部分由三个文件组成,必须放在项目的根目录,如下: 文件 必填 作用 app.js 是 小程序逻辑-小程序入口文件 a ...

  8. springboot3时代创建springboot2程序项目

    springboot3时代创建springboot2程序项目 目前,IDEA,springboot 官网,都不能创建基于JDK8(JDK1.8)的springboot程序了. 解决办法: 1. 先在官 ...

  9. C#.NET 使用Windows证书库中的证书

    public static X509Certificate2 GetCertificate(string commonName, StoreName storeName) { X509Certific ...

  10. 使用 OpenTelemetry 构建可观测性 05 - 传播和行李(Propagation & Baggage)

    我们开发的应用程序可能具有不同的形态和架构:有些是单体应用,有些是微服务.为单体应用程序添加遥测数据相对来说简单,因为所有数据都在同一进程中.然而对于微服务应用程序,情况可能会更具挑战性. 通常,分布 ...