# 将 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 依赖 ```lua -- 修改前 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 依赖 ```lua -- 修改前 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 库链接 ```lua -- 修改前 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 ```cpp #include #include #include #include // 移除所有 stb_image 相关的定义和 include // #define STB_IMAGE_IMPLEMENTATION // #include namespace frostbite2D { Ptr Texture::loadFromFile(const std::string& path) { Asset& asset = Asset::get(); std::string resolvedPath = asset.resolveAssetPath(path); std::vector 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(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(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