diff --git a/panda/src/display/config_display.cxx b/panda/src/display/config_display.cxx index 0b46da0252..391a7e8676 100644 --- a/panda/src/display/config_display.cxx +++ b/panda/src/display/config_display.cxx @@ -298,6 +298,15 @@ ConfigVariableBool allow_incomplete_render "geometry is always paged in immediately when needed, holding up " "the frame render if necessary.")); +ConfigVariableBool old_alpha_blend +("old-alpha-blend", false, + PRC_DESC("Set this to true to enable the old alpha blending behavior from " + "Panda 1.9 in which the alpha value written out to the framebuffer " + "is squared. The new behavior is more intuitive when compositing " + "an semitransparent image produced using render-to-texture. You " + "should generally leave this false unless you have an effect that " + "relies on the old behavior, or you suspect an implementation bug.")); + ConfigVariableInt win_size ("win-size", "800 600", PRC_DESC("This is the default size at which to open a new window. This " diff --git a/panda/src/display/config_display.h b/panda/src/display/config_display.h index 1196389f5a..0b76e06472 100644 --- a/panda/src/display/config_display.h +++ b/panda/src/display/config_display.h @@ -68,6 +68,7 @@ extern EXPCL_PANDA_DISPLAY ConfigVariableBool default_stereo_camera; extern EXPCL_PANDA_DISPLAY ConfigVariableBool color_scale_via_lighting; extern EXPCL_PANDA_DISPLAY ConfigVariableBool alpha_scale_via_texture; extern EXPCL_PANDA_DISPLAY ConfigVariableBool allow_incomplete_render; +extern EXPCL_PANDA_DISPLAY ConfigVariableBool old_alpha_blend; extern EXPCL_PANDA_DISPLAY ConfigVariableInt win_size; extern EXPCL_PANDA_DISPLAY ConfigVariableInt win_origin; diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index 43bf6d3311..03b5e8b6cb 100644 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -3798,7 +3798,14 @@ do_issue_blending() { case TransparencyAttrib::M_multisample_mask: case TransparencyAttrib::M_dual: set_render_state(D3DRS_ALPHABLENDENABLE, TRUE); - set_render_state(D3DRS_SEPARATEALPHABLENDENABLE, FALSE); + if (old_alpha_blend) { + set_render_state(D3DRS_SEPARATEALPHABLENDENABLE, FALSE); + } else { + set_render_state(D3DRS_SEPARATEALPHABLENDENABLE, TRUE); + set_render_state(D3DRS_BLENDOPALPHA, D3DBLENDOP_ADD); + set_render_state(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE); + set_render_state(D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA); + } set_render_state(D3DRS_BLENDOP, D3DBLENDOP_ADD); set_render_state(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); set_render_state(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index f078ce0d8b..bba123ea92 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -7120,11 +7120,20 @@ do_issue_blending() { enable_multisample_alpha_mask(false); enable_blend(true); _glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + if (old_alpha_blend) { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } else { + _glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + } if (GLCAT.is_spam()) { GLCAT.spam() << "glBlendEquation(GL_FUNC_ADD)\n"; - GLCAT.spam() << "glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)\n"; + if (_supports_blend_equation_separate && !old_alpha_blend) { + GLCAT.spam() << "glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA)\n"; + } else { + GLCAT.spam() << "glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)\n"; + } } return; diff --git a/panda/src/tinydisplay/zbuffer.h b/panda/src/tinydisplay/zbuffer.h index 46190ef4e6..ced08b5e31 100644 --- a/panda/src/tinydisplay/zbuffer.h +++ b/panda/src/tinydisplay/zbuffer.h @@ -107,23 +107,26 @@ typedef unsigned int PIXEL; #define PCOMPONENT_BLEND(c1, c2, a2) \ ((((unsigned int)(c1) * ((unsigned int)0xffff - (unsigned int)(a2)) + (unsigned int)(c2) * (unsigned int)(a2))) >> 16) -#define _BLEND_RGB(r1, g1, b1, r2, g2, b2, a2) \ +#define PALPHA_BLEND(a1, a2) \ + ((((unsigned int)(a1) * ((unsigned int)0xffff - (unsigned int)(a2))) >> 16) + (unsigned int)(a2)) + +#define _BLEND_RGB(r1, g1, b1, a1, r2, g2, b2, a2) \ RGBA_TO_PIXEL(PCOMPONENT_BLEND(r1, r2, a2), \ PCOMPONENT_BLEND(g1, g2, a2), \ PCOMPONENT_BLEND(b1, b2, a2), \ - a2) + PALPHA_BLEND(a1, a2)) -#define _BLEND_SRGB(r1, g1, b1, r2, g2, b2, a2) \ +#define _BLEND_SRGB(r1, g1, b1, a1, r2, g2, b2, a2) \ SRGBA_TO_PIXEL(PCOMPONENT_BLEND(r1, r2, a2), \ PCOMPONENT_BLEND(g1, g2, a2), \ PCOMPONENT_BLEND(b1, b2, a2), \ - a2) + PALPHA_BLEND(a1, a2)) #define PIXEL_BLEND_RGB(rgb, r, g, b, a) \ - _BLEND_RGB(PIXEL_R(rgb), PIXEL_G(rgb), PIXEL_B(rgb), r, g, b, a) + _BLEND_RGB(PIXEL_R(rgb), PIXEL_G(rgb), PIXEL_B(rgb), PIXEL_A(rgb), r, g, b, a) #define PIXEL_BLEND_SRGB(rgb, r, g, b, a) \ - _BLEND_SRGB(PIXEL_SR(rgb), PIXEL_SG(rgb), PIXEL_SB(rgb), r, g, b, a) + _BLEND_SRGB(PIXEL_SR(rgb), PIXEL_SG(rgb), PIXEL_SB(rgb), PIXEL_A(rgb), r, g, b, a) typedef struct {