mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-03 08:08:43 +00:00
LibGL+LibGPU+LibSoftGPU: Implement constant blending color
Available since OpenGL 2.0, calling `glBlendColor` allows you to set a constant color to be used as a blend factor.
This commit is contained in:
parent
f3d3454976
commit
2831e68999
Notes:
sideshowbarker
2024-07-17 01:12:07 +09:00
Author: https://github.com/gmta
Commit: 2831e68999
Pull-request: https://github.com/SerenityOS/serenity/pull/23912
Reviewed-by: https://github.com/timschumi ✅
6 changed files with 71 additions and 24 deletions
|
@ -8,6 +8,19 @@
|
|||
|
||||
namespace GL {
|
||||
|
||||
void GLContext::gl_blend_color(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
|
||||
{
|
||||
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_blend_color, red, green, blue, alpha);
|
||||
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||
|
||||
m_blend_color = { red, green, blue, alpha };
|
||||
m_blend_color.clamp(0.f, 1.f);
|
||||
|
||||
auto options = m_rasterizer->options();
|
||||
options.blend_color = m_blend_color;
|
||||
m_rasterizer->set_options(options);
|
||||
}
|
||||
|
||||
void GLContext::gl_blend_equation_separate(GLenum rgb_mode, GLenum alpha_mode)
|
||||
{
|
||||
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_blend_equation_separate, rgb_mode, alpha_mode);
|
||||
|
@ -119,6 +132,14 @@ void GLContext::gl_blend_func(GLenum src_factor, GLenum dst_factor)
|
|||
return GPU::BlendFactor::DstAlpha;
|
||||
case GL_ONE_MINUS_DST_ALPHA:
|
||||
return GPU::BlendFactor::OneMinusDstAlpha;
|
||||
case GL_CONSTANT_COLOR:
|
||||
return GPU::BlendFactor::ConstantColor;
|
||||
case GL_ONE_MINUS_CONSTANT_COLOR:
|
||||
return GPU::BlendFactor::OneMinusConstantColor;
|
||||
case GL_CONSTANT_ALPHA:
|
||||
return GPU::BlendFactor::ConstantAlpha;
|
||||
case GL_ONE_MINUS_CONSTANT_ALPHA:
|
||||
return GPU::BlendFactor::OneMinusConstantAlpha;
|
||||
case GL_SRC_ALPHA_SATURATE:
|
||||
return GPU::BlendFactor::SrcAlphaSaturate;
|
||||
default:
|
||||
|
|
|
@ -48,6 +48,11 @@
|
|||
{"type": "GLubyte const*", "name": "bitmap"}
|
||||
]
|
||||
},
|
||||
"BlendColor": {
|
||||
"arguments": [
|
||||
{"type": "GLclampf", "name": ["red", "green", "blue", "alpha"]}
|
||||
]
|
||||
},
|
||||
"BlendEquation": {
|
||||
"arguments": [
|
||||
{"type": "GLenum", "name": "mode"},
|
||||
|
|
|
@ -148,6 +148,7 @@ public:
|
|||
GLboolean gl_is_list(GLuint list);
|
||||
void gl_flush();
|
||||
void gl_finish();
|
||||
void gl_blend_color(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
|
||||
void gl_blend_equation_separate(GLenum rgb_mode, GLenum alpha_mode);
|
||||
void gl_blend_func(GLenum src_factor, GLenum dst_factor);
|
||||
void gl_shade_model(GLenum mode);
|
||||
|
@ -334,6 +335,7 @@ private:
|
|||
GLenum m_culled_sides = GL_BACK;
|
||||
|
||||
bool m_blend_enabled = false;
|
||||
FloatVector4 m_blend_color { 0.f, 0.f, 0.f, 0.f };
|
||||
GLenum m_blend_source_factor = GL_ONE;
|
||||
GLenum m_blend_destination_factor = GL_ZERO;
|
||||
|
||||
|
@ -473,6 +475,7 @@ private:
|
|||
decltype(&GLContext::gl_cull_face),
|
||||
decltype(&GLContext::gl_call_list),
|
||||
decltype(&GLContext::gl_call_lists),
|
||||
decltype(&GLContext::gl_blend_color),
|
||||
decltype(&GLContext::gl_blend_equation_separate),
|
||||
decltype(&GLContext::gl_blend_func),
|
||||
decltype(&GLContext::gl_shade_model),
|
||||
|
|
|
@ -33,14 +33,18 @@ enum class BlendEquation {
|
|||
enum class BlendFactor {
|
||||
Zero,
|
||||
One,
|
||||
SrcAlpha,
|
||||
OneMinusSrcAlpha,
|
||||
SrcColor,
|
||||
OneMinusSrcColor,
|
||||
DstAlpha,
|
||||
OneMinusDstAlpha,
|
||||
DstColor,
|
||||
OneMinusDstColor,
|
||||
SrcAlpha,
|
||||
OneMinusSrcAlpha,
|
||||
DstAlpha,
|
||||
OneMinusDstAlpha,
|
||||
ConstantColor,
|
||||
OneMinusConstantColor,
|
||||
ConstantAlpha,
|
||||
OneMinusConstantAlpha,
|
||||
SrcAlphaSaturate,
|
||||
};
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ struct RasterizerOptions {
|
|||
AlphaTestFunction alpha_test_func { AlphaTestFunction::Always };
|
||||
float alpha_test_ref_value { 0 };
|
||||
bool enable_blending { false };
|
||||
FloatVector4 blend_color { 0.f, 0.f, 0.f, 0.f };
|
||||
BlendEquation blend_equation_rgb { BlendEquation::Add };
|
||||
BlendEquation blend_equation_alpha { BlendEquation::Add };
|
||||
BlendFactor blend_source_factor { BlendFactor::One };
|
||||
|
|
|
@ -137,37 +137,50 @@ ALWAYS_INLINE static void test_alpha(PixelQuad& quad, GPU::AlphaTestFunction alp
|
|||
|
||||
ALWAYS_INLINE static bool is_blend_factor_constant(GPU::BlendFactor blend_factor)
|
||||
{
|
||||
return (blend_factor == GPU::BlendFactor::One || blend_factor == GPU::BlendFactor::Zero);
|
||||
return blend_factor == GPU::BlendFactor::Zero
|
||||
|| blend_factor == GPU::BlendFactor::One
|
||||
|| blend_factor == GPU::BlendFactor::ConstantColor
|
||||
|| blend_factor == GPU::BlendFactor::OneMinusConstantColor
|
||||
|| blend_factor == GPU::BlendFactor::ConstantAlpha
|
||||
|| blend_factor == GPU::BlendFactor::OneMinusConstantAlpha;
|
||||
}
|
||||
|
||||
// OpenGL 2.0 § 4.1.8, table 4.2
|
||||
ALWAYS_INLINE static Vector4<f32x4> get_blend_factor(GPU::BlendFactor blend_factor, Vector4<f32x4> const& source_color, Vector4<f32x4> const& destination_color)
|
||||
ALWAYS_INLINE static Vector4<f32x4> get_blend_factor(GPU::BlendFactor blend_factor, FloatVector4 blend_color, Vector4<f32x4> const& source_color, Vector4<f32x4> const& destination_color)
|
||||
{
|
||||
switch (blend_factor) {
|
||||
case GPU::BlendFactor::DstAlpha:
|
||||
return to_vec4(destination_color.w());
|
||||
case GPU::BlendFactor::DstColor:
|
||||
return destination_color;
|
||||
case GPU::BlendFactor::Zero:
|
||||
return to_vec4(expand4(0.f));
|
||||
case GPU::BlendFactor::One:
|
||||
return to_vec4(expand4(1.f));
|
||||
case GPU::BlendFactor::OneMinusDstAlpha:
|
||||
return to_vec4(1.f - destination_color.w());
|
||||
case GPU::BlendFactor::OneMinusDstColor:
|
||||
return to_vec4(expand4(1.f)) - destination_color;
|
||||
case GPU::BlendFactor::OneMinusSrcAlpha:
|
||||
return to_vec4(1.f - source_color.w());
|
||||
case GPU::BlendFactor::SrcColor:
|
||||
return source_color;
|
||||
case GPU::BlendFactor::OneMinusSrcColor:
|
||||
return to_vec4(expand4(1.f)) - source_color;
|
||||
case GPU::BlendFactor::DstColor:
|
||||
return destination_color;
|
||||
case GPU::BlendFactor::OneMinusDstColor:
|
||||
return to_vec4(expand4(1.f)) - destination_color;
|
||||
case GPU::BlendFactor::SrcAlpha:
|
||||
return to_vec4(source_color.w());
|
||||
case GPU::BlendFactor::OneMinusSrcAlpha:
|
||||
return to_vec4(1.f - source_color.w());
|
||||
case GPU::BlendFactor::DstAlpha:
|
||||
return to_vec4(destination_color.w());
|
||||
case GPU::BlendFactor::OneMinusDstAlpha:
|
||||
return to_vec4(1.f - destination_color.w());
|
||||
case GPU::BlendFactor::ConstantColor:
|
||||
return expand4(blend_color);
|
||||
case GPU::BlendFactor::OneMinusConstantColor:
|
||||
return expand4(FloatVector4 { 1.f, 1.f, 1.f, 1.f } - blend_color);
|
||||
case GPU::BlendFactor::ConstantAlpha:
|
||||
return to_vec4(expand4(blend_color.w()));
|
||||
case GPU::BlendFactor::OneMinusConstantAlpha:
|
||||
return to_vec4(expand4(1.f - blend_color.w()));
|
||||
case GPU::BlendFactor::SrcAlphaSaturate: {
|
||||
auto saturated = min(source_color.w(), 1.f - destination_color.w());
|
||||
return { saturated, saturated, saturated, expand4(1.f) };
|
||||
}
|
||||
case GPU::BlendFactor::SrcColor:
|
||||
return source_color;
|
||||
case GPU::BlendFactor::Zero:
|
||||
return to_vec4(expand4(0.f));
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
@ -282,9 +295,9 @@ ALWAYS_INLINE void Device::rasterize(Gfx::IntRect& render_bounds, CB1 set_covera
|
|||
auto const destination_weights_are_constant = is_blend_factor_constant(m_options.blend_destination_factor);
|
||||
if (m_options.enable_blending) {
|
||||
if (source_weights_are_constant)
|
||||
source_weights = get_blend_factor(m_options.blend_source_factor, {}, {});
|
||||
source_weights = get_blend_factor(m_options.blend_source_factor, m_options.blend_color, {}, {});
|
||||
if (destination_weights_are_constant)
|
||||
destination_weights = get_blend_factor(m_options.blend_destination_factor, {}, {});
|
||||
destination_weights = get_blend_factor(m_options.blend_destination_factor, m_options.blend_color, {}, {});
|
||||
}
|
||||
|
||||
// Rasterize all quads
|
||||
|
@ -480,9 +493,9 @@ ALWAYS_INLINE void Device::rasterize(Gfx::IntRect& render_bounds, CB1 set_covera
|
|||
auto const destination_color = to_vec4(dst_u32);
|
||||
|
||||
if (!source_weights_are_constant)
|
||||
source_weights = get_blend_factor(m_options.blend_source_factor, source_color, destination_color);
|
||||
source_weights = get_blend_factor(m_options.blend_source_factor, m_options.blend_color, source_color, destination_color);
|
||||
if (!destination_weights_are_constant)
|
||||
destination_weights = get_blend_factor(m_options.blend_destination_factor, source_color, destination_color);
|
||||
destination_weights = get_blend_factor(m_options.blend_destination_factor, m_options.blend_color, source_color, destination_color);
|
||||
|
||||
out_color = blend_colors(m_options.blend_equation_rgb, m_options.blend_equation_alpha, source_color, source_weights, destination_color, destination_weights);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue