feat(资源加载): 替换stb_image为SDL_image并添加脚本解析功能

- 将stb_image替换为SDL_image以解决Switch平台兼容性问题
- 添加PVF资源包解析器和脚本解析器功能
- 修改各平台配置文件添加SDL_image依赖
- 更新纹理加载逻辑使用SDL_image API
- 新增脚本解析相关类用于处理游戏脚本数据
This commit is contained in:
2026-03-18 04:18:57 +08:00
parent a4883b433e
commit cb9f497fbb
17 changed files with 1647 additions and 32 deletions

View File

@@ -0,0 +1,169 @@
# 将 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 <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