SDL2 - 在纹理上绘制完全透明的圆形

7
我正在使用SDL 2.0开发2D游戏,我的光照系统存在问题。我想用雾填充屏幕,并在玩家周围创建透明的圆圈(左下角)。我知道如何使用SDL_BLENDMODE_MOD创建有色光源的黑暗房间(右下角),但是我无法创建雾气效果。我尝试使用每种SDL_SetRenderDrawBlendMode()和SDL_SetTextureBlendMode()的组合来覆盖多个纹理层在屏幕上,但是没有成功。我在StackOverflow上搜索到了一些解决方案,例如这里,但它们使用SDL surfaces和预先制作的灯光图像。我将动态更改输入图像(右上角)的形状和大小,因此需要更灵活的解决方案。
解决方案1:不使用白色圆圈和黑色背景,而是使用黑色圆圈和深蓝色背景。然后使用屏幕混合混合它得到雾效果(我在图像编辑器中测试过这个方法并得到了左下角的图像)。不幸的是,SDL没有SDL_BLENDMODE_SCREEN。
解决方案2:创建一个半透明的雾层并在其中打一个全透明的洞。不幸的是,我不知道如何用透明洞覆盖一个纹理。我尝试将绘画模式设置为SDL_BLENDMODE_NONE,并绘制一个完全透明的圆圈,但它只会创建完全不透明的圆圈。文档说可以替换目标alpha,但这似乎不起作用...

我也遇到了这个问题。如果你使用sdl2-gfx来绘制圆形,它会明确地将混合模式更改为SDL_BLENDMODE_ALPHABLEND,完全忽略你设置的混合模式。这里的(可怕的)解决方案是不使用 alpha 进行绘制,然后通过SDL_ComposeCustomBlendMode使用自定义混合模式将光层合并。 - Sandy Maguire
1个回答

0

以下是一系列建议,而非确定性答案。如果您可以使用着色器,则可以使用一行代码的片段着色器来实现您想要的效果。除此之外,我不知道有什么简单的解决方案可以完全满足您的需求。

首先,您可能需要在纹理的 alpha 通道中生成(或存储)您的“掩码”图像(而不是颜色通道),以便它在 alpha 混合中产生任何效果。

我建议在掩码纹理中使用反转的 alpha 值:将玩家周围的圆形(或其他形状)设置为,并用接近 255 的“雾值”(或者如果您使用实数,则为 1.0)填充雾部分。这样可以防止在中间的清晰圆圈中绘制任何内容。

现在,如果你已经用一个实心的“雾色”(可能不需要制作形状或其他东西)填满了整个遮罩纹理,并注意不要干扰 alpha 通道,那么将你的 SDL_SetTextureBlendMode() 设置为 SDL_BLENDMODE_BLEND 并做一个 SDL_RenderCopy(),你就可以达到你想要的效果。特别是当你在遮罩纹理中设置了明亮的“雾色”(而不是值,颜色),例如你样本图像中的青色。它不会完全匹配你的“屏幕混合模式”,但你可以接近。

你也可以尝试使用 SDL_BLENDMODE_ADD。它甚至可能会给你更好的效果(用于产生雾的效果)。

无论如何,在你的雾遮罩纹理中(这是所有混合中的“源”),你设置了一个实心的 雾色,并将 alpha 通道设置为一个实心的 雾值,然后仅在 alpha 通道中绘制玩家周围的空白区域,使用一个值为


我该如何将图像存储在纹理的alpha值中?我知道如何使用RenderCopy()在一个纹理上覆盖另一个纹理,但是我不知道如何访问纹理的alpha通道。 - DragonDePlatino

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接