From 52a7224d6ec86db4c18d18e658de0bbf79f649e2 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 14 Oct 2024 12:05:27 +0200 Subject: [PATCH 1/6] Fix various compiler warnings --- direct/src/interval/cMetaInterval.cxx | 4 +-- panda/src/display/graphicsStateGuardian.cxx | 14 ++++----- panda/src/egg2pg/eggSaver.cxx | 2 +- panda/src/glstuff/glShaderContext_src.cxx | 2 +- panda/src/text/textAssembler.cxx | 32 ++++++++++----------- pandatool/src/egg-qtess/isoPlacer.cxx | 2 +- 6 files changed, 28 insertions(+), 28 deletions(-) diff --git a/direct/src/interval/cMetaInterval.cxx b/direct/src/interval/cMetaInterval.cxx index 08f8887706..292b291a7c 100644 --- a/direct/src/interval/cMetaInterval.cxx +++ b/direct/src/interval/cMetaInterval.cxx @@ -679,7 +679,7 @@ write(std::ostream &out, int indent_level) const { int total_digits = num_decimals + 4; static const int max_digits = 32; // totally arbitrary nassertv(total_digits <= max_digits); - char format_str[16]; + char format_str[26]; sprintf(format_str, "%%%d.%df", total_digits, num_decimals); indent(out, indent_level) << get_name() << ":\n"; @@ -708,7 +708,7 @@ timeline(std::ostream &out) const { int total_digits = num_decimals + 4; static const int max_digits = 32; // totally arbitrary nassertv(total_digits <= max_digits); - char format_str[16]; + char format_str[26]; sprintf(format_str, "%%%d.%df", total_digits, num_decimals); int extra_indent_level = 0; diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index fb84f0cc96..2a89275809 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -1954,7 +1954,7 @@ fetch_specified_texture(Shader::ShaderTexSpec &spec, SamplerState &sampler, { const TextureAttrib *texattrib; if (_target_rs->get_attrib(texattrib)) { - size_t si = 0; + int si = 0; for (int i = 0; i < texattrib->get_num_on_stages(); ++i) { TextureStage *stage = texattrib->get_on_stage(i); TextureStage::Mode mode = stage->get_mode(); @@ -1977,7 +1977,7 @@ fetch_specified_texture(Shader::ShaderTexSpec &spec, SamplerState &sampler, { const TextureAttrib *texattrib; if (_target_rs->get_attrib(texattrib)) { - size_t si = 0; + int si = 0; for (int i = 0; i < texattrib->get_num_on_stages(); ++i) { TextureStage *stage = texattrib->get_on_stage(i); TextureStage::Mode mode = stage->get_mode(); @@ -2005,7 +2005,7 @@ fetch_specified_texture(Shader::ShaderTexSpec &spec, SamplerState &sampler, { const TextureAttrib *texattrib; if (_target_rs->get_attrib(texattrib)) { - size_t si = 0; + int si = 0; for (int i = 0; i < texattrib->get_num_on_stages(); ++i) { TextureStage *stage = texattrib->get_on_stage(i); TextureStage::Mode mode = stage->get_mode(); @@ -2034,7 +2034,7 @@ fetch_specified_texture(Shader::ShaderTexSpec &spec, SamplerState &sampler, { const TextureAttrib *texattrib; if (_target_rs->get_attrib(texattrib)) { - size_t si = 0; + int si = 0; for (int i = 0; i < texattrib->get_num_on_stages(); ++i) { TextureStage *stage = texattrib->get_on_stage(i); TextureStage::Mode mode = stage->get_mode(); @@ -2057,7 +2057,7 @@ fetch_specified_texture(Shader::ShaderTexSpec &spec, SamplerState &sampler, { const TextureAttrib *texattrib; if (_target_rs->get_attrib(texattrib)) { - size_t si = 0; + int si = 0; for (int i = 0; i < texattrib->get_num_on_stages(); ++i) { TextureStage *stage = texattrib->get_on_stage(i); TextureStage::Mode mode = stage->get_mode(); @@ -2086,7 +2086,7 @@ fetch_specified_texture(Shader::ShaderTexSpec &spec, SamplerState &sampler, { const TextureAttrib *texattrib; if (_target_rs->get_attrib(texattrib)) { - size_t si = 0; + int si = 0; for (int i = 0; i < texattrib->get_num_on_stages(); ++i) { TextureStage *stage = texattrib->get_on_stage(i); TextureStage::Mode mode = stage->get_mode(); @@ -2107,7 +2107,7 @@ fetch_specified_texture(Shader::ShaderTexSpec &spec, SamplerState &sampler, { const TextureAttrib *texattrib; if (_target_rs->get_attrib(texattrib)) { - size_t si = 0; + int si = 0; for (int i = 0; i < texattrib->get_num_on_stages(); ++i) { TextureStage *stage = texattrib->get_on_stage(i); TextureStage::Mode mode = stage->get_mode(); diff --git a/panda/src/egg2pg/eggSaver.cxx b/panda/src/egg2pg/eggSaver.cxx index c9a38c3b7b..6dbcba16d2 100644 --- a/panda/src/egg2pg/eggSaver.cxx +++ b/panda/src/egg2pg/eggSaver.cxx @@ -809,7 +809,7 @@ convert_primitive(const GeomVertexData *vertex_data, // Check for a texture. const TextureAttrib *ta; if (net_state->get_attrib(ta)) { - for (size_t i = 0; i < ta->get_num_on_stages(); ++i) { + for (size_t i = 0; i < (size_t)ta->get_num_on_stages(); ++i) { TextureStage *tex_stage = ta->get_on_stage(i); EggTexture *egg_tex = get_egg_texture(ta->get_on_texture(tex_stage)); diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index 129c617b13..1de385095f 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -1756,7 +1756,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { << " is bound to image unit " << binding << "\n"; } - if (binding >= _glsl_img_inputs.size()) { + if (binding >= (GLint)_glsl_img_inputs.size()) { _glsl_img_inputs.resize(binding + 1); } diff --git a/panda/src/text/textAssembler.cxx b/panda/src/text/textAssembler.cxx index 2bfb3a13a8..e17771ca31 100644 --- a/panda/src/text/textAssembler.cxx +++ b/panda/src/text/textAssembler.cxx @@ -427,14 +427,14 @@ calc_r_c(int &r, int &c, int n) const { c = 0; int i = row._row_start; while (i < n - 1) { - if (_text_string[i]._character != text_soft_hyphen_key && - _text_string[i]._character != text_soft_break_key) { + if (_text_string[i]._character != (char32_t)text_soft_hyphen_key && + _text_string[i]._character != (char32_t)text_soft_break_key) { ++c; } ++i; } - if (_text_string[n - 1]._character != text_soft_hyphen_key && - _text_string[n - 1]._character != text_soft_break_key) { + if (_text_string[n - 1]._character != (char32_t)text_soft_hyphen_key && + _text_string[n - 1]._character != (char32_t)text_soft_break_key) { ++c; if (_text_string[n - 1]._character == '\n') { is_real_char = false; @@ -478,8 +478,8 @@ calc_index(int r, int c) const { // we have to scan past them to get n precisely. int n = row._row_start; while (c > 0) { - if (_text_string[n]._character != text_soft_hyphen_key && - _text_string[n]._character != text_soft_break_key) { + if (_text_string[n]._character != (char32_t)text_soft_hyphen_key && + _text_string[n]._character != (char32_t)text_soft_break_key) { --c; } ++n; @@ -797,13 +797,13 @@ scan_wtext(TextAssembler::TextString &output_string, const wstring::const_iterator &send, TextAssembler::ComputedProperties *current_cprops) { while (si != send) { - if ((*si) == text_push_properties_key) { + if ((*si) == (wchar_t)text_push_properties_key) { // This indicates a nested properties structure. Pull off the name of // the TextProperties structure, which is everything until the next // text_push_properties_key. wstring wname; ++si; - while (si != send && (*si) != text_push_properties_key) { + while (si != send && (*si) != (wchar_t)text_push_properties_key) { wname += (*si); ++si; } @@ -834,20 +834,20 @@ scan_wtext(TextAssembler::TextString &output_string, } } - } else if ((*si) == text_pop_properties_key) { + } else if ((*si) == (wchar_t)text_pop_properties_key) { // This indicates the undoing of a previous push_properties_key. We // simply return to the previous level. ++si; return; - } else if ((*si) == text_embed_graphic_key) { + } else if ((*si) == (wchar_t)text_embed_graphic_key) { // This indicates an embedded graphic. Pull off the name of the // TextGraphic structure, which is everything until the next // text_embed_graphic_key. wstring graphic_wname; ++si; - while (si != send && (*si) != text_embed_graphic_key) { + while (si != send && (*si) != (wchar_t)text_embed_graphic_key) { graphic_wname += (*si); ++si; } @@ -979,7 +979,7 @@ wordwrap_text() { } if (isspacew(_text_string[q]._character) || - _text_string[q]._character == text_soft_break_key) { + _text_string[q]._character == (char32_t)text_soft_break_key) { if (!last_was_space) { any_spaces = true; // We only care about logging whether there is a soft-hyphen @@ -996,7 +996,7 @@ wordwrap_text() { // A soft hyphen character is not printed, but marks a point at which we // might hyphenate a word if we need to. - if (_text_string[q]._character == text_soft_hyphen_key) { + if (_text_string[q]._character == (char32_t)text_soft_hyphen_key) { if (wordwrap_width > 0.0f) { // We only consider this as a possible hyphenation point if (a) it // is not the very first character, and (b) there is enough room for @@ -1103,8 +1103,8 @@ wordwrap_text() { } for (size_t pi = p; pi < q; pi++) { - if (_text_string[pi]._character != text_soft_hyphen_key && - _text_string[pi]._character != text_soft_break_key) { + if (_text_string[pi]._character != (char32_t)text_soft_hyphen_key && + _text_string[pi]._character != (char32_t)text_soft_break_key) { _text_block.back()._string.push_back(_text_string[pi]); } else { _text_block.back()._got_soft_hyphens = true; @@ -1547,7 +1547,7 @@ assemble_row(TextAssembler::TextRow &row, xpos = (floor(xpos / tab_width) + 1.0f) * tab_width; prev_char = -1; - } else if (character == text_soft_hyphen_key) { + } else if (character == (char32_t)text_soft_hyphen_key) { // And so is the 'soft-hyphen' key character. } else if (graphic != nullptr) { diff --git a/pandatool/src/egg-qtess/isoPlacer.cxx b/pandatool/src/egg-qtess/isoPlacer.cxx index 0c4cebeefa..5cad7df8c5 100644 --- a/pandatool/src/egg-qtess/isoPlacer.cxx +++ b/pandatool/src/egg-qtess/isoPlacer.cxx @@ -106,7 +106,7 @@ get_scores(int subdiv, int across, double ratio, */ void IsoPlacer:: place(int count, pvector &iso_points) { - int i; + //int i; /* // Count up the average curvature. From 822d35d15b3370f9b3b4777b2ad781cff3cde0fc Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 14 Oct 2024 14:26:20 +0200 Subject: [PATCH 2/6] putil: Minor SimpleHashMap::remove() optimization --- panda/src/putil/simpleHashMap.I | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/panda/src/putil/simpleHashMap.I b/panda/src/putil/simpleHashMap.I index 4f322faa86..14fb96386b 100644 --- a/panda/src/putil/simpleHashMap.I +++ b/panda/src/putil/simpleHashMap.I @@ -287,8 +287,8 @@ remove(const Key &key) { // Now remove this element. size_t last = _num_entries - 1; - size_t index = (size_t)index_array[slot]; - if (index < _num_entries) { + int index = index_array[slot]; + if ((size_t)index < _num_entries) { // Find the last element in the index array. int other_slot = find_slot(_table[last]._key); nassertr(other_slot != -1, false); @@ -296,7 +296,7 @@ remove(const Key &key) { // Swap it with the last one, so that we don't get any gaps in the table // of entries. - _table[index] = std::move(_table[last]); + _table[(size_t)index] = std::move(_table[last]); index_array[(size_t)other_slot] = index; } @@ -316,13 +316,13 @@ remove(const Key &key) { // Now we have put a hole in the index array. If there was a hash conflict // in the slot after this one, we have to move it down to close the hole. slot = next_hash(slot); - while (has_slot(slot)) { - size_t index = (size_t)index_array[slot]; + index = index_array[slot]; + while (index >= 0) { size_t wants_slot = get_hash(_table[index]._key); if (wants_slot != slot) { // This one was a hash conflict; try to put it where it belongs. We // can't just put it in n, since maybe it belongs somewhere after n. - while (wants_slot != slot && has_slot(wants_slot)) { + while (wants_slot != slot && index_array[wants_slot] >= 0) { wants_slot = next_hash(wants_slot); } if (wants_slot != slot) { @@ -336,6 +336,7 @@ remove(const Key &key) { // Continue until we encounter the next unused slot. Until we do, we // can't be sure we've found all of the potential hash conflicts. slot = next_hash(slot); + index = index_array[slot]; } #ifdef _DEBUG From 42e2659636f0495f6c0e97b75f37f2212f0d861e Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 24 Oct 2024 15:39:43 +0200 Subject: [PATCH 3/6] filter: Add Khronos PBR Neutral tonemapping operator Closes #1661 Fixes #1659 Co-authored-by: Raytopia <54505044+raytopianprojects@users.noreply.github.com> --- direct/src/filter/CommonFilters.py | 68 ++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 18 deletions(-) diff --git a/direct/src/filter/CommonFilters.py b/direct/src/filter/CommonFilters.py index 8c4857f1f9..06c2875796 100644 --- a/direct/src/filter/CommonFilters.py +++ b/direct/src/filter/CommonFilters.py @@ -99,9 +99,15 @@ void fshader(out float4 o_color : COLOR, """ +class ToneMap: + ACES = object() + PBR_NEUTRAL = object() + + class FilterConfig: pass + class CommonFilters: """ Class CommonFilters implements certain common image postprocessing @@ -279,16 +285,19 @@ class CommonFilters: text = "//Cg\n" if "HighDynamicRange" in configuration: - text += "static const float3x3 aces_input_mat = {\n" - text += " {0.59719, 0.35458, 0.04823},\n" - text += " {0.07600, 0.90834, 0.01566},\n" - text += " {0.02840, 0.13383, 0.83777},\n" - text += "};\n" - text += "static const float3x3 aces_output_mat = {\n" - text += " { 1.60475, -0.53108, -0.07367},\n" - text += " {-0.10208, 1.10813, -0.00605},\n" - text += " {-0.00327, -0.07276, 1.07602},\n" - text += "};\n" + tonemap = configuration["HighDynamicRange"] + if tonemap is ToneMap.ACES: + text += "static const float3x3 aces_input_mat = {\n" + text += " {0.59719, 0.35458, 0.04823},\n" + text += " {0.07600, 0.90834, 0.01566},\n" + text += " {0.02840, 0.13383, 0.83777},\n" + text += "};\n" + text += "static const float3x3 aces_output_mat = {\n" + text += " { 1.60475, -0.53108, -0.07367},\n" + text += " {-0.10208, 1.10813, -0.00605},\n" + text += " {-0.00327, -0.07276, 1.07602},\n" + text += "};\n" + text += "void vshader(float4 vtx_position : POSITION,\n" text += " out float4 l_position : POSITION,\n" @@ -381,10 +390,30 @@ class CommonFilters: if ("ExposureAdjust" in configuration): text += " o_color.rgb *= k_exposure;\n" - # With thanks to Stephen Hill! - if ("HighDynamicRange" in configuration): - text += " float3 aces_color = mul(aces_input_mat, o_color.rgb);\n" - text += " o_color.rgb = saturate(mul(aces_output_mat, (aces_color * (aces_color + 0.0245786f) - 0.000090537f) / (aces_color * (0.983729f * aces_color + 0.4329510f) + 0.238081f)));\n" + if "HighDynamicRange" in configuration: + tonemap = configuration["HighDynamicRange"] + if tonemap is ToneMap.ACES: + # With thanks to Stephen Hill! + text += " float3 aces_color = mul(aces_input_mat, o_color.rgb);\n" + text += " o_color.rgb = saturate(mul(aces_output_mat, (aces_color * (aces_color + 0.0245786f) - 0.000090537f) / (aces_color * (0.983729f * aces_color + 0.4329510f) + 0.238081f)));\n" + elif tonemap is ToneMap.PBR_NEUTRAL: + text += " const float start_compression = 0.8 - 0.04;\n" + text += " const float desaturation = 0.15;\n" + + text += " float x = min(o_color.r, min(o_color.g, o_color.b));\n" + text += " float offset = x < 0.08 ? x - 6.25 * x * x : 0.04;\n" + text += " o_color.rgb -= offset;\n" + + text += " float peak = max(o_color.r, max(o_color.g, o_color.b));\n" + + text += " if (peak >= start_compression) {\n" + text += " const float d = 1.0 - start_compression;\n" + text += " float new_peak = 1.0 - d * d / (peak + d - start_compression);\n" + text += " o_color.rgb *= new_peak / peak;\n" + text += " float g = 1.0 - 1.0 / (desaturation * (peak - new_peak) + 1.0);\n" + + text += " o_color.rgb = lerp(o_color.rgb, new_peak * float3(1, 1, 1), g);\n" + text += "}\n" if ("GammaAdjust" in configuration): gamma = configuration["GammaAdjust"] @@ -662,10 +691,10 @@ class CommonFilters: return self.reconfigure(old_enable, "SrgbEncode") return True - def setHighDynamicRange(self): + def setHighDynamicRange(self, tonemap=ToneMap.ACES): """ Enables HDR rendering by using a floating-point framebuffer, disabling color clamping on the main scene, and applying a tone map - operator (ACES). + operator (ACES or Khronos PBR Neutral). It may also be necessary to use setExposureAdjust to perform exposure compensation on the scene, depending on the lighting intensity. @@ -673,8 +702,11 @@ class CommonFilters: .. versionadded:: 1.10.7 """ - fullrebuild = (("HighDynamicRange" in self.configuration) is False) - self.configuration["HighDynamicRange"] = 1 + fullrebuild = "HighDynamicRange" not in self.configuration or \ + self.configuration["HighDynamicRange"] is not tonemap + if tonemap is not ToneMap.ACES and tonemap is not ToneMap.PBR_NEUTRAL: + raise ValueError("Invalid value for tonemap") + self.configuration["HighDynamicRange"] = tonemap return self.reconfigure(fullrebuild, "HighDynamicRange") def delHighDynamicRange(self): From b022fc9301a14bf0dd75b391e8ecbd3cfbbce568 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 24 Oct 2024 16:10:35 +0200 Subject: [PATCH 4/6] stdpy: Fix glob not finding files in VFS Half of fix to #1675 --- direct/src/stdpy/glob.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/direct/src/stdpy/glob.py b/direct/src/stdpy/glob.py index d1a4946c0e..022a05aeb5 100755 --- a/direct/src/stdpy/glob.py +++ b/direct/src/stdpy/glob.py @@ -56,7 +56,7 @@ def glob1(dirname, pattern): dirname = unicode(dirname, sys.getfilesystemencoding() or sys.getdefaultencoding()) try: - names = os.listdir(dirname) + names = file.listdir(dirname) except os.error: return [] if pattern[0] != '.': From aa0462a35acb213aa4e969266d906dc7a388ed86 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 24 Oct 2024 16:17:49 +0200 Subject: [PATCH 5/6] fsm: Fix "no attribute notifier" error in requestNext/Prev Fixes #1644 --- direct/src/fsm/FSM.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/direct/src/fsm/FSM.py b/direct/src/fsm/FSM.py index eb67f55c0a..d4e95f6887 100644 --- a/direct/src/fsm/FSM.py +++ b/direct/src/fsm/FSM.py @@ -420,10 +420,12 @@ class FSM(DirectObject): cur_index = self.stateArray.index(self.state) new_index = (cur_index + 1) % len(self.stateArray) self.request(self.stateArray[new_index], args) - else: + elif hasattr(self, 'notifier'): assert self.notifier.debug( "stateArray empty. Can't switch to next.") - + else: + assert self.notify.debug( + "stateArray empty. Can't switch to next.") finally: self.fsmLock.release() @@ -438,9 +440,12 @@ class FSM(DirectObject): cur_index = self.stateArray.index(self.state) new_index = (cur_index - 1) % len(self.stateArray) self.request(self.stateArray[new_index], args) - else: + elif hasattr(self, 'notifier'): assert self.notifier.debug( "stateArray empty. Can't switch to next.") + else: + assert self.notify.debug( + "stateArray empty. Can't switch to next.") finally: self.fsmLock.release() From d758d2b232e6501c9a53c375a69d2c6f7916903c Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 24 Oct 2024 16:41:56 +0200 Subject: [PATCH 6/6] pgui: Fix crash when PGEntry removes itself w/ background focus Fixes #1650 --- panda/src/pgui/pgItem.cxx | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/panda/src/pgui/pgItem.cxx b/panda/src/pgui/pgItem.cxx index 1ad3441a63..e955613362 100644 --- a/panda/src/pgui/pgItem.cxx +++ b/panda/src/pgui/pgItem.cxx @@ -784,9 +784,14 @@ move(const MouseWatcherParameter ¶m) { */ void PGItem:: background_press(const MouseWatcherParameter ¶m) { - for (PGItem *item : _background_focus) { + // We have to be careful, because objects may remove themselves from the set + // while we're iterating over it. + auto it = _background_focus.begin(); + while (it != _background_focus.end()) { + PGItem *item = *it++; if (!item->get_focus()) { - item->press(param, true); + PT(PGItem) item_ref(item); + item_ref->press(param, true); } } } @@ -796,9 +801,12 @@ background_press(const MouseWatcherParameter ¶m) { */ void PGItem:: background_release(const MouseWatcherParameter ¶m) { - for (PGItem *item : _background_focus) { + auto it = _background_focus.begin(); + while (it != _background_focus.end()) { + PGItem *item = *it++; if (!item->get_focus()) { - item->release(param, true); + PT(PGItem) item_ref(item); + item_ref->release(param, true); } } } @@ -808,9 +816,12 @@ background_release(const MouseWatcherParameter ¶m) { */ void PGItem:: background_keystroke(const MouseWatcherParameter ¶m) { - for (PGItem *item : _background_focus) { + auto it = _background_focus.begin(); + while (it != _background_focus.end()) { + PGItem *item = *it++; if (!item->get_focus()) { - item->keystroke(param, true); + PT(PGItem) item_ref(item); + item_ref->keystroke(param, true); } } } @@ -820,9 +831,12 @@ background_keystroke(const MouseWatcherParameter ¶m) { */ void PGItem:: background_candidate(const MouseWatcherParameter ¶m) { - for (PGItem *item : _background_focus) { + auto it = _background_focus.begin(); + while (it != _background_focus.end()) { + PGItem *item = *it++; if (!item->get_focus()) { - item->candidate(param, true); + PT(PGItem) item_ref(item); + item_ref->candidate(param, true); } } }