diff --git a/direct/src/actor/Actor.py b/direct/src/actor/Actor.py index 253f946fe3..a5ecbaf1cb 100644 --- a/direct/src/actor/Actor.py +++ b/direct/src/actor/Actor.py @@ -1022,6 +1022,11 @@ class Actor(DirectObject, NodePath): if (partDict.has_key(partName)): del(partDict[partName]) + # remove the bundle handle, in case this part is ever + # loaded again in the future + if partName in self.__commonBundleHandles: + del self.__commonBundleHandles[partName] + def hidePart(self, partName, lodName="lodRoot"): """ Make the given part of the optionally given lod not render, diff --git a/dtool/LocalSetup.pp b/dtool/LocalSetup.pp index 686ae673ee..f177ce2cac 100644 --- a/dtool/LocalSetup.pp +++ b/dtool/LocalSetup.pp @@ -602,9 +602,6 @@ $[cdefine HAVE_DINKUM] /* Define if we have STL hash_map etc. available */ $[cdefine HAVE_STL_HASH] -/* Define if we have a gettimeofday() function. */ -$[cdefine HAVE_GETTIMEOFDAY] - /* Define if gettimeofday() takes only one parameter. */ $[cdefine GETTIMEOFDAY_ONE_PARAM] diff --git a/dtool/src/cppparser/cppFunctionType.h b/dtool/src/cppparser/cppFunctionType.h index 09cb46491f..021aeba5ce 100644 --- a/dtool/src/cppparser/cppFunctionType.h +++ b/dtool/src/cppparser/cppFunctionType.h @@ -35,6 +35,7 @@ public: F_destructor = 0x08, F_method_pointer = 0x10, F_unary_op = 0x20, + F_operator = 0x40, }; CPPFunctionType(CPPType *return_type, CPPParameterList *parameters, diff --git a/dtool/src/cppparser/cppInstanceIdentifier.cxx b/dtool/src/cppparser/cppInstanceIdentifier.cxx index aea8eee9ce..8db68d389d 100644 --- a/dtool/src/cppparser/cppInstanceIdentifier.cxx +++ b/dtool/src/cppparser/cppInstanceIdentifier.cxx @@ -134,12 +134,16 @@ add_func_modifier(CPPParameterList *params, int flags) { // is really a unary operator, so set the unary_op flag. Operators // () and [] are never considered unary operators. if (_ident != NULL && - _ident->get_simple_name().substr(0, 9) == "operator " && - _ident->get_simple_name() != string("operator ()") && - _ident->get_simple_name() != string("operator []")) { - if (params->_parameters.empty()) { - flags |= CPPFunctionType::F_unary_op; + _ident->get_simple_name().substr(0, 9) == "operator ") { + + if (_ident->get_simple_name() != string("operator ()") && + _ident->get_simple_name() != string("operator []")) { + if (params->_parameters.empty()) { + flags |= CPPFunctionType::F_unary_op; + } } + + flags |= CPPFunctionType::F_operator; } _modifiers.push_back(Modifier::func_type(params, flags)); diff --git a/dtool/src/interrogate/interfaceMaker.cxx b/dtool/src/interrogate/interfaceMaker.cxx index 82185500b5..717a0993d8 100644 --- a/dtool/src/interrogate/interfaceMaker.cxx +++ b/dtool/src/interrogate/interfaceMaker.cxx @@ -156,22 +156,24 @@ check_protocols() { } // Now are there any make_seq requests within this class? - CPPStructType *stype = _itype._cpptype->as_struct_type(); - if (stype != (CPPStructType *)NULL) { - CPPScope *scope = stype->get_scope(); - if (scope != (CPPScope *)NULL) { - CPPScope::Declarations::iterator di; - for (di = scope->_declarations.begin(); di != scope->_declarations.end(); ++di) { - CPPMakeSeq *cpp_make_seq = (*di)->as_make_seq(); - if (cpp_make_seq != (CPPMakeSeq *)NULL) { - string class_name = _itype.get_scoped_name(); - string clean_name = InterrogateBuilder::clean_identifier(class_name); - string wrapper_name = "MakeSeq_" + clean_name + "_" + cpp_make_seq->_seq_name; - MakeSeq *make_seq = new MakeSeq(wrapper_name, cpp_make_seq); - _make_seqs.push_back(make_seq); + if (_itype._cpptype != NULL) { + CPPStructType *stype = _itype._cpptype->as_struct_type(); + if (stype != (CPPStructType *)NULL) { + CPPScope *scope = stype->get_scope(); + if (scope != (CPPScope *)NULL) { + CPPScope::Declarations::iterator di; + for (di = scope->_declarations.begin(); di != scope->_declarations.end(); ++di) { + CPPMakeSeq *cpp_make_seq = (*di)->as_make_seq(); + if (cpp_make_seq != (CPPMakeSeq *)NULL) { + string class_name = _itype.get_scoped_name(); + string clean_name = InterrogateBuilder::clean_identifier(class_name); + string wrapper_name = "MakeSeq_" + clean_name + "_" + cpp_make_seq->_seq_name; + MakeSeq *make_seq = new MakeSeq(wrapper_name, cpp_make_seq); + _make_seqs.push_back(make_seq); - // Also add to the interrogate database. - builder.get_make_seq(cpp_make_seq, stype); + // Also add to the interrogate database. + builder.get_make_seq(cpp_make_seq, stype); + } } } } @@ -246,26 +248,20 @@ void InterfaceMaker:: generate_wrappers() { InterrogateDatabase *idb = InterrogateDatabase::get_ptr(); - // We use a while loop rather than a simple for loop, because we // might increase the number of types recursively during the // traversal. int ti = 0; - while (ti < idb->get_num_all_types()) - { - TypeIndex type_index = idb->get_all_type(ti); - record_object(type_index); - - - if(interrogate_type_is_enum(ti)) - { - int enum_count = interrogate_type_number_of_enum_values(ti); - for(int xx = 0; xx< enum_count; xx++) - { -// printf(" PyModule_AddIntConstant(module,\"%s\",%d)\n",interrogate_type_enum_value_name(ti,xx),interrogate_type_enum_value(ti,xx)); - } - } + while (ti < idb->get_num_all_types()) { + TypeIndex type_index = idb->get_all_type(ti); + record_object(type_index); + if (interrogate_type_is_enum(ti)) { + int enum_count = interrogate_type_number_of_enum_values(ti); + for (int xx = 0; xx < enum_count; ++xx) { +// printf(" PyModule_AddIntConstant(module,\"%s\",%d)\n",interrogate_type_enum_value_name(ti,xx),interrogate_type_enum_value(ti,xx)); + } + } ++ti; // printf(" New Type %d\n",ti); @@ -273,54 +269,43 @@ generate_wrappers() { int num_global_elements = idb->get_num_global_elements(); for (int gi = 0; gi < num_global_elements; ++gi) { - printf(" Global Type = %d",gi); + printf(" Global Type = %d", gi); TypeIndex type_index = idb->get_global_element(gi); record_object(type_index); } int num_functions = idb->get_num_global_functions(); - for (int fi = 0; fi < num_functions; fi++) - { + for (int fi = 0; fi < num_functions; fi++) { FunctionIndex func_index = idb->get_global_function(fi); record_function(dummy_type, func_index); - } - - + } int num_manifests = idb->get_num_global_manifests(); - for (int mi = 0; mi < num_manifests; mi++) - { + for (int mi = 0; mi < num_manifests; mi++) { ManifestIndex manifest_index = idb->get_global_manifest(mi); const InterrogateManifest &iman = idb->get_manifest(manifest_index); - if (iman.has_getter()) - { + if (iman.has_getter()) { FunctionIndex func_index = iman.get_getter(); record_function(dummy_type, func_index); } - printf(" Manafests %d\n",mi); - } - - + printf(" Manifests %d\n", mi); + } int num_elements = idb->get_num_global_elements(); - for (int ei = 0; ei < num_elements; ei++) - { - printf(" Element %d\n",ei); + for (int ei = 0; ei < num_elements; ei++) { + printf(" Element %d\n", ei); ElementIndex element_index = idb->get_global_element(ei); const InterrogateElement &ielement = idb->get_element(element_index); - if (ielement.has_getter()) - { + if (ielement.has_getter()) { FunctionIndex func_index = ielement.get_getter(); record_function(dummy_type, func_index); } - if (ielement.has_setter()) - { + if (ielement.has_setter()) { FunctionIndex func_index = ielement.get_setter(); record_function(dummy_type, func_index); } } - } //////////////////////////////////////////////////////////////////// @@ -491,6 +476,19 @@ separate_overloading() { return true; } +//////////////////////////////////////////////////////////////////// +// Function: InterfaceMaker::wrap_global_functions +// Access: Public, Virtual +// Description: This method should be overridden and redefined to +// return false for interfaces that don't support +// global functions and should therefore will only +// accept function remaps that have a class associated. +//////////////////////////////////////////////////////////////////// +bool InterfaceMaker:: +wrap_global_functions() { + return true; +} + //////////////////////////////////////////////////////////////////// // Function: InterfaceMaker::get_function_remaps // Access: Public @@ -625,21 +623,17 @@ record_function(const InterrogateType &itype, FunctionIndex func_index) { Function *func = new Function(wrapper_name, itype, ifunc); _functions.push_back(func); - -// printf(" Function Name = %s\n",ifunc.get_name().c_str()); +// printf(" Function Name = %s\n", ifunc.get_name().c_str()); // Now get all the valid FunctionRemaps for the function. - if (ifunc._instances != (InterrogateFunction::Instances *)NULL) - { + if (ifunc._instances != (InterrogateFunction::Instances *)NULL) { InterrogateFunction::Instances::const_iterator ii; - for (ii = ifunc._instances->begin();ii != ifunc._instances->end();++ii) - { + for (ii = ifunc._instances->begin(); ii != ifunc._instances->end(); ++ii) { CPPInstance *cppfunc = (*ii).second; CPPFunctionType *ftype = cppfunc->_type->as_function_type(); int max_default_parameters = 0; - if (separate_overloading()) - { + if (separate_overloading()) { // Count up the number of default parameters this function might // take. CPPParameterList *parameters = ftype->_parameters; diff --git a/dtool/src/interrogate/interfaceMaker.h b/dtool/src/interrogate/interfaceMaker.h index 8928afe556..9b12054750 100644 --- a/dtool/src/interrogate/interfaceMaker.h +++ b/dtool/src/interrogate/interfaceMaker.h @@ -56,14 +56,15 @@ public: virtual void write_includes(ostream &out); virtual void write_prototypes(ostream &out, ostream *out_h); virtual void write_functions(ostream &out); - virtual void write_module_support(ostream &out,ostream *out_h,InterrogateModuleDef *moduledefdef) {}; + virtual void write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) {}; - virtual void write_module(ostream &out, ostream *out_h,InterrogateModuleDef *def); + virtual void write_module(ostream &out, ostream *out_h, InterrogateModuleDef *def); virtual ParameterRemap *remap_parameter(CPPType *struct_type, CPPType *param_type); virtual bool synthesize_this_parameter(); virtual bool separate_overloading(); + virtual bool wrap_global_functions(); void get_function_remaps(vector &remaps); @@ -146,7 +147,7 @@ public: record_function_wrapper(InterrogateFunction &ifunc, FunctionWrapperIndex wrapper_index); - virtual Object * record_object(TypeIndex type_index); + virtual Object *record_object(TypeIndex type_index); void hash_function_signature(FunctionRemap *remap); diff --git a/dtool/src/interrogate/interfaceMakerPythonObj.cxx b/dtool/src/interrogate/interfaceMakerPythonObj.cxx index d3a219e18b..f38497c299 100644 --- a/dtool/src/interrogate/interfaceMakerPythonObj.cxx +++ b/dtool/src/interrogate/interfaceMakerPythonObj.cxx @@ -54,7 +54,7 @@ InterfaceMakerPythonObj:: // write_functions(). //////////////////////////////////////////////////////////////////// void InterfaceMakerPythonObj:: -write_prototypes(ostream &out,ostream *out_h) { +write_prototypes(ostream &out, ostream *out_h) { Functions::iterator fi; for (fi = _functions.begin(); fi != _functions.end(); ++fi) { Function *func = (*fi); diff --git a/dtool/src/interrogate/typeManager.cxx b/dtool/src/interrogate/typeManager.cxx index 8dc01d9855..03b742e6a3 100644 --- a/dtool/src/interrogate/typeManager.cxx +++ b/dtool/src/interrogate/typeManager.cxx @@ -807,24 +807,52 @@ is_unsigned_integer(CPPType *type) { } //////////////////////////////////////////////////////////////////// -// Function: TypeManager::is_unsigned_longlong +// Function: TypeManager::is_short // Access: Public, Static -// Description: Returns true if the indicated type is an unsigned -// "long long" type or larger, or at least a 64-bit -// unsigned integer. +// Description: Returns true if the indicated type is the "short" +// type, whether signed or unsigned. //////////////////////////////////////////////////////////////////// bool TypeManager:: -is_unsigned_longlong(CPPType *type) { +is_short(CPPType *type) { switch (type->get_subtype()) { case CPPDeclaration::ST_const: - return is_unsigned_longlong(type->as_const_type()->_wrapped_around); + return is_short(type->as_const_type()->_wrapped_around); case CPPDeclaration::ST_simple: { CPPSimpleType *simple_type = type->as_simple_type(); if (simple_type != (CPPSimpleType *)NULL) { return (simple_type->_type == CPPSimpleType::T_int && - (simple_type->_flags & (CPPSimpleType::F_longlong | CPPSimpleType::F_unsigned)) == (CPPSimpleType::F_longlong | CPPSimpleType::F_unsigned)); + (simple_type->_flags & CPPSimpleType::F_short) != 0); + } + } + break; + + default: + break; + } + + return false; +} + +//////////////////////////////////////////////////////////////////// +// Function: TypeManager::is_unsigned_short +// Access: Public, Static +// Description: Returns true if the indicated type is an unsigned +// "short" type. +//////////////////////////////////////////////////////////////////// +bool TypeManager:: +is_unsigned_short(CPPType *type) { + switch (type->get_subtype()) { + case CPPDeclaration::ST_const: + return is_unsigned_short(type->as_const_type()->_wrapped_around); + + case CPPDeclaration::ST_simple: + { + CPPSimpleType *simple_type = type->as_simple_type(); + if (simple_type != (CPPSimpleType *)NULL) { + return (simple_type->_type == CPPSimpleType::T_int && + (simple_type->_flags & (CPPSimpleType::F_short | CPPSimpleType::F_unsigned)) == (CPPSimpleType::F_short | CPPSimpleType::F_unsigned)); } } break; @@ -866,6 +894,64 @@ is_longlong(CPPType *type) { return false; } +//////////////////////////////////////////////////////////////////// +// Function: TypeManager::is_unsigned_longlong +// Access: Public, Static +// Description: Returns true if the indicated type is an unsigned +// "long long" type or larger, or at least a 64-bit +// unsigned integer. +//////////////////////////////////////////////////////////////////// +bool TypeManager:: +is_unsigned_longlong(CPPType *type) { + switch (type->get_subtype()) { + case CPPDeclaration::ST_const: + return is_unsigned_longlong(type->as_const_type()->_wrapped_around); + + case CPPDeclaration::ST_simple: + { + CPPSimpleType *simple_type = type->as_simple_type(); + if (simple_type != (CPPSimpleType *)NULL) { + return (simple_type->_type == CPPSimpleType::T_int && + (simple_type->_flags & (CPPSimpleType::F_longlong | CPPSimpleType::F_unsigned)) == (CPPSimpleType::F_longlong | CPPSimpleType::F_unsigned)); + } + } + break; + + default: + break; + } + + return false; +} + +//////////////////////////////////////////////////////////////////// +// Function: TypeManager::is_double +// Access: Public, Static +// Description: Returns true if the indicated type is the "double" +// type. +//////////////////////////////////////////////////////////////////// +bool TypeManager:: +is_double(CPPType *type) { + switch (type->get_subtype()) { + case CPPDeclaration::ST_const: + return is_float(type->as_const_type()->_wrapped_around); + + case CPPDeclaration::ST_simple: + { + CPPSimpleType *simple_type = type->as_simple_type(); + if (simple_type != (CPPSimpleType *)NULL) { + return (simple_type->_type == CPPSimpleType::T_double); + } + } + break; + + default: + break; + } + + return false; +} + //////////////////////////////////////////////////////////////////// // Function: TypeManager::is_float // Access: Public, Static diff --git a/dtool/src/interrogate/typeManager.h b/dtool/src/interrogate/typeManager.h index 938fca3c97..9123da52ed 100644 --- a/dtool/src/interrogate/typeManager.h +++ b/dtool/src/interrogate/typeManager.h @@ -80,8 +80,11 @@ public: static bool is_bool(CPPType *type); static bool is_integer(CPPType *type); static bool is_unsigned_integer(CPPType *type); - static bool is_unsigned_longlong(CPPType *type); + static bool is_short(CPPType *type); + static bool is_unsigned_short(CPPType *type); static bool is_longlong(CPPType *type); + static bool is_unsigned_longlong(CPPType *type); + static bool is_double(CPPType *type); static bool is_float(CPPType *type); static bool is_void(CPPType *type); static bool is_reference_count(CPPType *type); diff --git a/panda/src/bullet/bulletAllHitsRayResult.cxx b/panda/src/bullet/bulletAllHitsRayResult.cxx index 2a1bf63b94..953390820e 100644 --- a/panda/src/bullet/bulletAllHitsRayResult.cxx +++ b/panda/src/bullet/bulletAllHitsRayResult.cxx @@ -33,11 +33,6 @@ BulletAllHitsRayResult(const btVector3 &from_pos, const btVector3 &to_pos, const bool BulletAllHitsRayResult:: needsCollision(btBroadphaseProxy* proxy0) const { - // Original implementation: - //bool collides = (proxy0->m_collisionFilterGroup & m_collisionFilterMask) != 0; - //collides = collides && (m_collisionFilterGroup & proxy0->m_collisionFilterMask); - //return collides; - btCollisionObject *obj0 = (btCollisionObject *) proxy0->m_clientObject; PandaNode *node0 = (PandaNode *) obj0->getUserPointer(); CollideMask mask0 = node0->get_into_collide_mask(); @@ -45,6 +40,28 @@ needsCollision(btBroadphaseProxy* proxy0) const { return (_mask & mask0) != 0; } +//////////////////////////////////////////////////////////////////// +// Function: BulletAllHitsRayResult::addSingleResult +// Access: Protected +// Description: Override default implementation. +//////////////////////////////////////////////////////////////////// +btScalar BulletAllHitsRayResult:: +addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace) { + + // Store part/index information + if (rayResult.m_localShapeInfo) { + _shapePart.push_back(rayResult.m_localShapeInfo->m_shapePart); + _triangleIndex.push_back(rayResult.m_localShapeInfo->m_triangleIndex); + } + else { + _shapePart.push_back(-1); + _triangleIndex.push_back(-1); + } + + // Call the default implementation + return btCollisionWorld::AllHitsRayResultCallback::addSingleResult(rayResult, normalInWorldSpace); +}; + //////////////////////////////////////////////////////////////////// // Function: BulletAllHitsRayResult::get_from_pos // Access: Published @@ -117,6 +134,9 @@ get_hit(int idx) const { hit._pos = m_hitPointWorld[idx]; hit._fraction = m_hitFractions[idx]; + hit._shapePart = _shapePart[idx]; + hit._triangleIndex = _triangleIndex[idx]; + return hit; } @@ -164,3 +184,25 @@ get_hit_normal() const { return btVector3_to_LVector3(_normal); } +//////////////////////////////////////////////////////////////////// +// Function: BulletRayHit::get_shape_part +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +int BulletRayHit:: +get_shape_part() const { + + return _shapePart; +} + +//////////////////////////////////////////////////////////////////// +// Function: BulletRayHit::get_triangle_index +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +int BulletRayHit:: +get_triangle_index() const { + + return _triangleIndex; +} + diff --git a/panda/src/bullet/bulletAllHitsRayResult.h b/panda/src/bullet/bulletAllHitsRayResult.h index 5a3701f7b9..6825e0ff68 100644 --- a/panda/src/bullet/bulletAllHitsRayResult.h +++ b/panda/src/bullet/bulletAllHitsRayResult.h @@ -38,12 +38,18 @@ PUBLISHED: LVector3 get_hit_normal() const; PN_stdfloat get_hit_fraction() const; + int get_shape_part() const; + int get_triangle_index() const; + private: const btCollisionObject *_object; btVector3 _normal; btVector3 _pos; btScalar _fraction; + int _shapePart; + int _triangleIndex; + friend struct BulletAllHitsRayResult; }; @@ -68,12 +74,16 @@ PUBLISHED: public: virtual bool needsCollision(btBroadphaseProxy* proxy0) const; + virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace); private: BulletAllHitsRayResult(const btVector3 &from_pos, const btVector3 &to_pos, const CollideMask &mask); CollideMask _mask; + btAlignedObjectArray _shapePart; + btAlignedObjectArray _triangleIndex; + friend class BulletWorld; }; diff --git a/panda/src/bullet/bulletClosestHitRayResult.cxx b/panda/src/bullet/bulletClosestHitRayResult.cxx index 4b6d920e79..a1b2910b65 100644 --- a/panda/src/bullet/bulletClosestHitRayResult.cxx +++ b/panda/src/bullet/bulletClosestHitRayResult.cxx @@ -23,6 +23,8 @@ BulletClosestHitRayResult:: BulletClosestHitRayResult(const btVector3 &from_pos, const btVector3 &to_pos, const CollideMask &mask) : btCollisionWorld::ClosestRayResultCallback(from_pos, to_pos), _mask(mask) { + _shapePart = -1; + _triangleIndex = -1; } //////////////////////////////////////////////////////////////////// @@ -33,11 +35,6 @@ BulletClosestHitRayResult(const btVector3 &from_pos, const btVector3 &to_pos, co bool BulletClosestHitRayResult:: needsCollision(btBroadphaseProxy* proxy0) const { - // Original implementation: - //bool collides = (proxy0->m_collisionFilterGroup & m_collisionFilterMask) != 0; - //collides = collides && (m_collisionFilterGroup & proxy0->m_collisionFilterMask); - //return collides; - btCollisionObject *obj0 = (btCollisionObject *) proxy0->m_clientObject; PandaNode *node0 = (PandaNode *) obj0->getUserPointer(); CollideMask mask0 = node0->get_into_collide_mask(); @@ -45,6 +42,24 @@ needsCollision(btBroadphaseProxy* proxy0) const { return (_mask & mask0) != 0; } +//////////////////////////////////////////////////////////////////// +// Function: BulletAllHitsRayResult::addSingleResult +// Access: Protected +// Description: Override default implementation. +//////////////////////////////////////////////////////////////////// +btScalar BulletClosestHitRayResult:: +addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace) { + + // Store part/index information + if (rayResult.m_localShapeInfo) { + _shapePart = rayResult.m_localShapeInfo->m_shapePart; + _triangleIndex = rayResult.m_localShapeInfo->m_triangleIndex; + } + + // Call the default implementation + return btCollisionWorld::ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace); +}; + //////////////////////////////////////////////////////////////////// // Function: BulletClosestHitRayResult::has_hit // Access: Published @@ -123,3 +138,25 @@ get_to_pos() const { return btVector3_to_LPoint3(m_rayToWorld); } +//////////////////////////////////////////////////////////////////// +// Function: BulletClosestHitRayResult::get_shape_part +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +int BulletClosestHitRayResult:: +get_shape_part() const { + + return _shapePart; +} + +//////////////////////////////////////////////////////////////////// +// Function: BulletClosestHitRayResult::get_triangle_index +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +int BulletClosestHitRayResult:: +get_triangle_index() const { + + return _triangleIndex; +} + diff --git a/panda/src/bullet/bulletClosestHitRayResult.h b/panda/src/bullet/bulletClosestHitRayResult.h index a6c3f71af9..1a3846ab89 100644 --- a/panda/src/bullet/bulletClosestHitRayResult.h +++ b/panda/src/bullet/bulletClosestHitRayResult.h @@ -43,14 +43,21 @@ PUBLISHED: LVector3 get_hit_normal() const; PN_stdfloat get_hit_fraction() const; + int get_shape_part() const; + int get_triangle_index() const; + public: virtual bool needsCollision(btBroadphaseProxy* proxy0) const; + virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace); private: BulletClosestHitRayResult(const btVector3 &from_pos, const btVector3 &to_pos, const CollideMask &mask); CollideMask _mask; + int _shapePart; + int _triangleIndex; + friend class BulletWorld; }; diff --git a/panda/src/bullet/bulletWorld.cxx b/panda/src/bullet/bulletWorld.cxx index 0fc0671207..c570ff1e18 100644 --- a/panda/src/bullet/bulletWorld.cxx +++ b/panda/src/bullet/bulletWorld.cxx @@ -852,10 +852,11 @@ clear_contact_added_callback() { // Description: //////////////////////////////////////////////////////////////////// void BulletWorld:: -set_tick_callback(CallbackObject *obj) { +set_tick_callback(CallbackObject *obj, bool is_pretick) { nassertv(obj != NULL); _tick_callback_obj = obj; + _world->setInternalTickCallback(&BulletWorld::tick_callback, this, is_pretick); } //////////////////////////////////////////////////////////////////// @@ -867,6 +868,7 @@ void BulletWorld:: clear_tick_callback() { _tick_callback_obj = NULL; + _world->setInternalTickCallback(NULL); } /////////////////////////////////////////////////////////////////// @@ -880,8 +882,11 @@ tick_callback(btDynamicsWorld *world, btScalar timestep) { nassertv(world->getWorldUserInfo()); BulletWorld *w = static_cast(world->getWorldUserInfo()); - BulletTickCallbackData cbdata(timestep); - w->_tick_callback_obj->do_callback(&cbdata); + CallbackObject *obj = w->_tick_callback_obj; + if (obj) { + BulletTickCallbackData cbdata(timestep); + obj->do_callback(&cbdata); + } } //////////////////////////////////////////////////////////////////// @@ -895,7 +900,7 @@ set_filter_callback(CallbackObject *obj) { nassertv(obj != NULL); if (bullet_filter_algorithm != FA_callback) { - bullet_cat.warning() << "filter algorithm is not 'python-callback'" << endl; + bullet_cat.warning() << "filter algorithm is not 'callback'" << endl; } _filter_cb3._filter_callback_obj = obj; diff --git a/panda/src/bullet/bulletWorld.h b/panda/src/bullet/bulletWorld.h index d670a5786f..3ebfe59ce0 100644 --- a/panda/src/bullet/bulletWorld.h +++ b/panda/src/bullet/bulletWorld.h @@ -139,7 +139,7 @@ PUBLISHED: void set_contact_added_callback(CallbackObject *obj); void clear_contact_added_callback(); - void set_tick_callback(CallbackObject *obj); + void set_tick_callback(CallbackObject *obj, bool is_pretick=false); void clear_tick_callback(); void set_filter_callback(CallbackObject *obj); @@ -184,7 +184,7 @@ private: void sync_p2b(PN_stdfloat dt, int num_substeps); void sync_b2p(); - void tick_callback(btDynamicsWorld *world, btScalar timestep); + static void tick_callback(btDynamicsWorld *world, btScalar timestep); typedef PTA(PT(BulletRigidBodyNode)) BulletRigidBodies; typedef PTA(PT(BulletSoftBodyNode)) BulletSoftBodies; diff --git a/panda/src/bullet/bullet_utils.cxx b/panda/src/bullet/bullet_utils.cxx index 34e32eee90..521ea4a4b8 100644 --- a/panda/src/bullet/bullet_utils.cxx +++ b/panda/src/bullet/bullet_utils.cxx @@ -219,3 +219,12 @@ void get_node_transform(btTransform &trans, PandaNode *node) { trans.setOrigin(btv); } +//////////////////////////////////////////////////////////////////// +// Function: get_bullet_version +// Description: Returns the version of the linked Bullet library. +//////////////////////////////////////////////////////////////////// +int get_bullet_version() { + + return BT_BULLET_VERSION; +} + diff --git a/panda/src/bullet/bullet_utils.h b/panda/src/bullet/bullet_utils.h index 710d597a8e..fc9fa3542f 100644 --- a/panda/src/bullet/bullet_utils.h +++ b/panda/src/bullet/bullet_utils.h @@ -55,6 +55,7 @@ enum BulletUpAxis { }; EXPCL_PANDABULLET BulletUpAxis get_default_up_axis(); +EXPCL_PANDABULLET int get_bullet_version(); END_PUBLISH diff --git a/panda/src/display/displayRegion.I b/panda/src/display/displayRegion.I index 0ed2a2dcbb..e71bbd4271 100644 --- a/panda/src/display/displayRegion.I +++ b/panda/src/display/displayRegion.I @@ -239,17 +239,41 @@ get_texture_reload_priority() const { } //////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::get_cube_map_index +// Function: DisplayRegion::set_cube_map_index // Access: Published -// Description: Returns the cube map face index associated with this +// Description: Deprecated; replaced by set_target_tex_page(). +//////////////////////////////////////////////////////////////////// +INLINE void DisplayRegion:: +set_cube_map_index(int cube_map_index) { + set_target_tex_page(cube_map_index, 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::get_target_tex_page +// Access: Published +// Description: Returns the target page number associated with this // particular DisplayRegion, or -1 if it is not -// associated with a cube map. See -// set_cube_map_index(). +// associated with a page. See +// set_target_tex_page(). //////////////////////////////////////////////////////////////////// INLINE int DisplayRegion:: -get_cube_map_index() const { +get_target_tex_page() const { CDReader cdata(_cycler); - return cdata->_cube_map_index; + return cdata->_target_tex_page; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::get_target_tex_view +// Access: Published +// Description: Returns the target view number associated with this +// particular DisplayRegion, or -1 if it is not +// associated with a view. See +// set_target_tex_page(). +//////////////////////////////////////////////////////////////////// +INLINE int DisplayRegion:: +get_target_tex_view() const { + CDReader cdata(_cycler); + return cdata->_target_tex_view; } //////////////////////////////////////////////////////////////////// @@ -776,16 +800,29 @@ get_tex_view_offset() { } //////////////////////////////////////////////////////////////////// -// Function: DisplayRegionPipelineReader::get_cube_map_index -// Access: Public -// Description: Returns the cube map face index associated with this +// Function: DisplayRegionPipelineReader::get_target_tex_page +// Access: Published +// Description: Returns the target page number associated with this // particular DisplayRegion, or -1 if it is not -// associated with a cube map. See -// set_cube_map_index(). +// associated with a page. See +// set_target_tex_page(). //////////////////////////////////////////////////////////////////// INLINE int DisplayRegionPipelineReader:: -get_cube_map_index() const { - return _cdata->_cube_map_index; +get_target_tex_page() const { + return _cdata->_target_tex_page; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegionPipelineReader::get_target_tex_view +// Access: Published +// Description: Returns the target view number associated with this +// particular DisplayRegion, or -1 if it is not +// associated with a view. See +// set_target_tex_page(). +//////////////////////////////////////////////////////////////////// +INLINE int DisplayRegionPipelineReader:: +get_target_tex_view() const { + return _cdata->_target_tex_view; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/display/displayRegion.cxx b/panda/src/display/displayRegion.cxx index 9dd48f5284..dfdf3b9f8e 100644 --- a/panda/src/display/displayRegion.cxx +++ b/panda/src/display/displayRegion.cxx @@ -387,22 +387,29 @@ get_cull_traverser() { } //////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::set_cube_map_index +// Function: DisplayRegion::set_target_tex_page // Access: Published, Virtual // Description: This is a special parameter that is only used when -// rendering the faces of a cube map. Normally you -// should not need to set it directly. This sets up the -// DisplayRegion to render to the nth cube map face; the -// value must be between 0 and 5, inclusive. A normal -// DisplayRegion that is not associated with any -// particular cube map should be set to -1. +// rendering the faces of a cube map or multipage and/or +// multiview texture. +// +// This sets up the DisplayRegion to render to the ith +// page and jth view of its associated texture(s); the +// value must be consistent with the range of values +// availble to the texture. A normal DisplayRegion that +// is not associated with any particular page should be +// set to page -1 and view 0. +// +// This is particularly useful when rendering cube maps +// and/or stereo textures. //////////////////////////////////////////////////////////////////// void DisplayRegion:: -set_cube_map_index(int cube_map_index) { +set_target_tex_page(int page, int view) { int pipeline_stage = Thread::get_current_pipeline_stage(); nassertv(pipeline_stage == 0); CDWriter cdata(_cycler); - cdata->_cube_map_index = cube_map_index; + cdata->_target_tex_page = page; + cdata->_target_tex_view = view; } //////////////////////////////////////////////////////////////////// @@ -816,7 +823,8 @@ CData() : _sort(0), _stereo_channel(Lens::SC_mono), _tex_view_offset(0), - _cube_map_index(-1) + _target_tex_page(-1), + _target_tex_view(-1) { } @@ -841,7 +849,8 @@ CData(const DisplayRegion::CData ©) : _sort(copy._sort), _stereo_channel(copy._stereo_channel), _tex_view_offset(copy._tex_view_offset), - _cube_map_index(copy._cube_map_index) + _target_tex_page(copy._target_tex_page), + _target_tex_view(copy._target_tex_view) { } diff --git a/panda/src/display/displayRegion.h b/panda/src/display/displayRegion.h index 9c1b7ef837..8ab64d7eca 100644 --- a/panda/src/display/displayRegion.h +++ b/panda/src/display/displayRegion.h @@ -111,8 +111,10 @@ PUBLISHED: virtual void set_cull_traverser(CullTraverser *trav); CullTraverser *get_cull_traverser(); - virtual void set_cube_map_index(int cube_map_index); - INLINE int get_cube_map_index() const; + INLINE void set_cube_map_index(int cube_map_index); + virtual void set_target_tex_page(int page, int view); + INLINE int get_target_tex_page() const; + INLINE int get_target_tex_view() const; INLINE void set_cull_callback(CallbackObject *object); INLINE void clear_cull_callback(); @@ -210,7 +212,8 @@ private: int _sort; Lens::StereoChannel _stereo_channel; int _tex_view_offset; - int _cube_map_index; + int _target_tex_page; + int _target_tex_view; PT(CallbackObject) _cull_callback; PT(CallbackObject) _draw_callback; @@ -308,7 +311,8 @@ public: INLINE Lens::StereoChannel get_stereo_channel() const; INLINE int get_tex_view_offset(); INLINE bool get_clear_depth_between_eyes() const; - INLINE int get_cube_map_index() const; + INLINE int get_target_tex_page() const; + INLINE int get_target_tex_view() const; INLINE CallbackObject *get_draw_callback() const; INLINE void get_pixels(int &pl, int &pr, int &pb, int &pt) const; diff --git a/panda/src/display/graphicsOutput.I b/panda/src/display/graphicsOutput.I index 31545d99f9..7e4e80d8ad 100644 --- a/panda/src/display/graphicsOutput.I +++ b/panda/src/display/graphicsOutput.I @@ -862,12 +862,14 @@ end_frame_spam(FrameMode mode) { //////////////////////////////////////////////////////////////////// // Function: GraphicsOutput::clear_cube_map_selection // Access: Public -// Description: Clear the variables that select a cube-map face. +// Description: Clear the variables that select a cube-map face (or +// other multipage or multiview texture face). //////////////////////////////////////////////////////////////////// INLINE void GraphicsOutput:: clear_cube_map_selection() { - _cube_map_index = -1; - _cube_map_dr = NULL; + _target_tex_page = -1; + _target_tex_view = -1; + _prev_page_dr = NULL; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/display/graphicsOutput.cxx b/panda/src/display/graphicsOutput.cxx index e843bab755..05863d4751 100644 --- a/panda/src/display/graphicsOutput.cxx +++ b/panda/src/display/graphicsOutput.cxx @@ -106,9 +106,9 @@ GraphicsOutput(GraphicsEngine *engine, GraphicsPipe *pipe, _is_valid = false; _flip_ready = false; - _cube_map_index = -1; - _cube_map_dr = NULL; - _tex_view_offset = -1; + _target_tex_page = -1; + _target_tex_view = -1; + _prev_page_dr = NULL; _sort = 0; _child_sort = 0; _got_child_sort = false; @@ -1069,7 +1069,7 @@ make_cube_map(const string &name, int size, NodePath &camera_rig, DisplayRegion *dr; dr = buffer->make_display_region(); - dr->set_cube_map_index(i); + dr->set_target_tex_page(i, 0); dr->copy_clear_settings(*this); dr->set_camera(camera_np); } @@ -1341,13 +1341,16 @@ end_frame(FrameMode mode, Thread *current_thread) { //////////////////////////////////////////////////////////////////// void GraphicsOutput:: change_scenes(DisplayRegionPipelineReader *new_dr) { - int new_cube_map_index = new_dr->get_cube_map_index(); - if (new_cube_map_index != -1 && - new_cube_map_index != _cube_map_index) { - int old_cube_map_index = _cube_map_index; - DisplayRegion *old_cube_map_dr = _cube_map_dr; - _cube_map_index = new_cube_map_index; - _cube_map_dr = new_dr->get_object(); + int new_target_tex_page = new_dr->get_target_tex_page(); + int new_target_tex_view = new_dr->get_target_tex_view(); + if ((new_target_tex_page != -1 && new_target_tex_page != _target_tex_page) || + new_target_tex_view != _target_tex_view) { + int old_target_tex_page = _target_tex_page; + int old_target_tex_view = _target_tex_view; + DisplayRegion *old_page_dr = _prev_page_dr; + _target_tex_page = new_target_tex_page; + _target_tex_view = new_target_tex_view; + _prev_page_dr = new_dr->get_object(); CDReader cdata(_cycler); RenderTextures::const_iterator ri; @@ -1356,83 +1359,55 @@ change_scenes(DisplayRegionPipelineReader *new_dr) { Texture *texture = (*ri)._texture; if (rtm_mode != RTM_none) { if (rtm_mode == RTM_bind_or_copy || rtm_mode == RTM_bind_layered) { - // In render-to-texture mode, switch the rendering backend to - // the new cube map face, so that the subsequent frame will be - // rendered to the new face. + // In render-to-texture mode, switch the rendering backend + // to the new page, so that the subsequent frame will be + // rendered to the correct page. + select_target_tex_page(_target_tex_page, _target_tex_view); - select_cube_map(new_cube_map_index); - - } else if (old_cube_map_index != -1) { + } else if (old_target_tex_page != -1) { // In copy-to-texture mode, copy the just-rendered framebuffer - // to the old cube map face. - nassertv(old_cube_map_dr != (DisplayRegion *)NULL); + // to the old texture page. + + // TODO: we should probably pass the view parameter into + // framebuffer_copy_to_xxx(), as we do the page parameter. + // Instead these methods draw the view parameter from + // dr->get_target_tex_view(), which is not altogether wrong + // but is a strange approach. + + nassertv(old_page_dr != (DisplayRegion *)NULL); if (display_cat.is_debug()) { display_cat.debug() << "Copying texture for " << get_name() << " at scene change.\n"; display_cat.debug() - << "cube_map_index = " << old_cube_map_index << "\n"; + << "target_tex_page = " << old_target_tex_page << "\n"; } RenderBuffer buffer = _gsg->get_render_buffer(get_draw_buffer_type(), get_fb_properties()); if (rtm_mode == RTM_copy_ram) { - _gsg->framebuffer_copy_to_ram(texture, old_cube_map_index, - old_cube_map_dr, buffer); + _gsg->framebuffer_copy_to_ram(texture, old_target_tex_page, + old_page_dr, buffer); } else { - _gsg->framebuffer_copy_to_texture(texture, old_cube_map_index, - old_cube_map_dr, buffer); + _gsg->framebuffer_copy_to_texture(texture, old_target_tex_page, + old_page_dr, buffer); } } } } } - - int new_tex_view_offset = new_dr->get_tex_view_offset(); - if (new_tex_view_offset != _tex_view_offset) { - int old_tex_view_offset = _tex_view_offset; - //DisplayRegion *old_cube_map_dr = _cube_map_dr; - _tex_view_offset = new_tex_view_offset; - //_cube_map_dr = new_dr->get_object(); - - CDReader cdata(_cycler); - RenderTextures::const_iterator ri; - for (ri = cdata->_textures.begin(); ri != cdata->_textures.end(); ++ri) { - RenderTextureMode rtm_mode = (*ri)._rtm_mode; - Texture *texture = (*ri)._texture; - if (rtm_mode == RTM_bind_or_copy || rtm_mode == RTM_bind_layered) { - // In render-to-texture mode, switch the rendering backend to - // the new view, so that the subsequent frame will be - // rendered to the new view. - - select_tex_view(new_tex_view_offset); - break; - } - } - } } //////////////////////////////////////////////////////////////////// -// Function: GraphicsOutput::select_cube_map +// Function: GraphicsOutput::select_target_tex_page // Access: Public, Virtual // Description: Called internally when the window is in // render-to-a-texture mode and we are in the process of -// rendering the six faces of a cube map. This should -// do whatever needs to be done to switch the buffer to -// the indicated face. +// rendering the six faces of a cube map, or any other +// multi-page and/or multi-view texture. This should do +// whatever needs to be done to switch the buffer to the +// indicated page and view. //////////////////////////////////////////////////////////////////// void GraphicsOutput:: -select_cube_map(int) { -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsOutput::select_tex_view -// Access: Public, Virtual -// Description: Called internally when the window is in -// render-to-a-texture mode and the DisplayRegion -// requests that we switch rendering to a different -// texture view. -//////////////////////////////////////////////////////////////////// -void GraphicsOutput:: -select_tex_view(int) { +select_target_tex_page(int, int) { } //////////////////////////////////////////////////////////////////// @@ -1603,7 +1578,7 @@ copy_to_textures() { display_cat.debug() << "Copying texture for " << get_name() << " at frame end.\n"; display_cat.debug() - << "cube_map_index = " << _cube_map_index << "\n"; + << "target_tex_page = " << _target_tex_page << "\n"; } RenderTexturePlane plane = (*ri)._plane; RenderBuffer buffer(_gsg, DrawableRegion::get_renderbuffer_type(plane)); @@ -1613,24 +1588,24 @@ copy_to_textures() { } bool copied = false; - if (_cube_map_dr != (DisplayRegion *)NULL) { + if (_prev_page_dr != (DisplayRegion *)NULL) { if ((rtm_mode == RTM_copy_ram)||(rtm_mode == RTM_triggered_copy_ram)) { copied = - _gsg->framebuffer_copy_to_ram(texture, _cube_map_index, - _cube_map_dr, buffer); + _gsg->framebuffer_copy_to_ram(texture, _target_tex_page, + _prev_page_dr, buffer); } else { copied = - _gsg->framebuffer_copy_to_texture(texture, _cube_map_index, - _cube_map_dr, buffer); + _gsg->framebuffer_copy_to_texture(texture, _target_tex_page, + _prev_page_dr, buffer); } } else { if ((rtm_mode == RTM_copy_ram)||(rtm_mode == RTM_triggered_copy_ram)) { copied = - _gsg->framebuffer_copy_to_ram(texture, _cube_map_index, + _gsg->framebuffer_copy_to_ram(texture, _target_tex_page, _overlay_display_region, buffer); } else { copied = - _gsg->framebuffer_copy_to_texture(texture, _cube_map_index, + _gsg->framebuffer_copy_to_texture(texture, _target_tex_page, _overlay_display_region, buffer); } } diff --git a/panda/src/display/graphicsOutput.h b/panda/src/display/graphicsOutput.h index 9574a48015..1e40a7051b 100644 --- a/panda/src/display/graphicsOutput.h +++ b/panda/src/display/graphicsOutput.h @@ -260,8 +260,7 @@ public: virtual void end_frame(FrameMode mode, Thread *current_thread); void change_scenes(DisplayRegionPipelineReader *new_dr); - virtual void select_cube_map(int cube_map_index); - virtual void select_tex_view(int tex_view_offset); + virtual void select_target_tex_page(int page, int view); // These methods will be called within the app (main) thread. virtual void begin_flip(); @@ -311,9 +310,9 @@ protected: bool _stereo; string _name; bool _flip_ready; - int _cube_map_index; - DisplayRegion *_cube_map_dr; - int _tex_view_offset; + int _target_tex_page; + int _target_tex_view; + DisplayRegion *_prev_page_dr; PT(Geom) _texture_card; bool _trigger_copy; diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index bd6316fa84..fb630022d4 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -2754,7 +2754,7 @@ make_shadow_buffer(const NodePath &light_np, GraphicsOutputBase *host) { for (int i = 0; i < 6; ++i) { PT(DisplayRegion) dr = sbuffer->make_mono_display_region(0, 1, 0, 1); dr->set_lens_index(i); - dr->set_cube_map_index(i); + dr->set_target_tex_page(i, 0); dr->set_camera(light_np); dr->set_clear_depth_active(true); } diff --git a/panda/src/display/stereoDisplayRegion.cxx b/panda/src/display/stereoDisplayRegion.cxx index ba16b1ce6c..c328bc3a33 100644 --- a/panda/src/display/stereoDisplayRegion.cxx +++ b/panda/src/display/stereoDisplayRegion.cxx @@ -284,16 +284,16 @@ set_cull_traverser(CullTraverser *trav) { } //////////////////////////////////////////////////////////////////// -// Function: StereoDisplayRegion::set_cube_map_index +// Function: StereoDisplayRegion::set_target_tex_page // Access: Published, Virtual -// Description: Sets the cube_map_index on both the left and +// Description: Sets the page and view on both the left and // right DisplayRegions to the indicated value. //////////////////////////////////////////////////////////////////// void StereoDisplayRegion:: -set_cube_map_index(int cube_map_index) { - DisplayRegion::set_cube_map_index(cube_map_index); - _left_eye->set_cube_map_index(cube_map_index); - _right_eye->set_cube_map_index(cube_map_index); +set_target_tex_page(int page, int view) { + DisplayRegion::set_target_tex_page(page, view); + _left_eye->set_target_tex_page(page, view); + _right_eye->set_target_tex_page(page, view); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/display/stereoDisplayRegion.h b/panda/src/display/stereoDisplayRegion.h index 18e574c315..01b6c3905c 100644 --- a/panda/src/display/stereoDisplayRegion.h +++ b/panda/src/display/stereoDisplayRegion.h @@ -61,7 +61,7 @@ PUBLISHED: virtual void set_incomplete_render(bool incomplete_render); virtual void set_texture_reload_priority(int texture_reload_priority); virtual void set_cull_traverser(CullTraverser *trav); - virtual void set_cube_map_index(int cube_map_index); + virtual void set_target_tex_page(int page, int view); virtual void output(ostream &out) const; virtual PT(PandaNode) make_cull_result_graph(); diff --git a/panda/src/dxgsg8/wdxGraphicsBuffer8.cxx b/panda/src/dxgsg8/wdxGraphicsBuffer8.cxx index 8524ff21b4..fea31ccfcc 100644 --- a/panda/src/dxgsg8/wdxGraphicsBuffer8.cxx +++ b/panda/src/dxgsg8/wdxGraphicsBuffer8.cxx @@ -394,7 +394,7 @@ rebuild_bitplanes() { } //////////////////////////////////////////////////////////////////// -// Function: wdxGraphicsBuffer8::select_cube_map +// Function: wdxGraphicsBuffer8::select_target_tex_page // Access: Public, Virtual // Description: Called internally when the window is in // render-to-a-texture mode and we are in the process of @@ -403,8 +403,8 @@ rebuild_bitplanes() { // the indicated face. //////////////////////////////////////////////////////////////////// void wdxGraphicsBuffer8:: -select_cube_map(int cube_map_index) { - _cube_map_index = cube_map_index; +select_target_tex_page(int page, int view) { + _cube_map_index = page; HRESULT hr; Texture *color_tex = 0; diff --git a/panda/src/dxgsg8/wdxGraphicsBuffer8.h b/panda/src/dxgsg8/wdxGraphicsBuffer8.h index ab8b63a795..cb5d21ed9c 100644 --- a/panda/src/dxgsg8/wdxGraphicsBuffer8.h +++ b/panda/src/dxgsg8/wdxGraphicsBuffer8.h @@ -46,7 +46,7 @@ public: virtual bool begin_frame(FrameMode mode, Thread *current_thread); virtual void end_frame(FrameMode mode, Thread *current_thread); - virtual void select_cube_map(int cube_map_index); + virtual void select_target_tex_page(int page, int view); virtual void process_events(); diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index 8e7e3f8bd6..1eaef91715 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -1902,7 +1902,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr, // must use a render target type texture for StretchRect tex->set_render_to_texture(true); - int view = dr->get_tex_view_offset(); + int view = dr->get_target_tex_view(); TextureContext *tc = tex->prepare_now(view, get_prepared_objects(), this); if (tc == (TextureContext *)NULL) { return false; diff --git a/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx b/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx index e530e6701e..8fceeb9469 100644 --- a/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx +++ b/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx @@ -582,7 +582,7 @@ rebuild_bitplanes() { } //////////////////////////////////////////////////////////////////// -// Function: wdxGraphicsBuffer9::select_cube_map +// Function: wdxGraphicsBuffer9::select_target_tex_page // Access: Public, Virtual // Description: Called internally when the window is in // render-to-a-texture mode and we are in the process of @@ -591,13 +591,13 @@ rebuild_bitplanes() { // the indicated face. //////////////////////////////////////////////////////////////////// void wdxGraphicsBuffer9:: -select_cube_map(int cube_map_index) { +select_target_tex_page(int page, int view) { DWORD render_target_index; render_target_index = 0; - _cube_map_index = cube_map_index; + _cube_map_index = page; HRESULT hr; Texture *color_tex = 0; diff --git a/panda/src/dxgsg9/wdxGraphicsBuffer9.h b/panda/src/dxgsg9/wdxGraphicsBuffer9.h index 05e88a027f..91dfd0539f 100644 --- a/panda/src/dxgsg9/wdxGraphicsBuffer9.h +++ b/panda/src/dxgsg9/wdxGraphicsBuffer9.h @@ -46,7 +46,7 @@ public: virtual bool begin_frame(FrameMode mode, Thread *current_thread); virtual void end_frame(FrameMode mode, Thread *current_thread); - virtual void select_cube_map(int cube_map_index); + virtual void select_target_tex_page(int page, int view); virtual void process_events(); diff --git a/panda/src/glstuff/glGraphicsBuffer_src.cxx b/panda/src/glstuff/glGraphicsBuffer_src.cxx index 15fdd5cba7..a036d703ca 100644 --- a/panda/src/glstuff/glGraphicsBuffer_src.cxx +++ b/panda/src/glstuff/glGraphicsBuffer_src.cxx @@ -80,7 +80,7 @@ CLP(GraphicsBuffer)(GraphicsEngine *engine, GraphicsPipe *pipe, } _shared_depth_buffer = 0; - _active_cube_map_index = -1; + _bound_tex_page = -1; _bound_tex_view = 0; } @@ -125,7 +125,7 @@ begin_frame(FrameMode mode, Thread *current_thread) { begin_frame_spam(mode); check_host_valid(); - _active_cube_map_index = -1; + _bound_tex_page = -1; if (!_is_valid) { if (GLCAT.is_debug()) { @@ -1056,7 +1056,7 @@ end_frame(FrameMode mode, Thread *current_thread) { CLP(GraphicsStateGuardian) *glgsg; DCAST_INTO_V(glgsg, _gsg); glgsg->bind_fbo(0); - _active_cube_map_index = -1; + _bound_tex_page = -1; if (mode == FM_render) { generate_mipmaps(); @@ -1086,107 +1086,97 @@ set_size(int x, int y) { } //////////////////////////////////////////////////////////////////// -// Function: glGraphicsBuffer::select_cube_map +// Function: glGraphicsBuffer::select_target_tex_page // Access: Public, Virtual // Description: Called internally when the window is in // render-to-a-texture mode and we are in the process of -// rendering the six layers of a cube map. This should -// do whatever needs to be done to switch the buffer to -// the indicated face. +// rendering the six faces of a cube map, or any other +// multi-page and/or multi-view texture. This should do +// whatever needs to be done to switch the buffer to the +// indicated page and view. //////////////////////////////////////////////////////////////////// void CLP(GraphicsBuffer):: -select_cube_map(int cube_map_index) { - nassertv(cube_map_index >= 0 && cube_map_index < _fbo.size()); - - if (_active_cube_map_index != -1) { - // Resolve the multisample rendering for the previous face. - if (_requested_multisamples && _fbo_multisample) { - resolve_multisamples(); - } - } +select_target_tex_page(int page, int view) { + nassertv(page >= 0 && page < _fbo.size()); CLP(GraphicsStateGuardian) *glgsg; DCAST_INTO_V(glgsg, _gsg); - glgsg->bind_fbo(_fbo[cube_map_index]); - _active_cube_map_index = cube_map_index; + bool switched_page = (_bound_tex_page != page); + bool switched_view = (_bound_tex_view != view); + + if (switched_page) { + if (_bound_tex_page != -1) { + // Resolve the multisample rendering for the previous face. + if (_requested_multisamples && _fbo_multisample) { + resolve_multisamples(); + } + } + + glgsg->bind_fbo(_fbo[page]); + _bound_tex_page = page; + } + + if (switched_view || switched_page) { + // We assume that we've already configured the texture earlier + // in bind_bitplanes. Therefore, since we can safely assume that + // all texture views have the same format, we can just bind the + // new view here. + + Texture *tex = _tex[RTP_color]; + if (tex != NULL) { + if (view >= tex->get_num_views()) { + tex->set_num_views(view + 1); + } + + GLenum target = glgsg->get_texture_target(tex->get_texture_type()); + if (target == GL_TEXTURE_CUBE_MAP) { + target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + _bound_tex_page; + } + + // Create the OpenGL texture object. + TextureContext *tc = tex->prepare_now(view, glgsg->get_prepared_objects(), glgsg); + nassertv(tc != (TextureContext *)NULL); + CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc); + glgsg->update_texture(tc, true); + + if (GLCAT.is_spam()) { + GLCAT.spam() + << "Binding texture " << *tex + << " view " << view << " to color attachment.\n"; + } + +#ifndef OPENGLES + GLclampf priority = 1.0f; + glPrioritizeTextures(1, >c->_index, &priority); +#endif + glgsg->update_texture(tc, true); + + if (_rb_size_z == 1) { + if (target == GL_TEXTURE_3D) { + glgsg->_glFramebufferTexture3D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + target, gtc->_index, 0, _bound_tex_page); + } else if (target == GL_TEXTURE_2D_ARRAY_EXT) { + glgsg->_glFramebufferTextureLayer(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + gtc->_index, 0, _bound_tex_page); + } else { + glgsg->_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + target, gtc->_index, 0); + } + } else { + glgsg->_glFramebufferTexture(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + gtc->_index, 0); + } + + report_my_gl_errors(); + } + + _bound_tex_view = view; + } report_my_gl_errors(); } -//////////////////////////////////////////////////////////////////// -// Function: glGraphicsBuffer::select_tex_view -// Access: Public, Virtual -// Description: Called internally when the window is in -// render-to-a-texture mode and the DisplayRegion -// requests that we switch rendering to a different -// texture view. -// -// In the FBO case, we do this by re-binding the -// texture that is attached to the color plane. -//////////////////////////////////////////////////////////////////// -void CLP(GraphicsBuffer):: -select_tex_view(int view) { - CLP(GraphicsStateGuardian) *glgsg; - DCAST_INTO_V(glgsg, _gsg); - - if (view == _bound_tex_view) { - return; - } - - // We assume that we've already configured the texture earlier - // in bind_bitplanes. Therefore, since we can safely assume that - // all texture views have the same format, we can just bind the - // new view here. - - Texture *tex = _tex[RTP_color]; - if (tex != NULL) { - if (view >= tex->get_num_views()) { - tex->set_num_views(view + 1); - } - - GLenum target = glgsg->get_texture_target(tex->get_texture_type()); - if (target == GL_TEXTURE_CUBE_MAP) { - target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + _active_cube_map_index; - } - - // Create the OpenGL texture object. - TextureContext *tc = tex->prepare_now(view, glgsg->get_prepared_objects(), glgsg); - nassertv(tc != (TextureContext *)NULL); - CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc); - glgsg->update_texture(tc, true); - - GLCAT.spam() << "Binding texture " << *tex - << " view " << view << " to color attachment.\n"; - - #ifndef OPENGLES - GLclampf priority = 1.0f; - glPrioritizeTextures(1, >c->_index, &priority); - #endif - glgsg->update_texture(tc, true); - - if (_rb_size_z == 1) { - if (target == GL_TEXTURE_3D) { - glgsg->_glFramebufferTexture3D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, - target, gtc->_index, 0, _active_cube_map_index); - } else if (target == GL_TEXTURE_2D_ARRAY_EXT) { - glgsg->_glFramebufferTextureLayer(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, - gtc->_index, 0, _active_cube_map_index); - } else { - glgsg->_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, - target, gtc->_index, 0); - } - } else { - glgsg->_glFramebufferTexture(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, - gtc->_index, 0); - } - - report_my_gl_errors(); - } - - _bound_tex_view = view; -} - //////////////////////////////////////////////////////////////////// // Function: glGraphicsBuffer::open_buffer // Access: Protected, Virtual @@ -1528,8 +1518,8 @@ resolve_multisamples() { glgsg->report_my_gl_errors(); GLuint fbo = _fbo[0]; - if (_active_cube_map_index != -1) { - fbo = _fbo[_active_cube_map_index]; + if (_bound_tex_page != -1) { + fbo = _fbo[_bound_tex_page]; } glgsg->_glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, fbo); glgsg->_glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, _fbo_multisample); diff --git a/panda/src/glstuff/glGraphicsBuffer_src.h b/panda/src/glstuff/glGraphicsBuffer_src.h index 8c6117ec9a..21850b2cb6 100644 --- a/panda/src/glstuff/glGraphicsBuffer_src.h +++ b/panda/src/glstuff/glGraphicsBuffer_src.h @@ -74,8 +74,7 @@ public: virtual void set_size(int x, int y); - virtual void select_cube_map(int cube_map_index); - virtual void select_tex_view(int tex_view_offset); + virtual void select_target_tex_page(int page, int view); virtual bool share_depth_buffer(GraphicsOutput *graphics_output); virtual void unshare_depth_buffer(); @@ -129,7 +128,7 @@ private: // The cube map face we are currently drawing to or have just // finished drawing to, or -1 if we are not drawing to a cube map. - int _active_cube_map_index; + int _bound_tex_page; int _bound_tex_view; bool _initial_clear; diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 7fdb6f675b..cfeaaea617 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -3543,12 +3543,6 @@ update_texture(TextureContext *tc, bool force) { CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc); - if (GLCAT.is_debug() && gtc->get_texture()->get_name() != string("buf")) { - GLCAT.debug() - << "Considering update " << gtc->get_texture()->get_name() - << ": " << gtc->was_image_modified() << ", modified = " << gtc->get_texture()->get_image_modified() << "\n"; - } - if (gtc->was_image_modified()) { // If the texture image was modified, reload the texture. This // means we also re-specify the properties for good measure. @@ -4288,7 +4282,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr, } } - int view = dr->get_tex_view_offset(); + int view = dr->get_target_tex_view(); TextureContext *tc = tex->prepare_now(view, get_prepared_objects(), this); nassertr(tc != (TextureContext *)NULL, false); CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc); @@ -4469,6 +4463,13 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, component_type, format); } + nassertr(z < tex->get_z_size(), false); + + int view = dr->get_target_tex_view(); + if (view >= tex->get_num_views()) { + tex->set_num_views(view + 1); + } + GLenum external_format = get_external_image_format(tex); if (GLCAT.is_spam()) { @@ -4519,10 +4520,14 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, unsigned char *image_ptr = tex->modify_ram_image(); size_t image_size = tex->get_ram_image_size(); - if (z >= 0) { - nassertr(z < tex->get_z_size(), false); + if (z >= 0 || view > 0) { image_size = tex->get_expected_ram_page_size(); - image_ptr += z * image_size; + if (z >= 0) { + image_ptr += z * image_size; + } + if (view > 0) { + image_ptr += (view * tex->get_z_size()) * image_size; + } } GLP(ReadPixels)(xo, yo, w, h, @@ -9040,7 +9045,7 @@ upload_texture(CLP(TextureContext) *gtc, bool force) { // in the case of cube mapping, in which case // texture_target will be target for the overall // texture, e.g. GL_TEXTURE_CUBE_MAP, and page_target -// will the target for this particular page, +// will be the target for this particular page, // e.g. GL_TEXTURE_CUBE_MAP_POSITIVE_X. //////////////////////////////////////////////////////////////////// bool CLP(GraphicsStateGuardian):: @@ -9082,6 +9087,8 @@ upload_texture_image(CLP(TextureContext) *gtc, GLCAT.debug() << "loading uncompressed texture " << tex->get_name() << "\n"; } + GLCAT.debug() + << "page_target " << hex << page_target << dec << "\n"; } int num_ram_mipmap_levels = 0; @@ -9104,6 +9111,7 @@ upload_texture_image(CLP(TextureContext) *gtc, uses_mipmaps = false; } } + } else { num_ram_mipmap_levels = 1; if (uses_mipmaps) { diff --git a/panda/src/gobj/texture.I b/panda/src/gobj/texture.I index 810c652f3b..af06f05e08 100644 --- a/panda/src/gobj/texture.I +++ b/panda/src/gobj/texture.I @@ -31,9 +31,9 @@ INLINE PT(Texture) Texture:: make_copy() const { PT(Texture) tex = make_copy_impl(); CDWriter cdata_tex(tex->_cycler, true); - ++(cdata_tex->_properties_modified); - ++(cdata_tex->_image_modified); - ++(cdata_tex->_simple_image_modified); + cdata_tex->inc_properties_modified(); + cdata_tex->inc_image_modified(); + cdata_tex->inc_simple_image_modified(); return tex; } @@ -288,8 +288,8 @@ INLINE bool Texture:: load(const PNMImage &pnmimage, const LoaderOptions &options) { CDWriter cdata(_cycler, true); do_clear(cdata); - ++(cdata->_properties_modified); - ++(cdata->_image_modified); + cdata->inc_properties_modified(); + cdata->inc_image_modified(); if (do_load_one(cdata, pnmimage, get_name(), 0, 0, options)) { bool generate_mipmaps = ((options.get_texture_flags() & LoaderOptions::TF_generate_mipmaps) != 0); consider_auto_process_ram_image(generate_mipmaps || uses_mipmaps(), true); @@ -307,8 +307,8 @@ load(const PNMImage &pnmimage, const LoaderOptions &options) { INLINE bool Texture:: load(const PNMImage &pnmimage, int z, int n, const LoaderOptions &options) { CDWriter cdata(_cycler, true); - ++(cdata->_properties_modified); - ++(cdata->_image_modified); + cdata->inc_properties_modified(); + cdata->inc_image_modified(); if (do_load_one(cdata, pnmimage, get_name(), z, n, options)) { return true; } @@ -324,8 +324,8 @@ INLINE bool Texture:: load(const PfmFile &pfm, const LoaderOptions &options) { CDWriter cdata(_cycler, true); do_clear(cdata); - ++(cdata->_properties_modified); - ++(cdata->_image_modified); + cdata->inc_properties_modified(); + cdata->inc_image_modified(); if (do_load_one(cdata, pfm, get_name(), 0, 0, options)) { bool generate_mipmaps = ((options.get_texture_flags() & LoaderOptions::TF_generate_mipmaps) != 0); consider_auto_process_ram_image(generate_mipmaps || uses_mipmaps(), true); @@ -343,8 +343,8 @@ load(const PfmFile &pfm, const LoaderOptions &options) { INLINE bool Texture:: load(const PfmFile &pfm, int z, int n, const LoaderOptions &options) { CDWriter cdata(_cycler, true); - ++(cdata->_properties_modified); - ++(cdata->_image_modified); + cdata->inc_properties_modified(); + cdata->inc_image_modified(); if (do_load_one(cdata, pfm, get_name(), z, n, options)) { return true; } @@ -1412,7 +1412,7 @@ get_ram_image_compression() const { INLINE PTA_uchar Texture:: modify_ram_image() { CDWriter cdata(_cycler, true); - ++(cdata->_image_modified); + cdata->inc_image_modified(); return do_modify_ram_image(cdata); } @@ -1453,7 +1453,7 @@ get_uncompressed_ram_image() { INLINE PTA_uchar Texture:: make_ram_image() { CDWriter cdata(_cycler, true); - ++(cdata->_image_modified); + cdata->inc_image_modified(); return do_make_ram_image(cdata); } @@ -1537,7 +1537,7 @@ compress_ram_image(Texture::CompressionMode compression, GraphicsStateGuardianBase *gsg) { CDWriter cdata(_cycler, false); if (do_compress_ram_image(cdata, compression, quality_level, gsg)) { - ++(cdata->_image_modified); + cdata->inc_image_modified(); return true; } return false; @@ -1558,7 +1558,7 @@ INLINE bool Texture:: uncompress_ram_image() { CDWriter cdata(_cycler, false); if (do_uncompress_ram_image(cdata)) { - ++(cdata->_image_modified); + cdata->inc_image_modified(); return true; } return false; @@ -1723,7 +1723,7 @@ get_expected_ram_mipmap_page_size(int n) const { INLINE PTA_uchar Texture:: modify_ram_mipmap_image(int n) { CDWriter cdata(_cycler, false); - ++(cdata->_image_modified); + cdata->inc_image_modified(); return do_modify_ram_mipmap_image(cdata, n); } @@ -1739,7 +1739,7 @@ modify_ram_mipmap_image(int n) { INLINE PTA_uchar Texture:: make_ram_mipmap_image(int n) { CDWriter cdata(_cycler, false); - ++(cdata->_image_modified); + cdata->inc_image_modified(); return do_make_ram_mipmap_image(cdata, n); } @@ -1769,7 +1769,7 @@ set_ram_mipmap_image(int n, CPTA_uchar image, size_t page_size) { INLINE void Texture:: clear_ram_mipmap_images() { CDWriter cdata(_cycler, false); - ++(cdata->_image_modified); + cdata->inc_image_modified(); do_clear_ram_mipmap_images(cdata); } @@ -1790,7 +1790,7 @@ clear_ram_mipmap_images() { INLINE void Texture:: generate_ram_mipmap_images() { CDWriter cdata(_cycler, unlocked_ensure_ram_image(false)); - ++(cdata->_image_modified); + cdata->inc_image_modified(); do_generate_ram_mipmap_images(cdata); } @@ -2627,6 +2627,36 @@ is_dds_filename(const Filename &fullpath) { return (downcase(extension) == "dds"); } +//////////////////////////////////////////////////////////////////// +// Function: Texture::CData::inc_properties_modified +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void Texture::CData:: +inc_properties_modified() { + ++_properties_modified; +} + +//////////////////////////////////////////////////////////////////// +// Function: Texture::CData::inc_image_modified +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void Texture::CData:: +inc_image_modified() { + ++_image_modified; +} + +//////////////////////////////////////////////////////////////////// +// Function: Texture::CData::inc_simple_image_modified +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void Texture::CData:: +inc_simple_image_modified() { + ++_simple_image_modified; +} + //////////////////////////////////////////////////////////////////// // Function: Texture::RamImage::Constructor // Access: Public diff --git a/panda/src/gobj/texture.cxx b/panda/src/gobj/texture.cxx index 3cd11090e1..b4b96217f9 100644 --- a/panda/src/gobj/texture.cxx +++ b/panda/src/gobj/texture.cxx @@ -238,8 +238,8 @@ generate_normalization_cube_map(int size) { PTA_uchar image = do_make_ram_image(cdata); cdata->_keep_ram_image = true; - ++(cdata->_image_modified); - ++(cdata->_properties_modified); + cdata->inc_image_modified(); + cdata->inc_properties_modified(); PN_stdfloat half_size = (PN_stdfloat)size * 0.5f; PN_stdfloat center = half_size - 0.5f; @@ -345,8 +345,8 @@ generate_alpha_scale_map() { cdata->_magfilter = FT_nearest; cdata->_compression = CM_off; - ++(cdata->_image_modified); - ++(cdata->_properties_modified); + cdata->inc_image_modified(); + cdata->inc_properties_modified(); PTA_uchar image = do_make_ram_image(cdata); cdata->_keep_ram_image = true; @@ -366,8 +366,8 @@ bool Texture:: read(const Filename &fullpath, const LoaderOptions &options) { CDWriter cdata(_cycler, true); do_clear(cdata); - ++(cdata->_properties_modified); - ++(cdata->_image_modified); + cdata->inc_properties_modified(); + cdata->inc_image_modified(); return do_read(cdata, fullpath, Filename(), 0, 0, 0, 0, false, false, options, NULL); } @@ -389,8 +389,8 @@ read(const Filename &fullpath, const Filename &alpha_fullpath, const LoaderOptions &options) { CDWriter cdata(_cycler, true); do_clear(cdata); - ++(cdata->_properties_modified); - ++(cdata->_image_modified); + cdata->inc_properties_modified(); + cdata->inc_image_modified(); return do_read(cdata, fullpath, alpha_fullpath, primary_file_num_channels, alpha_file_channel, 0, 0, false, false, options, NULL); @@ -411,8 +411,8 @@ read(const Filename &fullpath, int z, int n, bool read_pages, bool read_mipmaps, const LoaderOptions &options) { CDWriter cdata(_cycler, true); - ++(cdata->_properties_modified); - ++(cdata->_image_modified); + cdata->inc_properties_modified(); + cdata->inc_image_modified(); return do_read(cdata, fullpath, Filename(), 0, 0, z, n, read_pages, read_mipmaps, options, NULL); } @@ -493,8 +493,8 @@ read(const Filename &fullpath, const Filename &alpha_fullpath, BamCacheRecord *record, const LoaderOptions &options) { CDWriter cdata(_cycler, true); - ++(cdata->_properties_modified); - ++(cdata->_image_modified); + cdata->inc_properties_modified(); + cdata->inc_image_modified(); return do_read(cdata, fullpath, alpha_fullpath, primary_file_num_channels, alpha_file_channel, z, n, read_pages, read_mipmaps, options, record); @@ -652,8 +652,8 @@ get_aux_data(const string &key) const { bool Texture:: read_txo(istream &in, const string &filename) { CDWriter cdata(_cycler, true); - ++(cdata->_properties_modified); - ++(cdata->_image_modified); + cdata->inc_properties_modified(); + cdata->inc_image_modified(); return do_read_txo(cdata, in, filename); } @@ -760,8 +760,8 @@ write_txo(ostream &out, const string &filename) const { bool Texture:: read_dds(istream &in, const string &filename, bool header_only) { CDWriter cdata(_cycler, true); - ++(cdata->_properties_modified); - ++(cdata->_image_modified); + cdata->inc_properties_modified(); + cdata->inc_image_modified(); return do_read_dds(cdata, in, filename, header_only); } @@ -1122,7 +1122,7 @@ set_ram_mipmap_pointer(int n, void *image, size_t page_size) { cdata->_ram_images[n]._page_size = page_size; //_ram_images[n]._image.clear(); wtf is going on?! cdata->_ram_images[n]._pointer_image = image; - ++(cdata->_image_modified); + cdata->inc_image_modified(); } //////////////////////////////////////////////////////////////////// @@ -1189,7 +1189,7 @@ new_simple_ram_image(int x_size, int y_size) { cdata->_simple_ram_image._image = PTA_uchar::empty_array(expected_page_size); cdata->_simple_ram_image._page_size = expected_page_size; cdata->_simple_image_date_generated = (PN_int32)time(NULL); - ++(cdata->_simple_image_modified); + cdata->inc_simple_image_modified(); return cdata->_simple_ram_image._image; } @@ -4127,8 +4127,8 @@ unlocked_ensure_ram_image(bool allow_compression) { cdataw->_format = cdata_tex->_format; cdataw->_component_type = cdata_tex->_component_type; - ++(cdataw->_properties_modified); - ++(cdataw->_image_modified); + cdataw->inc_properties_modified(); + cdataw->inc_image_modified(); } cdataw->_keep_ram_image = cdata_tex->_keep_ram_image; @@ -4343,7 +4343,7 @@ do_set_ram_image(CData *cdata, CPTA_uchar image, Texture::CompressionMode compre cdata->_ram_images[0]._page_size = page_size; cdata->_ram_images[0]._pointer_image = NULL; cdata->_ram_image_compression = compression; - ++(cdata->_image_modified); + cdata->inc_image_modified(); } } @@ -4404,7 +4404,7 @@ do_set_ram_mipmap_image(CData *cdata, int n, CPTA_uchar image, size_t page_size) cdata->_ram_images[n]._image = image.cast_non_const(); cdata->_ram_images[n]._pointer_image = NULL; cdata->_ram_images[n]._page_size = page_size; - ++(cdata->_image_modified); + cdata->inc_image_modified(); } } @@ -4839,7 +4839,7 @@ do_rescale_texture(CData *cdata) { new_image.quick_filter_from(orig_image); do_clear_ram_image(cdata); - ++(cdata->_image_modified); + cdata->inc_image_modified(); cdata->_x_size = new_x_size; cdata->_y_size = new_y_size; if (!do_load_one(cdata, new_image, get_name(), 0, 0, LoaderOptions())) { @@ -4871,7 +4871,7 @@ do_rescale_texture(CData *cdata) { do_clear_ram_image(cdata); cdata->_loaded_from_image = false; - ++(cdata->_image_modified); + cdata->inc_image_modified(); if (!do_load_one(cdata, new_image, get_name(), 0, 0, LoaderOptions())) { return false; } @@ -4933,9 +4933,9 @@ do_clear(CData *cdata) { CDReader cdata_tex(tex._cycler); do_assign(cdata, &tex, cdata_tex); - ++(cdata->_properties_modified); - ++(cdata->_image_modified); - ++(cdata->_simple_image_modified); + cdata->inc_properties_modified(); + cdata->inc_image_modified(); + cdata->inc_simple_image_modified(); } //////////////////////////////////////////////////////////////////// @@ -5008,7 +5008,7 @@ do_set_format(CData *cdata, Texture::Format format) { return; } cdata->_format = format; - ++(cdata->_properties_modified); + cdata->inc_properties_modified(); switch (cdata->_format) { case F_color_index: @@ -5091,7 +5091,7 @@ void Texture:: do_set_x_size(CData *cdata, int x_size) { if (cdata->_x_size != x_size) { cdata->_x_size = x_size; - ++(cdata->_image_modified); + cdata->inc_image_modified(); do_clear_ram_image(cdata); do_set_pad_size(cdata, 0, 0, 0); } @@ -5107,7 +5107,7 @@ do_set_y_size(CData *cdata, int y_size) { if (cdata->_y_size != y_size) { nassertv(cdata->_texture_type != Texture::TT_1d_texture || y_size == 1); cdata->_y_size = y_size; - ++(cdata->_image_modified); + cdata->inc_image_modified(); do_clear_ram_image(cdata); do_set_pad_size(cdata, 0, 0, 0); } @@ -5127,7 +5127,7 @@ do_set_z_size(CData *cdata, int z_size) { (cdata->_texture_type == Texture::TT_cube_map && z_size == 6) || (cdata->_texture_type == Texture::TT_2d_texture_array) || (z_size == 1)); cdata->_z_size = z_size; - ++(cdata->_image_modified); + cdata->inc_image_modified(); do_clear_ram_image(cdata); do_set_pad_size(cdata, 0, 0, 0); } @@ -5143,8 +5143,10 @@ do_set_num_views(CData *cdata, int num_views) { nassertv(num_views >= 1); if (cdata->_num_views != num_views) { cdata->_num_views = num_views; - ++(cdata->_image_modified); - do_clear_ram_image(cdata); + if (do_has_ram_image(cdata)) { + cdata->inc_image_modified(); + do_clear_ram_image(cdata); + } do_set_pad_size(cdata, 0, 0, 0); } } @@ -5157,7 +5159,7 @@ do_set_num_views(CData *cdata, int num_views) { void Texture:: do_set_wrap_u(CData *cdata, Texture::WrapMode wrap) { if (cdata->_wrap_u != wrap) { - ++(cdata->_properties_modified); + cdata->inc_properties_modified(); cdata->_wrap_u = wrap; } } @@ -5170,7 +5172,7 @@ do_set_wrap_u(CData *cdata, Texture::WrapMode wrap) { void Texture:: do_set_wrap_v(CData *cdata, Texture::WrapMode wrap) { if (cdata->_wrap_v != wrap) { - ++(cdata->_properties_modified); + cdata->inc_properties_modified(); cdata->_wrap_v = wrap; } } @@ -5183,7 +5185,7 @@ do_set_wrap_v(CData *cdata, Texture::WrapMode wrap) { void Texture:: do_set_wrap_w(CData *cdata, Texture::WrapMode wrap) { if (cdata->_wrap_w != wrap) { - ++(cdata->_properties_modified); + cdata->inc_properties_modified(); cdata->_wrap_w = wrap; } } @@ -5196,7 +5198,7 @@ do_set_wrap_w(CData *cdata, Texture::WrapMode wrap) { void Texture:: do_set_minfilter(CData *cdata, Texture::FilterType filter) { if (cdata->_minfilter != filter) { - ++(cdata->_properties_modified); + cdata->inc_properties_modified(); cdata->_minfilter = filter; } } @@ -5209,7 +5211,7 @@ do_set_minfilter(CData *cdata, Texture::FilterType filter) { void Texture:: do_set_magfilter(CData *cdata, Texture::FilterType filter) { if (cdata->_magfilter != filter) { - ++(cdata->_properties_modified); + cdata->inc_properties_modified(); cdata->_magfilter = filter; } } @@ -5222,7 +5224,7 @@ do_set_magfilter(CData *cdata, Texture::FilterType filter) { void Texture:: do_set_anisotropic_degree(CData *cdata, int anisotropic_degree) { if (cdata->_anisotropic_degree != anisotropic_degree) { - ++(cdata->_properties_modified); + cdata->inc_properties_modified(); cdata->_anisotropic_degree = anisotropic_degree; } } @@ -5235,7 +5237,7 @@ do_set_anisotropic_degree(CData *cdata, int anisotropic_degree) { void Texture:: do_set_border_color(CData *cdata, const LColor &color) { if (cdata->_border_color != color) { - ++(cdata->_properties_modified); + cdata->inc_properties_modified(); cdata->_border_color = color; } } @@ -5248,7 +5250,7 @@ do_set_border_color(CData *cdata, const LColor &color) { void Texture:: do_set_compression(CData *cdata, Texture::CompressionMode compression) { if (cdata->_compression != compression) { - ++(cdata->_properties_modified); + cdata->inc_properties_modified(); cdata->_compression = compression; if (do_has_ram_image(cdata)) { @@ -5273,7 +5275,7 @@ do_set_compression(CData *cdata, Texture::CompressionMode compression) { void Texture:: do_set_quality_level(CData *cdata, Texture::QualityLevel quality_level) { if (cdata->_quality_level != quality_level) { - ++(cdata->_properties_modified); + cdata->inc_properties_modified(); cdata->_quality_level = quality_level; } } @@ -5325,12 +5327,14 @@ do_get_ram_image(CData *cdata) { if (!do_has_ram_image(cdata) && do_can_reload(cdata)) { do_reload_ram_image(cdata, true); - // Normally, we don't update the cdata->_modified semaphores in a do_blah - // method, but we'll make an exception in this case, because it's - // easiest to modify these here, and only when we know it's - // needed. - ++(cdata->_image_modified); - ++(cdata->_properties_modified); + if (do_has_ram_image(cdata)) { + // Normally, we don't update the cdata->_modified semaphores in a do_blah + // method, but we'll make an exception in this case, because it's + // easiest to modify these here, and only when we know it's + // needed. + cdata->inc_image_modified(); + cdata->inc_properties_modified(); + } } if (cdata->_ram_images.empty()) { @@ -5539,7 +5543,7 @@ do_set_simple_ram_image(CData *cdata, CPTA_uchar image, int x_size, int y_size) cdata->_simple_ram_image._image = image.cast_non_const(); cdata->_simple_ram_image._page_size = image.size(); cdata->_simple_image_date_generated = (PN_int32)time(NULL); - ++(cdata->_simple_image_modified); + cdata->inc_simple_image_modified(); } //////////////////////////////////////////////////////////////////// @@ -5644,7 +5648,7 @@ do_clear_simple_ram_image(CData *cdata) { // We allow this exception: we update the _simple_image_modified // here, since no one really cares much about that anyway, and it's // convenient to do it here. - ++(cdata->_simple_image_modified); + cdata->inc_simple_image_modified(); } //////////////////////////////////////////////////////////////////// @@ -5804,7 +5808,7 @@ do_reload(CData *cdata) { do_reload_ram_image(cdata, true); if (do_has_ram_image(cdata)) { // An explicit call to reload() should increment image_modified. - ++(cdata->_image_modified); + cdata->inc_image_modified(); return true; } return false; @@ -7769,7 +7773,7 @@ do_fillin_body(CData *cdata, DatagramIterator &scan, BamReader *manager) { cdata->_format = (Format)scan.get_uint8(); cdata->_num_components = scan.get_uint8(); - ++(cdata->_properties_modified); + cdata->inc_properties_modified(); cdata->_auto_texture_scale = ATS_unspecified; if (manager->get_file_minor_ver() >= 28) { @@ -7797,7 +7801,7 @@ do_fillin_body(CData *cdata, DatagramIterator &scan, BamReader *manager) { cdata->_simple_ram_image._image = image; cdata->_simple_ram_image._page_size = u_size; - ++(cdata->_simple_image_modified); + cdata->inc_simple_image_modified(); } } @@ -7856,7 +7860,7 @@ do_fillin_rawdata(CData *cdata, DatagramIterator &scan, BamReader *manager) { cdata->_ram_images[n]._image = image; } cdata->_loaded_from_image = true; - ++(cdata->_image_modified); + cdata->inc_image_modified(); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/texture.h b/panda/src/gobj/texture.h index 73307e02da..638bbc4120 100644 --- a/panda/src/gobj/texture.h +++ b/panda/src/gobj/texture.h @@ -776,6 +776,9 @@ protected: } void do_assign(const CData *copy); + INLINE void inc_properties_modified(); + INLINE void inc_image_modified(); + INLINE void inc_simple_image_modified(); Filename _filename; Filename _alpha_filename; diff --git a/panda/src/gobj/textureContext.I b/panda/src/gobj/textureContext.I index a0202f6245..d3a857a9f6 100644 --- a/panda/src/gobj/textureContext.I +++ b/panda/src/gobj/textureContext.I @@ -98,6 +98,42 @@ was_simple_image_modified() const { return _simple_image_modified != _texture->get_simple_image_modified(); } +//////////////////////////////////////////////////////////////////// +// Function: TextureContext::get_properties_modified +// Access: Published +// Description: Returns a sequence number which is guaranteed to +// change at least every time the texture properties +// (unrelated to the image) are modified. +//////////////////////////////////////////////////////////////////// +INLINE UpdateSeq TextureContext:: +get_properties_modified() const { + return _properties_modified; +} + +//////////////////////////////////////////////////////////////////// +// Function: TextureContext::get_image_modified +// Access: Published +// Description: Returns a sequence number which is guaranteed to +// change at least every time the texture image data +// (including mipmap levels) are modified. +//////////////////////////////////////////////////////////////////// +INLINE UpdateSeq TextureContext:: +get_image_modified() const { + return _image_modified; +} + +//////////////////////////////////////////////////////////////////// +// Function: TextureContext::get_simple_image_modified +// Access: Published +// Description: Returns a sequence number which is guaranteed to +// change at least every time the texture's "simple" +// image data is modified. +//////////////////////////////////////////////////////////////////// +INLINE UpdateSeq TextureContext:: +get_simple_image_modified() const { + return _simple_image_modified; +} + //////////////////////////////////////////////////////////////////// // Function: TextureContext::update_data_size_bytes // Access: Public diff --git a/panda/src/gobj/textureContext.h b/panda/src/gobj/textureContext.h index 4bbb1d0cc9..660edeff3e 100644 --- a/panda/src/gobj/textureContext.h +++ b/panda/src/gobj/textureContext.h @@ -48,6 +48,10 @@ PUBLISHED: INLINE bool was_image_modified() const; INLINE bool was_simple_image_modified() const; + INLINE UpdateSeq get_properties_modified() const; + INLINE UpdateSeq get_image_modified() const; + INLINE UpdateSeq get_simple_image_modified() const; + public: INLINE void update_data_size_bytes(size_t new_data_size_bytes); INLINE void mark_loaded(); diff --git a/panda/src/pgraph/renderState.I b/panda/src/pgraph/renderState.I index c75d537658..8cce7408af 100644 --- a/panda/src/pgraph/renderState.I +++ b/panda/src/pgraph/renderState.I @@ -551,8 +551,18 @@ operator = (const Attribute ©) { INLINE int RenderState::Attribute:: compare_to(const Attribute &other) const { if (_attrib != other._attrib) { - return _attrib < other._attrib ? -1 : 1; + if (_attrib == NULL) { + return -1; + } else if (other._attrib == NULL) { + return 1; + } + + int c = _attrib->compare_to(*other._attrib); + if (c != 0) { + return c; + } } + return _override - other._override; } diff --git a/panda/src/putil/updateSeq.I b/panda/src/putil/updateSeq.I index ea5bbdd1b8..a47b2fccfc 100644 --- a/panda/src/putil/updateSeq.I +++ b/panda/src/putil/updateSeq.I @@ -264,6 +264,17 @@ operator ++ (int) { return temp; } +//////////////////////////////////////////////////////////////////// +// Function: UpdateSeq::get_seq +// Access: Published +// Description: Returns the internal integer value associated with +// the UpdateSeq. Useful for debugging only. +//////////////////////////////////////////////////////////////////// +INLINE AtomicAdjust::Integer UpdateSeq:: +get_seq() const { + return _seq; +} + //////////////////////////////////////////////////////////////////// // Function: UpdateSeq::output // Access: Published diff --git a/panda/src/putil/updateSeq.h b/panda/src/putil/updateSeq.h index 6fdee69da9..b6a55adf25 100644 --- a/panda/src/putil/updateSeq.h +++ b/panda/src/putil/updateSeq.h @@ -67,6 +67,8 @@ PUBLISHED: INLINE UpdateSeq operator ++ (); INLINE UpdateSeq operator ++ (int); + INLINE AtomicAdjust::Integer get_seq() const; + INLINE void output(ostream &out) const; private: diff --git a/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx b/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx index eaa344740b..3484249744 100644 --- a/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx +++ b/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx @@ -1359,7 +1359,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr, tex->setup_2d_texture(w, h, Texture::T_unsigned_byte, Texture::F_rgba); - int view = dr->get_tex_view_offset(); + int view = dr->get_target_tex_view(); TextureContext *tc = tex->prepare_now(view, get_prepared_objects(), this); nassertr(tc != (TextureContext *)NULL, false); TinyTextureContext *gtc = DCAST(TinyTextureContext, tc); @@ -1431,12 +1431,23 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, component_type, format); } + nassertr(z < tex->get_z_size(), false); + + int view = dr->get_target_tex_view(); + if (view >= tex->get_num_views()) { + tex->set_num_views(view + 1); + } + unsigned char *image_ptr = tex->modify_ram_image(); size_t image_size = tex->get_ram_image_size(); - if (z >= 0) { - nassertr(z < tex->get_z_size(), false); + if (z >= 0 || view > 0) { image_size = tex->get_expected_ram_page_size(); - image_ptr += z * image_size; + if (z >= 0) { + image_ptr += z * image_size; + } + if (view > 0) { + image_ptr += (view * tex->get_z_size()) * image_size; + } } PIXEL *ip = (PIXEL *)(image_ptr + image_size); diff --git a/panda/src/wgldisplay/wglGraphicsBuffer.cxx b/panda/src/wgldisplay/wglGraphicsBuffer.cxx index 3dd0df235a..5a3086e488 100644 --- a/panda/src/wgldisplay/wglGraphicsBuffer.cxx +++ b/panda/src/wgldisplay/wglGraphicsBuffer.cxx @@ -205,7 +205,7 @@ bind_texture_to_pbuffer() { } //////////////////////////////////////////////////////////////////// -// Function: wglGraphicsBuffer::select_cube_map +// Function: wglGraphicsBuffer::select_target_tex_page // Access: Public, Virtual // Description: Called internally when the window is in // render-to-a-texture mode and we are in the process of @@ -214,7 +214,7 @@ bind_texture_to_pbuffer() { // the indicated face. //////////////////////////////////////////////////////////////////// void wglGraphicsBuffer:: -select_cube_map(int cube_map_index) { +select_target_tex_page(int page, int view) { wglGraphicsStateGuardian *wglgsg; DCAST_INTO_V(wglgsg, _gsg); @@ -225,7 +225,7 @@ select_cube_map(int cube_map_index) { int ni = 0; iattrib_list[ni++] = WGL_CUBE_MAP_FACE_ARB; - iattrib_list[ni++] = WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + cube_map_index; + iattrib_list[ni++] = WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + page; // Terminate the list. nassertv(ni <= max_attrib_list); diff --git a/panda/src/wgldisplay/wglGraphicsBuffer.h b/panda/src/wgldisplay/wglGraphicsBuffer.h index 128d877331..94d7c7cf2d 100644 --- a/panda/src/wgldisplay/wglGraphicsBuffer.h +++ b/panda/src/wgldisplay/wglGraphicsBuffer.h @@ -49,7 +49,7 @@ public: virtual bool begin_frame(FrameMode mode, Thread *current_thread); virtual void end_frame(FrameMode mode, Thread *current_thread); - virtual void select_cube_map(int cube_map_index); + virtual void select_target_tex_page(int page, int view); virtual void process_events(); diff --git a/pandatool/src/maxegg/maxEggLoader.cxx b/pandatool/src/maxegg/maxEggLoader.cxx index 2c54ca7090..5129045100 100755 --- a/pandatool/src/maxegg/maxEggLoader.cxx +++ b/pandatool/src/maxegg/maxEggLoader.cxx @@ -296,7 +296,7 @@ void MaxEggJoint::CreateMaxBone(void) mbstowcs(wname, _egg_joint->get_name().c_str(), 1023); _node->SetName(wname); #else - _node->SetName(_egg_joint->get_name().c_str()); + _node->SetName((char*) _egg_joint->get_name().c_str()); #endif _node->SetObjOffsetRot(ooquat);