hide/show optimization

This commit is contained in:
David Rose 2008-11-13 15:55:07 +00:00
parent 450f5f3bf6
commit 22ecb41b4c
3 changed files with 90 additions and 27 deletions

View File

@ -1766,6 +1766,9 @@ do_issue_light() {
cur_ambient_light += light_obj->get_color();
} else {
const Colorf &color = light_obj->get_color();
// Don't bother binding the light if it has no color to contribute.
if (color[0] != 0.0 || color[1] != 0.0 || color[2] != 0.0) {
enable_light(num_enabled, true);
if (num_enabled == 0) {
begin_bind_lights();
@ -1776,6 +1779,7 @@ do_issue_light() {
}
}
}
}
for (i = num_enabled; i < _num_lights_enabled; ++i) {
enable_light(i, false);

View File

@ -1437,6 +1437,14 @@ compare_draw_mask(DrawMask running_draw_mask, DrawMask camera_mask) const {
nassertr(_cdata != (PandaNode::CData *)NULL, false);
nassertr(_cdata->_last_update == _cdata->_next_update, false);
// As a special case, if net_draw_show_mask is all 0, it means
// either that all nodes under this node are hidden to all cameras,
// or that none of them are renderable nodes (or some combination).
// In either case, we might as well short-circuit.
if (_cdata->_net_draw_show_mask.is_zero()) {
return false;
}
DrawMask net_draw_control_mask, net_draw_show_mask;
net_draw_control_mask = _cdata->_net_draw_control_mask;
net_draw_show_mask = _cdata->_net_draw_show_mask;

View File

@ -3710,29 +3710,68 @@ update_bounds(int pipeline_stage, PandaNode::CDLockedStageReader &cdata) {
net_collide_mask |= child_cdataw->_net_collide_mask;
if (drawmask_cat.is_debug()) {
drawmask_cat.debug(false)
<< "\nchild update " << *child << ":\n";
}
DrawMask child_control_mask = child_cdataw->_net_draw_control_mask;
DrawMask child_show_mask = child_cdataw->_net_draw_show_mask;
if (child_control_mask != DrawMask::all_off() ||
child_show_mask != DrawMask::all_off()) {
if (!(child_control_mask | child_show_mask).is_zero()) {
// This child includes a renderable node or subtree. Thus,
// we should propagate its draw masks.
renderable = true;
// Compute the set of control bits that are defined on this
// node, but not on the child node.
DrawMask new_control_mask = draw_control_mask & ~child_control_mask;
// Anywhere we have a control bit that our child does not,
// the child inherits our show bit.
DrawMask new_child_show_mask = (child_show_mask & ~new_control_mask) | (draw_show_mask & new_control_mask);
DrawMask new_child_control_mask = child_control_mask | new_control_mask;
// Now merge that result with our accumulated draw masks.
net_draw_control_mask |= new_child_control_mask;
net_draw_show_mask |= new_child_show_mask;
// For each bit position in the masks, we have assigned the
// following semantic meaning. The number on the left
// represents the pairing of the corresponding bit from the
// control mask and from the show mask:
// 00 : not a renderable node (control 0, show 0)
// 01 : a normally visible node (control 0, show 1)
// 10 : a hidden node (control 1, show 0)
// 11 : a show-through node (control 1, show 1)
// Now, when we accumulate these masks, we want to do so
// according to the following table, for each bit position:
// 00 01 10 11 (child)
// ---------------------
// 00 | 00 01 10 11
// 01 | 01 01 01* 11
// 10 | 10 01* 10 11
// 11 | 11 11 11 11
// (parent)
// This table is almost the same as the union of both masks,
// with one exception, marked with a * in the above table:
// if one is 10 and the other is 01--that is, one is hidden
// and the other is normally visible--then the result should
// be 01, normally visible. This is because we only want to
// propagate the hidden bit upwards if *all* renderable
// nodes are hidden.
// Get the set of exception bits for which the above rule
// applies. These are the bits for which both bits have
// flipped, but which were not the same in the original.
DrawMask exception_mask = (net_draw_control_mask ^ child_control_mask) & (net_draw_show_mask ^ child_show_mask);
exception_mask &= (net_draw_control_mask ^ net_draw_show_mask);
if (drawmask_cat.is_debug()) {
drawmask_cat.debug(false)
<< "exception_mask = " << exception_mask << "\n";
}
// Now compute the union, applying the above exception.
net_draw_control_mask |= child_control_mask;
net_draw_show_mask |= child_show_mask;
net_draw_control_mask &= ~exception_mask;
net_draw_show_mask |= exception_mask;
}
if (drawmask_cat.is_debug()) {
drawmask_cat.debug(false)
<< "\nchild update " << *child << ":\n"
<< "child_control_mask = " << child_control_mask
<< "\nchild_show_mask = " << child_show_mask
<< "\nnet_draw_control_mask = " << net_draw_control_mask
@ -3758,21 +3797,33 @@ update_bounds(int pipeline_stage, PandaNode::CDLockedStageReader &cdata) {
net_collide_mask |= child_cdata->_net_collide_mask;
// See comments in similar block above.
if (drawmask_cat.is_debug()) {
drawmask_cat.debug(false)
<< "\nchild fresh " << *child << ":\n";
}
DrawMask child_control_mask = child_cdata->_net_draw_control_mask;
DrawMask child_show_mask = child_cdata->_net_draw_show_mask;
if (child_control_mask != DrawMask::all_off() ||
child_show_mask != DrawMask::all_off()) {
if (!(child_control_mask | child_show_mask).is_zero()) {
renderable = true;
DrawMask new_control_mask = draw_control_mask & ~child_control_mask;
DrawMask new_child_show_mask = (child_show_mask & ~new_control_mask) | (draw_show_mask & new_control_mask);
DrawMask new_child_control_mask = child_control_mask | new_control_mask;
net_draw_control_mask |= new_child_control_mask;
net_draw_show_mask |= new_child_show_mask;
DrawMask exception_mask = (net_draw_control_mask ^ child_control_mask) & (net_draw_show_mask ^ child_show_mask);
exception_mask &= (net_draw_control_mask ^ net_draw_show_mask);
if (drawmask_cat.is_debug()) {
drawmask_cat.debug(false)
<< "exception_mask = " << exception_mask << "\n";
}
// Now compute the union, applying the above exception.
net_draw_control_mask |= child_control_mask;
net_draw_show_mask |= child_show_mask;
net_draw_control_mask &= ~exception_mask;
net_draw_show_mask |= exception_mask;
}
if (drawmask_cat.is_debug()) {
drawmask_cat.debug(false)
<< "\nchild fresh " << *child << ":\n"
<< "child_control_mask = " << child_control_mask
<< "\nchild_show_mask = " << child_show_mask
<< "\nnet_draw_control_mask = " << net_draw_control_mask