From 9be2f307c58a18e10b0802139ad4fde72ddc94fe Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 4 Mar 2021 19:51:15 +0100 Subject: [PATCH 1/5] text: Fix glyphs with flipped UVs not being processed correctly This caused the cheesy-accent code to not flip the caron correctly. --- panda/src/text/textGlyph.cxx | 71 +++++++++++++++++------------------- 1 file changed, 34 insertions(+), 37 deletions(-) diff --git a/panda/src/text/textGlyph.cxx b/panda/src/text/textGlyph.cxx index bb8d998175..ca9973ee6e 100644 --- a/panda/src/text/textGlyph.cxx +++ b/panda/src/text/textGlyph.cxx @@ -171,66 +171,63 @@ check_quad_geom() { // Check that the vertices are arranged in a square. GeomVertexReader vertex(vdata, InternalName::get_vertex()); + GeomVertexReader texcoord(vdata, InternalName::get_texcoord()); LVecBase3 v = vertex.get_data3(); if (!IS_NEARLY_ZERO(v[1])) { return; } + LTexCoord uv(0); + if (texcoord.has_column()) { + uv = texcoord.get_data2(); + } PN_stdfloat minx = v[0]; PN_stdfloat maxx = v[0]; PN_stdfloat miny = v[2]; PN_stdfloat maxy = v[2]; + PN_stdfloat minu = uv[0]; + PN_stdfloat maxu = uv[0]; + PN_stdfloat minv = uv[1]; + PN_stdfloat maxv = uv[1]; - for (int i = 0; i < 3; ++i) { + for (int i = 1; i < 4; ++i) { v = vertex.get_data3(); if (!IS_NEARLY_ZERO(v[1])) { return; } + if (texcoord.has_column()) { + uv = texcoord.get_data2(); + } if (!IS_NEARLY_EQUAL(v[0], minx) && !IS_NEARLY_EQUAL(v[0], maxx)) { if (!IS_NEARLY_EQUAL(minx, maxx)) { return; } - minx = min(v[0], minx); - maxx = max(v[0], maxx); + if (v[0] < minx) { + minx = v[0]; + minu = uv[0]; + } + if (v[0] > maxx) { + maxx = v[0]; + maxu = uv[0]; + } } if (!IS_NEARLY_EQUAL(v[2], miny) && !IS_NEARLY_EQUAL(v[2], maxy)) { if (!IS_NEARLY_EQUAL(miny, maxy)) { return; } - miny = min(v[2], miny); - maxy = max(v[2], maxy); + if (v[2] < miny) { + miny = v[2]; + minv = uv[1]; + } + if (v[2] > maxy) { + maxy = v[2]; + maxv = uv[1]; + } } - } - - PN_stdfloat minu = 0; - PN_stdfloat maxu = 0; - PN_stdfloat minv = 0; - PN_stdfloat maxv = 0; - - // Same for the texcoord data. - if (format->has_column(InternalName::get_texcoord())) { - GeomVertexReader texcoord(vdata, InternalName::get_texcoord()); - LVecBase2 tc = texcoord.get_data2(); - minu = tc[0]; - maxu = tc[0]; - minv = tc[1]; - maxv = tc[1]; - - for (int i = 0; i < 3; ++i) { - tc = texcoord.get_data2(); - if (!IS_NEARLY_EQUAL(tc[0], minu) && !IS_NEARLY_EQUAL(tc[0], maxu)) { - if (!IS_NEARLY_EQUAL(minu, maxu)) { - return; - } - minu = min(tc[0], minu); - maxu = max(tc[0], maxu); - } - if (!IS_NEARLY_EQUAL(tc[1], minv) && !IS_NEARLY_EQUAL(tc[1], maxv)) { - if (!IS_NEARLY_EQUAL(minv, maxv)) { - return; - } - minv = min(tc[1], minv); - maxv = max(tc[1], maxv); - } + if (!IS_NEARLY_EQUAL(uv[0], minu) && !IS_NEARLY_EQUAL(uv[0], maxu)) { + return; + } + if (!IS_NEARLY_EQUAL(uv[1], minv) && !IS_NEARLY_EQUAL(uv[1], maxv)) { + return; } } From 2e3ce27865b3221d00352ddc6de4855cf6a7a8a8 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 4 Mar 2021 20:45:53 +0100 Subject: [PATCH 2/5] device: Add Windows gamepad mapping with VID:PID 2563:0523 From https://discourse.panda3d.org/t/gamepad-emulator-and-panda/27336 --- panda/src/device/winRawInputDevice.cxx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/panda/src/device/winRawInputDevice.cxx b/panda/src/device/winRawInputDevice.cxx index 010766edf0..96c9b1adbe 100644 --- a/panda/src/device/winRawInputDevice.cxx +++ b/panda/src/device/winRawInputDevice.cxx @@ -81,6 +81,10 @@ static const struct DeviceMapping { {0x054c, 0x0ba0, InputDevice::DeviceClass::gamepad, QB_rstick_from_z, {"face_x", "face_a", "face_b", "face_y", "lshoulder", "rshoulder", 0, 0, "back", "start", "lstick", "rstick", "guide", 0} }, + // PS2 controller connected through a USB adapter + {0x2563, 0x0523, InputDevice::DeviceClass::gamepad, QB_rstick_from_z | QB_no_analog_triggers, + {"face_y", "face_b", "face_a", "face_x", "lshoulder", "rshoulder", "ltrigger", "rtrigger", "back", "start", "lstick", "rstick"} + }, {0}, }; From b4a242a4e3cd4f04585e9332235026888c645421 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 4 Mar 2021 20:48:14 +0100 Subject: [PATCH 3/5] x11: Provide labels for more keys (esp. international keys) --- panda/src/x11display/x11GraphicsWindow.cxx | 41 ++++++++++++++++++++-- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/panda/src/x11display/x11GraphicsWindow.cxx b/panda/src/x11display/x11GraphicsWindow.cxx index bc0433bac3..f63a5b263a 100644 --- a/panda/src/x11display/x11GraphicsWindow.cxx +++ b/panda/src/x11display/x11GraphicsWindow.cxx @@ -2023,14 +2023,49 @@ get_keyboard_map() const { // Compose a label for some keys; I have not yet been able to find an API // that does this effectively. - if (sym >= XK_a && sym <= XK_z) { + if (sym >= XK_exclam && sym <= XK_asciitilde) { label = toupper((char)sym); } else if (sym >= XK_F1 && sym <= XK_F35) { label = "F" + format_string(sym - XK_F1 + 1); } - else if (sym >= XK_exclamdown && sym <= XK_ydiaeresis) { - // A latin-1 symbol. Translate this to the label. + else if (sym > 0x1000000 && sym < 0x1110000) { + // Unicode code point. Encode as UTF-8. + char32_t ch = sym & 0x0ffffff; + if ((ch & ~0x7f) == 0) { + label = string(1, (char)ch); + } + else if ((ch & ~0x7ff) == 0) { + label = + string(1, (char)((ch >> 6) | 0xc0)) + + string(1, (char)((ch & 0x3f) | 0x80)); + } + else if ((ch & ~0xffff) == 0) { + label = + string(1, (char)((ch >> 12) | 0xe0)) + + string(1, (char)(((ch >> 6) & 0x3f) | 0x80)) + + string(1, (char)((ch & 0x3f) | 0x80)); + } + else { + label = + string(1, (char)((ch >> 18) | 0xf0)) + + string(1, (char)(((ch >> 12) & 0x3f) | 0x80)) + + string(1, (char)(((ch >> 6) & 0x3f) | 0x80)) + + string(1, (char)((ch & 0x3f) | 0x80)); + } + } + else if ((sym >= XK_exclamdown && sym <= XK_umacron) + || (sym >= XK_OE && sym <= XK_Ydiaeresis) + || (sym >= XK_Serbian_dje && sym <= XK_Cyrillic_HARDSIGN) + || (sym >= XK_kana_fullstop && sym <= XK_semivoicedsound) + || (sym >= XK_Arabic_comma && sym <= XK_Arabic_sukun) + || (sym >= XK_Greek_ALPHAaccent && sym <= XK_Greek_omega) + || (sym >= XK_hebrew_doublelowline && sym <= XK_hebrew_taw) + || (sym >= XK_Thai_kokai && sym <= XK_Thai_lekkao) + || (sym >= XK_Hangul_Kiyeog && sym <= XK_Hangul_J_YeorinHieuh) + || sym == XK_EuroSign + || sym == XK_Korean_Won) { + // A non-unicode-based keysym. Translate this to the label. char buffer[255]; int nbytes = XkbTranslateKeySym(_display, &sym, 0, buffer, 255, 0); if (nbytes > 0) { From 1851cc35bcdc1f31f4a7632f6705cf7b81316d77 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 4 Mar 2021 21:50:10 +0100 Subject: [PATCH 4/5] models: Add dotless i to shipped static fonts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes it possible for Panda to synthesize the cheesy accent marks for íîì on top of the dotless form, which looks better than putting them on top of the dotted i. --- models/cmr12.egg | 19 ++++++++++++++++++- models/cmss12.egg | 19 ++++++++++++++++++- models/cmtt12.egg | 19 ++++++++++++++++++- 3 files changed, 54 insertions(+), 3 deletions(-) diff --git a/models/cmr12.egg b/models/cmr12.egg index 375273e679..d8656e27fd 100644 --- a/models/cmr12.egg +++ b/models/cmr12.egg @@ -1815,6 +1815,14 @@ 0.978659 0 0 } 476 { + 0.0080542 0.491814264 0 + { 0.948538 0.34035628 } + } + 477 { + 0.267978 0.491814264 0 + { 0.98848 0.34035628 } + } + 478 { 0 1 0 } } @@ -2673,9 +2681,18 @@ { 460 { vpool } } } } + 305 { + { + { chars } + { 276 277 476 477 { vpool } } + } + { + { 280 { vpool } } + } + } ds { { - { 476 { vpool } } + { 478 { vpool } } } } } diff --git a/models/cmss12.egg b/models/cmss12.egg index 4b1915d088..0c531838ca 100644 --- a/models/cmss12.egg +++ b/models/cmss12.egg @@ -1815,6 +1815,14 @@ 0.978659 0 0 } 476 { + 0.174627 0.506365 0 + { 0.531719 0.544 } + } + 477 { + 0.0428523 0.506365 0 + { 0.510343 0.544 } + } + 478 { 0 1 0 } } @@ -2673,9 +2681,18 @@ { 460 { vpool } } } } + 305 { + { + { chars } + { 231 232 476 477 { vpool } } + } + { + { 235 { vpool } } + } + } ds { { - { 476 { vpool } } + { 478 { vpool } } } } } diff --git a/models/cmtt12.egg b/models/cmtt12.egg index fb6fea56d3..b44c9bb322 100644 --- a/models/cmtt12.egg +++ b/models/cmtt12.egg @@ -1815,6 +1815,14 @@ 0.518605 0 0 } 476 { + 0.0609865 0.4672 0 + { 0.305895 0.43927125 } + } + 477 { + 0.457619 0.4672 0 + { 0.37422 0.43927125 } + } + 478 { 0 1 0 } } @@ -2678,9 +2686,18 @@ { 465 { vpool } } } } + 305 { + { + { chars } + { 221 222 476 477 { vpool } } + } + { + { 225 { vpool } } + } + } ds { { - { 476 { vpool } } + { 478 { vpool } } } } } From 5cadd86d1edf86182347d4d14b6f95cf108aa57c Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 5 Mar 2021 11:57:05 +0100 Subject: [PATCH 5/5] glgsg: Fix get_screenshot() for multisample FBOs An FM_refresh bind should not bind the multisample FBO, but the resolved one (and while we're at it, FM_refresh should not try to resolve multisamples). --- panda/src/glstuff/glGraphicsBuffer_src.cxx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/panda/src/glstuff/glGraphicsBuffer_src.cxx b/panda/src/glstuff/glGraphicsBuffer_src.cxx index d484a174e4..7413fef56e 100644 --- a/panda/src/glstuff/glGraphicsBuffer_src.cxx +++ b/panda/src/glstuff/glGraphicsBuffer_src.cxx @@ -283,6 +283,12 @@ begin_frame(FrameMode mode, Thread *current_thread) { } else if (mode == FM_refresh) { // Just bind the FBO. rebuild_bitplanes(); + + // Bind the non-multisample FBO, since we won't be rendering anything and + // the caller probably wanted to grab a screenshot. + if (_fbo_multisample != 0 && !_fbo.empty()) { + glgsg->bind_fbo(_fbo[0]); + } } // The host window may not have had sRGB enabled, so we need to do this. @@ -1330,11 +1336,12 @@ end_frame(FrameMode mode, Thread *current_thread) { nassertv(_gsg != nullptr); // Resolve Multisample rendering if using it. - if (_requested_multisamples && _fbo_multisample) { + if (_requested_multisamples && _fbo_multisample && mode != FM_refresh) { resolve_multisamples(); } if (mode == FM_render) { + // Should happen *after* resolving multisamples, with the non-MS FBO bound. copy_to_textures(); }