- 将stb_image替换为SDL_image以解决Switch平台兼容性问题 - 添加PVF资源包解析器和脚本解析器功能 - 修改各平台配置文件添加SDL_image依赖 - 更新纹理加载逻辑使用SDL_image API - 新增脚本解析相关类用于处理游戏脚本数据
4.8 KiB
4.8 KiB
将 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;
}
// ... 其余函数保持不变
}
实施步骤
- 修改 3 个平台配置文件,添加 SDL_image 依赖
- 修改 texture.cpp,替换 stb_image 为 SDL_image
- 清理 xmake 缓存
- 重新编译项目
- 测试所有平台
注意事项
- SDL_image 支持的图片格式包括: PNG, JPEG, BMP, GIF, TIFF, WebP 等
- 确保所有平台都能正确链接 SDL_image 库
- Switch 平台的 devkitPro/portlibs 应该已经包含 SDL2_image