changed CircBuffer to use STL-like interface

This commit is contained in:
David Rose 2001-06-12 18:56:57 +00:00
parent 1cde0e2b8e
commit f2eddac535
56 changed files with 1264 additions and 253 deletions

View File

@ -213,8 +213,8 @@ update(Character *character) {
DCAST_INTO_V(joint, character->get_part(vt._joint_index));
mat =
joint->_initial_net_transform_inverse *
joint->_net_transform;
joint->_initial_net_transform_inverse *
joint->_net_transform;
}
Vertices::const_iterator vi;

View File

@ -11,6 +11,7 @@
#define SOURCES \
config_display.h displayRegion.I displayRegion.h \
geomContext.I geomContext.h geomNodeContext.I geomNodeContext.h \
graphicsChannel.I graphicsChannel.h graphicsLayer.I \
graphicsLayer.h graphicsPipe.I graphicsPipe.N graphicsPipe.h \
graphicsStateGuardian.I graphicsStateGuardian.N \
@ -20,21 +21,25 @@
hardwareChannel.h interactiveGraphicsPipe.I \
interactiveGraphicsPipe.h noninteractiveGraphicsPipe.I \
noninteractiveGraphicsPipe.h pipeSpec.I pipeSpec.h \
savedContext.I savedContext.h \
savedFrameBuffer.I savedFrameBuffer.h textureContext.I \
textureContext.h
#define INCLUDED_SOURCES \
config_display.cxx displayRegion.cxx graphicsChannel.cxx \
config_display.cxx displayRegion.cxx \
geomContext.cxx geomNodeContext.cxx graphicsChannel.cxx \
graphicsLayer.cxx graphicsPipe.cxx graphicsStateGuardian.cxx \
graphicsWindow.cxx graphicsWindowInputDevice.cxx \
hardwareChannel.cxx interactiveGraphicsPipe.cxx \
noninteractiveGraphicsPipe.cxx pipeSpec.cxx \
savedContext.cxx \
savedFrameBuffer.cxx textureContext.cxx
#define INSTALL_HEADERS \
config_display.h \
displayRegion.I displayRegion.h displayRegionStack.I \
displayRegionStack.h frameBufferStack.I frameBufferStack.h \
geomContext.I geomContext.h geomNodeContext.I geomNodeContext.h \
graphicsChannel.I graphicsChannel.h graphicsLayer.I graphicsLayer.h \
graphicsPipe.I graphicsPipe.h graphicsStateGuardian.I \
graphicsStateGuardian.h graphicsWindow.I graphicsWindow.h \
@ -42,6 +47,7 @@
hardwareChannel.I hardwareChannel.h interactiveGraphicsPipe.I \
interactiveGraphicsPipe.h noninteractiveGraphicsPipe.I \
noninteractiveGraphicsPipe.h pipeSpec.I pipeSpec.h renderBuffer.h \
savedContext.I savedContext.h \
savedFrameBuffer.I savedFrameBuffer.h textureContext.I \
textureContext.h

View File

@ -1,5 +1,7 @@
#include "displayRegion.cxx"
#include "geomContext.cxx"
#include "geomNodeContext.cxx"
#include "graphicsChannel.cxx"
#include "graphicsLayer.cxx"
#include "graphicsPipe.cxx"

View File

@ -4,5 +4,6 @@
#include "interactiveGraphicsPipe.cxx"
#include "noninteractiveGraphicsPipe.cxx"
#include "pipeSpec.cxx"
#include "savedContext.cxx"
#include "savedFrameBuffer.cxx"
#include "textureContext.cxx"

View File

@ -0,0 +1,27 @@
// Filename: geomContext.I
// Created by: drose (11Jun01)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: GeomContext::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomContext::
GeomContext(Geom *geom) : _geom(geom) {
}

View File

@ -0,0 +1,21 @@
// Filename: geomContext.cxx
// Created by: drose (11Jun01)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "geomContext.h"
TypeHandle GeomContext::_type_handle;

View File

@ -0,0 +1,75 @@
// Filename: geomContext.h
// Created by: drose (11Jun01)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#ifndef GEOMCONTEXT_H
#define GEOMCONTEXT_H
#include <pandabase.h>
#include "savedContext.h"
class Geom;
////////////////////////////////////////////////////////////////////
// Class : GeomContext
// Description : This is a special class object, similar to a
// TextureContext, that holds all the information
// returned by a particular GSG to cache the rendering
// information associated with one or more Geoms. This
// is similar to, but different from, a GeomNode
// context, which is associated with the containing
// GeomNode class; a GSG might prefer to associate data
// with either the Geom or the GeomNode or both.
//
// This allows the GSG to precompute some information
// necessary for drawing the Geoms as quickly as
// possible and reuse that information across multiple
// frames. Typically, only static Geoms
// (e.g. nonindexed) will be assigned GeomContexts.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA GeomContext : public SavedContext {
public:
INLINE GeomContext(Geom *geom);
// This cannot be a PT(Geom), because the geom and the GSG
// both own their GeomContexts! That would create a circular
// reference count.
Geom *_geom;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
SavedContext::init_type();
register_type(_type_handle, "GeomContext",
SavedContext::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 "geomContext.I"
#endif

View File

@ -0,0 +1,29 @@
// Filename: geomNodeContext.I
// Created by: drose (11Jun01)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: GeomNodeContext::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomNodeContext::
GeomNodeContext(GeomNode *node) :
_node(node)
{
}

View File

@ -0,0 +1,21 @@
// Filename: geomNodeContext.cxx
// Created by: drose (11Jun01)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "geomNodeContext.h"
TypeHandle GeomNodeContext::_type_handle;

View File

@ -0,0 +1,75 @@
// Filename: geomNodeContext.h
// Created by: drose (11Jun01)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#ifndef GEOMNODECONTEXT_H
#define GEOMNODECONTEXT_H
#include <pandabase.h>
#include "savedContext.h"
class GeomNode;
////////////////////////////////////////////////////////////////////
// Class : GeomNodeContext
// Description : This is a special class object, similar to a
// TextureContext, that holds all the information
// returned by a particular GSG to cache the rendering
// information associated with one or more GeomNodes.
// This is similar to, but different from, a Geom
// context, which is associated with the containing Geom
// class; a GSG might prefer to associate data with
// either the Geom or the GeomNode or both.
//
// This allows the GSG to precompute some information
// necessary for drawing the Geoms as quickly as
// possible and reuse that information across multiple
// frames. Typically, only static Geoms
// (e.g. nonindexed) will be assigned GeomContexts.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA GeomNodeContext : public SavedContext {
public:
INLINE GeomNodeContext(GeomNode *node);
// This cannot be a PT(GeomNode), because the geomNode and the GSG
// both own their GeomNodeContexts! That would create a circular
// reference count.
GeomNode *_node;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
SavedContext::init_type();
register_type(_type_handle, "GeomNodeContext",
SavedContext::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 "geomNodeContext.I"
#endif

View File

@ -29,6 +29,10 @@
#ifndef CPPPARSER
PStatCollector GraphicsStateGuardian::_total_texusage_pcollector("Texture usage");
PStatCollector GraphicsStateGuardian::_active_texusage_pcollector("Texture usage:Active");
PStatCollector GraphicsStateGuardian::_total_geom_pcollector("Prepared Geoms");
PStatCollector GraphicsStateGuardian::_active_geom_pcollector("Prepared Geoms:Active");
PStatCollector GraphicsStateGuardian::_total_geom_node_pcollector("Prepared GeomNodes");
PStatCollector GraphicsStateGuardian::_active_geom_node_pcollector("Prepared GeomNodes:Active");
PStatCollector GraphicsStateGuardian::_total_texmem_pcollector("Texture memory");
PStatCollector GraphicsStateGuardian::_used_texmem_pcollector("Texture memory:In use");
PStatCollector GraphicsStateGuardian::_texmgrmem_total_pcollector("Texture manager");
@ -93,52 +97,6 @@ GraphicsStateGuardian::
~GraphicsStateGuardian() {
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::release_all_textures
// Access: Public
// Description: Frees the resources for all textures associated with
// this GSG.
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
release_all_textures() {
// We must get a copy of the _prepared_textures list first, because
// each call to release_texture() will remove that texture from the
// list, and we don't want to traverse a list while we're modifying
// it!
Textures temp = _prepared_textures;
for (Textures::const_iterator ti = temp.begin();
ti != temp.end();
++ti) {
release_texture(*ti);
}
// Now that we've released all of the textures, the
// _prepared_textures list should have completely emptied itself.
nassertv(_prepared_textures.empty());
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::clear_attribute
// Access: Public
// Description: Explicitly clear the indicated attribute, specified
// by the TypeHandle of its associated transition. If
// the attribute is not set already, this does nothing;
// if it is set, it resets it to its default value.
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
clear_attribute(TypeHandle type) {
NodeAttributes::iterator ai = _state.find(type);
if (ai != _state.end()) {
// The state is already set; get the initial value and reset it.
PT(NodeAttribute) initial = (*ai).second->make_initial();
initial->issue(this);
// Now remove the state entry from the set.
_state.erase(ai);
}
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::reset
// Access: Public, Virtual
@ -421,6 +379,163 @@ enable_frame_clear(bool clear_color, bool clear_depth) {
}
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::release_all_textures
// Access: Public
// Description: Frees the resources for all textures associated with
// this GSG.
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
release_all_textures() {
// We must get a copy of the _prepared_textures list first, because
// each call to release_texture() will remove that texture from the
// list, and we don't want to traverse a list while we're modifying
// it!
Textures temp = _prepared_textures;
for (Textures::const_iterator ti = temp.begin();
ti != temp.end();
++ti) {
release_texture(*ti);
}
// Now that we've released all of the textures, the
// _prepared_textures list should have completely emptied itself.
nassertv(_prepared_textures.empty());
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::release_all_geoms
// Access: Public
// Description: Frees the resources for all Geoms and GeomNodes
// associated with this GSG. Warning! This may make
// the Geoms unrenderable, if the Panda-level
// information has been deleted.
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
release_all_geoms() {
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::clear_attribute
// Access: Public
// Description: Explicitly clear the indicated attribute, specified
// by the TypeHandle of its associated transition. If
// the attribute is not set already, this does nothing;
// if it is set, it resets it to its default value.
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
clear_attribute(TypeHandle type) {
NodeAttributes::iterator ai = _state.find(type);
if (ai != _state.end()) {
// The state is already set; get the initial value and reset it.
PT(NodeAttribute) initial = (*ai).second->make_initial();
initial->issue(this);
// Now remove the state entry from the set.
_state.erase(ai);
}
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::prepare_texture
// Access: Public, Virtual
// Description: Prepares the indicated texture for retained-mode
// rendering. In the future, this texture may be
// applied simply by calling apply_texture() with the
// value returned by this function.
////////////////////////////////////////////////////////////////////
TextureContext *GraphicsStateGuardian::
prepare_texture(Texture *) {
return (TextureContext *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::apply_texture
// Access: Public, Virtual
// Description: Applies the texture previously indicated via a call
// to prepare_texture() to the graphics state, so that
// geometry rendered in the future will be rendered with
// the given texture.
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
apply_texture(TextureContext *) {
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::release_texture
// Access: Public, Virtual
// Description: Frees the resources previously allocated via a call
// to prepare_texture(), including deleting the
// TextureContext itself, if necessary.
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
release_texture(TextureContext *) {
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::prepare_geom_node
// Access: Public, Virtual
// Description: Prepares the indicated GeomNode for retained-mode
// rendering. If this function returns non-NULL, the
// value returned will be passed back to a future call
// to draw_geom_node(), which is expected to draw the
// contents of the node.
////////////////////////////////////////////////////////////////////
GeomNodeContext *GraphicsStateGuardian::
prepare_geom_node(GeomNode *) {
return (GeomNodeContext *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::draw_geom_node
// Access: Public, Virtual
// Description: Draws a GeomNode previously indicated by a call to
// prepare_geom_node().
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
draw_geom_node(GeomNode *node, GeomNodeContext *) {
int num_geoms = node->get_num_geoms();
for (int i = 0; i < num_geoms; i++) {
node->get_geom(i)->draw(this);
}
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::release_geom_node
// Access: Public, Virtual
// Description: Frees the resources previously allocated via a call
// to prepare_geom_node(), including deleting the
// GeomNodeContext itself, if necessary.
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
release_geom_node(GeomNodeContext *) {
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::prepare_geom
// Access: Public, Virtual
// Description: Prepares the indicated Geom for retained-mode
// rendering. The value returned by this function will
// be passed back into future calls to draw_tristrip(),
// etc., along with the Geom pointer.
////////////////////////////////////////////////////////////////////
GeomContext *GraphicsStateGuardian::
prepare_geom(Geom *) {
return (GeomContext *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::release_geom
// Access: Public, Virtual
// Description: Frees the resources previously allocated via a call
// to prepare_geom(), including deleting the GeomContext
// itself, if necessary.
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
release_geom(GeomContext *) {
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::wants_normals
// Access: Public, Virtual
@ -517,6 +632,86 @@ unmark_prepared_texture(TextureContext *tc) {
return removed;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::mark_prepared_geom
// Access: Protected
// Description: This is intended to be called from within
// prepare_geom(). It adds the indicated GeomContext
// pointer to the _prepared_geoms set, and returns true
// if it was successfully added (i.e. it was not already
// in the set).
////////////////////////////////////////////////////////////////////
bool GraphicsStateGuardian::
mark_prepared_geom(GeomContext *gc) {
bool prepared = _prepared_geoms.insert(gc).second;
#ifdef DO_PSTATS
if (prepared) {
_total_geom_pcollector.add_level(1);
}
#endif
return prepared;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::unmark_prepared_geom
// Access: Protected
// Description: This is intended to be called from within
// release_geom(). It removes the indicated GeomContext
// pointer from the _prepared_geoms set, and returns
// true if it was successfully removed (i.e. it had been
// in the set).
////////////////////////////////////////////////////////////////////
bool GraphicsStateGuardian::
unmark_prepared_geom(GeomContext *gc) {
bool removed = (_prepared_geoms.erase(gc) != 0);
#ifdef DO_PSTATS
if (removed) {
_total_geom_pcollector.sub_level(1);
}
#endif
return removed;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::mark_prepared_geom_node
// Access: Protected
// Description: This is intended to be called from within
// prepare_geom_node(). It adds the indicated
// GeomNodeContext pointer to the _prepared_geom_nodes
// set, and returns true if it was successfully added
// (i.e. it was not already in the set).
////////////////////////////////////////////////////////////////////
bool GraphicsStateGuardian::
mark_prepared_geom_node(GeomNodeContext *gnc) {
bool prepared = _prepared_geom_nodes.insert(gnc).second;
#ifdef DO_PSTATS
if (prepared) {
_total_geom_node_pcollector.add_level(1);
}
#endif
return prepared;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::unmark_prepared_geom_node
// Access: Protected
// Description: This is intended to be called from within
// release_geom_node(). It removes the indicated
// GeomNodeContext pointer from the _prepared_geom_nodes
// set, and returns true if it was successfully removed
// (i.e. it had been in the set).
////////////////////////////////////////////////////////////////////
bool GraphicsStateGuardian::
unmark_prepared_geom_node(GeomNodeContext *gnc) {
bool removed = (_prepared_geom_nodes.erase(gnc) != 0);
#ifdef DO_PSTATS
if (removed) {
_total_geom_node_pcollector.sub_level(1);
}
#endif
return removed;
}
#ifdef DO_PSTATS
////////////////////////////////////////////////////////////////////
@ -529,6 +724,8 @@ void GraphicsStateGuardian::
init_frame_pstats() {
_current_textures.clear();
_active_texusage_pcollector.clear_level();
_total_geom_pcollector.clear_level();
_total_geom_node_pcollector.clear_level();
// Also clear out our other counters while we're here.
_vertices_tristrip_pcollector.clear_level();
@ -560,6 +757,37 @@ add_to_texture_record(TextureContext *tc) {
}
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::add_to_geom_record
// Access: Protected
// Description: Records that the indicated Geom has been drawn this
// frame. This function is only used to update the
// PStats current_texmem collector; it gets compiled out
// if we aren't using PStats.
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
add_to_geom_record(GeomContext *gc) {
if (gc != (GeomContext *)NULL && _current_geoms.insert(gc).second) {
_active_geom_pcollector.add_level(1);
}
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::add_to_geom_node_record
// Access: Protected
// Description: Records that the indicated GeomNode has been drawn
// this frame. This function is only used to update the
// PStats current_texmem collector; it gets compiled out
// if we aren't using PStats.
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
add_to_geom_node_record(GeomNodeContext *gnc) {
if (gnc != (GeomNodeContext *)NULL &&
_current_geom_nodes.insert(gnc).second) {
_active_geom_node_pcollector.add_level(1);
}
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::record_state_change
// Access: Protected

View File

@ -79,10 +79,22 @@ PUBLISHED:
void enable_frame_clear(bool clear_color, bool clear_depth);
void release_all_textures();
void release_all_geoms();
void clear_attribute(TypeHandle type);
public:
virtual TextureContext *prepare_texture(Texture *tex);
virtual void apply_texture(TextureContext *tc);
virtual void release_texture(TextureContext *tc);
virtual GeomNodeContext *prepare_geom_node(GeomNode *node);
virtual void draw_geom_node(GeomNode *node, GeomNodeContext *gnc);
virtual void release_geom_node(GeomNodeContext *gnc);
virtual GeomContext *prepare_geom(Geom *geom);
virtual void release_geom(GeomContext *gc);
virtual void clear(const RenderBuffer &buffer)=0;
virtual void clear(const RenderBuffer &buffer, const DisplayRegion* region)=0;
@ -148,18 +160,28 @@ protected:
bool mark_prepared_texture(TextureContext *tc);
bool unmark_prepared_texture(TextureContext *tc);
bool mark_prepared_geom(GeomContext *gc);
bool unmark_prepared_geom(GeomContext *gc);
bool mark_prepared_geom_node(GeomNodeContext *gnc);
bool unmark_prepared_geom_node(GeomNodeContext *gnc);
#ifdef DO_PSTATS
// These functions are used to update the active texture memory
// usage record (and other frame-based measurements) in Pstats.
void init_frame_pstats();
void add_to_texture_record(TextureContext *tc);
void add_to_geom_record(GeomContext *gc);
void add_to_geom_node_record(GeomNodeContext *gnc);
void record_state_change(TypeHandle type);
pset<TextureContext *> _current_textures;
pset<GeomContext *> _current_geoms;
pset<GeomNodeContext *> _current_geom_nodes;
#else
INLINE void init_frame_pstats() { }
INLINE void add_to_texture_record(TextureContext *) { }
INLINE void record_state_change(TypeHandle type) { }
INLINE void add_to_geom_record(GeomContext *) { }
INLINE void add_to_geom_node_record(GeomNodeContext *) { }
INLINE void record_state_change(TypeHandle) { }
INLINE void count_node(Node *) { }
#endif
@ -192,6 +214,10 @@ public:
// Statistics
static PStatCollector _total_texusage_pcollector;
static PStatCollector _active_texusage_pcollector;
static PStatCollector _total_geom_pcollector;
static PStatCollector _active_geom_pcollector;
static PStatCollector _total_geom_node_pcollector;
static PStatCollector _active_geom_node_pcollector;
static PStatCollector _total_texmem_pcollector;
static PStatCollector _used_texmem_pcollector;
static PStatCollector _texmgrmem_total_pcollector;
@ -208,8 +234,14 @@ public:
static PStatCollector _geom_nodes_pcollector;
private:
// NOTE: on win32 another DLL (e.g. libpandadx.dll) cannot access
// these sets directly due to exported template issue
typedef pset<TextureContext *> Textures;
Textures _prepared_textures; // NOTE: on win32 another DLL (e.g. libpandadx.dll) cannot access set directly due to exported template issue
Textures _prepared_textures;
typedef pset<GeomContext *> Geoms;
Geoms _prepared_geoms;
typedef pset<GeomNodeContext *> GeomNodes;
GeomNodes _prepared_geom_nodes;
public:
void traverse_prepared_textures(bool (*pertex_callbackfn)(TextureContext *,void *),void *callback_arg);

View File

@ -0,0 +1,26 @@
// Filename: savedContext.I
// Created by: drose (11Jun01)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: SavedContext::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE SavedContext::
SavedContext() {
}

View File

@ -0,0 +1,21 @@
// Filename: savedContext.cxx
// Created by: drose (11Jun01)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "savedContext.h"
TypeHandle SavedContext::_type_handle;

View File

@ -0,0 +1,56 @@
// Filename: savedContext.h
// Created by: drose (11Jun01)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#ifndef SAVEDCONTEXT_H
#define SAVEDCONTEXT_H
#include <pandabase.h>
#include <typedObject.h>
////////////////////////////////////////////////////////////////////
// Class : SavedContext
// Description : This is the base class for both a TextureContext and
// a GeomContext.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA SavedContext : public TypedObject {
public:
INLINE SavedContext();
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
TypedObject::init_type();
register_type(_type_handle, "SavedContext",
TypedObject::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 "savedContext.I"
#endif

View File

@ -21,7 +21,7 @@
#include <pandabase.h>
#include <typedObject.h>
#include "savedContext.h"
class Texture;
@ -38,7 +38,7 @@ class Texture;
// internal handle for the texture and store it here.
// The texture stores all of these handles internally.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA TextureContext : public TypedObject {
class EXPCL_PANDA TextureContext : public SavedContext {
public:
INLINE TextureContext(Texture *tex);
@ -54,9 +54,9 @@ public:
return _type_handle;
}
static void init_type() {
TypedObject::init_type();
SavedContext::init_type();
register_type(_type_handle, "TextureContext",
TypedObject::get_class_type());
SavedContext::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();

View File

@ -324,7 +324,7 @@ request_download(const string &file_name, const Filename &file_dest,
_lock.lock();
#endif
if (_token_board->_waiting.is_full()) {
if (_token_board->_waiting.full()) {
downloader_cat.error()
<< "Downloader::request_download() - Too many pending requests\n";
return 0;
@ -338,7 +338,7 @@ request_download(const string &file_name, const Filename &file_dest,
tok = new DownloaderToken(_next_token++, file_name, file_dest,
event_name, first_byte, last_byte, total_bytes,
partial_content, sync);
_token_board->_waiting.insert(tok);
_token_board->_waiting.push_back(tok);
#ifdef HAVE_IPC
_request_cond->signal();
@ -348,7 +348,7 @@ request_download(const string &file_name, const Filename &file_dest,
} else {
// If we're not running asynchronously, process the load request
// directly now.
if (_token_board->_waiting.is_full()) {
if (_token_board->_waiting.full()) {
downloader_cat.error()
<< "Downloader::request_download() - Too many pending requests\n";
return 0;
@ -361,7 +361,7 @@ request_download(const string &file_name, const Filename &file_dest,
tok = new DownloaderToken(_next_token++, file_name, file_dest,
event_name, first_byte, last_byte, total_bytes,
partial_content, sync);
_token_board->_waiting.insert(tok);
_token_board->_waiting.push_back(tok);
process_request();
}
@ -384,8 +384,9 @@ process_request() {
}
// If there is actually a request token - process it
while (!_token_board->_waiting.is_empty()) {
PT(DownloaderToken) tok = _token_board->_waiting.extract();
while (!_token_board->_waiting.empty()) {
PT(DownloaderToken) tok = _token_board->_waiting.front();
_token_board->_waiting.pop_front();
int ret = download(tok->_file_name, tok->_file_dest, tok->_event_name,
tok->_first_byte, tok->_last_byte, tok->_total_bytes,
tok->_partial_content, tok->_sync, tok->_id);
@ -393,7 +394,7 @@ process_request() {
PT_Event return_event = new Event(tok->_event_name);
return_event->add_parameter(EventParameter((int)tok->_id));
if (ret == DS_success) {
_token_board->_done.insert(tok);
_token_board->_done.push_back(tok);
return_event->add_parameter(EventParameter(DS_success));
// Throw a "done" event now.

View File

@ -1170,7 +1170,7 @@ draw_prim_inner_loop(int nVerts, const Geom *geom, DWORD perFlags) {
// Description:
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian::
draw_point(const GeomPoint *geom) {
draw_point(GeomPoint *geom, GeomContext *gc) {
activate();
#ifdef GSG_VERBOSE
@ -1314,7 +1314,7 @@ draw_point(const GeomPoint *geom) {
// Description:
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian::
draw_line(const GeomLine* geom) {
draw_line(GeomLine* geom, GeomContext *gc) {
activate();
#ifdef GSG_VERBOSE
@ -1425,7 +1425,7 @@ draw_line(const GeomLine* geom) {
// Description:
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian::
draw_linestrip(const GeomLinestrip* geom) {
draw_linestrip(GeomLinestrip* geom, GeomContext *gc) {
activate();
#ifdef GSG_VERBOSE
@ -1585,7 +1585,7 @@ struct draw_sprite_vertex_less {
// Description:
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian::
draw_sprite(const GeomSprite *geom) {
draw_sprite(GeomSprite *geom, GeomContext *gc) {
// this is a little bit of a mess, but it's ok. Here's the deal:
// we want to draw, and draw quickly, an arbitrarily large number
@ -1909,7 +1909,7 @@ draw_sprite(const GeomSprite *geom) {
// Description:
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian::
draw_polygon(const GeomPolygon *geom) {
draw_polygon(GeomPolygon *geom, GeomContext *gc) {
activate();
#ifdef GSG_VERBOSE
@ -1990,7 +1990,7 @@ draw_polygon(const GeomPolygon *geom) {
// Description:
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian::
draw_tri(const GeomTri *geom) {
draw_tri(GeomTri *geom, GeomContext *gc) {
// activate();
#ifdef GSG_VERBOSE
@ -2290,7 +2290,7 @@ draw_tri(const GeomTri *geom) {
// Description:
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian::
draw_quad(const GeomQuad *geom) {
draw_quad(GeomQuad *geom, GeomContext *gc) {
activate();
#if 1
@ -2359,7 +2359,7 @@ draw_quad(const GeomQuad *geom) {
// Description:
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian::
draw_tristrip(const GeomTristrip *geom) {
draw_tristrip(GeomTristrip *geom, GeomContext *gc) {
#ifdef GSG_VERBOSE
dxgsg_cat.debug() << "draw_tristrip()" << endl;
@ -2375,7 +2375,7 @@ draw_tristrip(const GeomTristrip *geom) {
// Description:
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian::
draw_trifan(const GeomTrifan *geom) {
draw_trifan(GeomTrifan *geom, GeomContext *gc) {
#ifdef GSG_VERBOSE
dxgsg_cat.debug() << "draw_trifan()" << endl;
@ -2391,7 +2391,7 @@ draw_trifan(const GeomTrifan *geom) {
// Description: handles trifans and tristrips
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian::
draw_multitri(const Geom *geom, D3DPRIMITIVETYPE trilisttype) {
draw_multitri(Geom *geom, D3DPRIMITIVETYPE trilisttype) {
int nPrims = geom->get_num_prims();
const int *pLengthArr = geom->get_lengths();
@ -3000,7 +3000,7 @@ GenerateSphere(void *pVertexSpace,DWORD dwVertSpaceByteSize,
// Description:
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian::
draw_sphere(const GeomSphere *geom) {
draw_sphere(GeomSphere *geom, GeomContext *gc) {
#define SPHERE_NUMSLICES 16
#define SPHERE_NUMSTACKS 10
@ -5340,6 +5340,7 @@ void DXGraphicsStateGuardian::
dx_cleanup() {
release_all_textures();
release_all_geoms();
// Do a safe check for releasing the D3DDEVICE. RefCount should be zero.
if (_d3dDevice!=NULL) {

View File

@ -103,16 +103,16 @@ public:
const AllAttributesWrapper &initial_state,
const AllTransitionsWrapper &net_trans);
virtual void draw_point(const GeomPoint *geom);
virtual void draw_line(const GeomLine *geom);
virtual void draw_linestrip(const GeomLinestrip *geom);
virtual void draw_sprite(const GeomSprite *geom);
virtual void draw_polygon(const GeomPolygon *geom);
virtual void draw_quad(const GeomQuad *geom);
virtual void draw_tri(const GeomTri *geom);
virtual void draw_tristrip(const GeomTristrip *geom);
virtual void draw_trifan(const GeomTrifan *geom);
virtual void draw_sphere(const GeomSphere *geom);
virtual void draw_point(GeomPoint *geom, GeomContext *gc);
virtual void draw_line(GeomLine *geom, GeomContext *gc);
virtual void draw_linestrip(GeomLinestrip *geom, GeomContext *gc);
virtual void draw_sprite(GeomSprite *geom, GeomContext *gc);
virtual void draw_polygon(GeomPolygon *geom, GeomContext *gc);
virtual void draw_quad(GeomQuad *geom, GeomContext *gc);
virtual void draw_tri(GeomTri *geom, GeomContext *gc);
virtual void draw_tristrip(GeomTristrip *geom, GeomContext *gc);
virtual void draw_trifan(GeomTrifan *geom, GeomContext *gc);
virtual void draw_sphere(GeomSphere *geom, GeomContext *gc);
virtual TextureContext *prepare_texture(Texture *tex);
virtual void apply_texture(TextureContext *tc);
@ -264,7 +264,7 @@ protected:
void draw_prim_inner_loop(int nVerts, const Geom *geom, DWORD perFlags);
size_t draw_prim_setup(const Geom *geom) ;
void draw_multitri(const Geom *geom, D3DPRIMITIVETYPE tri_id);
void draw_multitri(Geom *geom, D3DPRIMITIVETYPE tri_id);
#ifdef DO_PSTATS
void report_texmgr_stats();

View File

@ -50,11 +50,11 @@ queue_event(CPT_Event event) {
#ifdef HAVE_IPC
mutex_lock lock(_lock);
#endif
if (_queue.is_full()) {
if (_queue.full()) {
event_cat.error()
<< "Ignoring event " << *event << "; event queue full.\n";
} else {
_queue.insert(event);
_queue.push_back(event);
if (event_cat.is_spam() || event_cat.is_debug()) {
if (event->get_name() == "NewFrame") {
// Don't bother us with this particularly spammy event.
@ -75,7 +75,7 @@ queue_event(CPT_Event event) {
////////////////////////////////////////////////////////////////////
bool EventQueue::
is_queue_empty() const {
return _queue.is_empty();
return _queue.empty();
}
@ -88,7 +88,9 @@ CPT_Event EventQueue::
dequeue_event() {
// We need no mutex protection here, as long as there is only one
// thread extracting events. The magic of circular buffers.
return _queue.extract();
CPT_Event result = _queue.front();
_queue.pop_front();
return result;
}
////////////////////////////////////////////////////////////////////

View File

@ -33,54 +33,130 @@ CircBuffer() {
_in = _out = 0;
}
////////////////////////////////////////////////////////////////////
// Function: CircBuffer::is_empty
// Function: CircBuffer::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class Thing, int max_size>
INLINE CircBuffer<Thing, max_size>::
~CircBuffer() {
}
////////////////////////////////////////////////////////////////////
// Function: CircBuffer::size
// Access: Public
// Description: Returns the number of items currently in the buffer.
// This can safely be called without synchronization
// from either the reader or the writer thread, but the
// size may of course vary without warning after the
// call.
////////////////////////////////////////////////////////////////////
template<class Thing, int max_size>
INLINE int CircBuffer<Thing, max_size>::
size() const {
int diff = _in - _out;
return (diff >= 0) ? diff : max_size + 1 - diff;
}
////////////////////////////////////////////////////////////////////
// Function: CircBuffer::empty
// Access: Public
// Description: Returns true if the buffer is empty. It is safe to
// call this without synchronization primitives from
// either the reader or the writer thread, but the
// result may vary without warning after the call.
////////////////////////////////////////////////////////////////////
template<class Thing, int max_size>
INLINE bool CircBuffer<Thing, max_size>::
is_empty() const {
empty() const {
return _in == _out;
}
////////////////////////////////////////////////////////////////////
// Function: CircBuffer::is_full
// Function: CircBuffer::full
// Access: Public
// Description:
// Description: Returns true if the buffer is full; if this is true,
// push_back() will fail. It is safe to call this
// without synchronization primitives from either the
// reader or the writer thread, but the result may vary
// without warning after the call.
////////////////////////////////////////////////////////////////////
template<class Thing, int max_size>
INLINE bool CircBuffer<Thing, max_size>::
is_full() const {
return _in == _out-1 || (_in==max_size && _out==0);
full() const {
// return _in == _out-1 || (_in==max_size && _out==0);
return ((_in + 1) % (max_size + 1)) == _out;
}
////////////////////////////////////////////////////////////////////
// Function: CircBuffer::peek
// Function: CircBuffer::front
// Access: Public
// Description:
// Description: Returns a reference to the first item in the queue.
// It is invalid to call this if empty() is true. It is
// safe to call this without synchronization only from
// the reading thread: the thread that calls pop_front().
////////////////////////////////////////////////////////////////////
template<class Thing, int max_size>
INLINE const Thing &CircBuffer<Thing, max_size>::
peek() const {
nassertr(!is_empty(), *(new Thing));
front() const {
nassertr(!empty(), _array[0]);
return _array[_out];
}
////////////////////////////////////////////////////////////////////
// Function: CircBuffer::front
// Access: Public
// Description: Returns a reference to the first item in the queue.
// It is invalid to call this if empty() is true. It is
// safe to call this without synchronization only from
// the reading thread: the thread that calls pop_front().
////////////////////////////////////////////////////////////////////
template<class Thing, int max_size>
INLINE Thing &CircBuffer<Thing, max_size>::
front() {
nassertr(!empty(), _array[0]);
return _array[_out];
}
////////////////////////////////////////////////////////////////////
// Function: CircBuffer::operator []
// Access: Public
// Description: Returns the nth element in the buffer. It is safe to
// call this without synchronization only from the
// reading thread: the thread that calls pop_front().
////////////////////////////////////////////////////////////////////
template<class Thing, int max_size>
INLINE const Thing &CircBuffer<Thing, max_size>::
operator[] (int n) const {
nassertr(!empty(), _array[0]);
return _array[(_out + n) % (max_size + 1)];
}
////////////////////////////////////////////////////////////////////
// Function: CircBuffer::operator []
// Access: Public
// Description: Returns the nth element in the buffer. It is safe to
// call this without synchronization only from the
// reading thread: the thread that calls pop_front().
////////////////////////////////////////////////////////////////////
template<class Thing, int max_size>
INLINE Thing &CircBuffer<Thing, max_size>::
operator[] (int n) {
nassertr(!empty(), _array[0]);
return _array[(_out + n) % (max_size + 1)];
}
////////////////////////////////////////////////////////////////////
// Function: CircBuffer::extract
// Function: CircBuffer::pop_front
// Access: Public
// Description:
// Description: Removes the first item from the buffer.
////////////////////////////////////////////////////////////////////
template<class Thing, int max_size>
INLINE Thing CircBuffer<Thing, max_size>::
extract() {
nassertr(!is_empty(), Thing());
Thing temp = _array[_out];
INLINE void CircBuffer<Thing, max_size>::
pop_front() {
nassertv(!empty());
// We need to clear out the old element to force its destructor to
// be called; it might be important. This will generate yet another
@ -89,19 +165,53 @@ extract() {
_array[_out] = Thing();
_out = (_out+1)%(max_size+1);
return temp;
}
////////////////////////////////////////////////////////////////////
// Function: CircBuffer::insert
// Function: CircBuffer::back
// Access: Public
// Description:
// Description: Returns a reference to the last item in the queue.
// It is invalid to call this if empty() is true. It is
// safe to call this without synchronization primitives
// only from the writing thread: the thread that calls
// push_back().
////////////////////////////////////////////////////////////////////
template<class Thing, int max_size>
INLINE const Thing &CircBuffer<Thing, max_size>::
back() const {
nassertr(!empty(), _array[0]);
return _array[(_in + max_size) % (max_size + 1)];
}
////////////////////////////////////////////////////////////////////
// Function: CircBuffer::back
// Access: Public
// Description: Returns a reference to the last item in the queue.
// It is invalid to call this if empty() is true. It is
// safe to call this without synchronization primitives
// only from the writing thread: the thread that calls
// push_back().
////////////////////////////////////////////////////////////////////
template<class Thing, int max_size>
INLINE Thing &CircBuffer<Thing, max_size>::
back() {
nassertr(!empty(), _array[0]);
return _array[(_in + max_size) % (max_size + 1)];
}
////////////////////////////////////////////////////////////////////
// Function: CircBuffer::push_back
// Access: Public
// Description: Adds an item to the end of the buffer. This may fail
// if full() is true.
////////////////////////////////////////////////////////////////////
template<class Thing, int max_size>
INLINE void CircBuffer<Thing, max_size>::
insert(const Thing &t) {
if (is_full()) {
push_back(const Thing &t) {
if (full()) {
express_cat.error()
<< "Circular buffer is full; cannot add requests.\n";
} else {

View File

@ -35,16 +35,32 @@ template<class Thing, int max_size>
class CircBuffer {
public:
INLINE CircBuffer();
INLINE ~CircBuffer();
INLINE bool is_empty() const;
INLINE bool is_full() const;
// Methods that are safe to call without synchronization primitives
// from either thread.
INLINE int size() const;
INLINE const Thing &peek() const;
INLINE Thing extract();
// Methods that are safe to call without synchronization primitives
// only from the reader thread.
INLINE bool empty() const;
INLINE void insert(const Thing &t);
INLINE const Thing &front() const;
INLINE Thing &front();
INLINE void pop_front();
protected:
INLINE const Thing &operator[] (int n) const;
INLINE Thing &operator[] (int n);
// Methods that are safe to call without synchronization primitives
// only from the writer thread.
INLINE bool full() const;
INLINE const Thing &back() const;
INLINE Thing &back();
INLINE void push_back(const Thing &t);
private:
Thing _array[max_size+1];
int _in, _out;
};

View File

@ -29,8 +29,9 @@ is_done_token(int id) {
// to do this since we can only examine tokens on the head of the
// done list, and the token we're looking for might not be at the
// head.
while (!_done.is_empty()) {
_really_done.push_back(_done.extract());
while (!_done.empty()) {
_really_done.push_back(_done.front());
_done.pop_front();
}
// Now we can search really_done for our desired id.
@ -57,8 +58,9 @@ get_done_token(int id) {
// to do this since we can only examine tokens on the head of the
// done list, and the token we're looking for might not be at the
// head.
while (!_done.is_empty()) {
_really_done.push_back(_done.extract());
while (!_done.empty()) {
_really_done.push_back(_done.front());
_done.pop_front();
}
// Now we can search really_done for our desired id.

View File

@ -190,6 +190,7 @@ GLGraphicsStateGuardian::
~GLGraphicsStateGuardian() {
free_pointers();
release_all_textures();
release_all_geoms();
}
////////////////////////////////////////////////////////////////////
@ -720,7 +721,7 @@ render_subgraph(RenderTraverser *traverser, Node *subgraph,
// Description:
////////////////////////////////////////////////////////////////////
void GLGraphicsStateGuardian::
draw_point(const GeomPoint *geom) {
draw_point(GeomPoint *geom, GeomContext *) {
// activate();
#ifdef GSG_VERBOSE
@ -779,7 +780,7 @@ draw_point(const GeomPoint *geom) {
// Description:
////////////////////////////////////////////////////////////////////
void GLGraphicsStateGuardian::
draw_line(const GeomLine* geom) {
draw_line(GeomLine *geom, GeomContext *) {
// activate();
#ifdef GSG_VERBOSE
@ -840,7 +841,7 @@ draw_line(const GeomLine* geom) {
// Description:
////////////////////////////////////////////////////////////////////
void GLGraphicsStateGuardian::
draw_linestrip(const GeomLinestrip* geom) {
draw_linestrip(GeomLinestrip *geom, GeomContext *) {
// activate();
#ifdef GSG_VERBOSE
@ -940,7 +941,7 @@ struct draw_sprite_vertex_less {
};
void GLGraphicsStateGuardian::
draw_sprite(const GeomSprite *geom) {
draw_sprite(GeomSprite *geom, GeomContext *) {
// this is a little bit of a mess, but it's ok. Here's the deal:
// we want to draw, and draw quickly, an arbitrarily large number
// of sprites all facing the screen. Performing the billboard math
@ -1226,7 +1227,7 @@ draw_sprite(const GeomSprite *geom) {
// Description:
////////////////////////////////////////////////////////////////////
void GLGraphicsStateGuardian::
draw_polygon(const GeomPolygon *geom) {
draw_polygon(GeomPolygon *geom, GeomContext *) {
// activate();
#ifdef GSG_VERBOSE
@ -1299,7 +1300,7 @@ draw_polygon(const GeomPolygon *geom) {
// Description:
////////////////////////////////////////////////////////////////////
void GLGraphicsStateGuardian::
draw_tri(const GeomTri *geom) {
draw_tri(GeomTri *geom, GeomContext *) {
// activate();
#ifdef GSG_VERBOSE
@ -1367,7 +1368,7 @@ draw_tri(const GeomTri *geom) {
// Description:
////////////////////////////////////////////////////////////////////
void GLGraphicsStateGuardian::
draw_quad(const GeomQuad *geom) {
draw_quad(GeomQuad *geom, GeomContext *) {
// activate();
#ifdef GSG_VERBOSE
@ -1435,7 +1436,7 @@ draw_quad(const GeomQuad *geom) {
// Description:
////////////////////////////////////////////////////////////////////
void GLGraphicsStateGuardian::
draw_tristrip(const GeomTristrip *geom) {
draw_tristrip(GeomTristrip *geom, GeomContext *) {
// activate();
#ifdef GSG_VERBOSE
@ -1525,7 +1526,7 @@ draw_tristrip(const GeomTristrip *geom) {
// Description:
////////////////////////////////////////////////////////////////////
void GLGraphicsStateGuardian::
draw_trifan(const GeomTrifan *geom) {
draw_trifan(GeomTrifan *geom, GeomContext *) {
// activate();
#ifdef GSG_VERBOSE
@ -1616,7 +1617,7 @@ draw_trifan(const GeomTrifan *geom) {
// Description:
////////////////////////////////////////////////////////////////////
void GLGraphicsStateGuardian::
draw_sphere(const GeomSphere *geom) {
draw_sphere(GeomSphere *geom, GeomContext *) {
// activate();
#ifdef GSG_VERBOSE

View File

@ -87,16 +87,16 @@ public:
const AllAttributesWrapper &initial_state,
const AllTransitionsWrapper &net_trans);
virtual void draw_point(const GeomPoint *geom);
virtual void draw_line(const GeomLine *geom);
virtual void draw_linestrip(const GeomLinestrip *geom);
virtual void draw_sprite(const GeomSprite *geom);
virtual void draw_polygon(const GeomPolygon *geom);
virtual void draw_quad(const GeomQuad *geom);
virtual void draw_tri(const GeomTri *geom);
virtual void draw_tristrip(const GeomTristrip *geom);
virtual void draw_trifan(const GeomTrifan *geom);
virtual void draw_sphere(const GeomSphere *geom);
virtual void draw_point(GeomPoint *geom, GeomContext *gc);
virtual void draw_line(GeomLine *geom, GeomContext *gc);
virtual void draw_linestrip(GeomLinestrip *geom, GeomContext *gc);
virtual void draw_sprite(GeomSprite *geom, GeomContext *gc);
virtual void draw_polygon(GeomPolygon *geom, GeomContext *gc);
virtual void draw_quad(GeomQuad *geom, GeomContext *gc);
virtual void draw_tri(GeomTri *geom, GeomContext *gc);
virtual void draw_tristrip(GeomTristrip *geom, GeomContext *gc);
virtual void draw_trifan(GeomTrifan *geom, GeomContext *gc);
virtual void draw_sphere(GeomSphere *geom, GeomContext *gc);
virtual TextureContext *prepare_texture(Texture *tex);
virtual void apply_texture(TextureContext *tc);
@ -111,7 +111,7 @@ public:
virtual void texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb);
virtual void texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb,
const DisplayRegion *dr);
const DisplayRegion *dr);
virtual void copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr);
virtual void copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,

View File

@ -20,6 +20,38 @@
TypeHandle dDrawable::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: Drawable::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
dDrawable::
dDrawable() : WritableConfigurable() {
MemoryUsage::update_type(this, this);
}
////////////////////////////////////////////////////////////////////
// Function: Drawable::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
dDrawable::
~dDrawable() {
}
////////////////////////////////////////////////////////////////////
// Function: Drawable::draw
// Access: Public, Virtual
// Description: Actually draws the Drawable with the indicated GSG.
// At this level, this doesn't do very much.
////////////////////////////////////////////////////////////////////
void dDrawable::
draw(GraphicsStateGuardianBase *) {
if (is_dirty()) {
config();
}
}
////////////////////////////////////////////////////////////////////
// Function: Drawable::propagate_stale_bound
// Access: Protected, Virtual

View File

@ -46,15 +46,13 @@ class BamWriter;
// to their variable names
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA dDrawable : public ReferenceCount, public WritableConfigurable,
public BoundedObject {
public BoundedObject {
public:
dDrawable() : WritableConfigurable() {
MemoryUsage::update_type(this, this);
}
virtual ~dDrawable() { }
dDrawable();
virtual ~dDrawable();
virtual void draw(GraphicsStateGuardianBase *) { if (is_dirty()) config(); }
virtual void draw(GraphicsStateGuardianBase *);
protected:
virtual void propagate_stale_bound();

View File

@ -142,6 +142,8 @@ ostream &operator << (ostream &out, GeomAttrType t) {
////////////////////////////////////////////////////////////////////
Geom::
Geom(void) : dDrawable() {
_prepared_gsg = (GraphicsStateGuardianBase *)NULL;
_prepared_context = (GeomContext *)NULL;
init();
}
@ -152,6 +154,8 @@ Geom(void) : dDrawable() {
////////////////////////////////////////////////////////////////////
Geom::
Geom(const Geom& copy) : dDrawable() {
_prepared_gsg = (GraphicsStateGuardianBase *)NULL;
_prepared_context = (GeomContext *)NULL;
*this = copy;
}
@ -161,7 +165,8 @@ Geom(const Geom& copy) : dDrawable() {
// Description:
////////////////////////////////////////////////////////////////////
Geom::
~Geom(void) {
~Geom() {
unprepare();
}
////////////////////////////////////////////////////////////////////
@ -192,8 +197,8 @@ operator = (const Geom &copy) {
_get_color = copy._get_color;
_get_texcoord = copy._get_texcoord;
if (copy.is_dirty())
make_dirty();
mark_bound_stale();
make_dirty();
}
////////////////////////////////////////////////////////////////////
@ -376,13 +381,30 @@ get_tris() const {
return PTA_ushort();
}
////////////////////////////////////////////////////////////////////
// Function: Geom::draw
// Access: Public, Virtual
// Description: Actually draws the Geom with the indicated GSG.
////////////////////////////////////////////////////////////////////
void Geom::
draw(GraphicsStateGuardianBase *gsg) {
if (is_dirty()) {
config();
}
if (_prepared_gsg == gsg) {
draw_immediate(gsg, _prepared_context);
} else {
draw_immediate(gsg, (GeomContext *)NULL);
}
}
////////////////////////////////////////////////////////////////////
// Function: Geom::config
// Access: Public
// Access: Public, Virtual
// Description: Configure rendering based on current settings
////////////////////////////////////////////////////////////////////
void Geom::
config(void) {
config() {
WritableConfigurable::config();
// Only per vertex binding makes any sense
@ -417,6 +439,9 @@ config(void) {
} else {
_get_color = get_color_noop;
}
// Mark the Geom as needing to be prepared again.
unprepare();
}
////////////////////////////////////////////////////////////////////
@ -448,12 +473,86 @@ output(ostream &out) const {
}
////////////////////////////////////////////////////////////////////
// Function: Geom::init
// Function: Geom::prepare
// Access: Public
// Description: Creates a context for the Geom on the particular
// GSG, if it does not already exist. Returns the new
// (or old) GeomContext.
//
// If the given GeomContext pointer is non-NULL, it will
// be passed to the GSG, which may or may not choose to
// extend the existing GeomContext, or create a totally
// new one.
////////////////////////////////////////////////////////////////////
GeomContext *Geom::
prepare(GraphicsStateGuardianBase *gsg) {
if (gsg != _prepared_gsg) {
GeomContext *gc = gsg->prepare_geom(this);
if (gc != (GeomContext *)NULL) {
unprepare();
_prepared_context = gc;
_prepared_gsg = gsg;
}
return gc;
}
return _prepared_context;
}
////////////////////////////////////////////////////////////////////
// Function: Geom::unprepare
// Access: Public
// Description: Frees the context allocated on all GSG's for which
// the geom has been declared.
////////////////////////////////////////////////////////////////////
void Geom::
unprepare() {
if (_prepared_gsg != (GraphicsStateGuardianBase *)NULL) {
_prepared_gsg->release_geom(_prepared_context);
_prepared_gsg = (GraphicsStateGuardianBase *)NULL;
_prepared_context = (GeomContext *)NULL;
}
}
////////////////////////////////////////////////////////////////////
// Function: Geom::unprepare
// Access: Public
// Description: Frees the geom context only on the indicated GSG,
// if it exists there.
////////////////////////////////////////////////////////////////////
void Geom::
unprepare(GraphicsStateGuardianBase *gsg) {
if (_prepared_gsg == gsg) {
_prepared_gsg->release_geom(_prepared_context);
_prepared_gsg = (GraphicsStateGuardianBase *)NULL;
_prepared_context = (GeomContext *)NULL;
}
}
////////////////////////////////////////////////////////////////////
// Function: Geom::clear_gsg
// Access: Public
// Description: Removes the indicated GSG from the Geom's known
// GSG's, without actually releasing the geom on that
// GSG. This is intended to be called only from
// GSG::release_geom(); it should never be called by
// user code.
////////////////////////////////////////////////////////////////////
void Geom::
clear_gsg(GraphicsStateGuardianBase *gsg) {
if (_prepared_gsg == gsg) {
_prepared_gsg = (GraphicsStateGuardianBase *)NULL;
_prepared_context = (GeomContext *)NULL;
}
}
////////////////////////////////////////////////////////////////////
// Function: Geom::init
// Access: Protected
// Description:
////////////////////////////////////////////////////////////////////
void Geom::
init(void) {
init() {
int i;
_coords.clear();
@ -779,10 +878,12 @@ write_verbose(ostream &out, int indent_level) const {
////////////////////////////////////////////////////////////////////
// Function: Geom::get_min_max
// Access: Public
// Description:
// Description: Expands min and max, if necessary, to include the
// complete bounding rectangle that encloses all the
// vertices.
////////////////////////////////////////////////////////////////////
void Geom::
get_min_max(Vertexf& min, Vertexf& max) const {
get_min_max(Vertexf &min, Vertexf &max) const {
int numv = _coords.size();
for (int i = 0; i < numv; i++) {

View File

@ -113,11 +113,11 @@ public:
typedef const Colorf &GetNextColor(ColorIterator &);
Geom( void );
Geom( const Geom& copy );
~Geom( void );
Geom();
Geom(const Geom &copy);
~Geom();
void operator = ( const Geom &copy );
void operator = (const Geom &copy);
virtual Geom *make_copy() const=0;
PUBLISHED:
@ -127,51 +127,49 @@ PUBLISHED:
public:
// From parent dDrawable
virtual void draw(GraphicsStateGuardianBase *gsg) {
dDrawable::draw(gsg); draw_immediate(gsg);
}
virtual void draw(GraphicsStateGuardianBase *gsg);
// From parent Configurable
virtual void config( void );
virtual void config();
// Immediate mode drawing functions - issue graphics commands
virtual void draw_immediate(GraphicsStateGuardianBase *) const = 0;
virtual void print_draw_immediate( void ) const = 0;
virtual void draw_immediate(GraphicsStateGuardianBase *gsg, GeomContext *gc) = 0;
virtual void print_draw_immediate() const = 0;
public:
void get_min_max( Vertexf& min, Vertexf& max ) const;
void get_min_max(Vertexf &min, Vertexf &max) const;
void set_coords( const PTA_Vertexf &coords,
void set_coords(const PTA_Vertexf &coords,
GeomBindType bind,
const PTA_ushort &vindex =
PTA_ushort());
void set_normals(const PTA_Normalf &norms,
GeomBindType bind,
const PTA_ushort &vindex =
PTA_ushort() );
void set_normals( const PTA_Normalf &norms,
GeomBindType bind,
const PTA_ushort &nindex =
PTA_ushort() );
void set_colors( const PTA_Colorf &colors,
GeomBindType bind,
const PTA_ushort &cindex =
PTA_ushort() );
void set_texcoords( const PTA_TexCoordf &texcoords,
GeomBindType bind,
const PTA_ushort &tindex =
PTA_ushort() );
const PTA_ushort &nindex =
PTA_ushort());
void set_colors(const PTA_Colorf &colors,
GeomBindType bind,
const PTA_ushort &cindex =
PTA_ushort());
void set_texcoords(const PTA_TexCoordf &texcoords,
GeomBindType bind,
const PTA_ushort &tindex =
PTA_ushort());
void get_coords( PTA_Vertexf &coords,
void get_coords(PTA_Vertexf &coords,
GeomBindType &bind,
PTA_ushort &vindex) const;
void get_normals(PTA_Normalf &norms,
GeomBindType &bind,
PTA_ushort &vindex) const;
void get_normals( PTA_Normalf &norms,
GeomBindType &bind,
PTA_ushort &nindex) const;
void get_colors( PTA_Colorf &colors,
GeomBindType &bind,
PTA_ushort &cindex) const;
void get_texcoords( PTA_TexCoordf &texcoords,
GeomBindType &bind,
PTA_ushort &tindex) const;
PTA_ushort &nindex) const;
void get_colors(PTA_Colorf &colors,
GeomBindType &bind,
PTA_ushort &cindex) const;
void get_texcoords(PTA_TexCoordf &texcoords,
GeomBindType &bind,
PTA_ushort &tindex) const;
PUBLISHED:
INLINE GeomBindType get_binding(int attr) const;
@ -186,7 +184,7 @@ PUBLISHED:
public:
INLINE void set_num_prims(int num);
INLINE int get_num_prims(void) const;
INLINE int get_num_prims() const;
INLINE void set_lengths(const PTA_int &lengths);
INLINE PTA_int get_lengths() const;
@ -219,9 +217,13 @@ public:
INLINE ColorIterator make_color_iterator() const;
INLINE const Colorf &get_next_color(ColorIterator &citerator) const;
protected:
GeomContext *prepare(GraphicsStateGuardianBase *gsg);
void unprepare();
void unprepare(GraphicsStateGuardianBase *gsg);
void clear_gsg(GraphicsStateGuardianBase *gsg);
void init( void );
protected:
void init();
virtual void recompute_bound();
protected:
@ -246,6 +248,14 @@ protected:
GetNextTexCoord *_get_texcoord;
GetNextColor *_get_color;
// Unlike a Texture, a Geom only stores the pointer to one GSG that
// it has been prepared into. If it is prepared into another GSG,
// it automatically unprepares itself from the first one. This is
// intended to reduce memory overhead that would otherwise be
// required to support a little-used feature (having two
// simultaneous GSG's).
GraphicsStateGuardianBase *_prepared_gsg;
GeomContext *_prepared_context;
public:
//static void register_with_read_factory(void);

View File

@ -48,8 +48,8 @@ make_copy() const {
// Description:
////////////////////////////////////////////////////////////////////
void GeomLine::
draw_immediate(GraphicsStateGuardianBase *gsg) const {
gsg->draw_line(this);
draw_immediate(GraphicsStateGuardianBase *gsg, GeomContext *gc) {
gsg->draw_line(this, gc);
}
////////////////////////////////////////////////////////////////////

View File

@ -31,7 +31,7 @@ public:
GeomLine( void ) : Geom() { _width = 1.0; }
virtual Geom *make_copy() const;
virtual void print_draw_immediate( void ) const { }
virtual void draw_immediate(GraphicsStateGuardianBase *gsg) const;
virtual void draw_immediate(GraphicsStateGuardianBase *gsg, GeomContext *gc);
virtual int get_num_vertices_per_prim() const {
return 2;

View File

@ -49,8 +49,8 @@ make_copy() const {
// Description:
////////////////////////////////////////////////////////////////////
void GeomLinestrip::
draw_immediate(GraphicsStateGuardianBase *gsg) const {
gsg->draw_linestrip(this);
draw_immediate(GraphicsStateGuardianBase *gsg, GeomContext *gc) {
gsg->draw_linestrip(this, gc);
}
////////////////////////////////////////////////////////////////////

View File

@ -31,7 +31,7 @@ public:
GeomLinestrip(void) : Geom() { _width = 1.0; }
virtual Geom *make_copy() const;
virtual void print_draw_immediate( void ) const { }
virtual void draw_immediate(GraphicsStateGuardianBase *gsg) const;
virtual void draw_immediate(GraphicsStateGuardianBase *gsg, GeomContext *gc);
// Undefined for this type of primitive
virtual int get_num_vertices_per_prim() const {

View File

@ -57,8 +57,8 @@ print_draw_immediate(void) const {
// Description:
////////////////////////////////////////////////////////////////////
void GeomPoint::
draw_immediate(GraphicsStateGuardianBase *gsg) const {
gsg->draw_point(this);
draw_immediate(GraphicsStateGuardianBase *gsg, GeomContext *gc) {
gsg->draw_point(this, gc);
}
////////////////////////////////////////////////////////////////////

View File

@ -31,7 +31,7 @@ public:
virtual Geom *make_copy() const;
virtual void print_draw_immediate() const;
virtual void draw_immediate(GraphicsStateGuardianBase *gsg) const;
virtual void draw_immediate(GraphicsStateGuardianBase *gsg, GeomContext *gc);
virtual int get_num_vertices_per_prim() const {
return 1;

View File

@ -57,8 +57,8 @@ print_draw_immediate(void) const {
// Description:
////////////////////////////////////////////////////////////////////
void GeomPolygon::
draw_immediate(GraphicsStateGuardianBase *gsg) const {
gsg->draw_polygon(this);
draw_immediate(GraphicsStateGuardianBase *gsg, GeomContext *gc) {
gsg->draw_polygon(this, gc);
}
////////////////////////////////////////////////////////////////////

View File

@ -30,7 +30,7 @@ public:
GeomPolygon() : Geom() { }
virtual Geom *make_copy() const;
virtual void print_draw_immediate() const;
virtual void draw_immediate(GraphicsStateGuardianBase *gsg) const;
virtual void draw_immediate(GraphicsStateGuardianBase *gsg, GeomContext *gc);
virtual int get_num_vertices_per_prim() const {
return 0;

View File

@ -58,8 +58,8 @@ print_draw_immediate(void) const {
// Description:
////////////////////////////////////////////////////////////////////
void GeomQuad::
draw_immediate(GraphicsStateGuardianBase *gsg) const {
gsg->draw_quad(this);
draw_immediate(GraphicsStateGuardianBase *gsg, GeomContext *gc) {
gsg->draw_quad(this, gc);
}
////////////////////////////////////////////////////////////////////

View File

@ -30,7 +30,7 @@ public:
GeomQuad() { }
virtual Geom *make_copy() const;
virtual void print_draw_immediate() const;
virtual void draw_immediate(GraphicsStateGuardianBase *gsg) const;
virtual void draw_immediate(GraphicsStateGuardianBase *gsg, GeomContext *gc);
virtual int get_num_vertices_per_prim() const {
return 4;

View File

@ -40,8 +40,8 @@ make_copy() const {
}
void GeomSphere::
draw_immediate(GraphicsStateGuardianBase *gsg) const {
gsg->draw_sphere(this);
draw_immediate(GraphicsStateGuardianBase *gsg, GeomContext *gc) {
gsg->draw_sphere(this, gc);
}
////////////////////////////////////////////////////////////////////

View File

@ -42,7 +42,7 @@ public:
GeomSphere() : Geom() { }
virtual Geom *make_copy() const;
virtual void print_draw_immediate() const { }
virtual void draw_immediate(GraphicsStateGuardianBase *gsg) const;
virtual void draw_immediate(GraphicsStateGuardianBase *gsg, GeomContext *gc);
virtual int get_num_vertices_per_prim() const {
return 2;

View File

@ -75,8 +75,8 @@ print_draw_immediate(void) const {
// Description:
////////////////////////////////////////////////////////////////////
void GeomSprite::
draw_immediate(GraphicsStateGuardianBase *gsg) const {
gsg->draw_sprite(this);
draw_immediate(GraphicsStateGuardianBase *gsg, GeomContext *gc) {
gsg->draw_sprite(this, gc);
}
////////////////////////////////////////////////////////////////////

View File

@ -33,7 +33,7 @@ public:
virtual Geom *make_copy() const;
virtual void print_draw_immediate() const;
virtual void draw_immediate(GraphicsStateGuardianBase *gsg) const;
virtual void draw_immediate(GraphicsStateGuardianBase *gsg, GeomContext *gc);
virtual int get_num_vertices_per_prim() const { return 1; }
virtual int get_num_more_vertices_than_components() const { return 0; }

View File

@ -183,8 +183,8 @@ print_draw_immediate(void) const
// Description:
////////////////////////////////////////////////////////////////////
void GeomTri::
draw_immediate(GraphicsStateGuardianBase *gsg) const {
gsg->draw_tri(this);
draw_immediate(GraphicsStateGuardianBase *gsg, GeomContext *gc) {
gsg->draw_tri(this, gc);
}
////////////////////////////////////////////////////////////////////

View File

@ -30,7 +30,7 @@ public:
GeomTri() { }
virtual Geom *make_copy() const;
virtual void print_draw_immediate() const;
virtual void draw_immediate(GraphicsStateGuardianBase *gsg) const;
virtual void draw_immediate(GraphicsStateGuardianBase *gsg, GeomContext *gc);
virtual int get_num_vertices_per_prim() const {
return 3;

View File

@ -199,8 +199,8 @@ print_draw_immediate( void ) const
// Description:
////////////////////////////////////////////////////////////////////
void GeomTrifan::
draw_immediate(GraphicsStateGuardianBase *gsg) const {
gsg->draw_trifan(this);
draw_immediate(GraphicsStateGuardianBase *gsg, GeomContext *gc) {
gsg->draw_trifan(this, gc);
}
////////////////////////////////////////////////////////////////////

View File

@ -32,7 +32,7 @@ public:
virtual Geom *make_copy() const;
virtual void print_draw_immediate( void ) const;
int get_num_tris( void ) const;
virtual void draw_immediate(GraphicsStateGuardianBase *gsg) const;
virtual void draw_immediate(GraphicsStateGuardianBase *gsg, GeomContext *gc);
virtual int get_num_vertices_per_prim() const {
return 0;

View File

@ -272,8 +272,8 @@ void GeomTristrip::print_draw_immediate( void ) const
// Access:
// Description:
////////////////////////////////////////////////////////////////////
void GeomTristrip::draw_immediate(GraphicsStateGuardianBase *gsg) const {
gsg->draw_tristrip(this);
void GeomTristrip::draw_immediate(GraphicsStateGuardianBase *gsg, GeomContext *gc) {
gsg->draw_tristrip(this, gc);
}
////////////////////////////////////////////////////////////////////

View File

@ -31,7 +31,7 @@ public:
virtual Geom *make_copy() const;
virtual void print_draw_immediate() const;
int get_num_tris() const;
virtual void draw_immediate(GraphicsStateGuardianBase *gsg) const;
virtual void draw_immediate(GraphicsStateGuardianBase *gsg, GeomContext *gc);
virtual int get_num_vertices_per_prim() const {
return 0;

View File

@ -30,6 +30,10 @@
class RenderBuffer;
class GraphicsWindow;
class GeomContext;
class GeomNodeContext;
class GeomNode;
class Geom;
class GeomPoint;
class GeomLine;
class GeomLinestrip;
@ -111,21 +115,28 @@ public:
// inconvenient to declare each of those types to be friends of this
// class.
virtual void draw_point(const GeomPoint *geom)=0;
virtual void draw_line(const GeomLine *geom)=0;
virtual void draw_linestrip(const GeomLinestrip *geom)=0;
virtual void draw_sprite(const GeomSprite *geom)=0;
virtual void draw_polygon(const GeomPolygon *geom)=0;
virtual void draw_quad(const GeomQuad *geom)=0;
virtual void draw_tri(const GeomTri *geom)=0;
virtual void draw_tristrip(const GeomTristrip *geom)=0;
virtual void draw_trifan(const GeomTrifan *geom)=0;
virtual void draw_sphere(const GeomSphere *geom)=0;
virtual TextureContext *prepare_texture(Texture *tex)=0;
virtual void apply_texture(TextureContext *tc)=0;
virtual void release_texture(TextureContext *tc)=0;
virtual GeomNodeContext *prepare_geom_node(GeomNode *node)=0;
virtual void draw_geom_node(GeomNode *node, GeomNodeContext *gnc)=0;
virtual void release_geom_node(GeomNodeContext *gnc)=0;
virtual GeomContext *prepare_geom(Geom *geom)=0;
virtual void release_geom(GeomContext *gc)=0;
virtual void draw_point(GeomPoint *geom, GeomContext *gc)=0;
virtual void draw_line(GeomLine *geom, GeomContext *gc)=0;
virtual void draw_linestrip(GeomLinestrip *geom, GeomContext *gc)=0;
virtual void draw_sprite(GeomSprite *geom, GeomContext *gc)=0;
virtual void draw_polygon(GeomPolygon *geom, GeomContext *gc)=0;
virtual void draw_quad(GeomQuad *geom, GeomContext *gc)=0;
virtual void draw_tri(GeomTri *geom, GeomContext *gc)=0;
virtual void draw_tristrip(GeomTristrip *geom, GeomContext *gc)=0;
virtual void draw_trifan(GeomTrifan *geom, GeomContext *gc)=0;
virtual void draw_sphere(GeomSphere *geom, GeomContext *gc)=0;
virtual void copy_texture(TextureContext *tc, const DisplayRegion *dr)=0;
virtual void copy_texture(TextureContext *tc, const DisplayRegion *dr,
const RenderBuffer &rb)=0;

View File

@ -149,7 +149,7 @@ request_load(const Filename &filename, const string &event_name) {
_lock.lock();
#endif
if (_token_board->_waiting.is_full()) {
if (_token_board->_waiting.full()) {
loader_cat.error()
<< "Loader::request_load() - Too many pending requests\n";
return 0;
@ -161,7 +161,7 @@ request_load(const Filename &filename, const string &event_name) {
}
tok = new LoaderToken(_next_token++, filename, event_name);
_token_board->_waiting.insert(tok);
_token_board->_waiting.push_back(tok);
#ifdef HAVE_IPC
_request_cond->signal();
@ -171,7 +171,7 @@ request_load(const Filename &filename, const string &event_name) {
} else {
// If we're not running asynchronously, process the load request
// directly now.
if (_token_board->_waiting.is_full()) {
if (_token_board->_waiting.full()) {
loader_cat.error()
<< "Loader::request_load() - Too many pending requests\n";
return 0;
@ -183,7 +183,7 @@ request_load(const Filename &filename, const string &event_name) {
}
tok = new LoaderToken(_next_token++, filename, event_name);
_token_board->_waiting.insert(tok);
_token_board->_waiting.push_back(tok);
process_request();
}
@ -264,15 +264,16 @@ process_request() {
}
// If there is actually a request token - process it
while (!_token_board->_waiting.is_empty()) {
PT(LoaderToken) tok = _token_board->_waiting.extract();
while (!_token_board->_waiting.empty()) {
PT(LoaderToken) tok = _token_board->_waiting.front();
_token_board->_waiting.pop_front();
tok->_node = load_file(tok->_path);
if (tok->_node == NULL) {
loader_cat.error()
<< "Loader::callback() - couldn't find file: "
<< tok->_path << "\n";
} else {
_token_board->_done.insert(tok);
_token_board->_done.push_back(tok);
// Throw a "done" event now.
if (!tok->_event_name.empty()) {

View File

@ -137,6 +137,10 @@ static LevelCollectorProperties level_properties[] = {
{ 1, "Texture memory:In use", { 0.0, 1.0, 1.0 } },
{ 1, "Texture manager", { 1.0, 0.0, 0.0 }, "MB", 12, 1048576 },
{ 1, "Texture manager:Resident", { 1.0, 1.0, 0.0 } },
{ 1, "Prepared Geoms", { 1.0, 0.0, 0.5 }, "", 500 },
{ 1, "Prepared Geoms:Active", { 0.5, 1.0, 0.8 } },
{ 1, "Prepared GeomNodes", { 1.0, 0.0, 0.5 }, "", 500 },
{ 1, "Prepared GeomNodes:Active", { 0.5, 1.0, 0.8 } },
{ 1, "Vertices", { 0.5, 0.2, 0.0 }, "K", 10, 1000 },
{ 1, "Vertices:Other", { 0.2, 0.2, 0.2 } },
{ 1, "Vertices:Triangles", { 0.8, 0.8, 0.8 } },

View File

@ -124,9 +124,9 @@ sub_render(NodeRelation *arc, const AllAttributesWrapper &attrib,
geom.set_coords(verts, G_PER_VERTEX);
geom.set_num_prims(1);
gsg->draw_sphere(&geom);
gsg->draw_sphere(&geom, NULL);
gsg->set_state(_inside_attrib, false);
gsg->draw_sphere(&geom);
gsg->draw_sphere(&geom, NULL);
} else {
sgattrib_cat.warning()

View File

@ -35,6 +35,8 @@ TypeHandle GeomNode::_type_handle;
////////////////////////////////////////////////////////////////////
GeomNode::
GeomNode(const string &name) : NamedNode(name), _num_geoms(0) {
_prepared_gsg = (GraphicsStateGuardianBase *)NULL;
_prepared_context = (GeomNodeContext *)NULL;
}
////////////////////////////////////////////////////////////////////
@ -48,6 +50,8 @@ GeomNode(const GeomNode &copy) :
_geoms(copy._geoms),
_num_geoms(0)
{
_prepared_gsg = (GraphicsStateGuardianBase *)NULL;
_prepared_context = (GeomNodeContext *)NULL;
}
////////////////////////////////////////////////////////////////////
@ -57,6 +61,7 @@ GeomNode(const GeomNode &copy) :
////////////////////////////////////////////////////////////////////
void GeomNode::
operator = (const GeomNode &copy) {
unprepare();
NamedNode::operator = (copy);
_geoms = copy._geoms;
_num_geoms = 0;
@ -69,6 +74,7 @@ operator = (const GeomNode &copy) {
////////////////////////////////////////////////////////////////////
GeomNode::
~GeomNode() {
unprepare();
}
////////////////////////////////////////////////////////////////////
@ -146,9 +152,87 @@ write_verbose(ostream &out, int indent_level) const {
////////////////////////////////////////////////////////////////////
void GeomNode::
draw(GraphicsStateGuardianBase *gsg) {
Geoms::const_iterator gi;
for (gi = _geoms.begin(); gi != _geoms.end(); ++gi) {
(*gi)->draw(gsg);
if (_prepared_gsg == gsg) {
gsg->draw_geom_node(this, _prepared_context);
} else {
Geoms::const_iterator gi;
for (gi = _geoms.begin(); gi != _geoms.end(); ++gi) {
(*gi)->draw(gsg);
}
}
}
////////////////////////////////////////////////////////////////////
// Function: GeomNode::prepare
// Access: Public
// Description: Creates a context for the GeomNode on the particular
// GSG, if it does not already exist. Returns the new
// (or old) GeomNodeContext.
//
// If the given GeomNodeContext pointer is non-NULL, it will
// be passed to the GSG, which may or may not choose to
// extend the existing GeomNodeContext, or create a totally
// new one.
////////////////////////////////////////////////////////////////////
GeomNodeContext *GeomNode::
prepare(GraphicsStateGuardianBase *gsg) {
if (gsg != _prepared_gsg) {
GeomNodeContext *gc = gsg->prepare_geom_node(this);
if (gc != (GeomNodeContext *)NULL) {
unprepare();
_prepared_context = gc;
_prepared_gsg = gsg;
}
return gc;
}
return _prepared_context;
}
////////////////////////////////////////////////////////////////////
// Function: GeomNode::unprepare
// Access: Public
// Description: Frees the context allocated on all GSG's for which
// the geom has been declared.
////////////////////////////////////////////////////////////////////
void GeomNode::
unprepare() {
if (_prepared_gsg != (GraphicsStateGuardianBase *)NULL) {
_prepared_gsg->release_geom_node(_prepared_context);
_prepared_gsg = (GraphicsStateGuardianBase *)NULL;
_prepared_context = (GeomNodeContext *)NULL;
}
}
////////////////////////////////////////////////////////////////////
// Function: GeomNode::unprepare
// Access: Public
// Description: Frees the geom context only on the indicated GSG,
// if it exists there.
////////////////////////////////////////////////////////////////////
void GeomNode::
unprepare(GraphicsStateGuardianBase *gsg) {
if (_prepared_gsg == gsg) {
_prepared_gsg->release_geom_node(_prepared_context);
_prepared_gsg = (GraphicsStateGuardianBase *)NULL;
_prepared_context = (GeomNodeContext *)NULL;
}
}
////////////////////////////////////////////////////////////////////
// Function: GeomNode::clear_gsg
// Access: Public
// Description: Removes the indicated GSG from the Geom's known
// GSG's, without actually releasing the geom on that
// GSG. This is intended to be called only from
// GSG::release_geom_node(); it should never be called by
// user code.
////////////////////////////////////////////////////////////////////
void GeomNode::
clear_gsg(GraphicsStateGuardianBase *gsg) {
if (_prepared_gsg == gsg) {
_prepared_gsg = (GraphicsStateGuardianBase *)NULL;
_prepared_context = (GeomNodeContext *)NULL;
}
}
@ -189,10 +273,10 @@ remove_geom(int n) {
} else {
// Copy-on-write.
size_t num_geoms = _geoms.size();
int num_geoms = _geoms.size();
Geoms new_geoms;
new_geoms.reserve(num_geoms - 1);
size_t i;
int i;
for (i = 0; i < n; i++) {
new_geoms.push_back(_geoms[i]);
}
@ -204,6 +288,7 @@ remove_geom(int n) {
nassertv(_geoms.get_ref_count() == 1);
}
unprepare();
mark_bound_stale();
}
@ -215,6 +300,7 @@ remove_geom(int n) {
void GeomNode::
clear() {
_geoms.clear();
unprepare();
mark_bound_stale();
}
@ -239,6 +325,7 @@ add_geom(dDrawable *geom) {
_geoms.push_back(geom);
}
unprepare();
mark_bound_stale();
return _geoms.size() - 1;
}
@ -268,6 +355,7 @@ add_geoms_from(const GeomNode *other) {
_geoms.v().insert(_geoms.end(), geoms_begin, geoms_end);
}
unprepare();
mark_bound_stale();
}

View File

@ -30,6 +30,7 @@
class GraphicsStateGuardianBase;
class AllAttributesWrapper;
class GeomNodeContext;
////////////////////////////////////////////////////////////////////
// Class : GeomNode
@ -56,6 +57,11 @@ PUBLISHED:
public:
void draw(GraphicsStateGuardianBase *gsg);
GeomNodeContext *prepare(GraphicsStateGuardianBase *gsg);
void unprepare();
void unprepare(GraphicsStateGuardianBase *gsg);
void clear_gsg(GraphicsStateGuardianBase *gsg);
PUBLISHED:
int get_num_geoms() const;
dDrawable *get_geom(int n) const;
@ -71,6 +77,12 @@ private:
typedef PTA(PT(dDrawable)) Geoms;
Geoms _geoms;
// These are essentially similar to the same fields in Geom. They
// are used only if the GSG supports a node-level Geom context, as
// opposed to strictly a Geom-level context.
GraphicsStateGuardianBase *_prepared_gsg;
GeomNodeContext *_prepared_context;
public:
static void register_with_read_factory(void);
virtual void write_datagram(BamWriter* manager, Datagram &me);

View File

@ -148,6 +148,7 @@ transform_vertices(GeomNode *node, const LMatrix4f &mat) {
if (any_changed) {
node->_geoms = new_geoms;
node->unprepare();
node->mark_bound_stale();
return true;
}