在某些而非全部表面上调用时,SDL_GetRGBA返回垃圾的问题

时间:2019-03-05 09:17:22

标签: c++ sdl-2

我有一个用于创建纹理的bmp图像

SDL_Surface *temp = SDL_LoadBMP((RES + path + ".bmp").c_str());
surface = SDL_ConvertSurfaceFormat(temp,SDL_PIXELFORMAT_ABGR8888,0);
SDL_FreeSurface(temp);
texture = SDL_CreateTextureFromSurface(renderer, surface);

,然后保存为自定义文件的一部分(之前和之后的所有内容都很好)

struct PixelRGBA{
    unsigned char r,g,b,a;
};  
PixelRGBA *surfaceToPixel(SDL_Surface *surface){
    PixelRGBA *ret = new PixelRGBA[surface->w * surface->h];
    SDL_LockSurface(surface);
    for (unsigned long long i = 0; i < surface->w * surface->h; i++){
        SDL_GetRGBA(
            ((unsigned int *)surface->pixels)[i],
            surface->format,
            &(ret[i].r),
            &(ret[i].g),
            &(ret[i].b),
            &(ret[i].a));
        std::cout << (unsigned int)ret[i].r << " " << (unsigned int)ret[i].g << " " << (unsigned int)ret[i].b << " " << (unsigned int)ret[i].a << std::endl;
    }
    SDL_UnlockSurface(surface);
    return ret;
}
#define BINO(x) write((char *)&x, sizeof(x))
std::ostream &operator<<(std::ostream &os, const PixelRGBA &obj)
{
    os.BINO(obj.r)
        .BINO(obj.g)
        .BINO(obj.b)
        .BINO(obj.a);
    return os;
}
//How it is saved
PixelRGBA *pixels = surfaceToPixel(obj.surface);
for (unsigned long long i = 0; i < w * h; i++)
    os << pixels[i];  

在下一次运行中,我将加载此自定义文件而不是bmp

#define BINI(x) read((char *)&x, sizeof(x))
std::istream &operator>>(std::istream &is, PixelRGBA &obj)
{
    is.BINI(obj.r)
      .BINI(obj.g)
      .BINI(obj.b)
      .BINI(obj.a);
    return is;
}
SDL_Texture *textureFromSurface(SDL_Surface *surface)
{
    SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
    return texture;
}
SDL_Surface *surfaceFromRGBA(PixelRGBA *data, int w, int h)
{
    SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormatFrom(
        (void *)data,
        w,
        h,
        sizeof(PixelRGBA)*8,
        sizeof(PixelRGBA) * w,
        SDL_PIXELFORMAT_ABGR8888);
    return surface;
}
//How it is loaded
PixelRGBA pixels[w * h];
for (unsigned long long i = 0; i < w * h; i++)
    is >> pixels[i];
obj.surface = surfaceFromRGBA(pixels, w, h);
obj.texture = textureFromSurface(obj.surface);  

到目前为止一切正常。
但是,当我然后尝试保存从内存创建的此表面时,使用与从bmp创建的表面相同的方法,该方法可以正常工作-surfaceToRGBA返回完整的垃圾,没有错误地格式化,只是垃圾(如果总是相似,则第一个像素应为00 00 00 00,但变为DD FF FF FF)。
我用HxD和std :: cout检查了bmp一切都按预期工作,它完全按我的要求保存。而且我可以很好地加载自定义文件。
只有当我尝试重新保存它时,它才会损坏并保存随机内容。
但是即使这样,文件的大小也不会改变,其余文件仍然完好无损并按预期加载(已通过HxD和调试器检查)。

文档说,从表面创建纹理不会改变它,它不会被释放,也无法在其他任何地方访问。我花了一整天的时间尝试各种不同的事情,例如测试surfaceToPixel中的表面间距/像素大小是否有问题,surfaceFromRGBA中的格式是否有问题(这就是为什么我知道它不是不匹配的格式,我已经看到了看起来像什么,它无法将00 00 00 00转换为DD FF FF FF fe),但发生了完全相同的事情。

我机智。它不是世界末日,因为它生成后我真的不需要重新保存它。我仍然可以加载完整版本的自定义文件。真的很不满意。
因此,除非有人弄清楚f在这里发生了什么,否则我将继续并继续制作程序的其他部分。

0 个答案:

没有答案