Raylib alpha 混合无法正常工作?

问题描述 投票:0回答:1

我正在使用 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 中有一个解决方案,而不必编写自己的着色器。

opengl alpha blending raylib
1个回答
0
投票

我想通了。首先,您必须#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中的查找表中,因此您可以准确理解它们是什么。

(顺便说一句,显然这个混合问题仅在您绘制到不同的渲染目标时才存在(绘制到纹理而不是屏幕)。)

© www.soinside.com 2019 - 2024. All rights reserved.