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)
* [Daniel Stokes](https://opencollective.com/daniel-stokes)
* [David Rose](https://opencollective.com/david-rose)
* [Carnetsoft](https://cs-driving-simulator.com/)
## Benefactors
@ -23,14 +22,14 @@ This is a list of all the people who are contributing financially to Panda3D. I
* Sam Edwards
* Max Voss
* Will Nielsen
## 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
* Kyle Roach
* Brian Lach
## Backers

View File

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

View File

@ -192,21 +192,21 @@ class Loader(DirectObject):
pathname), the return value will be a NodePath to the model
loaded if the load was successful, or None otherwise. If the
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
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
return a copy from that if the model can be found there. If
the bam cache is enabled (via the model-cache-dir config
The default is to look in the `.ModelPool` (RAM) cache first,
and return a copy from that if the model can be found there.
If the bam cache is enabled (via the `model-cache-dir` config
variable), then that will be consulted next, and if both
caches fail, the file will be loaded from disk. If noCache is
True, then neither cache will be consulted or updated.
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
load attempts of the same model. Normally, you should leave
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
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
file). (If modelPath is a list of filenames, then IOError is
raised if *any* of the models could not be loaded.)
file). (If modelPath is a list of filenames, then `IOError`
is raised if *any* of the models could not be loaded.)
If callback is not None, then the model load will be performed
asynchronously. In this case, loadModel() will initiate a
@ -235,7 +235,7 @@ class Loader(DirectObject):
True asynchronous model loading requires Panda to have been
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
behaves exactly as described, except that loadModel() might
not return immediately.
@ -420,7 +420,7 @@ class Loader(DirectObject):
def saveModel(self, modelPath, node, loaderOptions = None,
callback = None, extraArgs = [], priority = 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
a callback is used, the model is saved asynchronously, and the
true/false status is passed to the callback function. """
@ -508,8 +508,8 @@ class Loader(DirectObject):
"""
modelPath is a string.
This loads a special model as a TextFont object, for rendering
text with a TextNode. A font file must be either a special
This loads a special model as a `TextFont` object, for rendering
text with a `TextNode`. A font file must be either a special
egg file (or bam file) generated with egg-mkfont, which is
considered a static font, or a standard font file (like a TTF
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
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
font, as it allows text to have any arbitrary color assigned
at generation time. However, if you want to use a colored
@ -695,7 +695,8 @@ class Loader(DirectObject):
texturePath is a string.
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
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.
If minfilter or magfilter is not None, they should be a symbol
like SamplerState.FTLinear or SamplerState.FTNearest. (minfilter
may be further one of the Mipmap filter type symbols.) These
specify the filter mode that will automatically be applied to
the texture when it is loaded. Note that this setting may
like `SamplerState.FTLinear` or `SamplerState.FTNearest`.
(minfilter may be further one of the Mipmap filter type symbols.)
These specify the filter mode that will automatically be applied
to the texture when it is loaded. Note that this setting may
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.
If anisotropicDegree is not None, it specifies the anisotropic degree
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.
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
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.
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
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.
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
more hash characters ('#'), which will be filled in with the
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
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
"sound effect" file (that is, uses the sfxManager to load the
sound). There is no distinction between sound effect files
and music files other than the particular AudioManager used to
load the sound file, but this distinction allows the sound
and music files other than the particular `AudioManager` used
to load the sound file, but this distinction allows the sound
effects and/or the music files to be adjusted as a group,
independently of the other group."""
@ -965,8 +966,8 @@ class Loader(DirectObject):
"""Loads one or more sound files, specifically designated as a
"music" file (that is, uses the musicManager to load the
sound). There is no distinction between sound effect files
and music files other than the particular AudioManager used to
load the sound file, but this distinction allows the sound
and music files other than the particular `AudioManager` used
to load the sound file, but this distinction allows the sound
effects and/or the music files to be adjusted as a group,
independently of the other group."""
if(self.base.musicManager):
@ -1052,7 +1053,7 @@ class Loader(DirectObject):
callback = None, extraArgs = []):
""" Performs a model.flattenStrong() operation in a sub-thread
(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.

View File

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

View File

@ -62,7 +62,7 @@ PUBLISHED:
void clear_colliders();
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)
void set_recorder(CollisionRecorder *recorder);

View File

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

View File

@ -1920,6 +1920,8 @@ reset() {
get_extension_func("glUniform3uiv");
_glUniform4uiv = (PFNGLUNIFORM4UIVPROC)
get_extension_func("glUniform4uiv");
_glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC)
get_extension_func("glVertexAttribI4ui");
} else if (has_extension("GL_EXT_gpu_shader4")) {
_glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC)
@ -1934,10 +1936,13 @@ reset() {
get_extension_func("glUniform3uivEXT");
_glUniform4uiv = (PFNGLUNIFORM4UIVPROC)
get_extension_func("glUniform4uivEXT");
_glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC)
get_extension_func("glVertexAttribI4uiEXT");
} else {
_glBindFragDataLocation = nullptr;
_glVertexAttribIPointer = nullptr;
_glVertexAttribI4ui = nullptr;
}
if (is_at_least_gl_version(4, 1) ||
has_extension("GL_ARB_vertex_attrib_64bit")) {
@ -1966,8 +1971,11 @@ reset() {
get_extension_func("glVertexAttribPointerARB");
_glBindFragDataLocation = nullptr;
_glVertexAttribI4ui = nullptr;
_glVertexAttribIPointer = nullptr;
_glVertexAttribLPointer = nullptr;
} else {
_glVertexAttribI4ui = nullptr;
}
#endif
@ -2014,8 +2022,11 @@ reset() {
if (is_at_least_gles_version(3, 0)) {
_glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)
get_extension_func("glVertexAttribIPointer");
_glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC)
get_extension_func("glVertexAttribI4ui");
} else {
_glVertexAttribIPointer = nullptr;
_glVertexAttribI4ui = nullptr;
}
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 PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *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 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);
@ -1015,6 +1016,7 @@ public:
PFNGLVALIDATEPROGRAMPROC _glValidateProgram;
PFNGLVERTEXATTRIB4FVPROC _glVertexAttrib4fv;
PFNGLVERTEXATTRIB4DVPROC _glVertexAttrib4dv;
PFNGLVERTEXATTRIBI4UIPROC _glVertexAttribI4ui;
PFNGLVERTEXATTRIBPOINTERPROC _glVertexAttribPointer;
PFNGLVERTEXATTRIBIPOINTERPROC _glVertexAttribIPointer;
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());
#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++) {
int index = add_transform(transform_table, blend.get_transform(i),
already_added);
nassertv(index <= 4);
nassertv(index < 4);
weights[index] = blend.get_weight(i);
}
if (weight.has_column()) {

View File

@ -54,7 +54,7 @@ operator = (const MatrixLens &copy) {
* 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
* 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.
*
* 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.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: Implementation :: CPython
Topic :: Games/Entertainment
Topic :: Multimedia