mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
Add premultiplied alpha mode, for convenience
This commit is contained in:
parent
2971915618
commit
2bf886fc5b
@ -3822,6 +3822,13 @@ do_issue_blending() {
|
||||
set_render_state(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
return;
|
||||
|
||||
case TransparencyAttrib::M_premultiplied_alpha:
|
||||
set_render_state(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
set_render_state(D3DRS_BLENDOP, D3DBLENDOP_ADD);
|
||||
set_render_state(D3DRS_SRCBLEND, D3DBLEND_ONE);
|
||||
set_render_state(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
return;
|
||||
|
||||
default:
|
||||
dxgsg9_cat.error()
|
||||
<< "invalid transparency mode " << (int)transparency_mode << endl;
|
||||
|
@ -183,6 +183,8 @@ string_alpha_mode(const string &string) {
|
||||
return AM_binary;
|
||||
} else if (cmp_nocase_uh(string, "dual") == 0) {
|
||||
return AM_dual;
|
||||
} else if (cmp_nocase_uh(string, "premultiplied") == 0) {
|
||||
return AM_premultiplied;
|
||||
} else {
|
||||
return AM_unspecified;
|
||||
}
|
||||
@ -260,6 +262,8 @@ ostream &operator << (ostream &out, EggRenderMode::AlphaMode mode) {
|
||||
return out << "binary";
|
||||
case EggRenderMode::AM_dual:
|
||||
return out << "dual";
|
||||
case EggRenderMode::AM_premultiplied:
|
||||
return out << "premultiplied";
|
||||
}
|
||||
|
||||
nassertr(false, out);
|
||||
|
@ -45,7 +45,8 @@ PUBLISHED:
|
||||
AM_ms, // TransparencyAttrib::M_multisample
|
||||
AM_ms_mask, // TransparencyAttrib::M_multisample_mask
|
||||
AM_binary, // TransparencyAttrib::M_binary
|
||||
AM_dual // TransparencyAttrib::M_dual
|
||||
AM_dual, // TransparencyAttrib::M_dual
|
||||
AM_premultiplied // TransparencyAttrib::M_premultiplied_alpha
|
||||
};
|
||||
|
||||
enum DepthWriteMode {
|
||||
|
@ -333,6 +333,10 @@ fill_state(EggPrimitive *egg_prim) {
|
||||
add_attrib(TransparencyAttrib::make(TransparencyAttrib::M_dual));
|
||||
break;
|
||||
|
||||
case EggRenderMode::AM_premultiplied:
|
||||
add_attrib(TransparencyAttrib::make(TransparencyAttrib::M_premultiplied_alpha));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -692,6 +692,9 @@ convert_primitive(const GeomVertexData *vertex_data,
|
||||
tex_trans = EggRenderMode::AM_blend;
|
||||
}
|
||||
break;
|
||||
case TransparencyAttrib::M_premultiplied_alpha:
|
||||
tex_trans = EggRenderMode::AM_premultiplied;
|
||||
break;
|
||||
case TransparencyAttrib::M_multisample:
|
||||
tex_trans = EggRenderMode::AM_ms;
|
||||
break;
|
||||
@ -705,7 +708,6 @@ convert_primitive(const GeomVertexData *vertex_data,
|
||||
tex_trans = EggRenderMode::AM_dual;
|
||||
break;
|
||||
default: // intentional fall-through
|
||||
case TransparencyAttrib::M_notused:
|
||||
break;
|
||||
}
|
||||
if (tex_trans != EggRenderMode::AM_unspecified) {
|
||||
|
@ -6722,6 +6722,19 @@ do_issue_blending() {
|
||||
}
|
||||
return;
|
||||
|
||||
case TransparencyAttrib::M_premultiplied_alpha:
|
||||
enable_multisample_alpha_one(false);
|
||||
enable_multisample_alpha_mask(false);
|
||||
enable_blend(true);
|
||||
_glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam() << "glBlendEquation(GL_FUNC_ADD)\n";
|
||||
GLCAT.spam() << "glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)\n";
|
||||
}
|
||||
return;
|
||||
|
||||
case TransparencyAttrib::M_multisample:
|
||||
// We need to enable *both* of these in M_multisample case.
|
||||
enable_multisample_alpha_one(true);
|
||||
|
@ -131,6 +131,7 @@ add_object(CullableObject *object, const CullTraverser *traverser) {
|
||||
if (object->_state->get_attrib(trans)) {
|
||||
switch (trans->get_mode()) {
|
||||
case TransparencyAttrib::M_alpha:
|
||||
case TransparencyAttrib::M_premultiplied_alpha:
|
||||
// M_alpha implies an alpha-write test, so we don't waste time writing
|
||||
// 0-valued pixels.
|
||||
object->_state = object->_state->compose(get_alpha_state());
|
||||
|
@ -47,7 +47,7 @@ apply_transform_and_state(CullTraverser *trav) {
|
||||
_node_reader.compose_draw_mask(_draw_mask);
|
||||
|
||||
apply_transform_and_state(trav, _node_reader.get_transform(),
|
||||
node_state, _node_reader.get_effects(),
|
||||
MOVE(node_state), _node_reader.get_effects(),
|
||||
_node_reader.get_off_clip_planes());
|
||||
}
|
||||
|
||||
|
@ -1853,8 +1853,8 @@ determine_bin_index() {
|
||||
string bin_name;
|
||||
_draw_order = 0;
|
||||
|
||||
const CullBinAttrib *bin = DCAST(CullBinAttrib, get_attrib(CullBinAttrib::get_class_slot()));
|
||||
if (bin != (const CullBinAttrib *)NULL) {
|
||||
const CullBinAttrib *bin;
|
||||
if (get_attrib(bin)) {
|
||||
bin_name = bin->get_bin_name();
|
||||
_draw_order = bin->get_draw_order();
|
||||
}
|
||||
@ -1864,10 +1864,11 @@ determine_bin_index() {
|
||||
// opaque or transparent, based on the transparency setting.
|
||||
bin_name = "opaque";
|
||||
|
||||
const TransparencyAttrib *transparency = DCAST(TransparencyAttrib, get_attrib(TransparencyAttrib::get_class_slot()));
|
||||
if (transparency != (const TransparencyAttrib *)NULL) {
|
||||
const TransparencyAttrib *transparency;
|
||||
if (get_attrib(transparency)) {
|
||||
switch (transparency->get_mode()) {
|
||||
case TransparencyAttrib::M_alpha:
|
||||
case TransparencyAttrib::M_premultiplied_alpha:
|
||||
case TransparencyAttrib::M_dual:
|
||||
// These transparency modes require special back-to-front sorting.
|
||||
bin_name = "transparent";
|
||||
|
@ -55,6 +55,10 @@ output(ostream &out) const {
|
||||
out << "alpha";
|
||||
break;
|
||||
|
||||
case M_premultiplied_alpha:
|
||||
out << "premultiplied alpha";
|
||||
break;
|
||||
|
||||
case M_multisample:
|
||||
out << "multisample";
|
||||
break;
|
||||
@ -70,9 +74,6 @@ output(ostream &out) const {
|
||||
case M_dual:
|
||||
out << "dual";
|
||||
break;
|
||||
|
||||
case M_notused:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ PUBLISHED:
|
||||
// corresponded to M_none or M_alpha).
|
||||
M_none = 0, // No transparency.
|
||||
M_alpha = 1, // Normal transparency, panda will sort back-to-front.
|
||||
M_notused, // Unused placeholder. Do not use this.
|
||||
M_premultiplied_alpha, // Assume textures use premultiplied alpha.
|
||||
M_multisample, // Uses ms buffer, alpha values modified to 1.0.
|
||||
M_multisample_mask, // Uses ms buffer, alpha values not modified.
|
||||
M_binary, // Only writes pixels with alpha >= 0.5.
|
||||
|
@ -209,6 +209,7 @@ analyze_renderstate(const RenderState *rs) {
|
||||
const TransparencyAttrib *transparency;
|
||||
rs->get_attrib_def(transparency);
|
||||
if ((transparency->get_mode() == TransparencyAttrib::M_alpha)||
|
||||
(transparency->get_mode() == TransparencyAttrib::M_premultiplied_alpha)||
|
||||
(transparency->get_mode() == TransparencyAttrib::M_dual)) {
|
||||
_have_alpha_blend = true;
|
||||
}
|
||||
|
@ -804,6 +804,21 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
||||
}
|
||||
break;
|
||||
|
||||
case TransparencyAttrib::M_premultiplied_alpha:
|
||||
{
|
||||
// Implement a color mask, with pre-multiplied alpha blending.
|
||||
int op_a = get_color_blend_op(ColorBlendAttrib::O_one);
|
||||
int op_b = get_color_blend_op(ColorBlendAttrib::O_one_minus_incoming_alpha);
|
||||
|
||||
if (srgb_blend) {
|
||||
_c->zb->store_pix_func = store_pixel_funcs_sRGB[op_a][op_b][color_channels];
|
||||
} else {
|
||||
_c->zb->store_pix_func = store_pixel_funcs[op_a][op_b][color_channels];
|
||||
}
|
||||
color_write_state = 2; // cgeneral
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user