Files
Frostbite2D/.opencode/plans/replace_stb_with_sdl_image.md
Lenheart cb9f497fbb feat(资源加载): 替换stb_image为SDL_image并添加脚本解析功能
- 将stb_image替换为SDL_image以解决Switch平台兼容性问题
- 添加PVF资源包解析器和脚本解析器功能
- 修改各平台配置文件添加SDL_image依赖
- 更新纹理加载逻辑使用SDL_image API
- 新增脚本解析相关类用于处理游戏脚本数据
2026-03-18 04:18:57 +08:00

4.8 KiB
Raw Blame History

将 stb_image 替换为 SDL_image 完整计划

概述

将项目中的 stb_image 完全替换为 SDL_image以解决 Switch 平台兼容性问题。

修改文件清单

1. 平台配置文件3个文件

  • platform/mingw.lua - Windows/Mingw 配置
  • platform/linux.lua - Linux 配置
  • platform/switch.lua - Switch 配置

2. 核心代码文件1个文件

  • Frostbite2D/src/frostbite2D/graphics/texture.cpp - 纹理加载实现

详细修改方案

修改 1: platform/mingw.lua

变更: 添加 SDL_image 依赖

-- 修改前
add_requires("libsdl2", {configs = {shared = true}})
add_requires("glm")

-- 修改后
add_requires("libsdl2", {configs = {shared = true}})
add_requires("libsdl2_image", {configs = {shared = true}})
add_requires("glm")

-- 在 add_packages 部分添加
add_packages("libsdl2")
add_packages("libsdl2_image")
add_packages("glm")

修改 2: platform/linux.lua

变更: 添加 SDL_image 依赖

-- 修改前
add_requires("libsdl2", {configs = {shared = true,wayland = true}})
add_requires("glm")

-- 修改后
add_requires("libsdl2", {configs = {shared = true,wayland = true}})
add_requires("libsdl2_image")
add_requires("glm")

-- 在 add_packages 部分添加
add_packages("libsdl2")
add_packages("libsdl2_image")
add_packages("glm")

修改 3: platform/switch.lua

变更: 添加 SDL2_image 库链接

-- 修改前
add_syslinks("SDL2_mixer", "SDL2", "opusfile", "opus", "vorbisidec", "ogg",
                     "modplug", "mpg123", "FLAC", "GLESv2", "EGL", "glapi", "drm_nouveau",
                     {public = true})

-- 修改后
add_syslinks("SDL2_mixer", "SDL2_image", "SDL2", "opusfile", "opus", "vorbisidec", "ogg",
                     "modplug", "mpg123", "FLAC", "GLESv2", "EGL", "glapi", "drm_nouveau",
                     {public = true})

修改 4: texture.cpp

变更: 完全重写 loadFromFile 函数,使用 SDL_image

#include <cstdio>
#include <cstdlib>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>

// 移除所有 stb_image 相关的定义和 include
// #define STB_IMAGE_IMPLEMENTATION
// #include <stb/stb_image.h>

namespace frostbite2D {

Ptr<Texture> Texture::loadFromFile(const std::string& path) {
  Asset& asset = Asset::get();
  std::string resolvedPath = asset.resolveAssetPath(path);
  std::vector<uint8> fileData;
  
  SDL_Log("LoadQ");
  if (!asset.readBinaryFile(path, fileData)) {
    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to read texture file: %s", resolvedPath.c_str());
    return nullptr;
  }
  SDL_Log("LoadQ1: file size = %zu bytes", fileData.size());
  
  if (fileData.empty()) {
    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Texture file is empty: %s", resolvedPath.c_str());
    return nullptr;
  }
  
  // 使用 SDL_image 从内存加载
  SDL_RWops* rw = SDL_RWFromConstMem(fileData.data(), static_cast<int>(fileData.size()));
  if (!rw) {
    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create RWops: %s", SDL_GetError());
    return nullptr;
  }
  
  SDL_Surface* surface = IMG_Load_RW(rw, 1);
  if (!surface) {
    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to load image: %s", IMG_GetError());
    SDL_FreeRW(rw);
    return nullptr;
  }
  
  SDL_Log("LoadQ2: %dx%d, format: %d", surface->w, surface->h, surface->format->format);
  
  // 确定格式
  GLenum format;
  int channels;
  if (surface->format->BytesPerPixel == 4) {
    format = GL_RGBA;
    channels = 4;
  } else {
    format = GL_RGB;
    channels = 3;
  }
  
  int width = surface->w;
  int height = surface->h;
  
  uint32_t textureID;
  glGenTextures(1, &textureID);
  glBindTexture(GL_TEXTURE_2D, textureID);
  
  glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, surface->pixels);
  
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  
  glBindTexture(GL_TEXTURE_2D, 0);
  
  SDL_FreeSurface(surface);
  
  auto texture = Ptr<Texture>(new Texture(width, height, textureID));
  texture->path_ = resolvedPath;
  texture->channels_ = channels;
  
  SDL_Log("Loaded texture: %s (%dx%d, %d channels)", resolvedPath.c_str(), width, height, channels);
  
  return texture;
}

// ... 其余函数保持不变
}

实施步骤

  1. 修改 3 个平台配置文件,添加 SDL_image 依赖
  2. 修改 texture.cpp替换 stb_image 为 SDL_image
  3. 清理 xmake 缓存
  4. 重新编译项目
  5. 测试所有平台

注意事项

  • SDL_image 支持的图片格式包括: PNG, JPEG, BMP, GIF, TIFF, WebP 等
  • 确保所有平台都能正确链接 SDL_image 库
  • Switch 平台的 devkitPro/portlibs 应该已经包含 SDL2_image