more pstats options with z-buffer

This commit is contained in:
David Rose 2006-03-29 23:37:46 +00:00
parent 92a5776b2c
commit 5173168621
9 changed files with 56 additions and 23 deletions

View File

@ -47,6 +47,12 @@ ConfigVariableDouble octree_multiassign_ratio
"order to be assigned to the node itself. If the object is smaller "
"than this, it will be multiply assigned to the node's children."));
ConfigVariableBool show_octree
("show-octree", false,
PRC_DESC("When true, visualizes the octree created for the hierarchical "
"Z-buffer algorithm, by drawing wireframe cubes around each "
"nonempty octree cell."));
////////////////////////////////////////////////////////////////////
// Function: init_libcull
// Description: Initializes the library. This must be called at

View File

@ -24,6 +24,7 @@
#include "dconfig.h"
#include "configVariableInt.h"
#include "configVariableDouble.h"
#include "configVariableBool.h"
class DSearchPath;
@ -32,6 +33,7 @@ NotifyCategoryDecl(cull, EXPCL_PANDA, EXPTP_PANDA);
extern ConfigVariableInt max_objects_per_octree_node;
extern ConfigVariableDouble octree_multiassign_ratio;
extern ConfigVariableBool show_octree;
extern EXPCL_PANDA void init_libcull();

View File

@ -59,7 +59,8 @@ operator = (const CullBinHierarchicalZBuffer::ObjectData &copy) {
////////////////////////////////////////////////////////////////////
INLINE CullBinHierarchicalZBuffer::
CullBinHierarchicalZBuffer(const string &name, GraphicsStateGuardianBase *gsg) :
CullBin(name, gsg)
CullBin(name, gsg),
_draw_occlusion_pcollector(_draw_this_pcollector, "Occlusion")
{
nassertv(_gsg->get_supports_occlusion_query());
}
@ -75,6 +76,17 @@ initial_assign(const CullBinHierarchicalZBuffer::ObjectData &object_data) {
_objects.push_back(object_data);
}
////////////////////////////////////////////////////////////////////
// Function: CullBinHierarchicalZBuffer::OctreeNode::get_total_num_objects
// Access: Public
// Description: Returns the total number of objects in this node and
// all nested nodes.
////////////////////////////////////////////////////////////////////
INLINE int CullBinHierarchicalZBuffer::OctreeNode::
get_total_num_objects() const {
return _total_num_objects;
}
////////////////////////////////////////////////////////////////////
// Function: CullBinHierarchicalZBuffer::OctreeNode::reassign
// Access: Public
@ -84,6 +96,7 @@ initial_assign(const CullBinHierarchicalZBuffer::ObjectData &object_data) {
////////////////////////////////////////////////////////////////////
INLINE void CullBinHierarchicalZBuffer::OctreeNode::
reassign(const CullBinHierarchicalZBuffer::ObjectData &object_data) {
++_total_num_objects;
if (object_data._bounds->get_radius() / _half_side >= octree_multiassign_ratio) {
// The object is large enough to keep in this node.
//cerr << " reassigning.\n";

View File

@ -32,6 +32,7 @@
#include "thread.h"
PStatCollector CullBinHierarchicalZBuffer::_wait_occlusion_pcollector("Wait:Occlusion test");
PStatCollector CullBinHierarchicalZBuffer::_geoms_occluded_pcollector("Geoms:Occluded");
PT(Geom) CullBinHierarchicalZBuffer::_octree_solid_test;
PT(Geom) CullBinHierarchicalZBuffer::_octree_wireframe_viz;
@ -160,8 +161,13 @@ draw() {
// The octree cell is at least partially visible. Draw it, and
// continue recursion.
pending._octree_node->draw(*this);
if (show_octree) {
pending._octree_node->draw_wireframe(*this);
}
} else {
pending._octree_node->draw_wireframe(*this);
// The octree cell is completely occluded. Don't draw any of
// it, and don't recurse into it.
_geoms_occluded_pcollector.add_level(pending._octree_node->get_total_num_objects());
}
_pending_nodes.pop_front();
}
@ -175,6 +181,7 @@ draw() {
////////////////////////////////////////////////////////////////////
CullBinHierarchicalZBuffer::OctreeNode::
OctreeNode() {
_total_num_objects = 0;
for (int i = 0; i < 8; ++i) {
_corners[i] = (OctreeNode *)NULL;
}
@ -190,6 +197,7 @@ OctreeNode(float mid_x, float mid_y, float mid_z, float half_side) :
_mid(mid_x, mid_y, mid_z),
_half_side(half_side)
{
_total_num_objects = 0;
for (int i = 0; i < 8; ++i) {
_corners[i] = (OctreeNode *)NULL;
}
@ -254,10 +262,9 @@ make_initial_bounds() {
////////////////////////////////////////////////////////////////////
void CullBinHierarchicalZBuffer::OctreeNode::
group_objects() {
//cerr << "group_objects, " << _objects.size() << " objects.\n";
if ((int)_objects.size() <= max_objects_per_octree_node) {
// No need to do any more subdividing.
//cerr << " small enough.\n";
_total_num_objects += (int)_objects.size();
return;
}
@ -268,7 +275,6 @@ group_objects() {
Objects::const_iterator oi;
for (oi = old_objects.begin(); oi != old_objects.end(); ++oi) {
//cerr << " object " << (oi - old_objects.begin()) << "\n";
const ObjectData &object_data = (*oi);
const LPoint3f &c = object_data._bounds->get_center();
float r = object_data._bounds->get_radius();
@ -354,7 +360,7 @@ group_objects() {
// occlusion query object representing this test.
////////////////////////////////////////////////////////////////////
PT(OcclusionQueryContext) CullBinHierarchicalZBuffer::OctreeNode::
occlusion_test(GraphicsStateGuardianBase *gsg) {
occlusion_test(CullBinHierarchicalZBuffer &bin) {
// Draw the bounding volume for visualization. This is
// complicated because we're doing this at such a low level, here
// in the middle of the draw task--we've already completed the
@ -364,21 +370,22 @@ occlusion_test(GraphicsStateGuardianBase *gsg) {
CPT(TransformState) net_transform = TransformState::make_pos_hpr_scale
(_mid, LVecBase3f(0.0f, 0.0f, 0.0f),
LVecBase3f(_half_side, _half_side, _half_side));
CPT(TransformState) world_transform = gsg->get_scene()->get_world_transform();
CPT(TransformState) world_transform = bin._gsg->get_scene()->get_world_transform();
CPT(TransformState) modelview_transform = world_transform->compose(net_transform);
CPT(RenderState) state = get_octree_solid_test_state();
PT(GeomMunger) munger = gsg->get_geom_munger(state);
PT(GeomMunger) munger = bin._gsg->get_geom_munger(state);
CPT(Geom) viz = get_octree_solid_test();
CPT(GeomVertexData) munged_data = viz->get_vertex_data();
munger->munge_geom(viz, munged_data);
gsg->set_state_and_transform(state, modelview_transform);
bin._gsg->set_state_and_transform(state, modelview_transform);
gsg->begin_occlusion_query();
viz->draw(gsg, munger, munged_data);
return gsg->end_occlusion_query();
PStatTimer timer(bin._draw_occlusion_pcollector);
bin._gsg->begin_occlusion_query();
viz->draw(bin._gsg, munger, munged_data);
return bin._gsg->end_occlusion_query();
}
////////////////////////////////////////////////////////////////////
@ -395,10 +402,7 @@ draw(CullBinHierarchicalZBuffer &bin) {
Objects::const_iterator oi;
for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
CullableObject *object = (*oi)._object;
if (object->_already_drawn) {
//cerr << "skipping object.\n";
} else {
//cerr << "drawing object.\n";
if (!object->_already_drawn) {
CullHandler::draw(object, bin._gsg);
object->_already_drawn = true;
}
@ -409,7 +413,7 @@ draw(CullBinHierarchicalZBuffer &bin) {
if (_corners[i] != (OctreeNode *)NULL) {
PendingNode pending;
pending._octree_node = _corners[i];
pending._query = _corners[i]->occlusion_test(bin._gsg);
pending._query = _corners[i]->occlusion_test(bin);
bin._pending_nodes.push_back(pending);
}
}
@ -560,8 +564,6 @@ multi_assign(const CullBinHierarchicalZBuffer::ObjectData &object_data) {
const LPoint3f &c = object_data._bounds->get_center();
float r = object_data._bounds->get_radius();
//cerr << "multi_assigning " << c << " vs. " << _mid << "\n";
if (c[0] + r <= _mid[0]) {
// -X
if (c[1] + r <= _mid[1]) {
@ -726,7 +728,6 @@ multi_assign(const CullBinHierarchicalZBuffer::ObjectData &object_data) {
////////////////////////////////////////////////////////////////////
INLINE void CullBinHierarchicalZBuffer::OctreeNode::
make_corner(int index) {
//cerr << "making corner " << hex << index << dec << "\n";
nassertv(_corners[index] == NULL);
OctreeNode *node = NULL;

View File

@ -98,18 +98,21 @@ private:
void make_initial_bounds();
void group_objects();
PT(OcclusionQueryContext) occlusion_test(GraphicsStateGuardianBase *gsg);
PT(OcclusionQueryContext) occlusion_test(CullBinHierarchicalZBuffer &bin);
void draw(CullBinHierarchicalZBuffer &bin);
void draw_wireframe(CullBinHierarchicalZBuffer &bin);
INLINE void initial_assign(const ObjectData &object_data);
INLINE int get_total_num_objects() const;
private:
INLINE void reassign(const ObjectData &object_data);
INLINE void assign_to_corner(int index, const ObjectData &object_data);
void multi_assign(const ObjectData &object_data);
void make_corner(int index);
int _total_num_objects;
Objects _objects;
OctreeNode *_corners[8];
LPoint3f _mid;
@ -129,7 +132,9 @@ private:
typedef pdeque<PendingNode> PendingNodes;
PendingNodes _pending_nodes;
PStatCollector _draw_occlusion_pcollector;
static PStatCollector _wait_occlusion_pcollector;
static PStatCollector _geoms_occluded_pcollector;
static PT(Geom) _octree_solid_test;
static PT(Geom) _octree_wireframe_viz;

View File

@ -45,7 +45,7 @@
#include <sys/time.h>
#endif
PStatCollector GraphicsEngine::_wait_pcollector("Wait");
PStatCollector GraphicsEngine::_wait_pcollector("Wait:Thread sync");
PStatCollector GraphicsEngine::_cycle_pcollector("App:Cycle");
PStatCollector GraphicsEngine::_app_pcollector("App:Show code");
PStatCollector GraphicsEngine::_render_frame_pcollector("App:render_frame");
@ -640,6 +640,7 @@ render_frame() {
CullTraverser::_nodes_pcollector.clear_level();
CullTraverser::_geom_nodes_pcollector.clear_level();
CullTraverser::_geoms_pcollector.clear_level();
CullTraverser::_geoms_occluded_pcollector.clear_level();
GeomCacheManager::_geom_cache_active_pcollector.clear_level();
GeomCacheManager::_geom_cache_record_pcollector.clear_level();
GeomCacheManager::_geom_cache_erase_pcollector.clear_level();

View File

@ -40,6 +40,7 @@
PStatCollector CullTraverser::_nodes_pcollector("Nodes");
PStatCollector CullTraverser::_geom_nodes_pcollector("Nodes:GeomNodes");
PStatCollector CullTraverser::_geoms_pcollector("Geoms");
PStatCollector CullTraverser::_geoms_occluded_pcollector("Geoms:Occluded");
TypeHandle CullTraverser::_type_handle;

View File

@ -93,6 +93,7 @@ public:
static PStatCollector _nodes_pcollector;
static PStatCollector _geom_nodes_pcollector;
static PStatCollector _geoms_pcollector;
static PStatCollector _geoms_occluded_pcollector;
private:
void show_bounds(CullTraverserData &data, bool tight);

View File

@ -108,7 +108,9 @@ struct LevelCollectorProperties {
static TimeCollectorProperties time_properties[] = {
{ 1, "Wait", { 0.6, 0.6, 0.6 } },
{ 0, "Wait:Mutex block", { 1.0, 0.0, 0.0 } },
{ 0, "Wait:Mutex block", { 0.5, 0.0, 1.0 } },
{ 1, "Wait:Thread sync", { 0.0, 1.0, 0.5 } },
{ 1, "Wait:Occlusion test", { 1.0, 0.5, 0.0 } },
{ 1, "App", { 0.0, 0.8, 0.4 }, 1.0 / 30.0 },
{ 1, "App:Collisions", { 1.0, 0.5, 0.0 } },
{ 1, "App:Collisions:Reset", { 0.0, 0.0, 0.5 } },
@ -181,6 +183,7 @@ static LevelCollectorProperties level_properties[] = {
{ 1, "Nodes", { 0.4, 0.2, 0.8 }, "", 500.0 },
{ 1, "Nodes:GeomNodes", { 0.8, 0.2, 0.0 } },
{ 1, "Geoms", { 0.4, 0.8, 0.3 }, "", 500.0 },
{ 1, "Geoms:Occluded", { 0.8, 0.2, 0.2 } },
{ 1, "Cull volumes", { 0.7, 0.6, 0.9 }, "", 500.0 },
{ 1, "Cull volumes:Transforms", { 0.9, 0.6, 0.0 } },
{ 1, "State changes", { 1.0, 0.5, 0.2 }, "", 500.0 },