diff --git a/direct/src/filter/CommonFilters.py b/direct/src/filter/CommonFilters.py index 85d0a18f16..942b2748f6 100644 --- a/direct/src/filter/CommonFilters.py +++ b/direct/src/filter/CommonFilters.py @@ -100,6 +100,11 @@ void fshader(out float4 o_color : COLOR, """ +class ToneMap: + ACES = object() + PBR_NEUTRAL = object() + + class FilterConfig: pass @@ -279,16 +284,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 +389,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" + 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"] @@ -668,10 +696,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. @@ -679,8 +707,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): diff --git a/direct/src/fsm/FSM.py b/direct/src/fsm/FSM.py index 06efc4b1a5..e7a4498691 100644 --- a/direct/src/fsm/FSM.py +++ b/direct/src/fsm/FSM.py @@ -485,9 +485,8 @@ class FSM(DirectObject): new_index = (cur_index + 1) % len(self.stateArray) return self.request(self.stateArray[new_index], args) else: - assert self.notifier.debug( + assert self.notify.debug( "stateArray empty. Can't switch to next.") - finally: self.fsmLock.release() @@ -503,7 +502,7 @@ class FSM(DirectObject): new_index = (cur_index - 1) % len(self.stateArray) return self.request(self.stateArray[new_index], args) else: - assert self.notifier.debug( + assert self.notify.debug( "stateArray empty. Can't switch to next.") finally: self.fsmLock.release() diff --git a/direct/src/interval/cMetaInterval.cxx b/direct/src/interval/cMetaInterval.cxx index 3627a99bc0..a203167557 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/direct/src/stdpy/glob.py b/direct/src/stdpy/glob.py index 3b4f0fefb5..8944548a6c 100755 --- a/direct/src/stdpy/glob.py +++ b/direct/src/stdpy/glob.py @@ -52,7 +52,7 @@ def glob1(dirname, pattern): if not dirname: dirname = os.curdir try: - names = os.listdir(dirname) + names = file.listdir(dirname) except os.error: return [] if pattern[0] != '.': diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index 2fa9c43cfc..f411bb9fcc 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -1839,7 +1839,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/pgui/pgItem.cxx b/panda/src/pgui/pgItem.cxx index 7d2e884f82..d612e889cc 100644 --- a/panda/src/pgui/pgItem.cxx +++ b/panda/src/pgui/pgItem.cxx @@ -775,9 +775,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); } } } @@ -787,9 +792,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); } } } @@ -799,9 +807,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); } } } @@ -811,9 +822,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); } } } diff --git a/panda/src/putil/simpleHashMap.I b/panda/src/putil/simpleHashMap.I index 6c61aaeea7..b6641205c5 100644 --- a/panda/src/putil/simpleHashMap.I +++ b/panda/src/putil/simpleHashMap.I @@ -292,8 +292,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); @@ -301,7 +301,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; } @@ -321,13 +321,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) { @@ -341,6 +341,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 diff --git a/panda/src/text/textAssembler.cxx b/panda/src/text/textAssembler.cxx index 5c7a929923..8843ab0edb 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; @@ -798,13 +798,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; } @@ -835,20 +835,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; } @@ -980,7 +980,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 @@ -997,7 +997,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 @@ -1104,8 +1104,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; @@ -1577,7 +1577,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) {