diff --git a/BACKERS.md b/BACKERS.md index 1c5a10d555..86fc18b77d 100644 --- a/BACKERS.md +++ b/BACKERS.md @@ -24,6 +24,7 @@ This is a list of all the people who are contributing financially to Panda3D. I * Sam Edwards * Max Voss * Hawkheart +* Dan Mlodecki ## Enthusiasts diff --git a/direct/src/gui/DirectOptionMenu.py b/direct/src/gui/DirectOptionMenu.py index 2adf21cf69..be6af85ee8 100644 --- a/direct/src/gui/DirectOptionMenu.py +++ b/direct/src/gui/DirectOptionMenu.py @@ -114,6 +114,7 @@ class DirectOptionMenu(DirectButton): ) # Make sure it is on top of all the other gui widgets self.popupMenu.setBin('gui-popup', 0) + self.highlightedIndex = None if not self['items']: return # Create a new component for each item diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 9858981a7b..02f82cbaf1 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -945,7 +945,8 @@ if (COMPILER=="GCC"): # CgGL is covered by the Cg framework, and we don't need X11 components on OSX if not PkgSkip("NVIDIACG"): SmartPkgEnable("CGGL", "", ("CgGL"), "Cg/cgGL.h", thirdparty_dir = "nvidiacg") - SmartPkgEnable("X11", "x11", "X11", ("X11", "X11/Xlib.h", "X11/XKBlib.h")) + if GetTarget() != "android": + SmartPkgEnable("X11", "x11", "X11", ("X11", "X11/Xlib.h", "X11/XKBlib.h")) if GetHost() != "darwin": # Workaround for an issue where pkg-config does not include this path diff --git a/makepanda/makepandacore.py b/makepanda/makepandacore.py index 5603e2de20..73cd444d0d 100644 --- a/makepanda/makepandacore.py +++ b/makepanda/makepandacore.py @@ -1341,22 +1341,22 @@ def GetThirdpartyDir(): THIRDPARTYDIR = base + "/darwin-libs-a/" elif (target == 'linux'): - if (target_arch.startswith("arm")): + if target_arch in ("aarch64", "arm64"): + THIRDPARTYDIR = base + "/linux-libs-arm64/" + elif target_arch.startswith("arm"): THIRDPARTYDIR = base + "/linux-libs-arm/" elif (target_arch in ("x86_64", "amd64")): THIRDPARTYDIR = base + "/linux-libs-x64/" - elif target_arch == "aarch64": - THIRDPARTYDIR = base + "/linux-libs-aarch64/" else: THIRDPARTYDIR = base + "/linux-libs-a/" elif (target == 'freebsd'): - if (target_arch.startswith("arm")): + if target_arch in ("aarch64", "arm64"): + THIRDPARTYDIR = base + "/freebsd-libs-arm64/" + elif target_arch.startswith("arm"): THIRDPARTYDIR = base + "/freebsd-libs-arm/" elif (target_arch in ("x86_64", "amd64")): THIRDPARTYDIR = base + "/freebsd-libs-x64/" - elif target_arch == "aarch64": - THIRDPARTYDIR = base + "/freebsd-libs-aarch64/" else: THIRDPARTYDIR = base + "/freebsd-libs-a/" diff --git a/panda/src/display/windowProperties.h b/panda/src/display/windowProperties.h index 4a19834072..89af1715d1 100644 --- a/panda/src/display/windowProperties.h +++ b/panda/src/display/windowProperties.h @@ -68,7 +68,11 @@ PUBLISHED: INLINE void set_origin(const LPoint2i &origin); INLINE void set_origin(int x_origin, int y_origin); +#ifdef CPPPARSER + INLINE LPoint2i get_origin() const; +#else INLINE const LPoint2i &get_origin() const; +#endif INLINE int get_x_origin() const; INLINE int get_y_origin() const; INLINE bool has_origin() const; @@ -77,7 +81,11 @@ PUBLISHED: INLINE void set_size(const LVector2i &size); INLINE void set_size(int x_size, int y_size); +#ifdef CPPPARSER + INLINE LVector2i get_size() const; +#else INLINE const LVector2i &get_size() const; +#endif INLINE int get_x_size() const; INLINE int get_y_size() const; INLINE bool has_size() const; @@ -92,7 +100,11 @@ PUBLISHED: set_mouse_mode, clear_mouse_mode); INLINE void set_title(const std::string &title); +#ifdef CPPPARSER + INLINE std::string get_title() const; +#else INLINE const std::string &get_title() const; +#endif INLINE bool has_title() const; INLINE void clear_title(); MAKE_PROPERTY2(title, has_title, get_title, set_title, clear_title); @@ -158,14 +170,22 @@ PUBLISHED: set_cursor_hidden, clear_cursor_hidden); INLINE void set_icon_filename(const Filename &icon_filename); +#ifdef CPPPARSER + INLINE Filename get_icon_filename() const; +#else INLINE const Filename &get_icon_filename() const; +#endif INLINE bool has_icon_filename() const; INLINE void clear_icon_filename(); MAKE_PROPERTY2(icon_filename, has_icon_filename, get_icon_filename, set_icon_filename, clear_icon_filename); INLINE void set_cursor_filename(const Filename &cursor_filename); +#ifdef CPPPARSER + INLINE Filename get_cursor_filename() const; +#else INLINE const Filename &get_cursor_filename() const; +#endif INLINE bool has_cursor_filename() const; INLINE void clear_cursor_filename(); MAKE_PROPERTY2(cursor_filename, has_cursor_filename, get_cursor_filename, diff --git a/panda/src/glstuff/glCgShaderContext_src.cxx b/panda/src/glstuff/glCgShaderContext_src.cxx index 13f01c4232..7d65fdd976 100644 --- a/panda/src/glstuff/glCgShaderContext_src.cxx +++ b/panda/src/glstuff/glCgShaderContext_src.cxx @@ -49,18 +49,9 @@ CLP(CgShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderConte nassertv(s->get_language() == Shader::SL_Cg); // Get a Cg context for this GSG. - CGcontext context = glgsg->_cg_context; - if (context == 0) { - // The GSG doesn't have a Cg context yet. Create one. - glgsg->_cg_context = context = cgCreateContext(); - -#if CG_VERSION_NUM >= 3100 - // This just sounds like a good thing to do. - cgGLSetContextGLSLVersion(context, cgGLDetectGLSLVersion()); - if (glgsg->_shader_caps._active_vprofile == CG_PROFILE_GLSLV) { - cgGLSetContextOptimalOptions(context, CG_PROFILE_GLSLC); - } -#endif + CGcontext context = glgsg->get_cg_context(); + if (context == nullptr) { + return; } // Ask the shader to compile itself for us and to give us the resulting Cg diff --git a/panda/src/glstuff/glGraphicsBuffer_src.cxx b/panda/src/glstuff/glGraphicsBuffer_src.cxx index 4627f89d5c..7872ae96da 100644 --- a/panda/src/glstuff/glGraphicsBuffer_src.cxx +++ b/panda/src/glstuff/glGraphicsBuffer_src.cxx @@ -1935,6 +1935,9 @@ resolve_multisamples() { #endif report_my_gl_errors(); + // Bind the regular FBO as read buffer for the sake of copy_to_textures. + glgsg->_glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, fbo); + #ifndef OPENGLES if (_have_any_color) { glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 6f6d153bb0..1ea41b9c35 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -93,6 +93,11 @@ PStatCollector CLP(GraphicsStateGuardian)::_fbo_bind_pcollector("Draw:Bind FBO") PStatCollector CLP(GraphicsStateGuardian)::_check_error_pcollector("Draw:Check errors"); PStatCollector CLP(GraphicsStateGuardian)::_check_residency_pcollector("*:PStats:Check residency"); +#if defined(HAVE_CG) && !defined(OPENGLES) +AtomicAdjust::Integer CLP(GraphicsStateGuardian)::_num_gsgs_with_cg_contexts = 0; +pvector CLP(GraphicsStateGuardian)::_destroyed_cg_contexts; +#endif + // The following noop functions are assigned to the corresponding glext // function pointers in the class, in case the functions are not defined by // the GL, just so it will always be safe to call the extension functions. @@ -530,7 +535,7 @@ CLP(GraphicsStateGuardian)(GraphicsEngine *engine, GraphicsPipe *pipe) : _shader_point_size = false; #endif -#ifdef HAVE_CG +#if defined(HAVE_CG) && !defined(OPENGLES) _cg_context = 0; #endif @@ -11784,13 +11789,48 @@ set_state_and_transform(const RenderState *target, void CLP(GraphicsStateGuardian):: free_pointers() { #if defined(HAVE_CG) && !defined(OPENGLES) - if (_cg_context != 0) { - cgDestroyContext(_cg_context); - _cg_context = 0; + if (_cg_context) { + _destroyed_cg_contexts.push_back(_cg_context); + _cg_context = nullptr; + + // Don't destroy the Cg context until the last GSG that uses Cg has been + // destroyed. This works around a Cg bug, see #1117. + if (!AtomicAdjust::dec(_num_gsgs_with_cg_contexts)) { + for (CGcontext context : _destroyed_cg_contexts) { + cgDestroyContext(context); + } + _destroyed_cg_contexts.clear(); + } } #endif } +/** + * Returns a Cg context for this GSG. + */ +#if defined(HAVE_CG) && !defined(OPENGLES) +CGcontext CLP(GraphicsStateGuardian):: +get_cg_context() { + CGcontext context = _cg_context; + if (context == nullptr) { + context = cgCreateContext(); + +#if CG_VERSION_NUM >= 3100 + // This just sounds like a good thing to do. + cgGLSetContextGLSLVersion(context, cgGLDetectGLSLVersion()); + if (_shader_caps._active_vprofile == CG_PROFILE_GLSLV) { + cgGLSetContextOptimalOptions(context, CG_PROFILE_GLSLC); + } +#endif + + AtomicAdjust::inc(_num_gsgs_with_cg_contexts); + _cg_context = context; + } + + return context; +} +#endif + /** * This is called by set_state_and_transform() when the texture state has * changed. diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index 4a56f6beda..7f0814041c 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -510,6 +510,10 @@ protected: virtual void free_pointers(); +#if defined(HAVE_CG) && !defined(OPENGLES) + CGcontext get_cg_context(); +#endif + #ifndef OPENGLES_1 INLINE void enable_vertex_attrib_array(GLuint index); INLINE void disable_vertex_attrib_array(GLuint index); @@ -693,8 +697,10 @@ protected: GLfloat _max_line_width; -#ifdef HAVE_CG +#if defined(HAVE_CG) && !defined(OPENGLES) CGcontext _cg_context; + static AtomicAdjust::Integer _num_gsgs_with_cg_contexts; + static pvector _destroyed_cg_contexts; #endif #ifdef SUPPORT_IMMEDIATE_MODE diff --git a/panda/src/gobj/geomPrimitive.cxx b/panda/src/gobj/geomPrimitive.cxx index 6529de2f80..ca51d95079 100644 --- a/panda/src/gobj/geomPrimitive.cxx +++ b/panda/src/gobj/geomPrimitive.cxx @@ -442,18 +442,50 @@ offset_vertices(int offset) { consider_elevate_index_type(cdata, cdata->_max_vertex + offset); - int strip_cut_index = get_strip_cut_index(cdata->_index_type); + { + GeomVertexArrayDataHandle handle(cdata->_vertices.get_write_pointer(), + Thread::get_current_thread()); - GeomVertexRewriter index(do_modify_vertices(cdata), 0); - while (!index.is_at_end()) { - int vertex = index.get_data1i(); + size_t num_rows = (size_t)handle.get_num_rows(); + unsigned char *ptr = handle.get_write_pointer(); + switch (cdata->_index_type) { + case GeomEnums::NT_uint8: + for (size_t i = 0; i < num_rows; ++i) { + uint8_t &v = ((uint8_t *)ptr)[i]; + if (v != 0xff) { + v += offset; + } + } + break; - if (vertex != strip_cut_index) { - index.set_data1i(vertex + offset); + case GeomEnums::NT_uint16: + for (size_t i = 0; i < num_rows; ++i) { + uint16_t &v = ((uint16_t *)ptr)[i]; + if (v != 0xffff) { + v += offset; + } + } + break; + + case GeomEnums::NT_uint32: + for (size_t i = 0; i < num_rows; ++i) { + uint32_t &v = ((uint32_t *)ptr)[i]; + if (v != 0xffffffff) { + v += offset; + } + } + break; + + default: + nassert_raise("unsupported index type"); + break; } } - } else { + cdata->_modified = Geom::get_next_modified(); + cdata->_got_minmax = false; + } + else { CDWriter cdata(_cycler, true); cdata->_first_vertex += offset; diff --git a/panda/src/physics/physical.h b/panda/src/physics/physical.h index fd3b9c343a..c101376a38 100644 --- a/panda/src/physics/physical.h +++ b/panda/src/physics/physical.h @@ -64,14 +64,18 @@ PUBLISHED: INLINE int get_num_linear_forces() const; INLINE PT(LinearForce) get_linear_force(int index) const; MAKE_SEQ(get_linear_forces, get_num_linear_forces, get_linear_force); + MAKE_SEQ_PROPERTY(linear_forces, get_num_linear_forces, get_linear_force); INLINE int get_num_angular_forces() const; INLINE PT(AngularForce) get_angular_force(int index) const; MAKE_SEQ(get_angular_forces, get_num_angular_forces, get_angular_force); + MAKE_SEQ_PROPERTY(angular_forces, get_num_angular_forces, get_angular_force); INLINE void set_viscosity(PN_stdfloat viscosity); INLINE PN_stdfloat get_viscosity() const; + MAKE_PROPERTY(viscosity, get_viscosity); const PhysicsObjectCollection get_objects() const; + MAKE_PROPERTY(objects, get_objects); virtual void output(std::ostream &out = std::cout) const; virtual void write_physics_objects( diff --git a/panda/src/physics/physicalNode.I b/panda/src/physics/physicalNode.I index 407cf52f5a..d4d7e6c879 100644 --- a/panda/src/physics/physicalNode.I +++ b/panda/src/physics/physicalNode.I @@ -16,12 +16,11 @@ */ INLINE void PhysicalNode:: clear() { - PhysicalsVector::iterator it; - for (it = _physicals.begin(); it != _physicals.end(); ++it) { - nassertd((*it)->_physical_node == this) continue; - (*it)->_physical_node = nullptr; + for (Physical *physical : _physicals) { + nassertd(physical->_physical_node == this) continue; + physical->_physical_node = nullptr; } - _physicals.erase(_physicals.begin(), _physicals.end()); + _physicals.clear(); } /** @@ -42,10 +41,14 @@ get_num_physicals() const { } /** - + * Adds a Physical to this PhysicalNode. If it is already added to this node, + * does nothing. It is an error to add a Physical to multiple PhysicalNodes. */ INLINE void PhysicalNode:: add_physical(Physical *physical) { - _physicals.push_back(physical); - physical->_physical_node = this; + if (physical->_physical_node != this) { + nassertv(physical->_physical_node == nullptr); + _physicals.push_back(physical); + physical->_physical_node = this; + } } diff --git a/panda/src/physics/physicalNode.cxx b/panda/src/physics/physicalNode.cxx index 0fcabeeb8a..18858b6201 100644 --- a/panda/src/physics/physicalNode.cxx +++ b/panda/src/physics/physicalNode.cxx @@ -14,7 +14,11 @@ #include "physicalNode.h" #include "physicsManager.h" +#include + // static stuff. +static std::atomic_flag warned_copy_physical_node = ATOMIC_FLAG_INIT; + TypeHandle PhysicalNode::_type_handle; /** @@ -39,13 +43,12 @@ PhysicalNode(const PhysicalNode ©) : */ PhysicalNode:: ~PhysicalNode() { - PhysicalsVector::iterator it; - for (it = _physicals.begin(); it != _physicals.end(); ++it) { - Physical *physical = *it; - nassertd(physical->_physical_node == this) continue; - physical->_physical_node = nullptr; - if (physical->_physics_manager != nullptr) { - physical->_physics_manager->remove_physical(physical); + for (Physical *physical : _physicals) { + if (physical->_physical_node == this) { + physical->_physical_node = nullptr; + if (physical->_physics_manager != nullptr) { + physical->_physics_manager->remove_physical(physical); + } } } } @@ -55,6 +58,12 @@ PhysicalNode:: */ PandaNode *PhysicalNode:: make_copy() const { + if (!_physicals.empty() && !warned_copy_physical_node.test_and_set()) { + // This is a problem, because a Physical can only be on one PhysicalNode. + //FIXME: Figure out a solution. + physics_cat.warning() + << "Detected attempt to copy PhysicalNode object with physicals.\n"; + } return new PhysicalNode(*this); } @@ -63,13 +72,12 @@ make_copy() const { */ void PhysicalNode:: add_physicals_from(const PhysicalNode &other) { - pvector< PT(Physical) >::iterator last = _physicals.end() - 1; - + size_t num_physicals = _physicals.size(); _physicals.insert(_physicals.end(), other._physicals.begin(), other._physicals.end()); - for (; last != _physicals.end(); last++) { - (*last)->_physical_node = this; + for (size_t i = num_physicals; i < _physicals.size(); ++i) { + _physicals[i]->_physical_node = this; } } diff --git a/panda/src/physics/physicsObject.h b/panda/src/physics/physicsObject.h index a5b8c8897f..851430b1c5 100644 --- a/panda/src/physics/physicsObject.h +++ b/panda/src/physics/physicsObject.h @@ -99,6 +99,18 @@ PUBLISHED: virtual void output(std::ostream &out) const; virtual void write(std::ostream &out, int indent=0) const; +PUBLISHED: + MAKE_PROPERTY(active, get_active, set_active); + MAKE_PROPERTY(mass, get_mass, set_mass); + MAKE_PROPERTY(position, get_position, set_position); + MAKE_PROPERTY(last_position, get_last_position, set_last_position); + MAKE_PROPERTY(velocity, get_velocity, set_velocity); + MAKE_PROPERTY(implicit_velocity, get_implicit_velocity); + MAKE_PROPERTY(terminal_velocity, get_terminal_velocity, set_terminal_velocity); + MAKE_PROPERTY(oriented, get_oriented, set_oriented); + MAKE_PROPERTY(orientation, get_orientation, set_orientation); + MAKE_PROPERTY(rotation, get_rotation, set_rotation); + private: // physical LPoint3 _position; // aka _center_of_mass