经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C 语言 » 查看文章
SDL3 入门(5):纹理渲染
来源:cnblogs  作者:小时了了  时间:2024/7/15 8:45:27  对本文有异议

创建纹理

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

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

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

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

  1. uint8_t pixels[4 * 2 * 2] = {
  2. 0, 0, 255, 255, // b, g, r, a
  3. 0, 255, 0, 255, //
  4. 255, 0, 0, 255, //
  5. 0, 255, 255, 255 //
  6. };

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

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

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

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

  1. SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_NONE);
  2. SDL_SetTextureScaleMode(texture, SDL_SCALEMODE_NEAREST);

渲染纹理

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

  1. // 计算目标矩形
  2. int width = 0;
  3. int height = 0;
  4. SDL_GetRenderOutputSize(renderer, &width, &height);
  5. SDL_FRect dst_rect{};
  6. dst_rect.w = width * 0.5f;
  7. dst_rect.h = height * 0.5f;
  8. dst_rect.x = (width - dst_rect.w) * 0.5f;
  9. dst_rect.y = (height - dst_rect.h) * 0.5f;
  10. // 渲染
  11. SDL_SetRenderDrawColor(renderer, 16, 0, 16, 255);
  12. SDL_RenderClear(renderer);
  13. SDL_RenderTexture(renderer, texture, nullptr, &dst_rect);
  14. SDL_RenderPresent(renderer);

渲染效果如下:

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

  1. SDL_SetTextureScaleMode(texture, SDL_SCALEMODE_LINEAR);

渲染效果:

纹理格式

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

  1. void PrintSupportedTextureFormats(SDL_Renderer* renderer)
  2. {
  3. SDL_PixelFormatEnum* texture_format = static_cast<SDL_PixelFormatEnum*>(SDL_GetProperty(
  4. SDL_GetRendererProperties(renderer), SDL_PROP_RENDERER_TEXTURE_FORMATS_POINTER, nullptr));
  5. int index = 0;
  6. while (texture_format && *texture_format != SDL_PIXELFORMAT_UNKNOWN) {
  7. SDL_Log("Texture format[%d]: %s", index, SDL_GetPixelFormatName(*texture_format));
  8. ++texture_format;
  9. ++index;
  10. }
  11. }

使用不同的图形引擎创建渲染器时支持的纹理格式也不相同,下面是在一台 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 格式被包括软件实现在内的所有图形引擎支持,这正是我们前面选择使用该格式创建纹理的原因,可以方便的选择各个图形引擎进行测试。

原文链接:https://www.cnblogs.com/xrunning/p/18301980

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号