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

170 lines
4.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 将 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