c++ - SDL2 - 在纹理上绘制完全透明的圆圈

标签 c++ sdl-2 lighting alphablending

我正在使用 SDL 2.0 开发一款 2D 游戏,但我的光照系统出现了问题。我想用雾填充屏幕并在播放器周围创建一个透明圆圈(左下角)。我知道如何使用 SDL_BLENDMODE_MOD(右下角)用有色光制作暗室,但我无法制作雾。我已经尝试使用我能想到的 SDL_SetRenderDrawBlendMode() 和 SDL_SetTextureBlendMode() 的每种组合在屏幕上分层多个纹理。

image

我在 StackOverflow 上搜索并找到了解决方案,例如 this ,但他们使用 SDL 表面和预制光图像。我将动态更改输入图像(右上角)的形状和大小,因此我需要更灵活的东西。

解决方案 1:我没有使用白色圆圈和黑色背景,而是使用黑色圆圈和海军蓝背景。然后我使用 screen blending 混合它得到我的雾(我已经在图像编辑器中测试它以获得左下角的图像)。遗憾的是,SDL 没有 SDL_BLENDMODE_SCREEN。

解决方案 2:创建一个半透明的雾层并在其中打一个全透明的孔。不幸的是,我不知道如何用透明孔覆盖纹理。我试过设置我的 drawing mode到 SDL_BLENDMODE_NONE 并绘制一个完全透明的圆圈,但它只会创建完全不透明的圆圈。文档说我可以替换目标 alpha,但这似乎不起作用...

最佳答案

(以下是一系列的建议,不是一个确定的答案。如果你可以使用着色器,你的答案是单线片段着色器。除此之外,我不知道一个简单的解决方案可以准确地给出你想要。)

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

而且我建议在蒙版纹理中使用倒置的 alpha 值:将玩家周围的圆(或任何形状)设置为,并用接近 255 的“雾值”填充雾部分(或 1.0,如果您使用的是实数。)这可以防止任何东西被绘制在中间的透明圆圈中。

现在,如果您已经用纯色“雾色”填充了整个 mask 纹理(可能不需要制作形状或其他任何东西),请注意不要干扰 alpha channel ,设置您的 SDL_SetTextureBlendMode()SDL_BLENDMODE_BLEND 并执行 SDL_RenderCopy(),您将实现您想要的效果。特别是如果您在 mask 纹理中设置了明亮的“雾色”(不是值,颜色),例如就像样本图像中的青色。它不会完全匹配您的“屏幕混合模式”,但您可以接近。

您也可以尝试使用 SDL_BLENDMODE_ADD。它甚至可能会给您带来更好的效果(对于雾化效果。)

无论如何,重申一下,在您的雾蒙版纹理(这是所有混合中的“源”)中,您设置了纯色雾色,并将 alpha channel 设置为纯色雾值,然后仅在 alpha channel 中绘制玩家周围的清晰区域,使用值.

关于c++ - SDL2 - 在纹理上绘制完全透明的圆圈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37494999/

相关文章:

opengl - 使用 SDL2 和 OpenGL 渲染文本

c++ - 以 float 作为非类型的模板特化

c++ - 递归调用可变参数模板函数重载时调用不明确

c++ - std::sort 如何处理对列表?

c++ - SDL2 不将在单独函数中创建的图像渲染到 SDL_RenderPresent (C++)

Python OLA 类型错误 : can only assign array

c++ - 32 位数字的十六进制表示

c++ - OpenGL矩形莫名其妙地占据了整个窗口

opengl - 如何在 OpenGL 中快速轻松地创建与场景无关的阴影,而无需着色器

在 opengl 中创建太阳系 - 照明未按计划工作