【发布时间】:2019-04-09 13:31:59
【问题描述】:
我会尽量使这个问题简洁明了,但请不要犹豫,要求澄清。
我正在处理遗留代码,我正在尝试从磁盘加载数千个 8 位图像,以便为每个图像创建纹理。
我尝试了多种方法,现在我正试图将我的 8 位图像加载到 32 位表面,然后从该表面创建纹理。
问题:在将 8 位图像加载到 32 位表面时,当我尝试 SDL_CreateTextureFromSurface 时,我最终得到了很多完全空白的纹理(充满透明像素,0x00000000)。
并不是所有的纹理都是错误的,我想。每次我运行程序时,我都会得到不同的“坏”纹理。有时多,有时少。而且当我跟踪程序时,我总是以正确的纹理结束(这是时间问题吗?)
我知道加载到SDL_Surface 的工作正常,因为我将所有表面保存到磁盘,它们都是正确的。但是我使用NVidia NSight Graphics检查了纹理,其中一半以上是空白的。
这是有问题的代码:
int __cdecl IMG_SavePNG(SDL_Surface*, const char*);
SDL_Texture* Resource8bitToTexture32(SDL_Renderer* renderer, SDL_Color* palette, int paletteSize, void* dataAddress, int Width, int Height)
{
u32 uiCurrentOffset;
u32 uiSourceLinearSize = (Width * Height);
SDL_Color *currentColor;
char strSurfacePath[500];
// The texture we're creating
SDL_Texture* newTexture = NULL;
// Load image at specified address
SDL_Surface* tempSurface = SDL_CreateRGBSurface(0x00, Width, Height, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
SDL_SetSurfaceBlendMode(tempSurface, SDL_BLENDMODE_NONE);
if(SDL_MUSTLOCK(tempSurface)
SDL_LockSurface(tempSurface);
for(uiCurrentOffset = 0; uiCurrentOffset < uiSourceLinearSize; uiCurrentOffset++)
{
currentColor = &palette[pSourceData[uiCurrentOffset]];
if(pSourceData[uiCurrentOffset] != PC_COLOR_TRANSPARENT)
{
((u32*)tempSurface->pixels)[uiCurrentOffset] = (u32)((currentColor->a << 24) + (currentColor->r << 16) + (currentColor->g << 8) + (currentColor->b << 0));
}
}
if(SDL_MUSTLOCK(tempSurface)
SDL_UnlockSurface(tempSurface);
// Create texture from surface pixels
newTexture = SDL_CreateTextureFromSurface(renderer, tempSurface);
// Save the surface to disk for verification only
sprintf(strSurfacePath, "c:\\tmp\\surfaces\\%s.png", GenerateUniqueName());
IMG_SavePNG(tempSurface, strSurfacePath);
// Get rid of old loaded surface
SDL_FreeSurface(tempSurface);
return newTexture;
}
请注意,在原始代码中,我正在检查边界,并在 SDL_Create* 之后检查 NULL。我也知道最好有一个纹理的精灵表,而不是单独加载每个纹理。
编辑: 这是我在 NSight 中观察到的一个示例,如果我捕获一个帧并使用资源视图。
前 3186 个纹理是正确的。然后我得到 43 个空纹理。然后我得到 228 个正确的纹理。然后是100个坏的。然后是 539 个正确的。然后是665个坏的。它像那样随机运行,每次运行程序时都会发生变化。
同样,每次IMG_SavePNG 保存的表面都是正确的。这似乎表明当我打电话给SDL_CreateTextureFromSurface 时发生了一些事情,但在那时,我不想排除任何事情,因为这是一个非常奇怪的问题,而且它到处都闻到了未定义的行为。但我就是找不到问题。
【问题讨论】:
-
听起来您正在某处处理未定义的行为。我将首先摆脱
Lock/Unlock Surface电话;由于表面未经过 RLE 优化,因此不需要它们。另外,我认为您可能会丢失memset调用以将像素归零。它们已经为零。 -
感谢您的评论!你说得对,我会删除
SDL_memset。 help page for SDL_LockSurface 似乎表明我们应该在访问像素之前锁定,而不是因为表面是 RLE 优化的。我会在锁定和解锁之前向SDL_MUSTLOCK添加支票。 -
参见this page 关于 SDL 文档需要注意的一点是,它参差不齐,因此您几乎必须阅读整个内容,然后阅读源代码。
-
我测试了有无表面锁定,但我仍然遇到同样的问题。我将编辑我的问题以添加我正在观察的问题类型的示例。
-
“坏”是指像素映射到错误的颜色?