- 将stb_image替换为SDL_image以解决Switch平台兼容性问题 - 添加PVF资源包解析器和脚本解析器功能 - 修改各平台配置文件添加SDL_image依赖 - 更新纹理加载逻辑使用SDL_image API - 新增脚本解析相关类用于处理游戏脚本数据
170 lines
4.8 KiB
Markdown
170 lines
4.8 KiB
Markdown
# 将 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
|