Merge branch 'release/1.10.x'

This commit is contained in:
rdb 2020-11-17 23:56:00 +01:00
commit d62146a317
12 changed files with 67 additions and 38 deletions

View File

@ -15,7 +15,6 @@ This is a list of all the people who are contributing financially to Panda3D. I
* [Mitchell Stokes](https://opencollective.com/mitchell-stokes) * [Mitchell Stokes](https://opencollective.com/mitchell-stokes)
* [Daniel Stokes](https://opencollective.com/daniel-stokes) * [Daniel Stokes](https://opencollective.com/daniel-stokes)
* [David Rose](https://opencollective.com/david-rose) * [David Rose](https://opencollective.com/david-rose)
* [Carnetsoft](https://cs-driving-simulator.com/)
## Benefactors ## Benefactors
@ -23,14 +22,14 @@ This is a list of all the people who are contributing financially to Panda3D. I
* Sam Edwards * Sam Edwards
* Max Voss * Max Voss
* Will Nielsen
## Enthusiasts ## Enthusiasts
![Benefactors](https://opencollective.com/panda3d/tiers/enthusiast.svg?avatarHeight=48&width=600) ![Enthusiasts](https://opencollective.com/panda3d/tiers/enthusiast.svg?avatarHeight=48&width=600)
* Eric Thomson * Eric Thomson
* Kyle Roach * Kyle Roach
* Brian Lach
## Backers ## Backers

View File

@ -242,7 +242,11 @@ class VersionInfoResource(object):
length, value_length = unpack('<HH', data[0:4]) length, value_length = unpack('<HH', data[0:4])
offset = 40 + value_length + (value_length & 1) offset = 40 + value_length + (value_length & 1)
dwords = array('I') dwords = array('I')
if sys.version_info >= (3, 2):
dwords.frombytes(bytes(data[40:offset]))
else:
dwords.fromstring(bytes(data[40:offset])) dwords.fromstring(bytes(data[40:offset]))
if len(dwords) > 0: if len(dwords) > 0:
self.signature = dwords[0] self.signature = dwords[0]
if len(dwords) > 1: if len(dwords) > 1:

View File

@ -192,21 +192,21 @@ class Loader(DirectObject):
pathname), the return value will be a NodePath to the model pathname), the return value will be a NodePath to the model
loaded if the load was successful, or None otherwise. If the loaded if the load was successful, or None otherwise. If the
input modelPath is a list of pathnames, the return value will input modelPath is a list of pathnames, the return value will
be a list of NodePaths and/or Nones. be a list of `.NodePath` objects and/or Nones.
loaderOptions may optionally be passed in to control details loaderOptions may optionally be passed in to control details
about the way the model is searched and loaded. See the about the way the model is searched and loaded. See the
LoaderOptions class for more. `.LoaderOptions` class for more.
The default is to look in the ModelPool (RAM) cache first, and The default is to look in the `.ModelPool` (RAM) cache first,
return a copy from that if the model can be found there. If and return a copy from that if the model can be found there.
the bam cache is enabled (via the model-cache-dir config If the bam cache is enabled (via the `model-cache-dir` config
variable), then that will be consulted next, and if both variable), then that will be consulted next, and if both
caches fail, the file will be loaded from disk. If noCache is caches fail, the file will be loaded from disk. If noCache is
True, then neither cache will be consulted or updated. True, then neither cache will be consulted or updated.
If allowInstance is True, a shared instance may be returned If allowInstance is True, a shared instance may be returned
from the ModelPool. This is dangerous, since it is easy to from the `.ModelPool`. This is dangerous, since it is easy to
accidentally modify the shared instance, and invalidate future accidentally modify the shared instance, and invalidate future
load attempts of the same model. Normally, you should leave load attempts of the same model. Normally, you should leave
allowInstance set to False, which will always return a unique allowInstance set to False, which will always return a unique
@ -214,10 +214,10 @@ class Loader(DirectObject):
If okMissing is True, None is returned if the model is not If okMissing is True, None is returned if the model is not
found or cannot be read, and no error message is printed. found or cannot be read, and no error message is printed.
Otherwise, an IOError is raised if the model is not found or Otherwise, an `IOError` is raised if the model is not found or
cannot be read (similar to attempting to open a nonexistent cannot be read (similar to attempting to open a nonexistent
file). (If modelPath is a list of filenames, then IOError is file). (If modelPath is a list of filenames, then `IOError`
raised if *any* of the models could not be loaded.) is raised if *any* of the models could not be loaded.)
If callback is not None, then the model load will be performed If callback is not None, then the model load will be performed
asynchronously. In this case, loadModel() will initiate a asynchronously. In this case, loadModel() will initiate a
@ -235,7 +235,7 @@ class Loader(DirectObject):
True asynchronous model loading requires Panda to have been True asynchronous model loading requires Panda to have been
compiled with threading support enabled (you can test compiled with threading support enabled (you can test
Thread.isThreadingSupported()). In the absence of threading `.Thread.isThreadingSupported()`). In the absence of threading
support, the asynchronous interface still exists and still support, the asynchronous interface still exists and still
behaves exactly as described, except that loadModel() might behaves exactly as described, except that loadModel() might
not return immediately. not return immediately.
@ -420,7 +420,7 @@ class Loader(DirectObject):
def saveModel(self, modelPath, node, loaderOptions = None, def saveModel(self, modelPath, node, loaderOptions = None,
callback = None, extraArgs = [], priority = None, callback = None, extraArgs = [], priority = None,
blocking = None): blocking = None):
""" Saves the model (a NodePath or PandaNode) to the indicated """ Saves the model (a `NodePath` or `PandaNode`) to the indicated
filename path. Returns true on success, false on failure. If filename path. Returns true on success, false on failure. If
a callback is used, the model is saved asynchronously, and the a callback is used, the model is saved asynchronously, and the
true/false status is passed to the callback function. """ true/false status is passed to the callback function. """
@ -508,8 +508,8 @@ class Loader(DirectObject):
""" """
modelPath is a string. modelPath is a string.
This loads a special model as a TextFont object, for rendering This loads a special model as a `TextFont` object, for rendering
text with a TextNode. A font file must be either a special text with a `TextNode`. A font file must be either a special
egg file (or bam file) generated with egg-mkfont, which is egg file (or bam file) generated with egg-mkfont, which is
considered a static font, or a standard font file (like a TTF considered a static font, or a standard font file (like a TTF
file) that is supported by FreeType, which is considered a file) that is supported by FreeType, which is considered a
@ -573,7 +573,7 @@ class Loader(DirectObject):
If color is not None, it should be a VBase4 specifying the If color is not None, it should be a VBase4 specifying the
foreground color of the font. Specifying this option breaks foreground color of the font. Specifying this option breaks
TextNode.setColor(), so you almost never want to use this `TextNode.setColor()`, so you almost never want to use this
option; the default (white) is the most appropriate for a option; the default (white) is the most appropriate for a
font, as it allows text to have any arbitrary color assigned font, as it allows text to have any arbitrary color assigned
at generation time. However, if you want to use a colored at generation time. However, if you want to use a colored
@ -695,7 +695,8 @@ class Loader(DirectObject):
texturePath is a string. texturePath is a string.
Attempt to load a texture from the given file path using Attempt to load a texture from the given file path using
TexturePool class. `TexturePool` class. Returns a `Texture` object, or raises
`IOError` if the file could not be loaded.
okMissing should be True to indicate the method should return okMissing should be True to indicate the method should return
None if the texture file is not found. If it is False, the None if the texture file is not found. If it is False, the
@ -713,17 +714,17 @@ class Loader(DirectObject):
the texture and the number of expected mipmap images. the texture and the number of expected mipmap images.
If minfilter or magfilter is not None, they should be a symbol If minfilter or magfilter is not None, they should be a symbol
like SamplerState.FTLinear or SamplerState.FTNearest. (minfilter like `SamplerState.FTLinear` or `SamplerState.FTNearest`.
may be further one of the Mipmap filter type symbols.) These (minfilter may be further one of the Mipmap filter type symbols.)
specify the filter mode that will automatically be applied to These specify the filter mode that will automatically be applied
the texture when it is loaded. Note that this setting may to the texture when it is loaded. Note that this setting may
override the texture's existing settings, even if it has override the texture's existing settings, even if it has
already been loaded. See egg-texture-cards for a more robust already been loaded. See `egg-texture-cards` for a more robust
way to apply per-texture filter types and settings. way to apply per-texture filter types and settings.
If anisotropicDegree is not None, it specifies the anisotropic degree If anisotropicDegree is not None, it specifies the anisotropic degree
to apply to the texture when it is loaded. Like minfilter and to apply to the texture when it is loaded. Like minfilter and
magfilter, egg-texture-cards may be a more robust way to apply magfilter, `egg-texture-cards` may be a more robust way to apply
this setting. this setting.
If multiview is true, it indicates to load a multiview or If multiview is true, it indicates to load a multiview or
@ -769,7 +770,7 @@ class Loader(DirectObject):
""" """
texturePattern is a string that contains a sequence of one or texturePattern is a string that contains a sequence of one or
more hash characters ('#'), which will be filled in with the more hash characters ('#'), which will be filled in with the
z-height number. Returns a 3-D Texture object, suitable for z-height number. Returns a 3-D `Texture` object, suitable for
rendering volumetric textures. rendering volumetric textures.
okMissing should be True to indicate the method should return okMissing should be True to indicate the method should return
@ -826,7 +827,7 @@ class Loader(DirectObject):
""" """
texturePattern is a string that contains a sequence of one or texturePattern is a string that contains a sequence of one or
more hash characters ('#'), which will be filled in with the more hash characters ('#'), which will be filled in with the
z-height number. Returns a 2-D Texture array object, suitable z-height number. Returns a 2-D `Texture` array object, suitable
for rendering array of textures. for rendering array of textures.
okMissing should be True to indicate the method should return okMissing should be True to indicate the method should return
@ -884,7 +885,7 @@ class Loader(DirectObject):
texturePattern is a string that contains a sequence of one or texturePattern is a string that contains a sequence of one or
more hash characters ('#'), which will be filled in with the more hash characters ('#'), which will be filled in with the
face index number (0 through 6). Returns a six-face cube map face index number (0 through 6). Returns a six-face cube map
Texture object. `Texture` object.
okMissing should be True to indicate the method should return okMissing should be True to indicate the method should return
None if the texture file is not found. If it is False, the None if the texture file is not found. If it is False, the
@ -951,8 +952,8 @@ class Loader(DirectObject):
"""Loads one or more sound files, specifically designated as a """Loads one or more sound files, specifically designated as a
"sound effect" file (that is, uses the sfxManager to load the "sound effect" file (that is, uses the sfxManager to load the
sound). There is no distinction between sound effect files sound). There is no distinction between sound effect files
and music files other than the particular AudioManager used to and music files other than the particular `AudioManager` used
load the sound file, but this distinction allows the sound to load the sound file, but this distinction allows the sound
effects and/or the music files to be adjusted as a group, effects and/or the music files to be adjusted as a group,
independently of the other group.""" independently of the other group."""
@ -965,8 +966,8 @@ class Loader(DirectObject):
"""Loads one or more sound files, specifically designated as a """Loads one or more sound files, specifically designated as a
"music" file (that is, uses the musicManager to load the "music" file (that is, uses the musicManager to load the
sound). There is no distinction between sound effect files sound). There is no distinction between sound effect files
and music files other than the particular AudioManager used to and music files other than the particular `AudioManager` used
load the sound file, but this distinction allows the sound to load the sound file, but this distinction allows the sound
effects and/or the music files to be adjusted as a group, effects and/or the music files to be adjusted as a group,
independently of the other group.""" independently of the other group."""
if(self.base.musicManager): if(self.base.musicManager):
@ -1052,7 +1053,7 @@ class Loader(DirectObject):
callback = None, extraArgs = []): callback = None, extraArgs = []):
""" Performs a model.flattenStrong() operation in a sub-thread """ Performs a model.flattenStrong() operation in a sub-thread
(if threading is compiled into Panda). The model may be a (if threading is compiled into Panda). The model may be a
single NodePath, or it may be a list of NodePaths. single `.NodePath`, or it may be a list of NodePaths.
Each model is duplicated and flattened in the sub-thread. Each model is duplicated and flattened in the sub-thread.

View File

@ -152,6 +152,7 @@ class ShowBase(DirectObject.DirectObject):
self.wantStats = self.config.GetBool('want-pstats', 0) self.wantStats = self.config.GetBool('want-pstats', 0)
self.wantTk = False self.wantTk = False
self.wantWx = False self.wantWx = False
self.wantDirect = False
#: Fill this in with a function to invoke when the user "exits" #: Fill this in with a function to invoke when the user "exits"
#: the program by closing the main window. #: the program by closing the main window.
@ -3264,7 +3265,12 @@ class ShowBase(DirectObject.DirectObject):
def startDirect(self, fWantDirect = 1, fWantTk = 1, fWantWx = 0): def startDirect(self, fWantDirect = 1, fWantTk = 1, fWantWx = 0):
self.startTk(fWantTk) self.startTk(fWantTk)
self.startWx(fWantWx) self.startWx(fWantWx)
if self.wantDirect == fWantDirect:
return
self.wantDirect = fWantDirect self.wantDirect = fWantDirect
if self.wantDirect: if self.wantDirect:
# Use importlib to prevent this import from being picked up # Use importlib to prevent this import from being picked up
# by modulefinder when packaging an application. # by modulefinder when packaging an application.

View File

@ -62,7 +62,7 @@ PUBLISHED:
void clear_colliders(); void clear_colliders();
MAKE_SEQ_PROPERTY(colliders, get_num_colliders, get_collider); MAKE_SEQ_PROPERTY(colliders, get_num_colliders, get_collider);
void traverse(const NodePath &root); BLOCKING void traverse(const NodePath &root);
#if defined(DO_COLLISION_RECORDING) || !defined(CPPPARSER) #if defined(DO_COLLISION_RECORDING) || !defined(CPPPARSER)
void set_recorder(CollisionRecorder *recorder); void set_recorder(CollisionRecorder *recorder);

View File

@ -123,7 +123,8 @@ munge_data_impl(const GeomVertexData *data) {
} }
GeomVertexAnimationSpec animation = new_data->get_format()->get_animation(); GeomVertexAnimationSpec animation = new_data->get_format()->get_animation();
if (_shader_skinning || (_auto_shader && hardware_animated_vertices && if ((_shader_skinning && animation.get_animation_type() != AT_none) ||
(_auto_shader && hardware_animated_vertices &&
!basic_shaders_only && animation.get_animation_type() == AT_panda)) { !basic_shaders_only && animation.get_animation_type() == AT_panda)) {
animation.set_hardware(4, true); animation.set_hardware(4, true);

View File

@ -1920,6 +1920,8 @@ reset() {
get_extension_func("glUniform3uiv"); get_extension_func("glUniform3uiv");
_glUniform4uiv = (PFNGLUNIFORM4UIVPROC) _glUniform4uiv = (PFNGLUNIFORM4UIVPROC)
get_extension_func("glUniform4uiv"); get_extension_func("glUniform4uiv");
_glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC)
get_extension_func("glVertexAttribI4ui");
} else if (has_extension("GL_EXT_gpu_shader4")) { } else if (has_extension("GL_EXT_gpu_shader4")) {
_glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC) _glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC)
@ -1934,10 +1936,13 @@ reset() {
get_extension_func("glUniform3uivEXT"); get_extension_func("glUniform3uivEXT");
_glUniform4uiv = (PFNGLUNIFORM4UIVPROC) _glUniform4uiv = (PFNGLUNIFORM4UIVPROC)
get_extension_func("glUniform4uivEXT"); get_extension_func("glUniform4uivEXT");
_glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC)
get_extension_func("glVertexAttribI4uiEXT");
} else { } else {
_glBindFragDataLocation = nullptr; _glBindFragDataLocation = nullptr;
_glVertexAttribIPointer = nullptr; _glVertexAttribIPointer = nullptr;
_glVertexAttribI4ui = nullptr;
} }
if (is_at_least_gl_version(4, 1) || if (is_at_least_gl_version(4, 1) ||
has_extension("GL_ARB_vertex_attrib_64bit")) { has_extension("GL_ARB_vertex_attrib_64bit")) {
@ -1966,8 +1971,11 @@ reset() {
get_extension_func("glVertexAttribPointerARB"); get_extension_func("glVertexAttribPointerARB");
_glBindFragDataLocation = nullptr; _glBindFragDataLocation = nullptr;
_glVertexAttribI4ui = nullptr;
_glVertexAttribIPointer = nullptr; _glVertexAttribIPointer = nullptr;
_glVertexAttribLPointer = nullptr; _glVertexAttribLPointer = nullptr;
} else {
_glVertexAttribI4ui = nullptr;
} }
#endif #endif
@ -2014,8 +2022,11 @@ reset() {
if (is_at_least_gles_version(3, 0)) { if (is_at_least_gles_version(3, 0)) {
_glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC) _glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)
get_extension_func("glVertexAttribIPointer"); get_extension_func("glVertexAttribIPointer");
_glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC)
get_extension_func("glVertexAttribI4ui");
} else { } else {
_glVertexAttribIPointer = nullptr; _glVertexAttribIPointer = nullptr;
_glVertexAttribI4ui = nullptr;
} }
if (has_extension("GL_EXT_blend_func_extended")) { if (has_extension("GL_EXT_blend_func_extended")) {

View File

@ -186,6 +186,7 @@ typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei coun
typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program); typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program);
typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v);
typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble *v);
typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
typedef void (APIENTRYP PFNGLVERTEXATTRIBLPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNGLVERTEXATTRIBLPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
@ -1015,6 +1016,7 @@ public:
PFNGLVALIDATEPROGRAMPROC _glValidateProgram; PFNGLVALIDATEPROGRAMPROC _glValidateProgram;
PFNGLVERTEXATTRIB4FVPROC _glVertexAttrib4fv; PFNGLVERTEXATTRIB4FVPROC _glVertexAttrib4fv;
PFNGLVERTEXATTRIB4DVPROC _glVertexAttrib4dv; PFNGLVERTEXATTRIB4DVPROC _glVertexAttrib4dv;
PFNGLVERTEXATTRIBI4UIPROC _glVertexAttribI4ui;
PFNGLVERTEXATTRIBPOINTERPROC _glVertexAttribPointer; PFNGLVERTEXATTRIBPOINTERPROC _glVertexAttribPointer;
PFNGLVERTEXATTRIBIPOINTERPROC _glVertexAttribIPointer; PFNGLVERTEXATTRIBIPOINTERPROC _glVertexAttribIPointer;
PFNGLVERTEXATTRIBLPOINTERPROC _glVertexAttribLPointer; PFNGLVERTEXATTRIBLPOINTERPROC _glVertexAttribLPointer;

View File

@ -2461,6 +2461,10 @@ update_shader_vertex_arrays(ShaderContext *prev, bool force) {
_glgsg->_glVertexAttrib4fv(p, _glgsg->_scene_graph_color.get_data()); _glgsg->_glVertexAttrib4fv(p, _glgsg->_scene_graph_color.get_data());
#endif #endif
} }
else if (name == InternalName::get_transform_index() &&
_glgsg->_glVertexAttribI4ui != nullptr) {
_glgsg->_glVertexAttribI4ui(p, 0, 1, 2, 3);
}
} }
} }

View File

@ -659,7 +659,7 @@ copy_from(const GeomVertexData *source, bool keep_data_objects,
for (size_t i = 0; i < blend.get_num_transforms(); i++) { for (size_t i = 0; i < blend.get_num_transforms(); i++) {
int index = add_transform(transform_table, blend.get_transform(i), int index = add_transform(transform_table, blend.get_transform(i),
already_added); already_added);
nassertv(index <= 4); nassertv(index < 4);
weights[index] = blend.get_weight(i); weights[index] = blend.get_weight(i);
} }
if (weight.has_column()) { if (weight.has_column()) {

View File

@ -54,7 +54,7 @@ operator = (const MatrixLens &copy) {
* Explicitly specifies the projection matrix. This matrix should convert X * Explicitly specifies the projection matrix. This matrix should convert X
* and Y to the range [-film_size/2, film_size/2], where (-fs/2,-fs/2) is the * and Y to the range [-film_size/2, film_size/2], where (-fs/2,-fs/2) is the
* lower left corner of the screen and (fs/2, fs/2) is the upper right. Z * lower left corner of the screen and (fs/2, fs/2) is the upper right. Z
* should go to the range [-1, 1], where -1 is the far plane and 1 is the near * should go to the range [-1, 1], where -1 is the near plane and 1 is the far
* plane. Note that this is a left-handed Y-up coordinate system. * plane. Note that this is a left-handed Y-up coordinate system.
* *
* The default film_size for a MatrixLens is 2, so the default range is [-1, * The default film_size for a MatrixLens is 2, so the default range is [-1,

View File

@ -17,6 +17,7 @@ classifiers =
Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: Implementation :: CPython Programming Language :: Python :: Implementation :: CPython
Topic :: Games/Entertainment Topic :: Games/Entertainment
Topic :: Multimedia Topic :: Multimedia