我正在使用 ralib(它使用 OpenGL)来制作 2D 游戏。我有菜单按钮对象的精灵,我想在按钮上绘制一个白色的“蒙版”精灵,但给它一个透明度。 (只有蒙版才会具有透明度。)这将产生一个突出显示的按钮。
我得到的是这样的:
退出按钮实际上变暗了,这是不应该发生的。如果您在其他任何东西上合成一个完美的白色精灵,它应该变得更亮(除非 alpha 恰好为 0,在这种情况下原始精灵不会改变/与任何东西混合)。
MenuBut.hpp 中的一些代码:
int hi; // timer for highlight
const int hi_max = 20;
const float hi_alph = 0.333f;
在MenuBut.cpp中绘制代码
// this draws the regular MenuButton graphic
DrawTexturePro(GCN::TG->tex_grid_menubuts, (Rectangle){0, 32.0f*t, 320, 32}, (Rectangle){(float)x, (float)y, (float)320, (float)32}, (Vector2){0, 0}, 0.0f, (Color){255, 255, 255, 255);
if (hi > 0)
{
BeginBlendMode(BLEND_ALPHA);
// this draws a white mask sprite over the actual MenuButton graphic
DrawTexturePro(GCN::TG->tex_grid_menubuts, (Rectangle){320, 32.0f*t, 320, 32}, (Rectangle){(float)x, (float)y, (float)320, (float)32}, (Vector2){0, 0}, 0.0f, (Color){255, 255, 255, (unsigned char)round( 1.0f*(hi_alph*hi/hi_max)*255 )});
EndBlendMode();
}
// draw text for "Exit"
DrawTextEx(GCN::TG->fnt_AL, disp_text.c_str(), (Vector2){(float)(x + w/2 - MeasureTextEx(GCN::TG->fnt_AL, disp_text.c_str(), 24.0f, 1.0f).x/2), (float)(y+6)}, 24.0f, 1.0f, (Color){0, 0, 0, 255});
注意,如果我将 hi_alph 更改为更高的值,例如 0.750f,它确实会显得更亮,但过渡非常奇怪,就像它开始变暗然后突然变白。这种转变对眼睛来说有点痛苦。
我很确定某些东西不正确地混合了 RGB 值,因为在这两种情况下按钮似乎都很快变成灰色。
我已经尝试了所有其他可用的混合模式(自定义除外):BLEND_ADDITIVE、BLEND_MULTIPLIED、BLEND_ADD_COLORS、BLEND_SUBTRACT_COLORS、BLEND_ALPHA_PREMULTIPLY。其中一些产生相同的结果,另一些产生更奇怪的结果,这不是我想要的。
我寻找了 alpha 问题并发现了一些帖子。 这个SO主题是迄今为止最有帮助的解释预乘阿尔法如何工作的,我想我理解它。 另一个谈论了alpha问题,尽管它更深入到我不明白的OpenGL。
我其实并不了解OpenGL。我真的希望 raylib 中有一个解决方案,而不必编写自己的着色器。
我想通了。首先,您必须#include“rlgl.h”才能访问rlSetBlendFactorsSeparate函数,然后ofc开始使用混合模式BLEND_CUSTOM_SEPARATE。
然而,真正的关键是开始研究 OpenGL 如何与 Alpha 混合一起工作。不是 Raylib 帮助。 Raylib 的官方文档很少,只有 pdf 备忘单和常见问题解答。真正的文档是源代码本身及其注释,但除非您也了解 OpenGL 及其功能,否则您不会理解它。
无论如何,解决方案是
rlSetBlendFactorsSeparate(0x0302, 0x0303, 1, 0x0303, 0x8006, 0x8006);
BeginBlendMode(BLEND_CUSTOM_SEPARATE);
// do the draw here
EndBlendMode();
我什至从帮助线程和相关线程获得这些值,但这些特殊值存在于rlgl.h中的查找表中,因此您可以准确理解它们是什么。
(顺便说一句,显然这个混合问题仅在您绘制到不同的渲染目标时才存在(绘制到纹理而不是屏幕)。)