From 3dc09c38d30c04ccf08bd8b28c7b05919d0a9d53 Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 31 Jul 2021 09:56:52 +0200 Subject: [PATCH 01/29] dxgsg9: Fix crash when resizing window in multi-window setup Fixes #1167 --- panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index bd36f99da3..0138463260 100644 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -4767,6 +4767,9 @@ release_swap_chain(DXScreenData *new_context) { wdxdisplay9_cat.debug() << "Swapchain release failed:" << D3DERRORSTRING(hr) << "\n"; return false; } + if (new_context->_swap_chain == _swap_chain) { + _swap_chain = nullptr; + } } return true; } From ea45ff691dcc5ab7c25f57f932648a91e3e5f1f4 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 3 Aug 2021 11:43:11 +0200 Subject: [PATCH 02/29] display: Improve error message when display module isn't loaded --- panda/src/display/graphicsPipeSelection.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/panda/src/display/graphicsPipeSelection.cxx b/panda/src/display/graphicsPipeSelection.cxx index cdf68c3d1c..8be3f856a8 100644 --- a/panda/src/display/graphicsPipeSelection.cxx +++ b/panda/src/display/graphicsPipeSelection.cxx @@ -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"; } From 1f84469cd994b950b44b84599707fecdabd65d1c Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 3 Aug 2021 10:59:10 +0200 Subject: [PATCH 03/29] filter: Fix issue with cached CullResult persisting after cleanup This can cause issues if a DR gets assigned an inactive camera - the old cull result will persist and be used for draw. Possibly we need to do this in set_camera. Reproduced by #1166 --- direct/src/filter/FilterManager.py | 2 ++ panda/src/display/displayRegion.cxx | 9 +++++++++ panda/src/display/displayRegion.h | 1 + 3 files changed, 12 insertions(+) diff --git a/direct/src/filter/FilterManager.py b/direct/src/filter/FilterManager.py index 7e76bd686a..784a2cc2b3 100644 --- a/direct/src/filter/FilterManager.py +++ b/direct/src/filter/FilterManager.py @@ -366,6 +366,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() - 1000 self.basex = 0 self.basey = 0 diff --git a/panda/src/display/displayRegion.cxx b/panda/src/display/displayRegion.cxx index 4629a38f75..cddfd2b4a5 100644 --- a/panda/src/display/displayRegion.cxx +++ b/panda/src/display/displayRegion.cxx @@ -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. diff --git a/panda/src/display/displayRegion.h b/panda/src/display/displayRegion.h index 280edaa333..0aa9d2b998 100644 --- a/panda/src/display/displayRegion.h +++ b/panda/src/display/displayRegion.h @@ -160,6 +160,7 @@ PUBLISHED: bool get_screenshot(PNMImage &image); PT(Texture) get_screenshot(); + void clear_cull_result(); virtual PT(PandaNode) make_cull_result_graph(); public: From 7ac7a958436ae1c41b29b9a92a4b62d4525f3167 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 3 Aug 2021 11:42:04 +0200 Subject: [PATCH 04/29] glgsg: Delete multisample FBO properly Related to #1166 --- panda/src/glstuff/glGraphicsBuffer_src.cxx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/panda/src/glstuff/glGraphicsBuffer_src.cxx b/panda/src/glstuff/glGraphicsBuffer_src.cxx index e6d508ee9f..35a4e2f5db 100644 --- a/panda/src/glstuff/glGraphicsBuffer_src.cxx +++ b/panda/src/glstuff/glGraphicsBuffer_src.cxx @@ -1697,6 +1697,11 @@ close_buffer() { _fbo.clear(); } + if (_fbo_multisample != 0) { + glgsg->_glDeleteFramebuffers(1, &_fbo_multisample); + _fbo_multisample = 0; + } + report_my_gl_errors(); // Release the Gsg From 0932009e18fd4f3c3b5549b627f66fc740492ade Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 3 Aug 2021 13:25:56 +0200 Subject: [PATCH 05/29] pandatool: Fix typo in bam-info help page --- doc/man/bam-info.1 | 2 +- pandatool/src/bam/bamInfo.cxx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/man/bam-info.1 b/doc/man/bam-info.1 index c9432acd7a..b830554603 100644 --- a/doc/man/bam-info.1 +++ b/doc/man/bam-info.1 @@ -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. diff --git a/pandatool/src/bam/bamInfo.cxx b/pandatool/src/bam/bamInfo.cxx index a30a5066dd..291d33798c 100644 --- a/pandatool/src/bam/bamInfo.cxx +++ b/pandatool/src/bam/bamInfo.cxx @@ -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; From f30019af13e9a9372fafc831a69140a987889876 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 3 Aug 2021 15:49:11 +0200 Subject: [PATCH 06/29] tests: xfail vector floor division tests on Windows Can't figure this one out for now. --- tests/linmath/test_lvector2.py | 1 + tests/linmath/test_lvector3.py | 1 + tests/linmath/test_lvector4.py | 1 + 3 files changed, 3 insertions(+) diff --git a/tests/linmath/test_lvector2.py b/tests/linmath/test_lvector2.py index 1bb17aee7e..50d1e2e393 100644 --- a/tests/linmath/test_lvector2.py +++ b/tests/linmath/test_lvector2.py @@ -124,6 +124,7 @@ def test_vec2_ceil(): assert rounded_vector.y == -2 +@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): diff --git a/tests/linmath/test_lvector3.py b/tests/linmath/test_lvector3.py index 44fc17e015..03eafaa014 100644 --- a/tests/linmath/test_lvector3.py +++ b/tests/linmath/test_lvector3.py @@ -109,6 +109,7 @@ def test_vec3_ceil(): assert rounded_vector.z == 4 +@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): diff --git a/tests/linmath/test_lvector4.py b/tests/linmath/test_lvector4.py index 3fd283e2d3..a7ead81690 100644 --- a/tests/linmath/test_lvector4.py +++ b/tests/linmath/test_lvector4.py @@ -125,6 +125,7 @@ def test_vec4_ceil(): assert rounded_vector.w == 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): From d545dbd6ebff527a5b1ec67397b36e165a319e1e Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 3 Aug 2021 18:22:30 +0200 Subject: [PATCH 07/29] test_wheel: Fix for Python 3.4 [skip ci] --- makepanda/test_wheel.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/makepanda/test_wheel.py b/makepanda/test_wheel.py index 73e4bb8e13..e234891425 100755 --- a/makepanda/test_wheel.py +++ b/makepanda/test_wheel.py @@ -50,8 +50,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) From 5b30fa7adf6a02cf86b1f2c7d1ee019b91e141ba Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 3 Aug 2021 20:13:56 +0200 Subject: [PATCH 08/29] putil: Fix reading/writing BitArray from/to bam file on 64-bit Fixes #1181 --- panda/src/putil/bitArray.cxx | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/panda/src/putil/bitArray.cxx b/panda/src/putil/bitArray.cxx index aab43ee99e..e7364584f6 100644 --- a/panda/src/putil/bitArray.cxx +++ b/panda/src/putil/bitArray.cxx @@ -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(); } From 2a5b5030bad3438c1afcf3e21b615bbe8a8e55c7 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 4 Aug 2021 13:18:14 +0200 Subject: [PATCH 09/29] dtoolbase: Fix ability to use std::round() compiling for macOS 10.6 --- dtool/src/dtoolbase/dtoolbase_cc.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/dtool/src/dtoolbase/dtoolbase_cc.h b/dtool/src/dtoolbase/dtoolbase_cc.h index 8894469422..dd73c7554d 100644 --- a/dtool/src/dtoolbase/dtoolbase_cc.h +++ b/dtool/src/dtoolbase/dtoolbase_cc.h @@ -162,6 +162,18 @@ namespace std { __atomic_clear(&_flag, order); } }; + + ALWAYS_INLINE float round(float arg) { + return ::roundf(arg); + } + ALWAYS_INLINE double round(double arg) { + return ::round(arg); + } + ALWAYS_INLINE long double round(long double arg) { + return ::roundl(arg); + } + using ::roundf; + using ::roundl; }; #else // Expect that we have access to the header. From 4a33e8866ee2cd02b9d48570f7d7ef20c63c7e0e Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 4 Aug 2021 13:35:27 +0200 Subject: [PATCH 10/29] dtoolbase: Add missing overloads for std::round on macOS 10.6 --- dtool/src/dtoolbase/dtoolbase_cc.h | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/dtool/src/dtoolbase/dtoolbase_cc.h b/dtool/src/dtoolbase/dtoolbase_cc.h index dd73c7554d..9845adfcc1 100644 --- a/dtool/src/dtoolbase/dtoolbase_cc.h +++ b/dtool/src/dtoolbase/dtoolbase_cc.h @@ -172,6 +172,36 @@ namespace std { ALWAYS_INLINE long double round(long double arg) { return ::roundl(arg); } + ALWAYS_INLINE double round(signed char arg) { + return (double)arg; + } + ALWAYS_INLINE double round(unsigned char arg) { + return (double)arg; + } + ALWAYS_INLINE double round(short arg) { + return (double)arg; + } + ALWAYS_INLINE double round(unsigned short arg) { + return (double)arg; + } + ALWAYS_INLINE double round(int arg) { + return (double)arg; + } + ALWAYS_INLINE double round(unsigned int arg) { + return (double)arg; + } + ALWAYS_INLINE double round(long arg) { + return (double)arg; + } + ALWAYS_INLINE double round(unsigned long arg) { + return (double)arg; + } + ALWAYS_INLINE double round(long long arg) { + return (double)arg; + } + ALWAYS_INLINE double round(unsigned long long arg) { + return (double)arg; + } using ::roundf; using ::roundl; }; From 20e081482fb052fab2c48ba5fb7c0a4cda21335f Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 5 Aug 2021 09:36:51 +0200 Subject: [PATCH 11/29] glgsg: detect and fix overlapping SSBO bindings Fixes #1176 --- .../src/glstuff/glGraphicsStateGuardian_src.cxx | 2 ++ panda/src/glstuff/glGraphicsStateGuardian_src.h | 1 + panda/src/glstuff/glShaderContext_src.cxx | 16 ++++++++++++++++ 3 files changed, 19 insertions(+) diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 95521ece40..4f0a30df8a 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -2134,6 +2134,8 @@ reset() { get_extension_func("glGetProgramResourceName"); _glGetProgramResourceiv = (PFNGLGETPROGRAMRESOURCEIVPROC) get_extension_func("glGetProgramResourceiv"); + _glShaderStorageBlockBinding = (PFNGLSHADERSTORAGEBLOCKBINDINGPROC) + get_extension_func("glShaderStorageBlockBinding"); } else #endif { diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index 02e22961ce..19d4a63d68 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -1068,6 +1068,7 @@ public: PFNGLGETPROGRAMINTERFACEIVPROC _glGetProgramInterfaceiv; PFNGLGETPROGRAMRESOURCENAMEPROC _glGetProgramResourceName; PFNGLGETPROGRAMRESOURCEIVPROC _glGetProgramResourceiv; + PFNGLSHADERSTORAGEBLOCKBINDINGPROC _glShaderStorageBlockBinding; #endif // !OPENGLES GLenum _edge_clamp; diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index 2abe4659ea..e0db33e350 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -341,6 +341,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); @@ -349,6 +351,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]; From 8ad4234df8ac90131fadc161545c3ad159760c77 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 11 Aug 2021 09:19:03 +0200 Subject: [PATCH 12/29] pgui: prevent error when rendering in offscreen mode Fixes #1174 --- panda/src/pgui/pgTop.I | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/panda/src/pgui/pgTop.I b/panda/src/pgui/pgTop.I index 775e8cf827..24823b577b 100644 --- a/panda/src/pgui/pgTop.I +++ b/panda/src/pgui/pgTop.I @@ -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); + } } From 280175f267fc12046dbb6c2a5ee41773eb525087 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 26 Aug 2021 10:42:25 +0200 Subject: [PATCH 13/29] display: Support specifying depth range on DisplayRegion See https://discourse.panda3d.org/t/depthoffsetattrib-z-range-composition-order/27943/4 --- panda/src/display/displayRegion.I | 32 ++++++++ panda/src/display/displayRegion.cxx | 6 +- panda/src/display/displayRegion.h | 6 ++ .../glstuff/glGraphicsStateGuardian_src.cxx | 75 ++++++++++++++++--- .../src/glstuff/glGraphicsStateGuardian_src.h | 3 + tests/display/test_depth_buffer.py | 30 +++++++- 6 files changed, 137 insertions(+), 15 deletions(-) diff --git a/panda/src/display/displayRegion.I b/panda/src/display/displayRegion.I index 71b3a069cf..0377a90073 100644 --- a/panda/src/display/displayRegion.I +++ b/panda/src/display/displayRegion.I @@ -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, PN_stdfloat far) { + CDWriter cdata(_cycler, true); + cdata->_depth_range.set(near, far); +} + +/** + * + */ +INLINE void DisplayRegion:: +get_depth_range(PN_stdfloat &near, PN_stdfloat &far) const { + CDReader cdata(_cycler); + const LVecBase2 &range = cdata->_depth_range; + near = range[0]; + far = 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, PN_stdfloat &far) const { + const LVecBase2 &range = _cdata->_depth_range; + near = range[0]; + far = range[1]; +} + /** * Returns the GraphicsOutput that this DisplayRegion is ultimately associated * with, or NULL if no window is associated. diff --git a/panda/src/display/displayRegion.cxx b/panda/src/display/displayRegion.cxx index cddfd2b4a5..b29d490d03 100644 --- a/panda/src/display/displayRegion.cxx +++ b/panda/src/display/displayRegion.cxx @@ -738,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()); } @@ -757,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) { } diff --git a/panda/src/display/displayRegion.h b/panda/src/display/displayRegion.h index 0aa9d2b998..f5d25639a3 100644 --- a/panda/src/display/displayRegion.h +++ b/panda/src/display/displayRegion.h @@ -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; @@ -233,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 @@ -333,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; diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 74d9f208b3..426597b83e 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -528,6 +528,7 @@ CLP(GraphicsStateGuardian)(GraphicsEngine *engine, GraphicsPipe *pipe) : _scissor_enabled = false; _scissor_attrib_active = false; + _has_attrib_depth_range = false; _white_texture = 0; @@ -3337,6 +3338,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() @@ -3352,6 +3354,17 @@ 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; + } + // Set up all the enableddisabled flags to GL's known initial values: // everything off. _multisample_mode = 0; @@ -3926,6 +3939,33 @@ prepare_display_region(DisplayRegionPipelineReader *dr) { } } + PN_stdfloat near; + PN_stdfloat far; + dr->get_depth_range(near, far); +#ifdef GSG_VERBOSE + if (GLCAT.is_spam()) { + GLCAT.spam() + << "glDepthRange(" << near << ", " << far << ")" << endl; + } +#endif + +#ifdef OPENGLES + // OpenGL ES uses a single-precision call. + glDepthRangef((GLclampf)near, (GLclampf)far); +#else + // Mainline OpenGL uses a double-precision call. + if (!_use_remapped_depth_range) { + glDepthRange((GLclampd)near, (GLclampd)far); + } 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(near * 2.0 - 1.0, far * 2.0 - 1.0); + } +#endif // OPENGLES + _has_attrib_depth_range = false; + _depth_range_near = near; + _depth_range_far = far; + report_my_gl_errors(); } @@ -8151,24 +8191,35 @@ do_issue_depth_offset() { 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(); } diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index 83f2721fa3..656ee40e5b 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -675,6 +675,9 @@ protected: bool _scissor_enabled; bool _scissor_attrib_active; epvector _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; diff --git a/tests/display/test_depth_buffer.py b/tests/display/test_depth_buffer.py index c655758703..b1352fac14 100644 --- a/tests/display/test_depth_buffer.py +++ b/tests/display/test_depth_buffer.py @@ -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,28 @@ 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) + assert z == pytest.approx(0.25, rel=0.01) + + z = render_depth_pixel(depth_region, 10, near=1, far=10) + 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, 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) + assert z == pytest.approx(0.75, rel=0.01) + + z = render_depth_pixel(depth_region, 10, near=1, far=10) + assert z == pytest.approx(0.25, rel=0.01) + finally: + depth_region.set_depth_range(0, 1) From 53741ffa136978377d9a84cfd35110f45c1755dc Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 26 Aug 2021 10:45:09 +0200 Subject: [PATCH 14/29] pgraph: Implement new DepthBiasAttrib to replace DepthOffsetAttrib Fixes #1157 --- .../glstuff/glGraphicsStateGuardian_src.cxx | 61 +++++- .../src/glstuff/glGraphicsStateGuardian_src.h | 5 +- panda/src/pgraph/CMakeLists.txt | 2 + panda/src/pgraph/config_pgraph.cxx | 3 + panda/src/pgraph/depthBiasAttrib.I | 49 +++++ panda/src/pgraph/depthBiasAttrib.cxx | 180 ++++++++++++++++++ panda/src/pgraph/depthBiasAttrib.h | 115 +++++++++++ panda/src/pgraph/depthOffsetAttrib.h | 2 + panda/src/pgraph/nodePath.cxx | 39 +++- panda/src/pgraph/nodePath.h | 5 + panda/src/pgraph/p3pgraph_composite2.cxx | 1 + tests/display/test_depth_buffer.py | 40 ++++ 12 files changed, 491 insertions(+), 11 deletions(-) create mode 100644 panda/src/pgraph/depthBiasAttrib.I create mode 100644 panda/src/pgraph/depthBiasAttrib.cxx create mode 100644 panda/src/pgraph/depthBiasAttrib.h diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 426597b83e..6638903594 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -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 @@ -626,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()); @@ -3365,6 +3374,21 @@ reset() { _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; @@ -8173,19 +8197,34 @@ 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); } @@ -11785,11 +11824,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); } diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index 656ee40e5b..1bc31174c8 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -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(); @@ -772,6 +772,9 @@ public: bool _use_remapped_depth_range; PFNGLDEPTHRANGEDNVPROC _glDepthRangedNV; #endif +#ifndef OPENGLES_1 + PFNGLPOLYGONOFFSETCLAMPEXTPROC _glPolygonOffsetClamp; +#endif bool _supports_point_parameters; PFNGLPOINTPARAMETERFVPROC _glPointParameterfv; diff --git a/panda/src/pgraph/CMakeLists.txt b/panda/src/pgraph/CMakeLists.txt index 2eb4d98a06..85c041f01b 100644 --- a/panda/src/pgraph/CMakeLists.txt +++ b/panda/src/pgraph/CMakeLists.txt @@ -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 diff --git a/panda/src/pgraph/config_pgraph.cxx b/panda/src/pgraph/config_pgraph.cxx index d13e6e8c95..406f8fa41a 100644 --- a/panda/src/pgraph/config_pgraph.cxx +++ b/panda/src/pgraph/config_pgraph.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(); diff --git a/panda/src/pgraph/depthBiasAttrib.I b/panda/src/pgraph/depthBiasAttrib.I new file mode 100644 index 0000000000..6a73641c8e --- /dev/null +++ b/panda/src/pgraph/depthBiasAttrib.I @@ -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; +} diff --git a/panda/src/pgraph/depthBiasAttrib.cxx b/panda/src/pgraph/depthBiasAttrib.cxx new file mode 100644 index 0000000000..4a5e8273de --- /dev/null +++ b/panda/src/pgraph/depthBiasAttrib.cxx @@ -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(); +} diff --git a/panda/src/pgraph/depthBiasAttrib.h b/panda/src/pgraph/depthBiasAttrib.h new file mode 100644 index 0000000000..75fcdd3dc9 --- /dev/null +++ b/panda/src/pgraph/depthBiasAttrib.h @@ -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 diff --git a/panda/src/pgraph/depthOffsetAttrib.h b/panda/src/pgraph/depthOffsetAttrib.h index 54fef347d5..6f868cec88 100644 --- a/panda/src/pgraph/depthOffsetAttrib.h +++ b/panda/src/pgraph/depthOffsetAttrib.h @@ -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: diff --git a/panda/src/pgraph/nodePath.cxx b/panda/src/pgraph/nodePath.cxx index 5c7dbbbdaf..c6ea2bff6b 100644 --- a/panda/src/pgraph/nodePath.cxx +++ b/panda/src/pgraph/nodePath.cxx @@ -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" @@ -4684,6 +4685,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 +4733,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 diff --git a/panda/src/pgraph/nodePath.h b/panda/src/pgraph/nodePath.h index 187129d30c..66bf5eb9ae 100644 --- a/panda/src/pgraph/nodePath.h +++ b/panda/src/pgraph/nodePath.h @@ -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); diff --git a/panda/src/pgraph/p3pgraph_composite2.cxx b/panda/src/pgraph/p3pgraph_composite2.cxx index 88dc14b398..139ee34c63 100644 --- a/panda/src/pgraph/p3pgraph_composite2.cxx +++ b/panda/src/pgraph/p3pgraph_composite2.cxx @@ -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" diff --git a/tests/display/test_depth_buffer.py b/tests/display/test_depth_buffer.py index b1352fac14..947287428a 100644 --- a/tests/display/test_depth_buffer.py +++ b/tests/display/test_depth_buffer.py @@ -179,3 +179,43 @@ def test_depth_range(depth_region): 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 From 7462cee18b11d502438cb645a63a7a08e20cd01e Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 26 Aug 2021 10:47:38 +0200 Subject: [PATCH 15/29] dist: Use manylinux2010 instead of manylinux1 by default --- direct/src/dist/commands.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/direct/src/dist/commands.py b/direct/src/dist/commands.py index fec2793c2a..d2d4946dca 100644 --- a/direct/src/dist/commands.py +++ b/direct/src/dist/commands.py @@ -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'] } From 32b78a382a7659c56a019acecda5039a715b36e0 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 30 Aug 2021 14:00:59 +0200 Subject: [PATCH 16/29] express: Protect clock debug print with is_debug() check --- panda/src/express/trueClock.cxx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/panda/src/express/trueClock.cxx b/panda/src/express/trueClock.cxx index f60ddc22dc..3f7d66bc60 100644 --- a/panda/src/express/trueClock.cxx +++ b/panda/src/express/trueClock.cxx @@ -243,10 +243,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 From 481fc679962bff05cbab2d3f3b968cca72ad06ad Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 30 Aug 2021 14:01:43 +0200 Subject: [PATCH 17/29] gles2gsg: Support gl-depth-zero-to-one in OpenGL ES 2+ Requires GL_EXT_clip_control support in the driver. --- panda/src/gles2gsg/gles2gsg.h | 2 ++ panda/src/gles2gsg/panda_esgl2ext.h | 14 ++++++++++ .../glstuff/glGraphicsStateGuardian_src.cxx | 27 ++++++++++++------- .../src/glstuff/glGraphicsStateGuardian_src.h | 4 ++- 4 files changed, 36 insertions(+), 11 deletions(-) diff --git a/panda/src/gles2gsg/gles2gsg.h b/panda/src/gles2gsg/gles2gsg.h index c328c99ac4..044ac72991 100644 --- a/panda/src/gles2gsg/gles2gsg.h +++ b/panda/src/gles2gsg/gles2gsg.h @@ -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 diff --git a/panda/src/gles2gsg/panda_esgl2ext.h b/panda/src/gles2gsg/panda_esgl2ext.h index 6d5258fff0..888e8e2553 100644 --- a/panda/src/gles2gsg/panda_esgl2ext.h +++ b/panda/src/gles2gsg/panda_esgl2ext.h @@ -1050,6 +1050,20 @@ GL_APICALL void GL_APIENTRY glBufferStorageEXT (GLenum target, GLsizeiptr size, #endif #endif /* GL_EXT_buffer_storage */ +#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 */ diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 4f0a30df8a..2bbeff7665 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -3293,23 +3293,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 diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index 19d4a63d68..c889545fc9 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -761,9 +761,11 @@ 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 From 8c01f7fafff2385275eb3b94f2cf7afa75319468 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 30 Aug 2021 14:02:41 +0200 Subject: [PATCH 18/29] gles2gsg: Implement support for GL_EXT_clear_texture in OpenGL ES 2+ --- panda/src/gles2gsg/panda_esgl2ext.h | 10 ++++++++++ panda/src/glstuff/glGraphicsStateGuardian_src.cxx | 12 ++++++++++++ panda/src/glstuff/glGraphicsStateGuardian_src.h | 6 +++--- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/panda/src/gles2gsg/panda_esgl2ext.h b/panda/src/gles2gsg/panda_esgl2ext.h index 888e8e2553..a95d9b001b 100644 --- a/panda/src/gles2gsg/panda_esgl2ext.h +++ b/panda/src/gles2gsg/panda_esgl2ext.h @@ -1050,6 +1050,16 @@ 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 diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 2bbeff7665..8aba915666 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -1080,6 +1080,18 @@ reset() { _supports_clear_texture = true; } } +#elif !defined(OPENGLES_1) + if (has_extension("GL_EXT_clear_texture")) { + _glClearTexImage = (PFNGLCLEARTEXIMAGEEXTPROC) + get_extension_func("glClearTexImageEXT"); + + if (_glClearTexImage == nullptr) { + GLCAT.warning() + << "GL_EXT_clear_texture advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n"; + } else { + _supports_clear_texture = true; + } + } #endif _supports_clear_buffer = false; diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index c889545fc9..6457cc920c 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -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); @@ -804,7 +804,7 @@ public: #endif bool _supports_clear_texture; -#ifndef OPENGLES +#ifndef OPENGLES_1 PFNGLCLEARTEXIMAGEPROC _glClearTexImage; #endif From 2cc1633a772cd635bb8d95d420badf1f258b67d4 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 30 Aug 2021 14:03:17 +0200 Subject: [PATCH 19/29] pgraph: Clarify in find() documentation that this node not included --- panda/src/pgraph/nodePath.cxx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/panda/src/pgraph/nodePath.cxx b/panda/src/pgraph/nodePath.cxx index 5c7dbbbdaf..3e2430aa3c 100644 --- a/panda/src/pgraph/nodePath.cxx +++ b/panda/src/pgraph/nodePath.cxx @@ -309,6 +309,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 +351,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 { From b291db2556011a417844796a6ccc6ac495fb7450 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 30 Aug 2021 16:56:41 +0200 Subject: [PATCH 20/29] doc: Update release notes for 1.10.10 [skip ci] --- doc/ReleaseNotes | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/doc/ReleaseNotes b/doc/ReleaseNotes index d11b49b772..ccf0a771c3 100644 --- a/doc/ReleaseNotes +++ b/doc/ReleaseNotes @@ -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 From 3d386d2d630d928d6847bb41641073dbef592f19 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 30 Aug 2021 18:14:26 +0200 Subject: [PATCH 21/29] dist: Default to manylinux2010 for Python 3.10+ manylinux1 is not being offered for Python 3.10, so no thirdparty package will have wheels available for this --- direct/src/dist/commands.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/direct/src/dist/commands.py b/direct/src/dist/commands.py index 5a81ec49dc..47422a7e47 100644 --- a/direct/src/dist/commands.py +++ b/direct/src/dist/commands.py @@ -242,6 +242,9 @@ class build_apps(setuptools.Command): 'macosx_10_6_x86_64', 'win_amd64', ] + if sys.version_info >= (3, 10): + # manylinux1 is not offered for Python 3.10 anymore + self.platforms[0] = 'manylinux2010_x86_64' if sys.version_info >= (3, 8): # This version of Python is only available for 10.9+. self.platforms[1] = 'macosx_10_9_x86_64' @@ -1393,6 +1396,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'] } From cb4bcbe67ecbc5833ec4dcd39df35a76aede800b Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 30 Aug 2021 21:27:53 +0200 Subject: [PATCH 22/29] collide: Fix typo causing compile error on Windows with Python 3.10 --- panda/src/collide/collisionTraverser_ext.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda/src/collide/collisionTraverser_ext.cxx b/panda/src/collide/collisionTraverser_ext.cxx index 5dd6c171f6..460fab54aa 100644 --- a/panda/src/collide/collisionTraverser_ext.cxx +++ b/panda/src/collide/collisionTraverser_ext.cxx @@ -69,7 +69,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)); From 1fe5632ce20a8786f9d6f9d34c7ecdd2828d9138 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 30 Aug 2021 21:35:50 +0200 Subject: [PATCH 23/29] interrogatedb: Fix compilation error on Windows due to typo --- dtool/src/interrogatedb/py_wrappers.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dtool/src/interrogatedb/py_wrappers.cxx b/dtool/src/interrogatedb/py_wrappers.cxx index 6aed3d2bbb..7bcd57944c 100644 --- a/dtool/src/interrogatedb/py_wrappers.cxx +++ b/dtool/src/interrogatedb/py_wrappers.cxx @@ -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)); } /** From 6ac4af2f0b2d5135a723d81adbe1fd6c8ee20403 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 31 Aug 2021 09:17:31 +0200 Subject: [PATCH 24/29] Update BACKERS.md [skip ci] --- BACKERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/BACKERS.md b/BACKERS.md index 86fc18b77d..c34cb2a9d3 100644 --- a/BACKERS.md +++ b/BACKERS.md @@ -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 From 47836f11d802762ef89d452dd6e33b31f74c41f7 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 31 Aug 2021 09:17:59 +0200 Subject: [PATCH 25/29] readme: Update links for 1.10.10 [skip ci] --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index cc2404ee95..3be11f9b58 100644 --- a/README.md +++ b/README.md @@ -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: From 58879e05c9b566c15515f724ec65bc7179de1655 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 31 Aug 2021 11:31:24 +0200 Subject: [PATCH 26/29] Add Python 3.10 to setup.cfg [skip ci] --- setup.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.cfg b/setup.cfg index c3e6552be1..44e2b5dbef 100644 --- a/setup.cfg +++ b/setup.cfg @@ -22,6 +22,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 From c96189e53cb9267b09a51a9e162a6c23e00964c0 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 31 Aug 2021 14:01:03 +0200 Subject: [PATCH 27/29] display: Fix compilation on Windows (can't name variables near/far) --- panda/src/display/displayRegion.I | 16 ++++++++-------- .../glstuff/glGraphicsStateGuardian_src.cxx | 18 +++++++++--------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/panda/src/display/displayRegion.I b/panda/src/display/displayRegion.I index 0377a90073..ef18ab693e 100644 --- a/panda/src/display/displayRegion.I +++ b/panda/src/display/displayRegion.I @@ -162,20 +162,20 @@ set_dimensions(const LVecBase4 &dimensions) { * larger than the far value. */ INLINE void DisplayRegion:: -set_depth_range(PN_stdfloat near, PN_stdfloat far) { +set_depth_range(PN_stdfloat near_depth, PN_stdfloat far_depth) { CDWriter cdata(_cycler, true); - cdata->_depth_range.set(near, far); + cdata->_depth_range.set(near_depth, far_depth); } /** * */ INLINE void DisplayRegion:: -get_depth_range(PN_stdfloat &near, PN_stdfloat &far) const { +get_depth_range(PN_stdfloat &near_depth, PN_stdfloat &far_depth) const { CDReader cdata(_cycler); const LVecBase2 &range = cdata->_depth_range; - near = range[0]; - far = range[1]; + near_depth = range[0]; + far_depth = range[1]; } /** @@ -719,10 +719,10 @@ get_top(int i) const { * */ INLINE void DisplayRegionPipelineReader:: -get_depth_range(PN_stdfloat &near, PN_stdfloat &far) const { +get_depth_range(PN_stdfloat &near_depth, PN_stdfloat &far_depth) const { const LVecBase2 &range = _cdata->_depth_range; - near = range[0]; - far = range[1]; + near_depth = range[0]; + far_depth = range[1]; } /** diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 6638903594..e4e778326a 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -3963,32 +3963,32 @@ prepare_display_region(DisplayRegionPipelineReader *dr) { } } - PN_stdfloat near; - PN_stdfloat far; - dr->get_depth_range(near, far); + PN_stdfloat nearv; + PN_stdfloat farv; + dr->get_depth_range(nearv, farv); #ifdef GSG_VERBOSE if (GLCAT.is_spam()) { GLCAT.spam() - << "glDepthRange(" << near << ", " << far << ")" << endl; + << "glDepthRange(" << nearv << ", " << farv << ")" << endl; } #endif #ifdef OPENGLES // OpenGL ES uses a single-precision call. - glDepthRangef((GLclampf)near, (GLclampf)far); + glDepthRangef((GLclampf)nearv, (GLclampf)farv); #else // Mainline OpenGL uses a double-precision call. if (!_use_remapped_depth_range) { - glDepthRange((GLclampd)near, (GLclampd)far); + 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(near * 2.0 - 1.0, far * 2.0 - 1.0); + _glDepthRangedNV(nearv * 2.0 - 1.0, farv * 2.0 - 1.0); } #endif // OPENGLES _has_attrib_depth_range = false; - _depth_range_near = near; - _depth_range_far = far; + _depth_range_near = nearv; + _depth_range_far = farv; report_my_gl_errors(); } From 0ae8d8f31595d310b8716e1deb0402c69231a927 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 31 Aug 2021 14:02:49 +0200 Subject: [PATCH 28/29] tests: Robustify depth range test case --- tests/display/test_depth_buffer.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/display/test_depth_buffer.py b/tests/display/test_depth_buffer.py index 947287428a..cdbaffd370 100644 --- a/tests/display/test_depth_buffer.py +++ b/tests/display/test_depth_buffer.py @@ -159,23 +159,23 @@ def test_inverted_depth_clipping(depth_region): 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) + 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, 10, near=1, far=10) + 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, state=state) + 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) + 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, 10, near=1, far=10) + 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) From 2b0571ee92602bf24a07df8c9ef0587ea0b4e11a Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 31 Aug 2021 15:37:21 +0200 Subject: [PATCH 29/29] glgsg: Also pick up glClearTexSubImageEXT in OpenGL ES 2+ --- panda/src/glstuff/glGraphicsStateGuardian_src.cxx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 5c065b6a9b..d850364fe1 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -1108,10 +1108,12 @@ reset() { if (has_extension("GL_EXT_clear_texture")) { _glClearTexImage = (PFNGLCLEARTEXIMAGEEXTPROC) get_extension_func("glClearTexImageEXT"); + _glClearTexSubImage = (PFNGLCLEARTEXSUBIMAGEEXTPROC) + get_extension_func("glClearTexSubImageEXT"); - if (_glClearTexImage == nullptr) { + if (_glClearTexImage == nullptr || _glClearTexSubImage == nullptr) { GLCAT.warning() - << "GL_EXT_clear_texture advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n"; + << "GL_EXT_clear_texture advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n"; } else { _supports_clear_texture = true; }