对 SDL_SetSurfaceAlphaMod 的困惑
Confusion over SDL_SetSurfaceAlphaMod
我已阅读 SDL_SetSurfaceAlphaMod 上的文档。虽然 alpha 调制公式看起来非常简单,但我无法预测在代码中使用它的结果。显然我的理解是不完整的。
为了阐明我的想法,我写了一段代码(见下文)。 想法是在红色背景上放置四个黑色方块,两排两排。
顶部的两个方块是黑色的,因为这是使用 SDL_CreateRGBSurface 创建的表面的默认颜色。 SDL_FillRect 未使用。
底部的两个方块在创建后使用 SDL_FillRect 将它们设置为黑色(即使它们无论如何都是黑色的)。
左边的方块的 alpha 调制值为 0。
右侧方块的 alpha 调制值为 255。
int main(int argc, char ** argv)
{
SDL_Window * windowMain;
SDL_Surface * surfaceMain;
Uint32 rmask, gmask, bmask, amask;
// Main window suface - red background
windowMain = SDL_CreateWindow("Test Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 480, 360, 0);
surfaceMain = SDL_GetWindowSurface(windowMain);
Uint32 redBG = SDL_MapRGB(surfaceMain->format, 255, 0, 0);
SDL_FillRect(surfaceMain, NULL, redBG);
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
rmask = 0xff000000;
gmask = 0x00ff0000;
bmask = 0x0000ff00;
amask = 0x000000ff;
#else
rmask = 0x000000ff;
gmask = 0x0000ff00;
bmask = 0x00ff0000;
amask = 0xff000000;
#endif
SDL_Surface * noFillSquare = SDL_CreateRGBSurface(0, 100, 100, 32, rmask, gmask, bmask, amask);
SDL_Surface * blackFillSquare = SDL_CreateRGBSurface(0, 100, 100, 32, rmask, gmask, bmask, amask);
Uint32 blackFG = SDL_MapRGB(blackFillSquare->format, 0, 0, 0);
SDL_FillRect(blackFillSquare, NULL, blackFG);
while (true)
{
showSurface(noFillSquare, surfaceMain, 0, 0, 100, 50); // Top left rectangle
showSurface(noFillSquare, surfaceMain, 255, 0, 300, 50); // Top right rectangle (not displayed)
showSurface(blackFillSquare, surfaceMain, 0, 0, 100, 200); // Bottom left rectangle
showSurface(blackFillSquare, surfaceMain, 255, 0, 300, 200); // Bottom right rectangle
SDL_UpdateWindowSurface(windowMain);
}
return 1;
}
void showSurface(SDL_Surface * srcSurface, SDL_Surface * dstSurface, Uint8 srcAlpha, Uint8 dstAlpha, int x, int y)
{
SDL_Rect rect = { x, y, srcSurface->w, srcSurface->h };
SDL_SetSurfaceAlphaMod(srcSurface, srcAlpha);
SDL_SetSurfaceAlphaMod(dstSurface, dstAlpha);
SDL_BlitSurface(srcSurface, NULL, dstSurface, &rect);
}
运行代码显示结果:
Display from above code
如您所见,右上角的黑色方块未显示。
我想请求详细说明为什么一个方块没有出现,而其他三个出现。
我发现 SDL 2.0 文档非常粗略,尤其是涉及到曲面时。
创建表面时,SDL 会对像素数组执行 memset(0)
。它确实会产生黑色,但 alpha 也变为 0 - 这是完全透明的。将 0 乘以 alpha 修饰符仍会得到 0。
FillRect 将 alpha 替换为完全不透明的颜色,因为您使用 SDL_MapRGB
而不是例如SDL_MapRGBA
阿尔法为 0。
我用 2.0.10 版本覆盖了 SDL 2.0.9 包含文件和库,问题立即消失了。
我现在得到了预期的输出。
The correct output
不太确定之前出了什么问题 - 也许是一些不匹配的库文件?
我已阅读 SDL_SetSurfaceAlphaMod 上的文档。虽然 alpha 调制公式看起来非常简单,但我无法预测在代码中使用它的结果。显然我的理解是不完整的。
为了阐明我的想法,我写了一段代码(见下文)。 想法是在红色背景上放置四个黑色方块,两排两排。
顶部的两个方块是黑色的,因为这是使用 SDL_CreateRGBSurface 创建的表面的默认颜色。 SDL_FillRect 未使用。
底部的两个方块在创建后使用 SDL_FillRect 将它们设置为黑色(即使它们无论如何都是黑色的)。
左边的方块的 alpha 调制值为 0。
右侧方块的 alpha 调制值为 255。
int main(int argc, char ** argv)
{
SDL_Window * windowMain;
SDL_Surface * surfaceMain;
Uint32 rmask, gmask, bmask, amask;
// Main window suface - red background
windowMain = SDL_CreateWindow("Test Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 480, 360, 0);
surfaceMain = SDL_GetWindowSurface(windowMain);
Uint32 redBG = SDL_MapRGB(surfaceMain->format, 255, 0, 0);
SDL_FillRect(surfaceMain, NULL, redBG);
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
rmask = 0xff000000;
gmask = 0x00ff0000;
bmask = 0x0000ff00;
amask = 0x000000ff;
#else
rmask = 0x000000ff;
gmask = 0x0000ff00;
bmask = 0x00ff0000;
amask = 0xff000000;
#endif
SDL_Surface * noFillSquare = SDL_CreateRGBSurface(0, 100, 100, 32, rmask, gmask, bmask, amask);
SDL_Surface * blackFillSquare = SDL_CreateRGBSurface(0, 100, 100, 32, rmask, gmask, bmask, amask);
Uint32 blackFG = SDL_MapRGB(blackFillSquare->format, 0, 0, 0);
SDL_FillRect(blackFillSquare, NULL, blackFG);
while (true)
{
showSurface(noFillSquare, surfaceMain, 0, 0, 100, 50); // Top left rectangle
showSurface(noFillSquare, surfaceMain, 255, 0, 300, 50); // Top right rectangle (not displayed)
showSurface(blackFillSquare, surfaceMain, 0, 0, 100, 200); // Bottom left rectangle
showSurface(blackFillSquare, surfaceMain, 255, 0, 300, 200); // Bottom right rectangle
SDL_UpdateWindowSurface(windowMain);
}
return 1;
}
void showSurface(SDL_Surface * srcSurface, SDL_Surface * dstSurface, Uint8 srcAlpha, Uint8 dstAlpha, int x, int y)
{
SDL_Rect rect = { x, y, srcSurface->w, srcSurface->h };
SDL_SetSurfaceAlphaMod(srcSurface, srcAlpha);
SDL_SetSurfaceAlphaMod(dstSurface, dstAlpha);
SDL_BlitSurface(srcSurface, NULL, dstSurface, &rect);
}
运行代码显示结果:
Display from above code
如您所见,右上角的黑色方块未显示。
我想请求详细说明为什么一个方块没有出现,而其他三个出现。
我发现 SDL 2.0 文档非常粗略,尤其是涉及到曲面时。
创建表面时,SDL 会对像素数组执行 memset(0)
。它确实会产生黑色,但 alpha 也变为 0 - 这是完全透明的。将 0 乘以 alpha 修饰符仍会得到 0。
FillRect 将 alpha 替换为完全不透明的颜色,因为您使用 SDL_MapRGB
而不是例如SDL_MapRGBA
阿尔法为 0。
我用 2.0.10 版本覆盖了 SDL 2.0.9 包含文件和库,问题立即消失了。
我现在得到了预期的输出。
The correct output
不太确定之前出了什么问题 - 也许是一些不匹配的库文件?