real state sorting

This commit is contained in:
David Rose 2005-03-22 23:28:49 +00:00
parent 699fe45d8b
commit 6512581e90
13 changed files with 263 additions and 4 deletions

View File

@ -499,6 +499,7 @@ render_frame() {
// Reset our pcollectors that track data across the frame.
CullTraverser::_nodes_pcollector.clear_level();
CullTraverser::_geom_nodes_pcollector.clear_level();
CullTraverser::_geoms_pcollector.clear_level();
_transform_states_pcollector.set_level(TransformState::get_num_states());
_render_states_pcollector.set_level(RenderState::get_num_states());

View File

@ -393,7 +393,7 @@ set_state(const RenderState *state) {
if (state != _state) {
#ifndef NDEBUG
if (gsg_cat.is_spam()) {
gsg_cat.spam() << "Setting GSG state to:\n";
gsg_cat.spam() << "Setting GSG state to " << (void *)state << ":\n";
state->write(gsg_cat.spam(false), 2);
}
#endif

View File

@ -2609,8 +2609,6 @@ draw_sphere(GeomSphere *geom, GeomContext *gc) {
bool DXGraphicsStateGuardian8::
begin_draw_primitives(const qpGeom *geom, const qpGeomMunger *munger,
const qpGeomVertexData *vertex_data) {
DO_PSTATS_STUFF(_draw_primitive_pcollector.start());
if (!GraphicsStateGuardian::begin_draw_primitives(geom, munger, vertex_data)) {
return false;
}
@ -2718,7 +2716,6 @@ draw_tristrips(const qpGeomTristrips *primitive) {
void DXGraphicsStateGuardian8::
end_draw_primitives() {
GraphicsStateGuardian::end_draw_primitives();
DO_PSTATS_STUFF(_draw_primitive_pcollector.stop());
}
////////////////////////////////////////////////////////////////////

View File

@ -31,6 +31,7 @@
cullBinFixed.I cullBinFixed.h \
cullBinFrontToBack.I cullBinFrontToBack.h \
cullBinManager.I cullBinManager.h \
cullBinStateSorted.I cullBinStateSorted.h \
cullBinUnsorted.I cullBinUnsorted.h \
cullFaceAttrib.I cullFaceAttrib.h \
cullHandler.I cullHandler.h \
@ -127,6 +128,7 @@
cullBinFixed.cxx \
cullBinFrontToBack.cxx \
cullBinManager.cxx \
cullBinStateSorted.cxx \
cullBinUnsorted.cxx \
cullFaceAttrib.cxx \
cullHandler.cxx \
@ -221,6 +223,7 @@
cullBinFixed.I cullBinFixed.h \
cullBinFrontToBack.I cullBinFrontToBack.h \
cullBinManager.I cullBinManager.h \
cullBinStateSorted.I cullBinStateSorted.h \
cullBinUnsorted.I cullBinUnsorted.h \
cullFaceAttrib.I cullFaceAttrib.h \
cullHandler.I cullHandler.h \

View File

@ -36,6 +36,7 @@
#include "cullBinBackToFront.h"
#include "cullBinFixed.h"
#include "cullBinFrontToBack.h"
#include "cullBinStateSorted.h"
#include "cullBinUnsorted.h"
#include "cullTraverser.h"
#include "cullableObject.h"
@ -236,6 +237,7 @@ init_libpgraph() {
CullBinBackToFront::init_type();
CullBinFixed::init_type();
CullBinFrontToBack::init_type();
CullBinStateSorted::init_type();
CullBinUnsorted::init_type();
CullTraverser::init_type();
CullableObject::init_type();

View File

@ -20,6 +20,7 @@
#include "cullBinBackToFront.h"
#include "cullBinFrontToBack.h"
#include "cullBinFixed.h"
#include "cullBinStateSorted.h"
#include "cullBinUnsorted.h"
#include "renderState.h"
#include "cullResult.h"
@ -212,6 +213,9 @@ make_new_bin(int bin_index, GraphicsStateGuardianBase *gsg) {
case BT_fixed:
return new CullBinFixed(name, gsg);
case BT_state_sorted:
return new CullBinStateSorted(name, gsg);
default:
return new CullBinUnsorted(name, gsg);
}

View File

@ -0,0 +1,71 @@
// Filename: cullBinStateSorted.I
// Created by: drose (22Mar05)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: CullBinStateSorted::ObjectData::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE CullBinStateSorted::ObjectData::
ObjectData(CullableObject *object) :
_object(object)
{
}
////////////////////////////////////////////////////////////////////
// Function: CullBinStateSorted::ObjectData::operator <
// Access: Public
// Description: Specifies the correct sort ordering for these
// objects.
////////////////////////////////////////////////////////////////////
INLINE bool CullBinStateSorted::ObjectData::
operator < (const ObjectData &other) const {
const RenderState *sa = _object->_state;
const RenderState *sb = other._object->_state;
if (sa != sb) {
// First, group objects by texture, since conventional wisdom is
// that texture changes are the most expensive state changes in a
// graphics context.
const TextureAttrib *ta = sa->get_texture();
const TextureAttrib *tb = sb->get_texture();
if (ta != tb) {
return ta < tb;
}
// Then, sort by all the other states, in no particular order,
// just as long as objects with identical state are all grouped
// together.
return sa < sb;
}
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: CullBinStateSorted::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE CullBinStateSorted::
CullBinStateSorted(const string &name, GraphicsStateGuardianBase *gsg) :
CullBin(name, gsg)
{
}

View File

@ -0,0 +1,87 @@
// Filename: cullBinStateSorted.cxx
// Created by: drose (22Mar05)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#include "cullBinStateSorted.h"
#include "graphicsStateGuardianBase.h"
#include "geometricBoundingVolume.h"
#include "cullableObject.h"
#include "cullHandler.h"
#include "pStatTimer.h"
#include <algorithm>
TypeHandle CullBinStateSorted::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: CullBinStateSorted::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
CullBinStateSorted::
~CullBinStateSorted() {
Objects::iterator oi;
for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
CullableObject *object = (*oi)._object;
delete object;
}
}
////////////////////////////////////////////////////////////////////
// Function: CullBinStateSorted::add_object
// Access: Public, Virtual
// Description: Adds a geom, along with its associated state, to
// the bin for rendering.
////////////////////////////////////////////////////////////////////
void CullBinStateSorted::
add_object(CullableObject *object) {
_objects.push_back(ObjectData(object));
}
////////////////////////////////////////////////////////////////////
// Function: CullBinStateSorted::finish_cull
// Access: Public
// Description: Called after all the geoms have been added, this
// indicates that the cull process is finished for this
// frame and gives the bins a chance to do any
// post-processing (like sorting) before moving on to
// draw.
////////////////////////////////////////////////////////////////////
void CullBinStateSorted::
finish_cull() {
PStatTimer timer(_cull_this_pcollector);
sort(_objects.begin(), _objects.end());
}
////////////////////////////////////////////////////////////////////
// Function: CullBinStateSorted::draw
// Access: Public
// Description: Draws all the geoms in the bin, in the appropriate
// order.
////////////////////////////////////////////////////////////////////
void CullBinStateSorted::
draw() {
PStatTimer timer(_draw_this_pcollector);
Objects::const_iterator oi;
for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
CullableObject *object = (*oi)._object;
CullHandler::draw(object, _gsg);
}
}

View File

@ -0,0 +1,86 @@
// Filename: cullBinStateSorted.h
// Created by: drose (22Mar05)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#ifndef CULLBINSTATESORTED_H
#define CULLBINSTATESORTED_H
#include "pandabase.h"
#include "cullBin.h"
#include "geom.h"
#include "transformState.h"
#include "renderState.h"
#include "pointerTo.h"
////////////////////////////////////////////////////////////////////
// Class : CullBinStateSorted
// Description : A specific kind of CullBin that sorts geometry to
// collect items of the same state together, so that
// minimal state changes are required on the GSG to
// render them.
//
// This also sorts objects front-to-back within a
// particular state, to take advantage of hierarchical
// Z-buffer algorithms which can early-out when an
// object appears behind another one.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA CullBinStateSorted : public CullBin {
public:
INLINE CullBinStateSorted(const string &name, GraphicsStateGuardianBase *gsg);
virtual ~CullBinStateSorted();
virtual void add_object(CullableObject *object);
virtual void finish_cull();
virtual void draw();
private:
class ObjectData {
public:
INLINE ObjectData(CullableObject *object);
INLINE bool operator < (const ObjectData &other) const;
CullableObject *_object;
};
typedef pvector<ObjectData> Objects;
Objects _objects;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
CullBin::init_type();
register_type(_type_handle, "CullBinStateSorted",
CullBin::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
#include "cullBinStateSorted.I"
#endif

View File

@ -36,6 +36,7 @@
PStatCollector CullTraverser::_nodes_pcollector("Nodes");
PStatCollector CullTraverser::_geom_nodes_pcollector("Nodes:GeomNodes");
PStatCollector CullTraverser::_geoms_pcollector("Geoms");
TypeHandle CullTraverser::_type_handle;
@ -210,6 +211,7 @@ traverse_below(CullTraverserData &data) {
// Get all the Geoms, with no decalling.
int num_geoms = geom_node->get_num_geoms();
_geoms_pcollector.add_level(num_geoms);
for (int i = 0; i < num_geoms; i++) {
CullableObject *object = new CullableObject(data, geom_node, i);
_cull_handler->record_object(object);
@ -264,6 +266,7 @@ show_bounds(CullTraverserData &data) {
PT(Geom) bounds_viz = make_bounds_viz(node->get_bound());
if (bounds_viz != (Geom *)NULL) {
_geoms_pcollector.add_level(2);
CullableObject *outer_viz =
new CullableObject(bounds_viz, get_bounds_outer_viz_state(),
data._render_transform);
@ -417,6 +420,7 @@ start_decal(const CullTraverserData &data) {
CullableObject *object = separator;
GeomNode *geom_node = DCAST(GeomNode, node);
int num_geoms = geom_node->get_num_geoms();
_geoms_pcollector.add_level(num_geoms);
for (int i = num_geoms - 1; i >= 0; i--) {
object = new CullableObject(data, geom_node, i, object);
}
@ -474,6 +478,7 @@ r_get_decals(CullTraverserData &data, CullableObject *decals) {
GeomNode *geom_node = DCAST(GeomNode, node);
int num_geoms = geom_node->get_num_geoms();
_geoms_pcollector.add_level(num_geoms);
for (int i = num_geoms - 1; i >= 0; i--) {
decals = new CullableObject(data, geom_node, i, decals);
}

View File

@ -89,6 +89,7 @@ public:
// Statistics
static PStatCollector _nodes_pcollector;
static PStatCollector _geom_nodes_pcollector;
static PStatCollector _geoms_pcollector;
private:
void show_bounds(CullTraverserData &data);

View File

@ -19,6 +19,7 @@
#include "cullBinFixed.cxx"
#include "cullBinFrontToBack.cxx"
#include "cullBinManager.cxx"
#include "cullBinStateSorted.cxx"
#include "cullBinUnsorted.cxx"
#include "cullFaceAttrib.cxx"
#include "cullHandler.cxx"

View File

@ -165,6 +165,7 @@ static LevelCollectorProperties level_properties[] = {
{ 1, "Vertices:Display lists", { 0.8, 0.5, 1.0 } },
{ 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, "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 },