Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
551b8a2aba
|
|
@ -34,6 +34,7 @@ This is a list of all the people who are contributing financially to Panda3D. I
|
|||
* Kyle Roach
|
||||
* Brian Lach
|
||||
* C0MPU73R
|
||||
* Maxwell Dreytser
|
||||
|
||||
## Backers
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ Installing Panda3D
|
|||
==================
|
||||
|
||||
The latest Panda3D SDK can be downloaded from
|
||||
[this page](https://www.panda3d.org/download/sdk-1-10-9/).
|
||||
[this page](https://www.panda3d.org/download/sdk-1-10-10/).
|
||||
If you are familiar with installing Python packages, you can use
|
||||
the following command:
|
||||
|
||||
|
|
@ -64,8 +64,8 @@ depending on whether you are on a 32-bit or 64-bit system, or you can
|
|||
[click here](https://github.com/rdb/panda3d-thirdparty) for instructions on
|
||||
building them from source.
|
||||
|
||||
- https://www.panda3d.org/download/panda3d-1.10.9/panda3d-1.10.9-tools-win64.zip
|
||||
- https://www.panda3d.org/download/panda3d-1.10.9/panda3d-1.10.9-tools-win32.zip
|
||||
- https://www.panda3d.org/download/panda3d-1.10.10/panda3d-1.10.10-tools-win64.zip
|
||||
- https://www.panda3d.org/download/panda3d-1.10.10/panda3d-1.10.10-tools-win32.zip
|
||||
|
||||
After acquiring these dependencies, you can build Panda3D from the command
|
||||
prompt using the following command. Change the `--msvc-version` option based
|
||||
|
|
@ -136,7 +136,7 @@ macOS
|
|||
-----
|
||||
|
||||
On macOS, you will need to download a set of precompiled thirdparty packages in order to
|
||||
compile Panda3D, which can be acquired from [here](https://www.panda3d.org/download/panda3d-1.10.9/panda3d-1.10.9-tools-mac.tar.gz).
|
||||
compile Panda3D, which can be acquired from [here](https://www.panda3d.org/download/panda3d-1.10.10/panda3d-1.10.10-tools-mac.tar.gz).
|
||||
|
||||
After placing the thirdparty directory inside the panda3d source directory,
|
||||
you may build Panda3D using a command like the following:
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ class build_apps(setuptools.Command):
|
|||
self.exclude_modules = {}
|
||||
self.icons = {}
|
||||
self.platforms = [
|
||||
'manylinux1_x86_64',
|
||||
'manylinux2010_x86_64',
|
||||
'macosx_10_9_x86_64',
|
||||
'win_amd64',
|
||||
]
|
||||
|
|
@ -1330,6 +1330,8 @@ class bdist_apps(setuptools.Command):
|
|||
DEFAULT_INSTALLERS = {
|
||||
'manylinux1_x86_64': ['gztar'],
|
||||
'manylinux1_i686': ['gztar'],
|
||||
'manylinux2010_x86_64': ['gztar'],
|
||||
'manylinux2010_i686': ['gztar'],
|
||||
# Everything else defaults to ['zip']
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -367,6 +367,8 @@ class FilterManager(DirectObject):
|
|||
self.camstate = self.caminit
|
||||
self.camera.node().setInitialState(self.caminit)
|
||||
self.region.setCamera(self.camera)
|
||||
if hasattr(self.region, 'clearCullResult'):
|
||||
self.region.clearCullResult()
|
||||
self.nextsort = self.win.getSort() - 9
|
||||
self.basex = 0
|
||||
self.basey = 0
|
||||
|
|
|
|||
|
|
@ -1,3 +1,36 @@
|
|||
----------------------- RELEASE 1.10.10 -----------------------
|
||||
|
||||
This release fixes assorted, mostly very minor bugs.
|
||||
|
||||
* Round refresh rates when choosing display mode on macOS (#1144)
|
||||
* Vectors now support floor division
|
||||
* It is now possible to use round(), ceil() and floor() with vector types
|
||||
* Add RenderState::get_unused_states()
|
||||
* Fix assertion error in RenderState::get_num_unused_states()
|
||||
* Fix Assimp loader not importing normal vectors correctly (#1163)
|
||||
* Fix error when trying to render DirectGUI in offscreen mode (#1174)
|
||||
* Fix crash when resizing window in multi-window DirectX 9 application (#1167)
|
||||
* Fixes to enable compilation with recent OpenEXR and FFMpeg versions
|
||||
* Fix draw callback being called twice if cull callback calls upcall()
|
||||
* Improve error message when display module fails to load
|
||||
* Fix writing/reading BitArray to/from bam files on 64-bit systems (#1181)
|
||||
* evdev input devices (such as gamepads) are now supported in FreeBSD as well
|
||||
* Panda no longer tries to compress buffer textures when compression is enabled
|
||||
* Fix Geom::make_lines_in_place() (& points, patches) leaving invalid state
|
||||
* Fix memory leak when cleaning up FilterManager (#1166)
|
||||
* Fix memory leak deleting multisample OpenGL FBOs (#1166)
|
||||
* Fix auto-binding of SSBOs sometimes causing overlapping bindings (#1176)
|
||||
* PSSMCameraRig::update() now accepts a camera node directly
|
||||
* Support copying depth buffer for 32-bit depth with 8-bit stencil (#1142)
|
||||
* Prevent trying to copy depth from non-depth buffer in OpenGL renderer (#1142)
|
||||
* Fixes to format selection for OpenGL renderbuffers (#1137, #1141)
|
||||
* gl-depth-zero-to-one is now supported in OpenGL ES 2+ (if driver supports)
|
||||
* Maya models can contain more than three eggObjectTypes (#1134)
|
||||
* Fix black screen on Linux when switching fullscreen without a WM active
|
||||
* Fix Linux crash when trying to load a directory instead of a file (#1140)
|
||||
* Fix crash when loading an invalid font
|
||||
* Fix a very obscure unintended DirectGUI behavior change in 1.10.9
|
||||
|
||||
------------------------ RELEASE 1.10.9 -----------------------
|
||||
|
||||
This is a bugfix release which addresses some severe issues on macOS, as well as
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ List the scene graph hierarchy in the bam file.
|
|||
List explicitly each transition in the hierarchy.
|
||||
.TP
|
||||
.B \-g
|
||||
Output verbose information about the each Geom in the Bam file.
|
||||
Output verbose information about each Geom in the Bam file.
|
||||
.TP
|
||||
.B \-h
|
||||
Display this help page.
|
||||
|
|
|
|||
|
|
@ -371,7 +371,7 @@ static PyObject *Dtool_MutableSequenceWrapper_insert(PyObject *self, PyObject *a
|
|||
return PyErr_Format(PyExc_TypeError, "%s.insert() does not support negative indices", wrap->_base._name);
|
||||
}
|
||||
}
|
||||
return wrap->_insert_func(wrap->_base._self, (ssize_t)std::max(index, (Py_ssize_t)0), PyTuple_GET_ITEM(args, 1));
|
||||
return wrap->_insert_func(wrap->_base._self, (size_t)std::max(index, (Py_ssize_t)0), PyTuple_GET_ITEM(args, 1));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -38,8 +38,12 @@ def test_wheel(wheel, verbose=False):
|
|||
|
||||
# Install pytest into the environment, as well as our wheel.
|
||||
packages = ["pytest", wheel]
|
||||
if sys.version_info[0:2] == (3, 4) and sys.platform == "win32":
|
||||
packages += ["colorama==0.4.1"]
|
||||
if sys.version_info[0:2] == (3, 4):
|
||||
if sys.platform == "win32":
|
||||
packages += ["colorama==0.4.1"]
|
||||
|
||||
# See https://github.com/python-attrs/attrs/pull/807
|
||||
packages += ["attrs<21"]
|
||||
|
||||
if subprocess.call([python, "-m", "pip", "install"] + packages) != 0:
|
||||
shutil.rmtree(envdir)
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ __setstate__(PyObject *state) {
|
|||
_this->set_name(std::string(data, len));
|
||||
|
||||
_this->set_respect_prev_transform(PyTuple_GET_ITEM(state, 1) != Py_False);
|
||||
size_t num_colliders = (ssize_t)PyLong_AsLong(PyTuple_GET_ITEM(state, 2));
|
||||
size_t num_colliders = (size_t)PyLong_AsLong(PyTuple_GET_ITEM(state, 2));
|
||||
|
||||
for (size_t i = 0; i < num_colliders; ++i) {
|
||||
NodePath *collider = (NodePath *)DtoolInstance_VOID_PTR(PyTuple_GET_ITEM(state, i * 2 + 3));
|
||||
|
|
|
|||
|
|
@ -156,6 +156,28 @@ set_dimensions(const LVecBase4 &dimensions) {
|
|||
set_dimensions(0, dimensions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the range of the depth buffer this DisplayRegion writes to.
|
||||
* The parameters range from 0 to 1. It is legal for the near value to be
|
||||
* larger than the far value.
|
||||
*/
|
||||
INLINE void DisplayRegion::
|
||||
set_depth_range(PN_stdfloat near_depth, PN_stdfloat far_depth) {
|
||||
CDWriter cdata(_cycler, true);
|
||||
cdata->_depth_range.set(near_depth, far_depth);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
INLINE void DisplayRegion::
|
||||
get_depth_range(PN_stdfloat &near_depth, PN_stdfloat &far_depth) const {
|
||||
CDReader cdata(_cycler);
|
||||
const LVecBase2 &range = cdata->_depth_range;
|
||||
near_depth = range[0];
|
||||
far_depth = range[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the GraphicsOutput that this DisplayRegion is ultimately associated
|
||||
* with, or NULL if no window is associated.
|
||||
|
|
@ -693,6 +715,16 @@ get_top(int i) const {
|
|||
return _cdata->_regions[i]._dimensions[3];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
INLINE void DisplayRegionPipelineReader::
|
||||
get_depth_range(PN_stdfloat &near_depth, PN_stdfloat &far_depth) const {
|
||||
const LVecBase2 &range = _cdata->_depth_range;
|
||||
near_depth = range[0];
|
||||
far_depth = range[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the GraphicsOutput that this DisplayRegion is ultimately associated
|
||||
* with, or NULL if no window is associated.
|
||||
|
|
|
|||
|
|
@ -514,6 +514,15 @@ get_screenshot() {
|
|||
return tex;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void DisplayRegion::
|
||||
clear_cull_result() {
|
||||
CDCullWriter cdata_cull(_cycler_cull, true);
|
||||
cdata_cull->_cull_result = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a special scene graph constructed to represent the results of the
|
||||
* last frame's cull operation.
|
||||
|
|
@ -729,7 +738,8 @@ CData() :
|
|||
_stereo_channel(Lens::SC_mono),
|
||||
_tex_view_offset(0),
|
||||
_target_tex_page(-1),
|
||||
_scissor_enabled(true)
|
||||
_scissor_enabled(true),
|
||||
_depth_range(0, 1)
|
||||
{
|
||||
_regions.push_back(Region());
|
||||
}
|
||||
|
|
@ -748,7 +758,8 @@ CData(const DisplayRegion::CData ©) :
|
|||
_stereo_channel(copy._stereo_channel),
|
||||
_tex_view_offset(copy._tex_view_offset),
|
||||
_target_tex_page(copy._target_tex_page),
|
||||
_scissor_enabled(copy._scissor_enabled)
|
||||
_scissor_enabled(copy._scissor_enabled),
|
||||
_depth_range(copy._depth_range)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -82,6 +82,9 @@ PUBLISHED:
|
|||
virtual void set_dimensions(int i, const LVecBase4 &dimensions);
|
||||
MAKE_PROPERTY(dimensions, get_dimensions, set_dimensions);
|
||||
|
||||
INLINE void set_depth_range(PN_stdfloat near, PN_stdfloat far);
|
||||
INLINE void get_depth_range(PN_stdfloat &near, PN_stdfloat &far) const;
|
||||
|
||||
INLINE GraphicsOutput *get_window() const;
|
||||
GraphicsPipe *get_pipe() const;
|
||||
virtual bool is_stereo() const;
|
||||
|
|
@ -160,6 +163,7 @@ PUBLISHED:
|
|||
bool get_screenshot(PNMImage &image);
|
||||
PT(Texture) get_screenshot();
|
||||
|
||||
void clear_cull_result();
|
||||
virtual PT(PandaNode) make_cull_result_graph();
|
||||
|
||||
public:
|
||||
|
|
@ -232,6 +236,7 @@ private:
|
|||
}
|
||||
|
||||
Regions _regions;
|
||||
LVecBase2 _depth_range; // near, far
|
||||
|
||||
int _lens_index; // index into which lens of a camera is associated with this display region. 0 is default
|
||||
|
||||
|
|
@ -332,6 +337,8 @@ public:
|
|||
INLINE PN_stdfloat get_bottom(int i = 0) const;
|
||||
INLINE PN_stdfloat get_top(int i = 0) const;
|
||||
|
||||
INLINE void get_depth_range(PN_stdfloat &near, PN_stdfloat &far) const;
|
||||
|
||||
INLINE GraphicsOutput *get_window() const;
|
||||
GraphicsPipe *get_pipe() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -399,7 +399,7 @@ load_named_module(const string &name) {
|
|||
if (handle == nullptr) {
|
||||
std::string error = load_dso_error();
|
||||
display_cat.warning()
|
||||
<< "Unable to load " << dlname.get_basename() << ": " << error << std::endl;
|
||||
<< "Unable to load " << dlname.to_os_specific() << ": " << error << std::endl;
|
||||
return TypeHandle::none();
|
||||
}
|
||||
|
||||
|
|
@ -417,7 +417,7 @@ load_named_module(const string &name) {
|
|||
if (dso_symbol == nullptr) {
|
||||
// Couldn't find the module function.
|
||||
display_cat.warning()
|
||||
<< "Unable to find " << symbol_name << " in " << dlname.get_basename()
|
||||
<< "Unable to find " << symbol_name << " in " << dlname.to_os_specific()
|
||||
<< "\n";
|
||||
|
||||
} else {
|
||||
|
|
@ -447,7 +447,7 @@ load_named_module(const string &name) {
|
|||
// though, because it may have assigned itself into the
|
||||
// GraphicsPipeSelection table. So we carry on.
|
||||
display_cat.warning()
|
||||
<< "No default pipe type available for " << dlname.get_basename()
|
||||
<< "No default pipe type available for " << dlname.to_os_specific()
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4782,6 +4782,9 @@ release_swap_chain(DXScreenData *new_context) {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
if (new_context->_swap_chain == _swap_chain) {
|
||||
_swap_chain = nullptr;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -231,10 +231,12 @@ correct_time(double time) {
|
|||
// backward in the high-precision clock, since this does appear to happen
|
||||
// in a threaded environment.
|
||||
|
||||
clock_cat.debug()
|
||||
<< "Clock error detected; elapsed time " << time_delta
|
||||
<< "s on high-resolution counter, and " << tod_delta
|
||||
<< "s on time-of-day clock.\n";
|
||||
if (clock_cat.is_debug()) {
|
||||
clock_cat.debug()
|
||||
<< "Clock error detected; elapsed time " << time_delta
|
||||
<< "s on high-resolution counter, and " << tod_delta
|
||||
<< "s on time-of-day clock.\n";
|
||||
}
|
||||
++_error_count;
|
||||
|
||||
// If both are negative, we call it 0. If one is negative, we trust the
|
||||
|
|
|
|||
|
|
@ -120,6 +120,8 @@ typedef char GLchar;
|
|||
#define GL_ONE_MINUS_SRC1_COLOR GL_ONE_MINUS_SRC1_COLOR_EXT
|
||||
#define GL_SRC1_ALPHA GL_SRC1_ALPHA_EXT
|
||||
#define GL_ONE_MINUS_SRC1_ALPHA GL_ONE_MINUS_SRC1_ALPHA_EXT
|
||||
#define GL_LOWER_LEFT GL_LOWER_LEFT_EXT
|
||||
#define GL_ZERO_TO_ONE GL_ZERO_TO_ONE_EXT
|
||||
|
||||
#define GL_DEBUG_OUTPUT_SYNCHRONOUS GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR
|
||||
#define GL_DEBUG_TYPE_PERFORMANCE GL_DEBUG_TYPE_PERFORMANCE_KHR
|
||||
|
|
|
|||
|
|
@ -1050,6 +1050,30 @@ GL_APICALL void GL_APIENTRY glBufferStorageEXT (GLenum target, GLsizeiptr size,
|
|||
#endif
|
||||
#endif /* GL_EXT_buffer_storage */
|
||||
|
||||
#ifndef GL_EXT_clear_texture
|
||||
#define GL_EXT_clear_texture 1
|
||||
typedef void (GL_APIENTRYP PFNGLCLEARTEXIMAGEEXTPROC) (GLuint texture, GLint level, GLenum format, GLenum type, const void *data);
|
||||
typedef void (GL_APIENTRYP PFNGLCLEARTEXSUBIMAGEEXTPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GL_APICALL void GL_APIENTRY glClearTexImageEXT (GLuint texture, GLint level, GLenum format, GLenum type, const void *data);
|
||||
GL_APICALL void GL_APIENTRY glClearTexSubImageEXT (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data);
|
||||
#endif
|
||||
#endif /* GL_EXT_clear_texture */
|
||||
|
||||
#ifndef GL_EXT_clip_control
|
||||
#define GL_EXT_clip_control 1
|
||||
#define GL_LOWER_LEFT_EXT 0x8CA1
|
||||
#define GL_UPPER_LEFT_EXT 0x8CA2
|
||||
#define GL_NEGATIVE_ONE_TO_ONE_EXT 0x935E
|
||||
#define GL_ZERO_TO_ONE_EXT 0x935F
|
||||
#define GL_CLIP_ORIGIN_EXT 0x935C
|
||||
#define GL_CLIP_DEPTH_MODE_EXT 0x935D
|
||||
typedef void (GL_APIENTRYP PFNGLCLIPCONTROLEXTPROC) (GLenum origin, GLenum depth);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GL_APICALL void GL_APIENTRY glClipControlEXT (GLenum origin, GLenum depth);
|
||||
#endif
|
||||
#endif /* GL_EXT_clip_control */
|
||||
|
||||
#ifndef GL_EXT_color_buffer_float
|
||||
#define GL_EXT_color_buffer_float 1
|
||||
#endif /* GL_EXT_color_buffer_float */
|
||||
|
|
|
|||
|
|
@ -1695,6 +1695,11 @@ close_buffer() {
|
|||
_fbo.clear();
|
||||
}
|
||||
|
||||
if (_fbo_multisample != 0) {
|
||||
glgsg->_glDeleteFramebuffers(1, &_fbo_multisample);
|
||||
_fbo_multisample = 0;
|
||||
}
|
||||
|
||||
report_my_gl_errors();
|
||||
|
||||
// Release the Gsg
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@
|
|||
#include "alphaTestAttrib.h"
|
||||
#include "clipPlaneAttrib.h"
|
||||
#include "cullFaceAttrib.h"
|
||||
#include "depthBiasAttrib.h"
|
||||
#include "depthOffsetAttrib.h"
|
||||
#include "depthWriteAttrib.h"
|
||||
#include "fogAttrib.h"
|
||||
|
|
@ -156,6 +157,13 @@ null_glBlendColor(GLclampf, GLclampf, GLclampf, GLclampf) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifndef OPENGLES_1
|
||||
static void APIENTRY
|
||||
null_glPolygonOffsetClamp(GLfloat factor, GLfloat units, GLfloat clamp) {
|
||||
glPolygonOffset(factor, units);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OPENGLES_1
|
||||
// We have a default shader that will be applied when there isn't any shader
|
||||
// applied (e.g. if it failed to compile). We need this because OpenGL ES
|
||||
|
|
@ -528,6 +536,7 @@ CLP(GraphicsStateGuardian)(GraphicsEngine *engine, GraphicsPipe *pipe) :
|
|||
|
||||
_scissor_enabled = false;
|
||||
_scissor_attrib_active = false;
|
||||
_has_attrib_depth_range = false;
|
||||
|
||||
_white_texture = 0;
|
||||
|
||||
|
|
@ -625,6 +634,7 @@ reset() {
|
|||
_inv_state_mask.clear_bit(ColorAttrib::get_class_slot());
|
||||
_inv_state_mask.clear_bit(ColorScaleAttrib::get_class_slot());
|
||||
_inv_state_mask.clear_bit(CullFaceAttrib::get_class_slot());
|
||||
_inv_state_mask.clear_bit(DepthBiasAttrib::get_class_slot());
|
||||
_inv_state_mask.clear_bit(DepthOffsetAttrib::get_class_slot());
|
||||
_inv_state_mask.clear_bit(DepthTestAttrib::get_class_slot());
|
||||
_inv_state_mask.clear_bit(DepthWriteAttrib::get_class_slot());
|
||||
|
|
@ -1094,6 +1104,20 @@ reset() {
|
|||
_supports_clear_texture = true;
|
||||
}
|
||||
}
|
||||
#elif !defined(OPENGLES_1)
|
||||
if (has_extension("GL_EXT_clear_texture")) {
|
||||
_glClearTexImage = (PFNGLCLEARTEXIMAGEEXTPROC)
|
||||
get_extension_func("glClearTexImageEXT");
|
||||
_glClearTexSubImage = (PFNGLCLEARTEXSUBIMAGEEXTPROC)
|
||||
get_extension_func("glClearTexSubImageEXT");
|
||||
|
||||
if (_glClearTexImage == nullptr || _glClearTexSubImage == nullptr) {
|
||||
GLCAT.warning()
|
||||
<< "GL_EXT_clear_texture advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
|
||||
} else {
|
||||
_supports_clear_texture = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
_supports_clear_buffer = false;
|
||||
|
|
@ -2150,6 +2174,8 @@ reset() {
|
|||
get_extension_func("glGetProgramResourceName");
|
||||
_glGetProgramResourceiv = (PFNGLGETPROGRAMRESOURCEIVPROC)
|
||||
get_extension_func("glGetProgramResourceiv");
|
||||
_glShaderStorageBlockBinding = (PFNGLSHADERSTORAGEBLOCKBINDINGPROC)
|
||||
get_extension_func("glShaderStorageBlockBinding");
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
|
|
@ -3307,23 +3333,30 @@ reset() {
|
|||
#endif
|
||||
|
||||
// Set depth range from zero to one if requested.
|
||||
#ifndef OPENGLES
|
||||
#ifndef OPENGLES_1
|
||||
_use_depth_zero_to_one = false;
|
||||
_use_remapped_depth_range = false;
|
||||
|
||||
if (gl_depth_zero_to_one) {
|
||||
#ifndef OPENGLES
|
||||
PFNGLCLIPCONTROLPROC pglClipControl = nullptr;
|
||||
if (is_at_least_gl_version(4, 5) || has_extension("GL_ARB_clip_control")) {
|
||||
PFNGLCLIPCONTROLPROC pglClipControl =
|
||||
(PFNGLCLIPCONTROLPROC)get_extension_func("glClipControl");
|
||||
pglClipControl = (PFNGLCLIPCONTROLPROC)get_extension_func("glClipControl");
|
||||
}
|
||||
#else
|
||||
PFNGLCLIPCONTROLEXTPROC pglClipControl = nullptr;
|
||||
if (has_extension("GL_EXT_clip_control")) {
|
||||
pglClipControl = (PFNGLCLIPCONTROLEXTPROC)get_extension_func("glClipControlEXT");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pglClipControl != nullptr) {
|
||||
pglClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
|
||||
_use_depth_zero_to_one = true;
|
||||
if (pglClipControl != nullptr) {
|
||||
pglClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
|
||||
_use_depth_zero_to_one = true;
|
||||
|
||||
if (GLCAT.is_debug()) {
|
||||
GLCAT.debug()
|
||||
<< "Set zero-to-one depth using glClipControl\n";
|
||||
}
|
||||
if (GLCAT.is_debug()) {
|
||||
GLCAT.debug()
|
||||
<< "Set zero-to-one depth using glClipControl\n";
|
||||
}
|
||||
}/* else if (has_extension("GL_NV_depth_buffer_float")) {
|
||||
// Alternatively, all GeForce 8+ and even some AMD drivers support this
|
||||
|
|
@ -3335,6 +3368,7 @@ reset() {
|
|||
_glDepthRangedNV(-1.0, 1.0);
|
||||
_use_depth_zero_to_one = true;
|
||||
_use_remapped_depth_range = true;
|
||||
_has_attrib_depth_range = false;
|
||||
|
||||
if (GLCAT.is_debug()) {
|
||||
GLCAT.debug()
|
||||
|
|
@ -3350,6 +3384,32 @@ reset() {
|
|||
}
|
||||
#endif
|
||||
|
||||
if (_has_attrib_depth_range) {
|
||||
#ifdef OPENGLES
|
||||
glDepthRangef(0.0f, 1.0f);
|
||||
#else
|
||||
glDepthRange(0.0, 1.0);
|
||||
#endif
|
||||
_depth_range_near = 0;
|
||||
_depth_range_far = 1;
|
||||
_has_attrib_depth_range = false;
|
||||
}
|
||||
|
||||
#ifndef OPENGLES_1
|
||||
#ifndef OPENGLES
|
||||
if (is_at_least_gl_version(4, 6) || has_extension("GL_ARB_polygon_offset_clamp")) {
|
||||
_glPolygonOffsetClamp = (PFNGLPOLYGONOFFSETCLAMPEXTPROC)get_extension_func("glPolygonOffsetClamp");
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (has_extension("GL_EXT_polygon_offset_clamp")) {
|
||||
_glPolygonOffsetClamp = (PFNGLPOLYGONOFFSETCLAMPEXTPROC)get_extension_func("glPolygonOffsetClampEXT");
|
||||
}
|
||||
else {
|
||||
_glPolygonOffsetClamp = null_glPolygonOffsetClamp;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set up all the enableddisabled flags to GL's known initial values:
|
||||
// everything off.
|
||||
_multisample_mode = 0;
|
||||
|
|
@ -3924,6 +3984,33 @@ prepare_display_region(DisplayRegionPipelineReader *dr) {
|
|||
}
|
||||
}
|
||||
|
||||
PN_stdfloat nearv;
|
||||
PN_stdfloat farv;
|
||||
dr->get_depth_range(nearv, farv);
|
||||
#ifdef GSG_VERBOSE
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam()
|
||||
<< "glDepthRange(" << nearv << ", " << farv << ")" << endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef OPENGLES
|
||||
// OpenGL ES uses a single-precision call.
|
||||
glDepthRangef((GLclampf)nearv, (GLclampf)farv);
|
||||
#else
|
||||
// Mainline OpenGL uses a double-precision call.
|
||||
if (!_use_remapped_depth_range) {
|
||||
glDepthRange((GLclampd)nearv, (GLclampd)farv);
|
||||
} else {
|
||||
// If we have a remapped depth range, we should adjust the values to range
|
||||
// from -1 to 1. We need to use an NV extension to pass unclamped values.
|
||||
_glDepthRangedNV(nearv * 2.0 - 1.0, farv * 2.0 - 1.0);
|
||||
}
|
||||
#endif // OPENGLES
|
||||
_has_attrib_depth_range = false;
|
||||
_depth_range_near = nearv;
|
||||
_depth_range_far = farv;
|
||||
|
||||
report_my_gl_errors();
|
||||
}
|
||||
|
||||
|
|
@ -8131,42 +8218,68 @@ do_issue_fog() {
|
|||
*
|
||||
*/
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
do_issue_depth_offset() {
|
||||
const DepthOffsetAttrib *target_depth_offset = (const DepthOffsetAttrib *)
|
||||
_target_rs->get_attrib_def(DepthOffsetAttrib::get_class_slot());
|
||||
|
||||
do_issue_depth_bias() {
|
||||
const DepthOffsetAttrib *target_depth_offset;
|
||||
_target_rs->get_attrib_def(target_depth_offset);
|
||||
int offset = target_depth_offset->get_offset();
|
||||
|
||||
if (offset != 0) {
|
||||
const DepthBiasAttrib *target_depth_bias;
|
||||
if (_target_rs->get_attrib(target_depth_bias)) {
|
||||
GLfloat slope_factor = target_depth_bias->get_slope_factor();
|
||||
GLfloat constant_factor = target_depth_bias->get_constant_factor();
|
||||
|
||||
slope_factor -= offset;
|
||||
constant_factor -= offset;
|
||||
|
||||
#ifndef OPENGLES_1
|
||||
GLfloat clamp = target_depth_bias->get_clamp();
|
||||
_glPolygonOffsetClamp(slope_factor, constant_factor, clamp);
|
||||
#else
|
||||
glPolygonOffset(slope_factor, constant_factor);
|
||||
#endif
|
||||
enable_polygon_offset(true);
|
||||
}
|
||||
else if (offset != 0) {
|
||||
// The relationship between these two parameters is a little unclear and
|
||||
// poorly explained in the GL man pages.
|
||||
glPolygonOffset((GLfloat) -offset, (GLfloat) -offset);
|
||||
enable_polygon_offset(true);
|
||||
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
enable_polygon_offset(false);
|
||||
}
|
||||
|
||||
PN_stdfloat min_value = target_depth_offset->get_min_value();
|
||||
PN_stdfloat max_value = target_depth_offset->get_max_value();
|
||||
if (min_value != (PN_stdfloat)0.0 ||
|
||||
max_value != (PN_stdfloat)1.0 ||
|
||||
_has_attrib_depth_range) {
|
||||
min_value = _depth_range_far * min_value + _depth_range_near * (1 - min_value);
|
||||
max_value = _depth_range_far * max_value + _depth_range_near * (1 - max_value);
|
||||
|
||||
#ifdef GSG_VERBOSE
|
||||
GLCAT.spam()
|
||||
<< "glDepthRange(" << min_value << ", " << max_value << ")" << endl;
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam()
|
||||
<< "glDepthRange(" << min_value << ", " << max_value << ")" << endl;
|
||||
}
|
||||
#endif
|
||||
#ifdef OPENGLES
|
||||
// OpenGL ES uses a single-precision call.
|
||||
glDepthRangef((GLclampf)min_value, (GLclampf)max_value);
|
||||
// OpenGL ES uses a single-precision call.
|
||||
glDepthRangef((GLclampf)min_value, (GLclampf)max_value);
|
||||
#else
|
||||
// Mainline OpenGL uses a double-precision call.
|
||||
if (!_use_remapped_depth_range) {
|
||||
glDepthRange((GLclampd)min_value, (GLclampd)max_value);
|
||||
} else {
|
||||
// If we have a remapped depth range, we should adjust the values to range
|
||||
// from -1 to 1. We need to use an NV extension to pass unclamped values.
|
||||
_glDepthRangedNV(min_value * 2.0 - 1.0, max_value * 2.0 - 1.0);
|
||||
}
|
||||
// Mainline OpenGL uses a double-precision call.
|
||||
if (!_use_remapped_depth_range) {
|
||||
glDepthRange((GLclampd)min_value, (GLclampd)max_value);
|
||||
} else {
|
||||
// If we have a remapped depth range, we should adjust the values to range
|
||||
// from -1 to 1. We need to use an NV extension to pass unclamped values.
|
||||
_glDepthRangedNV(min_value * 2.0 - 1.0, max_value * 2.0 - 1.0);
|
||||
}
|
||||
#endif // OPENGLES
|
||||
|
||||
_has_attrib_depth_range = true;
|
||||
}
|
||||
|
||||
report_my_gl_errors();
|
||||
}
|
||||
|
||||
|
|
@ -11732,11 +11845,15 @@ set_state_and_transform(const RenderState *target,
|
|||
_state_mask.set_bit(cull_face_slot);
|
||||
}
|
||||
|
||||
int depth_bias_slot = DepthBiasAttrib::get_class_slot();
|
||||
int depth_offset_slot = DepthOffsetAttrib::get_class_slot();
|
||||
if (_target_rs->get_attrib(depth_offset_slot) != _state_rs->get_attrib(depth_offset_slot) ||
|
||||
if (_target_rs->get_attrib(depth_bias_slot) != _state_rs->get_attrib(depth_bias_slot) ||
|
||||
_target_rs->get_attrib(depth_offset_slot) != _state_rs->get_attrib(depth_offset_slot) ||
|
||||
!_state_mask.get_bit(depth_bias_slot) ||
|
||||
!_state_mask.get_bit(depth_offset_slot)) {
|
||||
// PStatGPUTimer timer(this, _draw_set_state_depth_offset_pcollector);
|
||||
do_issue_depth_offset();
|
||||
do_issue_depth_bias();
|
||||
_state_mask.set_bit(depth_bias_slot);
|
||||
_state_mask.set_bit(depth_offset_slot);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -229,10 +229,10 @@ typedef void (APIENTRYP PFNGLPROGRAMBINARYPROC) (GLuint program, GLenum binaryFo
|
|||
typedef void (APIENTRYP PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params);
|
||||
typedef void (APIENTRYP PFNGLBUFFERSTORAGEPROC) (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags);
|
||||
typedef void (APIENTRYP PFNGLBINDIMAGETEXTUREPROC) (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format);
|
||||
#endif // OPENGLES_1
|
||||
#ifndef OPENGLES
|
||||
typedef void (APIENTRYP PFNGLCLEARTEXIMAGEPROC) (GLuint texture, GLint level, GLenum format, GLenum type, const void *data);
|
||||
typedef void (APIENTRYP PFNGLCLEARTEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data);
|
||||
#endif // OPENGLES_1
|
||||
#ifndef OPENGLES
|
||||
typedef void (APIENTRYP PFNGLBINDTEXTURESPROC) (GLuint first, GLsizei count, const GLuint *textures);
|
||||
typedef void (APIENTRYP PFNGLBINDSAMPLERSPROC) (GLuint first, GLsizei count, const GLuint *samplers);
|
||||
typedef void (APIENTRYP PFNGLBINDIMAGETEXTURESPROC) (GLuint first, GLsizei count, const GLuint *textures);
|
||||
|
|
@ -454,7 +454,7 @@ protected:
|
|||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
void do_issue_fog();
|
||||
#endif
|
||||
void do_issue_depth_offset();
|
||||
void do_issue_depth_bias();
|
||||
void do_issue_shade_model();
|
||||
#ifndef OPENGLES_1
|
||||
void do_issue_shader();
|
||||
|
|
@ -675,6 +675,9 @@ protected:
|
|||
bool _scissor_enabled;
|
||||
bool _scissor_attrib_active;
|
||||
epvector<LVecBase4i> _scissor_array;
|
||||
PN_stdfloat _depth_range_near;
|
||||
PN_stdfloat _depth_range_far;
|
||||
bool _has_attrib_depth_range;
|
||||
|
||||
#ifndef OPENGLES_1
|
||||
BitMask32 _enabled_vertex_attrib_arrays;
|
||||
|
|
@ -764,11 +767,16 @@ protected:
|
|||
#endif
|
||||
|
||||
public:
|
||||
#ifndef OPENGLES
|
||||
#ifndef OPENGLES_1
|
||||
bool _use_depth_zero_to_one;
|
||||
bool _use_remapped_depth_range;
|
||||
#endif
|
||||
#ifndef OPENGLES
|
||||
PFNGLDEPTHRANGEDNVPROC _glDepthRangedNV;
|
||||
#endif
|
||||
#ifndef OPENGLES_1
|
||||
PFNGLPOLYGONOFFSETCLAMPEXTPROC _glPolygonOffsetClamp;
|
||||
#endif
|
||||
|
||||
bool _supports_point_parameters;
|
||||
PFNGLPOINTPARAMETERFVPROC _glPointParameterfv;
|
||||
|
|
@ -805,7 +813,7 @@ public:
|
|||
#endif
|
||||
|
||||
bool _supports_clear_texture;
|
||||
#ifndef OPENGLES
|
||||
#ifndef OPENGLES_1
|
||||
PFNGLCLEARTEXIMAGEPROC _glClearTexImage;
|
||||
PFNGLCLEARTEXSUBIMAGEPROC _glClearTexSubImage;
|
||||
#endif
|
||||
|
|
@ -1073,6 +1081,7 @@ public:
|
|||
PFNGLGETPROGRAMINTERFACEIVPROC _glGetProgramInterfaceiv;
|
||||
PFNGLGETPROGRAMRESOURCENAMEPROC _glGetProgramResourceName;
|
||||
PFNGLGETPROGRAMRESOURCEIVPROC _glGetProgramResourceiv;
|
||||
PFNGLSHADERSTORAGEBLOCKBINDINGPROC _glShaderStorageBlockBinding;
|
||||
#endif // !OPENGLES
|
||||
|
||||
GLenum _edge_clamp;
|
||||
|
|
|
|||
|
|
@ -339,6 +339,8 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
|
|||
block_maxlength = max(64, block_maxlength);
|
||||
char *block_name_cstr = (char *)alloca(block_maxlength);
|
||||
|
||||
BitArray bindings;
|
||||
|
||||
for (int i = 0; i < block_count; ++i) {
|
||||
block_name_cstr[0] = 0;
|
||||
_glgsg->_glGetProgramResourceName(_glsl_program, GL_SHADER_STORAGE_BLOCK, i, block_maxlength, nullptr, block_name_cstr);
|
||||
|
|
@ -347,6 +349,20 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
|
|||
GLint values[2];
|
||||
_glgsg->_glGetProgramResourceiv(_glsl_program, GL_SHADER_STORAGE_BLOCK, i, 2, props, 2, nullptr, values);
|
||||
|
||||
if (bindings.get_bit(values[0])) {
|
||||
// Binding index already in use, assign a different one.
|
||||
values[0] = bindings.get_lowest_off_bit();
|
||||
_glgsg->_glShaderStorageBlockBinding(_glsl_program, i, values[0]);
|
||||
}
|
||||
bindings.set_bit(values[0]);
|
||||
|
||||
if (GLCAT.is_debug()) {
|
||||
GLCAT.debug()
|
||||
<< "Active shader storage block " << block_name_cstr
|
||||
<< " with size " << values[1] << " is bound to binding "
|
||||
<< values[0] << "\n";
|
||||
}
|
||||
|
||||
StorageBlock block;
|
||||
block._name = InternalName::make(block_name_cstr);
|
||||
block._binding_index = values[0];
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ set(P3PGRAPH_HEADERS
|
|||
cullTraverserData.I cullTraverserData.h
|
||||
cullableObject.I cullableObject.h
|
||||
decalEffect.I decalEffect.h
|
||||
depthBiasAttrib.I depthBiasAttrib.h
|
||||
depthOffsetAttrib.I depthOffsetAttrib.h
|
||||
depthTestAttrib.I depthTestAttrib.h
|
||||
depthWriteAttrib.I depthWriteAttrib.h
|
||||
|
|
@ -131,6 +132,7 @@ set(P3PGRAPH_SOURCES
|
|||
cullTraverserData.cxx
|
||||
cullableObject.cxx
|
||||
decalEffect.cxx
|
||||
depthBiasAttrib.cxx
|
||||
depthOffsetAttrib.cxx
|
||||
depthTestAttrib.cxx
|
||||
depthWriteAttrib.cxx
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "cullTraverser.h"
|
||||
#include "cullableObject.h"
|
||||
#include "decalEffect.h"
|
||||
#include "depthBiasAttrib.h"
|
||||
#include "depthOffsetAttrib.h"
|
||||
#include "depthTestAttrib.h"
|
||||
#include "depthWriteAttrib.h"
|
||||
|
|
@ -416,6 +417,7 @@ init_libpgraph() {
|
|||
CullTraverser::init_type();
|
||||
CullableObject::init_type();
|
||||
DecalEffect::init_type();
|
||||
DepthBiasAttrib::init_type();
|
||||
DepthOffsetAttrib::init_type();
|
||||
DepthTestAttrib::init_type();
|
||||
DepthWriteAttrib::init_type();
|
||||
|
|
@ -489,6 +491,7 @@ init_libpgraph() {
|
|||
CullBinAttrib::register_with_read_factory();
|
||||
CullFaceAttrib::register_with_read_factory();
|
||||
DecalEffect::register_with_read_factory();
|
||||
DepthBiasAttrib::register_with_read_factory();
|
||||
DepthOffsetAttrib::register_with_read_factory();
|
||||
DepthTestAttrib::register_with_read_factory();
|
||||
DepthWriteAttrib::register_with_read_factory();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file depthBiasAttrib.I
|
||||
* @author rdb
|
||||
* @date 2021-08-24
|
||||
*/
|
||||
|
||||
/**
|
||||
* Use DepthBiasAttrib::make() to construct a new DepthBiasAttrib object.
|
||||
*/
|
||||
INLINE DepthBiasAttrib::
|
||||
DepthBiasAttrib(PN_stdfloat slope_factor, PN_stdfloat constant_factor,
|
||||
PN_stdfloat clamp) :
|
||||
_slope_factor(slope_factor),
|
||||
_constant_factor(constant_factor),
|
||||
_clamp(clamp)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the slope factor.
|
||||
*/
|
||||
INLINE PN_stdfloat DepthBiasAttrib::
|
||||
get_slope_factor() const {
|
||||
return _slope_factor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the constant factor.
|
||||
*/
|
||||
INLINE PN_stdfloat DepthBiasAttrib::
|
||||
get_constant_factor() const {
|
||||
return _constant_factor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum (or minimum, if negative) value of the bias. If zero,
|
||||
* no clamping is performed.
|
||||
*/
|
||||
INLINE PN_stdfloat DepthBiasAttrib::
|
||||
get_clamp() const {
|
||||
return _clamp;
|
||||
}
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file depthBiasAttrib.cxx
|
||||
* @author rdb
|
||||
* @date 2021-08-24
|
||||
*/
|
||||
|
||||
#include "depthBiasAttrib.h"
|
||||
#include "graphicsStateGuardianBase.h"
|
||||
#include "dcast.h"
|
||||
#include "bamReader.h"
|
||||
#include "bamWriter.h"
|
||||
#include "datagram.h"
|
||||
#include "datagramIterator.h"
|
||||
|
||||
TypeHandle DepthBiasAttrib::_type_handle;
|
||||
int DepthBiasAttrib::_attrib_slot;
|
||||
|
||||
/**
|
||||
* Constructs a new DepthBiasAttrib object that indicates the slope factor,
|
||||
* constant factor, and an optional clamping value.
|
||||
*/
|
||||
CPT(RenderAttrib) DepthBiasAttrib::
|
||||
make(PN_stdfloat slope_factor, PN_stdfloat constant_factor, PN_stdfloat clamp) {
|
||||
DepthBiasAttrib *attrib = new DepthBiasAttrib(slope_factor, constant_factor, clamp);
|
||||
return return_new(attrib);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a RenderAttrib that corresponds to whatever the standard default
|
||||
* properties for render attributes of this type ought to be.
|
||||
*/
|
||||
CPT(RenderAttrib) DepthBiasAttrib::
|
||||
make_default() {
|
||||
return return_new(new DepthBiasAttrib(0, 0, 0));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void DepthBiasAttrib::
|
||||
output(std::ostream &out) const {
|
||||
out << get_type() << ":(" << get_slope_factor() << ", " << get_constant_factor()
|
||||
<< ", " << get_clamp() << ")";
|
||||
}
|
||||
|
||||
/**
|
||||
* Intended to be overridden by derived DepthBiasAttrib types to return a
|
||||
* unique number indicating whether this DepthBiasAttrib is equivalent to
|
||||
* the other one.
|
||||
*
|
||||
* This should return 0 if the two DepthBiasAttrib objects are equivalent, a
|
||||
* number less than zero if this one should be sorted before the other one,
|
||||
* and a number greater than zero otherwise.
|
||||
*
|
||||
* This will only be called with two DepthBiasAttrib objects whose
|
||||
* get_type() functions return the same.
|
||||
*/
|
||||
int DepthBiasAttrib::
|
||||
compare_to_impl(const RenderAttrib *other) const {
|
||||
const DepthBiasAttrib *ta = (const DepthBiasAttrib *)other;
|
||||
|
||||
if (_slope_factor != ta->_slope_factor) {
|
||||
return _slope_factor < ta->_slope_factor ? -1 : 1;
|
||||
}
|
||||
if (_constant_factor != ta->_constant_factor) {
|
||||
return _constant_factor < ta->_constant_factor ? -1 : 1;
|
||||
}
|
||||
if (_clamp != ta->_clamp) {
|
||||
return _clamp < ta->_clamp ? -1 : 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Intended to be overridden by derived RenderAttrib types to return a unique
|
||||
* hash for these particular properties. RenderAttribs that compare the same
|
||||
* with compare_to_impl(), above, should return the same hash; RenderAttribs
|
||||
* that compare differently should return a different hash.
|
||||
*/
|
||||
size_t DepthBiasAttrib::
|
||||
get_hash_impl() const {
|
||||
size_t hash = 0;
|
||||
hash = float_hash().add_hash(hash, _slope_factor);
|
||||
hash = float_hash().add_hash(hash, _constant_factor);
|
||||
hash = float_hash().add_hash(hash, _clamp);
|
||||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Intended to be overridden by derived RenderAttrib types to specify how two
|
||||
* consecutive RenderAttrib objects of the same type interact.
|
||||
*
|
||||
* This should return the result of applying the other RenderAttrib to a node
|
||||
* in the scene graph below this RenderAttrib, which was already applied. In
|
||||
* most cases, the result is the same as the other RenderAttrib (that is, a
|
||||
* subsequent RenderAttrib completely replaces the preceding one). On the
|
||||
* other hand, some kinds of RenderAttrib (for instance, ColorTransformAttrib)
|
||||
* might combine in meaningful ways.
|
||||
*/
|
||||
CPT(RenderAttrib) DepthBiasAttrib::
|
||||
compose_impl(const RenderAttrib *other) const {
|
||||
const DepthBiasAttrib *ba = (const DepthBiasAttrib *)other;
|
||||
|
||||
return return_new(new DepthBiasAttrib(ba->_slope_factor + _slope_factor,
|
||||
ba->_constant_factor + _constant_factor,
|
||||
ba->_clamp));
|
||||
}
|
||||
|
||||
/**
|
||||
* Intended to be overridden by derived RenderAttrib types to specify how two
|
||||
* consecutive RenderAttrib objects of the same type interact.
|
||||
*
|
||||
* See invert_compose() and compose_impl().
|
||||
*/
|
||||
CPT(RenderAttrib) DepthBiasAttrib::
|
||||
invert_compose_impl(const RenderAttrib *other) const {
|
||||
const DepthBiasAttrib *ba = (const DepthBiasAttrib *)other;
|
||||
|
||||
return return_new(new DepthBiasAttrib(ba->_slope_factor - _slope_factor,
|
||||
ba->_constant_factor - _constant_factor,
|
||||
ba->_clamp));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells the BamReader how to create objects of type DepthBiasAttrib.
|
||||
*/
|
||||
void DepthBiasAttrib::
|
||||
register_with_read_factory() {
|
||||
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the contents of this object to the datagram for shipping out to a
|
||||
* Bam file.
|
||||
*/
|
||||
void DepthBiasAttrib::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
RenderAttrib::write_datagram(manager, dg);
|
||||
|
||||
dg.add_stdfloat(_slope_factor);
|
||||
dg.add_stdfloat(_constant_factor);
|
||||
dg.add_stdfloat(_clamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called by the BamReader's factory when a new object of
|
||||
* type DepthBiasAttrib is encountered in the Bam file. It should create
|
||||
* the DepthBiasAttrib and extract its information from the file.
|
||||
*/
|
||||
TypedWritable *DepthBiasAttrib::
|
||||
make_from_bam(const FactoryParams ¶ms) {
|
||||
DepthBiasAttrib *attrib = new DepthBiasAttrib(0, 0, 0);
|
||||
DatagramIterator scan;
|
||||
BamReader *manager;
|
||||
|
||||
parse_params(params, scan, manager);
|
||||
attrib->fillin(scan, manager);
|
||||
|
||||
return attrib;
|
||||
}
|
||||
|
||||
/**
|
||||
* This internal function is called by make_from_bam to read in all of the
|
||||
* relevant data from the BamFile for the new DepthBiasAttrib.
|
||||
*/
|
||||
void DepthBiasAttrib::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
RenderAttrib::fillin(scan, manager);
|
||||
|
||||
_slope_factor = scan.get_stdfloat();
|
||||
_constant_factor = scan.get_stdfloat();
|
||||
_clamp = scan.get_stdfloat();
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file depthBiasAttrib.h
|
||||
* @author rdb
|
||||
* @date 2021-08-24
|
||||
*/
|
||||
|
||||
#ifndef DEPTHBIASATTRIB_H
|
||||
#define DEPTHBIASATTRIB_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "renderAttrib.h"
|
||||
#include "luse.h"
|
||||
|
||||
class FactoryParams;
|
||||
|
||||
/**
|
||||
* This is a special kind of attribute that instructs the graphics driver to
|
||||
* apply an offset or bias to the generated depth values for rendered
|
||||
* polygons, before they are written to the depth buffer.
|
||||
*
|
||||
* This class replaces the old DepthOffsetAttrib, which had a more limited
|
||||
* parameterization. The differences are:
|
||||
* - The sign of the factor parameter was inverted.
|
||||
* - The slope and constant factors are specified separately.
|
||||
* - The factors are specified as floating-point instead of integer.
|
||||
* - There is a new clamp parameter.
|
||||
*
|
||||
* Nested DepthBiasAttrib values accumulate; that is, a DepthBiasAttrib
|
||||
* with a value of 1 beneath another DepthBiasAttrib with a value of 2
|
||||
* presents a net offset of 3. (A DepthBiasAttrib will not, however,
|
||||
* combine with any other DepthBiasAttribs with a lower override parameter.)
|
||||
*/
|
||||
class EXPCL_PANDA_PGRAPH DepthBiasAttrib : public RenderAttrib {
|
||||
private:
|
||||
INLINE DepthBiasAttrib(PN_stdfloat slope_factor, PN_stdfloat constant_factor,
|
||||
PN_stdfloat clamp = 0);
|
||||
|
||||
PUBLISHED:
|
||||
static CPT(RenderAttrib) make(PN_stdfloat slope_factor, PN_stdfloat constant_factor,
|
||||
PN_stdfloat clamp = 0);
|
||||
static CPT(RenderAttrib) make_default();
|
||||
|
||||
public:
|
||||
INLINE PN_stdfloat get_slope_factor() const;
|
||||
INLINE PN_stdfloat get_constant_factor() const;
|
||||
INLINE PN_stdfloat get_clamp() const;
|
||||
|
||||
PUBLISHED:
|
||||
MAKE_PROPERTY(slope_factor, get_slope_factor);
|
||||
MAKE_PROPERTY(constant_factor, get_constant_factor);
|
||||
MAKE_PROPERTY(clamp, get_clamp);
|
||||
|
||||
public:
|
||||
virtual void output(std::ostream &out) const;
|
||||
|
||||
protected:
|
||||
virtual int compare_to_impl(const RenderAttrib *other) const;
|
||||
virtual size_t get_hash_impl() const;
|
||||
virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const;
|
||||
virtual CPT(RenderAttrib) invert_compose_impl(const RenderAttrib *other) const;
|
||||
|
||||
private:
|
||||
PN_stdfloat _slope_factor;
|
||||
PN_stdfloat _constant_factor;
|
||||
PN_stdfloat _clamp;
|
||||
|
||||
PUBLISHED:
|
||||
static int get_class_slot() {
|
||||
return _attrib_slot;
|
||||
}
|
||||
virtual int get_slot() const {
|
||||
return get_class_slot();
|
||||
}
|
||||
MAKE_PROPERTY(class_slot, get_class_slot);
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
|
||||
protected:
|
||||
static TypedWritable *make_from_bam(const FactoryParams ¶ms);
|
||||
void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
RenderAttrib::init_type();
|
||||
register_type(_type_handle, "DepthBiasAttrib",
|
||||
RenderAttrib::get_class_type());
|
||||
_attrib_slot = register_slot(_type_handle, 100,
|
||||
new DepthBiasAttrib(0, 0, 0));
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
static int _attrib_slot;
|
||||
};
|
||||
|
||||
#include "depthBiasAttrib.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -46,6 +46,8 @@ class FactoryParams;
|
|||
* Also, and only tangentially related, the DepthOffsetAttrib can be used to
|
||||
* constrain the Z output value to a subset of the usual [0, 1] range (or
|
||||
* reversing its direction) by specifying a new min_value and max_value.
|
||||
*
|
||||
* @deprecated See DepthBiasAttrib and DisplayRegion::set_depth_range() instead.
|
||||
*/
|
||||
class EXPCL_PANDA_PGRAPH DepthOffsetAttrib : public RenderAttrib {
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -34,9 +34,10 @@
|
|||
#include "renderModeAttrib.h"
|
||||
#include "cullFaceAttrib.h"
|
||||
#include "alphaTestAttrib.h"
|
||||
#include "depthBiasAttrib.h"
|
||||
#include "depthOffsetAttrib.h"
|
||||
#include "depthTestAttrib.h"
|
||||
#include "depthWriteAttrib.h"
|
||||
#include "depthOffsetAttrib.h"
|
||||
#include "shaderAttrib.h"
|
||||
#include "billboardEffect.h"
|
||||
#include "compassEffect.h"
|
||||
|
|
@ -309,6 +310,8 @@ get_sort(Thread *current_thread) const {
|
|||
* Searches for a node below the referenced node that matches the indicated
|
||||
* string. Returns the shortest match found, if any, or an empty NodePath if
|
||||
* no match can be found.
|
||||
*
|
||||
* The referenced node itself is not considered in the search.
|
||||
*/
|
||||
NodePath NodePath::
|
||||
find(const string &path) const {
|
||||
|
|
@ -349,6 +352,8 @@ find_path_to(PandaNode *node) const {
|
|||
/**
|
||||
* Returns the complete set of all NodePaths that begin with this NodePath and
|
||||
* can be extended by path. The shortest paths will be listed first.
|
||||
*
|
||||
* The referenced node itself is not considered in the search.
|
||||
*/
|
||||
NodePathCollection NodePath::
|
||||
find_all_matches(const string &path) const {
|
||||
|
|
@ -4684,6 +4689,8 @@ get_depth_write() const {
|
|||
* bias is always an integer number, and each integer increment represents the
|
||||
* smallest possible increment in Z that is sufficient to completely resolve
|
||||
* two coplanar polygons. Positive numbers are closer towards the camera.
|
||||
*
|
||||
* @deprecated See set_depth_bias() instead, which provides more controls.
|
||||
*/
|
||||
void NodePath::
|
||||
set_depth_offset(int bias, int priority) {
|
||||
|
|
@ -4730,6 +4737,40 @@ get_depth_offset() const {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This instructs the graphics driver to apply an offset or bias to the
|
||||
* generated depth values for rendered polygons, before they are written to
|
||||
* the depth buffer. This can be used to shift polygons forward slightly, to
|
||||
* resolve depth conflicts, or self-shadowing artifacts on thin objects.
|
||||
* Positive numbers are further away from the camera.
|
||||
*/
|
||||
void NodePath::
|
||||
set_depth_bias(PN_stdfloat slope_factor, PN_stdfloat constant_factor, PN_stdfloat clamp, int priority) {
|
||||
nassertv_always(!is_empty());
|
||||
node()->set_attrib(DepthBiasAttrib::make(slope_factor, constant_factor, clamp), priority);
|
||||
}
|
||||
|
||||
/**
|
||||
* Completely removes any depth-bias adjustment that may have been set on
|
||||
* this node via set_depth_bias().
|
||||
*/
|
||||
void NodePath::
|
||||
clear_depth_bias() {
|
||||
nassertv_always(!is_empty());
|
||||
node()->clear_attrib(DepthBiasAttrib::get_class_slot());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a depth-bias adjustment has been explicitly set on this
|
||||
* particular node via set_depth_bias(). If this returns true, then
|
||||
* get_depth_bias() may be called to determine which has been set.
|
||||
*/
|
||||
bool NodePath::
|
||||
has_depth_bias() const {
|
||||
nassertr_always(!is_empty(), false);
|
||||
return node()->has_attrib(DepthBiasAttrib::get_class_slot());
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a billboard-type rotate to the indicated camera node, one time
|
||||
* only, and leaves the object rotated. This is similar in principle to
|
||||
|
|
|
|||
|
|
@ -811,6 +811,11 @@ PUBLISHED:
|
|||
bool has_depth_offset() const;
|
||||
int get_depth_offset() const;
|
||||
|
||||
void set_depth_bias(PN_stdfloat slope_factor, PN_stdfloat constant_factor,
|
||||
PN_stdfloat clamp = 0.0, int priority = 0);
|
||||
void clear_depth_bias();
|
||||
bool has_depth_bias() const;
|
||||
|
||||
void do_billboard_axis(const NodePath &camera, PN_stdfloat offset);
|
||||
void do_billboard_point_eye(const NodePath &camera, PN_stdfloat offset);
|
||||
void do_billboard_point_world(const NodePath &camera, PN_stdfloat offset);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include "cullTraverserData.cxx"
|
||||
#include "cullableObject.cxx"
|
||||
#include "decalEffect.cxx"
|
||||
#include "depthBiasAttrib.cxx"
|
||||
#include "depthOffsetAttrib.cxx"
|
||||
#include "depthTestAttrib.cxx"
|
||||
#include "depthWriteAttrib.cxx"
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ get_start_sort() const {
|
|||
*/
|
||||
INLINE void PGTop::
|
||||
add_region(MouseWatcherRegion *region) {
|
||||
nassertv(_watcher_group != nullptr);
|
||||
_watcher_group->add_region(region);
|
||||
if (_watcher_group != nullptr) {
|
||||
_watcher_group->add_region(region);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -909,10 +909,14 @@ normalize() {
|
|||
*/
|
||||
void BitArray::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) const {
|
||||
dg.add_uint32(_array.size());
|
||||
Array::const_iterator ai;
|
||||
for (ai = _array.begin(); ai != _array.end(); ++ai) {
|
||||
dg.add_uint32((*ai).get_word());
|
||||
dg.add_uint32(_array.size() * (num_bits_per_word >> 5));
|
||||
|
||||
for (MaskType &item : _array) {
|
||||
WordType word = item.get_word();
|
||||
for (size_t i = 0; i < num_bits_per_word; i += 32) {
|
||||
dg.add_uint32(word);
|
||||
word >>= 32;
|
||||
}
|
||||
}
|
||||
dg.add_uint8(_highest_bits);
|
||||
}
|
||||
|
|
@ -922,10 +926,16 @@ write_datagram(BamWriter *manager, Datagram &dg) const {
|
|||
*/
|
||||
void BitArray::
|
||||
read_datagram(DatagramIterator &scan, BamReader *manager) {
|
||||
size_t num_words = scan.get_uint32();
|
||||
_array = Array::empty_array(num_words);
|
||||
for (size_t i = 0; i < num_words; ++i) {
|
||||
_array[i] = WordType(scan.get_uint32());
|
||||
size_t num_words32 = scan.get_uint32();
|
||||
size_t num_bits = num_words32 << 5;
|
||||
|
||||
_array = Array::empty_array((num_bits + num_bits_per_word - 1) / num_bits_per_word);
|
||||
|
||||
for (size_t i = 0; i < num_bits; i += 32) {
|
||||
int w = i / num_bits_per_word;
|
||||
int b = i % num_bits_per_word;
|
||||
|
||||
_array[w].store(scan.get_uint32(), b, 32);
|
||||
}
|
||||
_highest_bits = scan.get_uint8();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ BamInfo() {
|
|||
|
||||
add_option
|
||||
("g", "", 0,
|
||||
"Output verbose information about the each Geom in the Bam file.",
|
||||
"Output verbose information about each Geom in the Bam file.",
|
||||
&BamInfo::dispatch_none, &_verbose_geoms);
|
||||
|
||||
_num_scene_graphs = 0;
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ classifiers =
|
|||
Programming Language :: Python :: 3.7
|
||||
Programming Language :: Python :: 3.8
|
||||
Programming Language :: Python :: 3.9
|
||||
Programming Language :: Python :: 3.10
|
||||
Programming Language :: Python :: Implementation :: CPython
|
||||
Topic :: Games/Entertainment
|
||||
Topic :: Multimedia
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ def depth_region(request, graphics_pipe):
|
|||
engine.remove_window(buffer)
|
||||
|
||||
|
||||
def render_depth_pixel(region, distance, near, far, clear=None, write=True):
|
||||
def render_depth_pixel(region, distance, near, far, clear=None, write=True, state=None):
|
||||
"""Renders a fragment at the specified distance using the specified render
|
||||
settings, and returns the resulting depth value."""
|
||||
|
||||
|
|
@ -65,6 +65,9 @@ def render_depth_pixel(region, distance, near, far, clear=None, write=True):
|
|||
scene.set_attrib(core.DepthTestAttrib.make(core.RenderAttrib.M_always))
|
||||
scene.set_depth_write(write)
|
||||
|
||||
if state:
|
||||
scene.set_state(scene.get_state().compose(state))
|
||||
|
||||
camera = scene.attach_new_node(core.Camera("camera"))
|
||||
camera.node().get_lens(0).set_near_far(near, far)
|
||||
camera.node().set_cull_bounds(core.OmniBoundingVolume())
|
||||
|
|
@ -151,3 +154,68 @@ def test_inverted_depth_clipping(depth_region):
|
|||
|
||||
# Just far enough; read a value close to 0.0.
|
||||
assert 0.01 > render_depth_pixel(depth_region, 9.999, near=10, far=1, clear=0.5)
|
||||
|
||||
|
||||
def test_depth_range(depth_region):
|
||||
try:
|
||||
depth_region.set_depth_range(0.25, 0.75)
|
||||
z = render_depth_pixel(depth_region, 1.00001, near=1, far=10, clear=0.0)
|
||||
assert z == pytest.approx(0.25, rel=0.01)
|
||||
|
||||
z = render_depth_pixel(depth_region, 9.99999, near=1, far=10, clear=0.0)
|
||||
assert z == pytest.approx(0.75, rel=0.01)
|
||||
|
||||
# Combines with DepthOffsetAttrib range.
|
||||
state = core.RenderState.make(core.DepthOffsetAttrib.make(0, 0.25, 0.75))
|
||||
z = render_depth_pixel(depth_region, 1.00001, near=1, far=10, clear=0.0, state=state)
|
||||
assert z == pytest.approx(0.375, rel=0.01)
|
||||
|
||||
# Reverse the depth range.
|
||||
depth_region.set_depth_range(0.75, 0.25)
|
||||
z = render_depth_pixel(depth_region, 1.00001, near=1, far=10, clear=0.0)
|
||||
assert z == pytest.approx(0.75, rel=0.01)
|
||||
|
||||
z = render_depth_pixel(depth_region, 9.99999, near=1, far=10, clear=0.0)
|
||||
assert z == pytest.approx(0.25, rel=0.01)
|
||||
finally:
|
||||
depth_region.set_depth_range(0, 1)
|
||||
|
||||
|
||||
def test_depth_bias(depth_region):
|
||||
# Without depth bias
|
||||
z_ref = render_depth_pixel(depth_region, 5, near=1, far=10)
|
||||
|
||||
# With constant positive depth bias
|
||||
state = core.RenderState.make(core.DepthBiasAttrib.make(0, 1))
|
||||
z = render_depth_pixel(depth_region, 5, near=1, far=10, state=state)
|
||||
assert z > z_ref
|
||||
|
||||
# With constant negative depth bias
|
||||
state = core.RenderState.make(core.DepthBiasAttrib.make(0, -1))
|
||||
z = render_depth_pixel(depth_region, 5, near=1, far=10, state=state)
|
||||
assert z < z_ref
|
||||
|
||||
# With slope-scaled depth bias (our quad has no slope)
|
||||
state = core.RenderState.make(core.DepthBiasAttrib.make(10, 0))
|
||||
z = render_depth_pixel(depth_region, 5, near=1, far=10, state=state)
|
||||
assert z == z_ref
|
||||
|
||||
# Same, but negative
|
||||
state = core.RenderState.make(core.DepthBiasAttrib.make(-10, 0))
|
||||
z = render_depth_pixel(depth_region, 5, near=1, far=10, state=state)
|
||||
assert z == z_ref
|
||||
|
||||
|
||||
def test_depth_offset(depth_region):
|
||||
# Without depth offset
|
||||
z_ref = render_depth_pixel(depth_region, 5, near=1, far=10)
|
||||
|
||||
# With constant positive depth offset
|
||||
state = core.RenderState.make(core.DepthOffsetAttrib.make(1))
|
||||
z = render_depth_pixel(depth_region, 5, near=1, far=10, state=state)
|
||||
assert z < z_ref
|
||||
|
||||
# With constant negative depth offset
|
||||
state = core.RenderState.make(core.DepthOffsetAttrib.make(-1))
|
||||
z = render_depth_pixel(depth_region, 5, near=1, far=10, state=state)
|
||||
assert z > z_ref
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from math import floor, ceil
|
||||
import sys
|
||||
|
||||
from panda3d.core import Vec2, Vec3, Vec4, Vec2F, Vec2D
|
||||
from panda3d import core
|
||||
|
|
@ -124,6 +125,7 @@ def test_vec2_rmul():
|
|||
assert 2 * Vec2(3, -4) == Vec2(6, -8)
|
||||
|
||||
|
||||
@pytest.mark.xfail(sys.platform == "win32", reason="unknown precision issue")
|
||||
@pytest.mark.parametrize("type", (core.LVecBase2f, core.LVecBase2d, core.LVecBase2i))
|
||||
def test_vec2_floordiv(type):
|
||||
with pytest.raises(ZeroDivisionError):
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from math import floor, ceil
|
||||
import sys
|
||||
|
||||
from panda3d.core import Vec2, Vec3, Vec3F, Vec3D
|
||||
from panda3d import core
|
||||
|
|
@ -109,6 +110,7 @@ def test_vec3_rmul():
|
|||
assert 2 * Vec3(0, 3, -4) == Vec3(0, 6, -8)
|
||||
|
||||
|
||||
@pytest.mark.xfail(sys.platform == "win32", reason="unknown precision issue")
|
||||
@pytest.mark.parametrize("type", (core.LVecBase3f, core.LVecBase3d, core.LVecBase3i))
|
||||
def test_vec3_floordiv(type):
|
||||
with pytest.raises(ZeroDivisionError):
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from math import floor, ceil
|
||||
import sys
|
||||
|
||||
from panda3d.core import Vec2, Vec3, Vec4, Vec4F, Vec4D
|
||||
from panda3d import core
|
||||
|
|
@ -125,6 +126,7 @@ def test_vec4_rmul():
|
|||
assert 2 * Vec4(0, 3, -4, 0.5) == Vec4(0, 6, -8, 1)
|
||||
|
||||
|
||||
@pytest.mark.xfail(sys.platform == "win32", reason="unknown precision issue")
|
||||
@pytest.mark.parametrize("type", (core.LVecBase4f, core.LVecBase4d, core.LVecBase4i))
|
||||
def test_vec4_floordiv(type):
|
||||
with pytest.raises(ZeroDivisionError):
|
||||
|
|
|
|||
Loading…
Reference in New Issue