fix miscellaneous bugs

This commit is contained in:
David Rose 2005-04-13 00:33:59 +00:00
parent 1f81458370
commit f24c240d76
20 changed files with 278 additions and 50 deletions

View File

@ -212,9 +212,10 @@ collect_nodes(EggGroupNode *group) {
// And remove it from the scene graph.
group->erase(i);
}
} else if (node->is_of_type(EggGroupNode::get_class_type())) {
// Here's a normal group node, not to be binned. Traverse.
if (node->is_of_type(EggGroupNode::get_class_type())) {
// Recursively traverse.
collect_nodes(DCAST(EggGroupNode, node));
}

View File

@ -365,7 +365,7 @@ write_object_types(ostream &out, int indent_level) const {
////////////////////////////////////////////////////////////////////
// Function: EggGroup::write_decal_flags
// Access: Public
// Description: Writes the flags related to decalling, if any.
// Description: Writes the flags related to decaling, if any.
////////////////////////////////////////////////////////////////////
void EggGroup::
write_decal_flags(ostream &out, int indent_level) const {
@ -544,6 +544,25 @@ determine_indexed() {
return EggGroupNode::determine_indexed();
}
////////////////////////////////////////////////////////////////////
// Function: EggGroup::determine_decal
// Access: Public, Virtual
// Description: Walks back up the hierarchy, looking for an EggGroup
// at this level or above that has the "decal" flag
// set. Returns the value of the decal flag if it
// is found, or false if it is not.
//
// In other words, returns true if the "decal" flag is
// in effect for the indicated node, false otherwise.
////////////////////////////////////////////////////////////////////
bool EggGroup::
determine_decal() {
if (get_decal_flag()) {
return true;
}
return EggGroupNode::determine_decal();
}
////////////////////////////////////////////////////////////////////
// Function: EggGroup::ref_vertex
// Access: Public

View File

@ -120,6 +120,7 @@ PUBLISHED:
virtual EggRenderMode *determine_draw_order();
virtual EggRenderMode *determine_bin();
virtual bool determine_indexed();
virtual bool determine_decal();
void set_group_type(GroupType type);
INLINE GroupType get_group_type() const;

View File

@ -198,6 +198,26 @@ determine_indexed() {
return _parent->determine_indexed();
}
////////////////////////////////////////////////////////////////////
// Function: EggNode::determine_decal
// Access: Public, Virtual
// Description: Walks back up the hierarchy, looking for an EggGroup
// at this level or above that has the "decal" flag
// set. Returns the value of the decal flag if it
// is found, or false if it is not.
//
// In other words, returns true if the "decal" flag is
// in effect for the indicated node, false otherwise.
////////////////////////////////////////////////////////////////////
bool EggNode::
determine_decal() {
if (_parent == (EggGroupNode *)NULL) {
// Too bad; we're done.
return false;
}
return _parent->determine_decal();
}
////////////////////////////////////////////////////////////////////
// Function: EggNode::parse_egg

View File

@ -80,6 +80,7 @@ PUBLISHED:
virtual EggRenderMode *determine_draw_order();
virtual EggRenderMode *determine_bin();
virtual bool determine_indexed();
virtual bool determine_decal();
virtual void write(ostream &out, int indent_level) const=0;
bool parse_egg(const string &egg_syntax);

View File

@ -238,7 +238,6 @@ egg_to_slider(const string &name) {
CharacterJointBundle *CharacterMaker::
make_bundle() {
build_joint_hierarchy(_egg_root, _skeleton_root);
_bundle->sort_descendants();
if (use_qpgeom) {
// The new, experimental Geom system.
@ -251,8 +250,9 @@ make_bundle() {
_character_node->_computed_vertices =
_comp_verts_maker.make_computed_vertices(_character_node, *this);
}
_bundle->sort_descendants();
parent_joint_nodes(_skeleton_root);
return _bundle;
}

View File

@ -1493,7 +1493,7 @@ separate_switches(EggNode *egg_node) {
bool parent_has_switch = false;
if (egg_node->is_of_type(EggGroup::get_class_type())) {
EggGroup *egg_group = DCAST(EggGroup, egg_node);
parent_has_switch = egg_group->get_switch_flag();
parent_has_switch = egg_group->get_switch_flag() || egg_group->has_lod();
}
if (egg_node->is_of_type(EggGroupNode::get_class_type())) {
@ -1778,7 +1778,11 @@ make_node(EggGroup *egg_group, PandaNode *parent) {
bool all_polysets = false;
bool any_hidden = false;
if (use_qpgeom) {
check_for_polysets(egg_group, all_polysets, any_hidden);
// We don't want to ever create a GeomNode under a "decal" flag,
// since that can confuse the decal reparenting.
if (!egg_group->determine_decal()) {
check_for_polysets(egg_group, all_polysets, any_hidden);
}
}
if (all_polysets && !any_hidden) {

View File

@ -513,7 +513,10 @@ draw(GraphicsStateGuardianBase *gsg, const qpGeomMunger *munger,
for (pi = cdata->_primitives.begin();
pi != cdata->_primitives.end();
++pi) {
(*pi)->draw(gsg);
const qpGeomPrimitive *primitive = (*pi);
if (primitive->get_num_vertices() != 0) {
(*pi)->draw(gsg);
}
}
gsg->end_draw_primitives();
}

View File

@ -30,6 +30,25 @@ is_registered() const {
return _is_registered;
}
////////////////////////////////////////////////////////////////////
// Function: qpGeomVertexArrayFormat::register_format
// Access: Published, Static
// Description: Adds the indicated format to the registry, if there
// is not an equivalent format already there; in either
// case, returns the pointer to the equivalent format
// now in the registry.
//
// This is similar to
// GeomVertexFormat::register_format(), except that you
// generally need not call it explicitly. Calling
// GeomVertexFormat::register_format() automatically
// registers all of the nested array formats.
////////////////////////////////////////////////////////////////////
INLINE CPT(qpGeomVertexArrayFormat) qpGeomVertexArrayFormat::
register_format(const qpGeomVertexArrayFormat *format) {
return get_registry()->register_format((qpGeomVertexArrayFormat *)format);
}
////////////////////////////////////////////////////////////////////
// Function: qpGeomVertexArrayFormat::get_stride
// Access: Published
@ -113,6 +132,19 @@ has_column(const InternalName *name) const {
return (get_column(name) != (qpGeomVertexColumn *)NULL);
}
////////////////////////////////////////////////////////////////////
// Function: qpGeomVertexArrayFormat::get_registry
// Access: Private
// Description: Returns the global registry object.
////////////////////////////////////////////////////////////////////
INLINE qpGeomVertexArrayFormat::Registry *qpGeomVertexArrayFormat::
get_registry() {
if (_registry == (Registry *)NULL) {
make_registry();
}
return _registry;
}
////////////////////////////////////////////////////////////////////
// Function: qpGeomVertexArrayFormat::consider_sort_columns
// Access: Private

View File

@ -25,6 +25,7 @@
#include "bamWriter.h"
#include "indirectLess.h"
qpGeomVertexArrayFormat::Registry *qpGeomVertexArrayFormat::_registry = NULL;
TypeHandle qpGeomVertexArrayFormat::_type_handle;
////////////////////////////////////////////////////////////////////
@ -185,6 +186,9 @@ operator = (const qpGeomVertexArrayFormat &copy) {
////////////////////////////////////////////////////////////////////
qpGeomVertexArrayFormat::
~qpGeomVertexArrayFormat() {
if (is_registered()) {
get_registry()->unregister_format(this);
}
Columns::iterator ci;
for (ci = _columns.begin(); ci != _columns.end(); ++ci) {
delete (*ci);
@ -501,6 +505,18 @@ sort_columns() {
sort(_columns.begin(), _columns.end(), IndirectLess<qpGeomVertexColumn>());
}
////////////////////////////////////////////////////////////////////
// Function: qpGeomVertexArrayFormat::make_registry
// Access: Private
// Description: Returns the global registry object.
////////////////////////////////////////////////////////////////////
void qpGeomVertexArrayFormat::
make_registry() {
if (_registry == (Registry *)NULL) {
_registry = new Registry;
}
}
////////////////////////////////////////////////////////////////////
// Function: qpGeomVertexArrayFormat::do_register
// Access: Private
@ -511,6 +527,17 @@ do_register() {
nassertv(!_is_registered);
_is_registered = true;
}
////////////////////////////////////////////////////////////////////
// Function: qpGeomVertexArrayFormat::do_unregister
// Access: Private
// Description: Called internally when the format is unregistered.
////////////////////////////////////////////////////////////////////
void qpGeomVertexArrayFormat::
do_unregister() {
nassertv(_is_registered);
_is_registered = false;
}
////////////////////////////////////////////////////////////////////
// Function: qpGeomVertexArrayFormat::register_with_read_factory
@ -613,3 +640,64 @@ fillin(DatagramIterator &scan, BamReader *manager) {
}
_columns_unsorted = false;
}
////////////////////////////////////////////////////////////////////
// Function: qpGeomVertexArrayFormat::Registry::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
qpGeomVertexArrayFormat::Registry::
Registry() {
}
////////////////////////////////////////////////////////////////////
// Function: qpGeomVertexArrayFormat::Registry::register_format
// Access: Public
// Description: Adds the indicated format to the registry, if there
// is not an equivalent format already there; in either
// case, returns the pointer to the equivalent format
// now in the registry.
//
// This must be called before a format may be used in a
// Geom. After this call, you should discard the
// original pointer you passed in (which may or may not
// now be invalid) and let its reference count decrement
// normally; you should use only the returned value from
// this point on.
////////////////////////////////////////////////////////////////////
CPT(qpGeomVertexArrayFormat) qpGeomVertexArrayFormat::Registry::
register_format(qpGeomVertexArrayFormat *format) {
if (format->is_registered()) {
return format;
}
// Save the incoming pointer in a local PointerTo, so that if it has
// a zero reference count and is not added into the map below, it
// will be automatically deleted when this function returns.
PT(qpGeomVertexArrayFormat) pt_format = format;
ArrayFormats::iterator fi = _formats.insert(format).first;
qpGeomVertexArrayFormat *new_format = (*fi);
if (!new_format->is_registered()) {
new_format->do_register();
}
return new_format;
}
////////////////////////////////////////////////////////////////////
// Function: qpGeomVertexArrayFormat::Registry::unregister_format
// Access: Public
// Description: Removes the indicated format from the registry.
// Normally this should not be done until the format is
// destructing.
////////////////////////////////////////////////////////////////////
void qpGeomVertexArrayFormat::Registry::
unregister_format(qpGeomVertexArrayFormat *format) {
nassertv(format->is_registered());
ArrayFormats::iterator fi = _formats.find(format);
nassertv(fi != _formats.end());
_formats.erase(fi);
format->do_unregister();
}

View File

@ -22,6 +22,7 @@
#include "pandabase.h"
#include "typedWritableReferenceCount.h"
#include "qpgeomVertexColumn.h"
#include "indirectCompareTo.h"
#include "pvector.h"
#include "pmap.h"
@ -90,6 +91,7 @@ PUBLISHED:
~qpGeomVertexArrayFormat();
INLINE bool is_registered() const;
INLINE static CPT(qpGeomVertexArrayFormat) register_format(const qpGeomVertexArrayFormat *format);
INLINE int get_stride() const;
INLINE void set_stride(int stride);
@ -123,9 +125,15 @@ public:
int compare_to(const qpGeomVertexArrayFormat &other) const;
private:
class Registry;
INLINE static Registry *get_registry();
static void make_registry();
void do_register();
void do_unregister();
INLINE void consider_sort_columns() const;
void sort_columns();
void do_register();
bool _is_registered;
int _stride;
@ -139,6 +147,19 @@ private:
typedef pmap<const InternalName *, qpGeomVertexColumn *> ColumnsByName;
ColumnsByName _columns_by_name;
// This is the global registry of all currently-in-use array formats.
typedef pset<qpGeomVertexArrayFormat *, IndirectCompareTo<qpGeomVertexArrayFormat> > ArrayFormats;
class EXPCL_PANDA Registry {
public:
Registry();
CPT(qpGeomVertexArrayFormat) register_format(qpGeomVertexArrayFormat *format);
void unregister_format(qpGeomVertexArrayFormat *format);
ArrayFormats _formats;
};
static Registry *_registry;
public:
static void register_with_read_factory();
virtual void write_datagram(BamWriter *manager, Datagram &dg);

View File

@ -1394,10 +1394,9 @@ finalize(BamReader *manager) {
for (size_t i = 0; i < cdata->_arrays.size(); ++i) {
CPT(qpGeomVertexArrayFormat) new_array_format = new_format->get_array(i);
CPT(qpGeomVertexArrayFormat) old_array_format = _format->get_array(i);
nassertv(cdata->_arrays[i]->_array_format == old_array_format);
nassertv(cdata->_arrays[i]->_array_format->compare_to(*new_array_format) == 0);
manager->change_pointer(old_array_format, new_array_format);
manager->change_pointer(cdata->_arrays[i]->_array_format, new_array_format);
cdata->_arrays[i]->_array_format = new_array_format;
}

View File

@ -503,9 +503,10 @@ do_register() {
nassertv(_columns_by_name.empty());
for (int array = 0; array < (int)_arrays.size(); ++array) {
const qpGeomVertexArrayFormat *array_format = _arrays[array];
CPT(qpGeomVertexArrayFormat) array_format = _arrays[array];
if (!array_format->is_registered()) {
((qpGeomVertexArrayFormat *)array_format)->do_register();
array_format = qpGeomVertexArrayFormat::register_format(array_format);
_arrays[array] = (qpGeomVertexArrayFormat *)array_format.p();
}
// Now add the names to the index.
@ -580,7 +581,6 @@ do_register() {
}
}
_is_registered = true;
get_array_info(InternalName::get_vertex(), _vertex_array_index,

View File

@ -1460,11 +1460,20 @@ fillin(DatagramIterator &scan, BamReader *manager, bool has_rawdata) {
////////////////////////////////////////////////////////////////////
void Texture::
write_datagram(BamWriter *manager, Datagram &me) {
bool has_rawdata = (bam_texture_mode == BTM_rawdata);
Filename filename = get_filename();
Filename alpha_filename = get_alpha_filename();
// Write out the texture's raw pixel data if (a) the current Bam
// Texture Mode requires that, or (b) there's no filename, so the
// file can't be loaded up from disk, but the raw pixel data is
// currently available in RAM.
// Otherwise, we just write out the filename, and assume whoever
// loads the bam file later will have access to the image file on
// disk.
bool has_rawdata =
(bam_texture_mode == BTM_rawdata || (has_ram_image() && filename.empty()));
switch (bam_texture_mode) {
case BTM_unchanged:
case BTM_rawdata:

View File

@ -128,8 +128,9 @@ add_object(CullableObject *object, const CullTraverser *traverser) {
get_dual_transparent_state_decals() :
get_dual_transparent_state();
transparent_part->_state = state->compose(transparent_state);
transparent_part->munge_geom(get_geom_munger(transparent_part->_state),
traverser);
transparent_part->munge_geom
(_gsg, get_geom_munger(transparent_part->_state),
traverser);
CullBin *bin = get_bin(transparent_part->_state->get_bin_index());
nassertv(bin != (CullBin *)NULL);
bin->add_object(transparent_part);
@ -156,7 +157,7 @@ add_object(CullableObject *object, const CullTraverser *traverser) {
// Munge vertices as needed for the GSG's requirements, and the
// object's current state.
object->munge_geom(get_geom_munger(object->_state), traverser);
object->munge_geom(_gsg, get_geom_munger(object->_state), traverser);
CullBin *bin = get_bin(object->_state->get_bin_index());
nassertv(bin != (CullBin *)NULL);

View File

@ -41,7 +41,8 @@ TypeHandle CullableObject::_type_handle;
// and/or its vertices.
////////////////////////////////////////////////////////////////////
void CullableObject::
munge_geom(const qpGeomMunger *munger, const CullTraverser *traverser) {
munge_geom(GraphicsStateGuardianBase *gsg,
const qpGeomMunger *munger, const CullTraverser *traverser) {
if (_geom != (Geom *)NULL) {
// Temporary test and dcast until the experimental Geom rewrite
// becomes the actual Geom rewrite.
@ -93,7 +94,11 @@ munge_geom(const qpGeomMunger *munger, const CullTraverser *traverser) {
}
}
if (_next != (CullableObject *)NULL) {
_next->munge_geom(munger, traverser);
if (_next->_state != (RenderState *)NULL) {
_next->munge_geom(gsg, gsg->get_geom_munger(_next->_state), traverser);
} else {
_next->munge_geom(gsg, munger, traverser);
}
}
}

View File

@ -57,7 +57,8 @@ public:
INLINE bool has_decals() const;
void munge_geom(const qpGeomMunger *munger, const CullTraverser *traverser);
void munge_geom(GraphicsStateGuardianBase *gsg,
const qpGeomMunger *munger, const CullTraverser *traverser);
INLINE void draw(GraphicsStateGuardianBase *gsg);
public:

View File

@ -35,7 +35,7 @@ void DrawCullHandler::
record_object(CullableObject *object, const CullTraverser *traverser) {
// Munge vertices as needed for the GSG's requirements, and the
// object's current state.
object->munge_geom(_gsg->get_geom_munger(object->_state), traverser);
object->munge_geom(_gsg, _gsg->get_geom_munger(object->_state), traverser);
// And draw the object, then dispense with it.
draw(object, _gsg);

View File

@ -127,23 +127,38 @@ void wglGraphicsStateGuardian::
reset() {
GLGraphicsStateGuardian::reset();
_supports_pbuffer = has_extension("WGL_ARB_pbuffer");
_supports_pixel_format = has_extension("WGL_ARB_pixel_format");
_supports_wgl_multisample = has_extension("WGL_ARB_multisample");
_supports_render_texture = has_extension("WGL_ARB_render_texture");
_supports_swap_control = has_extension("WGL_EXT_swap_control");
_wglCreatePbufferARB =
(PFNWGLCREATEPBUFFERARBPROC)wglGetProcAddress("wglCreatePbufferARB");
_wglGetPbufferDCARB =
(PFNWGLGETPBUFFERDCARBPROC)wglGetProcAddress("wglGetPbufferDCARB");
_wglReleasePbufferDCARB =
(PFNWGLRELEASEPBUFFERDCARBPROC)wglGetProcAddress("wglReleasePbufferDCARB");
_wglDestroyPbufferARB =
(PFNWGLDESTROYPBUFFERARBPROC)wglGetProcAddress("wglDestroyPbufferARB");
_wglQueryPbufferARB =
(PFNWGLQUERYPBUFFERARBPROC)wglGetProcAddress("wglQueryPbufferARB");
if (_supports_swap_control) {
_wglSwapIntervalEXT =
(PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
if (_wglSwapIntervalEXT == NULL) {
wgldisplay_cat.error()
<< "Driver claims to support WGL_EXT_swap_control extension, but does not define all functions.\n";
_supports_swap_control = false;
}
}
if (_supports_swap_control) {
// Set the video-sync setting up front, if we have the extension
// that supports it.
_wglSwapIntervalEXT(sync_video ? 1 : 0);
}
_supports_pbuffer = has_extension("WGL_ARB_pbuffer");
if (_supports_pbuffer) {
_wglCreatePbufferARB =
(PFNWGLCREATEPBUFFERARBPROC)wglGetProcAddress("wglCreatePbufferARB");
_wglGetPbufferDCARB =
(PFNWGLGETPBUFFERDCARBPROC)wglGetProcAddress("wglGetPbufferDCARB");
_wglReleasePbufferDCARB =
(PFNWGLRELEASEPBUFFERDCARBPROC)wglGetProcAddress("wglReleasePbufferDCARB");
_wglDestroyPbufferARB =
(PFNWGLDESTROYPBUFFERARBPROC)wglGetProcAddress("wglDestroyPbufferARB");
_wglQueryPbufferARB =
(PFNWGLQUERYPBUFFERARBPROC)wglGetProcAddress("wglQueryPbufferARB");
if (_wglCreatePbufferARB == NULL ||
_wglGetPbufferDCARB == NULL ||
_wglReleasePbufferDCARB == NULL ||
@ -155,14 +170,16 @@ reset() {
}
}
_wglGetPixelFormatAttribivARB =
(PFNWGLGETPIXELFORMATATTRIBIVARBPROC)wglGetProcAddress("wglGetPixelFormatAttribivARB");
_wglGetPixelFormatAttribfvARB =
(PFNWGLGETPIXELFORMATATTRIBFVARBPROC)wglGetProcAddress("wglGetPixelFormatAttribfvARB");
_wglChoosePixelFormatARB =
(PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
_supports_pixel_format = has_extension("WGL_ARB_pixel_format");
if (_supports_pixel_format) {
_wglGetPixelFormatAttribivARB =
(PFNWGLGETPIXELFORMATATTRIBIVARBPROC)wglGetProcAddress("wglGetPixelFormatAttribivARB");
_wglGetPixelFormatAttribfvARB =
(PFNWGLGETPIXELFORMATATTRIBFVARBPROC)wglGetProcAddress("wglGetPixelFormatAttribfvARB");
_wglChoosePixelFormatARB =
(PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
if (_wglGetPixelFormatAttribivARB == NULL ||
_wglGetPixelFormatAttribfvARB == NULL ||
_wglChoosePixelFormatARB == NULL) {
@ -172,14 +189,17 @@ reset() {
}
}
_wglBindTexImageARB =
(PFNWGLBINDTEXIMAGEARBPROC)wglGetProcAddress("wglBindTexImageARB");
_wglReleaseTexImageARB =
(PFNWGLRELEASETEXIMAGEARBPROC)wglGetProcAddress("wglReleaseTexImageARB");
_wglSetPbufferAttribARB =
(PFNWGLSETPBUFFERATTRIBARBPROC)wglGetProcAddress("wglSetPbufferAttribARB");
_supports_wgl_multisample = has_extension("WGL_ARB_multisample");
_supports_render_texture = has_extension("WGL_ARB_render_texture");
if (_supports_render_texture) {
_wglBindTexImageARB =
(PFNWGLBINDTEXIMAGEARBPROC)wglGetProcAddress("wglBindTexImageARB");
_wglReleaseTexImageARB =
(PFNWGLRELEASETEXIMAGEARBPROC)wglGetProcAddress("wglReleaseTexImageARB");
_wglSetPbufferAttribARB =
(PFNWGLSETPBUFFERATTRIBARBPROC)wglGetProcAddress("wglSetPbufferAttribARB");
if (_wglBindTexImageARB == NULL ||
_wglReleaseTexImageARB == NULL ||
_wglSetPbufferAttribARB == NULL) {

View File

@ -84,6 +84,9 @@ private:
static bool _twindow_class_registered;
public:
bool _supports_swap_control;
PFNWGLSWAPINTERVALEXTPROC _wglSwapIntervalEXT;
bool _supports_pbuffer;
PFNWGLCREATEPBUFFERARBPROC _wglCreatePbufferARB;
PFNWGLGETPBUFFERDCARBPROC _wglGetPbufferDCARB;