more pstats options with z-buffer
This commit is contained in:
parent
92a5776b2c
commit
5173168621
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,8 @@ operator = (const CullBinHierarchicalZBuffer::ObjectData ©) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
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";
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 },
|
||||
|
|
|
|||
Loading…
Reference in New Issue