From 034094d0a3cfc62bcffadd5c0be3ec72a3c34d00 Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 13 Sep 2023 09:59:46 -0700 Subject: [PATCH] dev-console work in progress --- .efrocachemap | 80 +-- CHANGELOG.md | 4 +- src/assets/.asset_manifest_private.json | 8 - src/assets/Makefile | 8 - src/assets/ba_data/python/baenv.py | 2 +- src/assets/ba_data/python/bauiv1lib/helpui.py | 340 ++++------ .../base/app_mode/app_mode_empty.cc | 2 +- .../component/post_process_component.h | 2 +- .../graphics/component/render_component.h | 4 +- src/ballistica/base/graphics/graphics.cc | 290 ++++---- src/ballistica/base/graphics/graphics.h | 10 +- .../base/graphics/graphics_server.cc | 40 +- .../base/graphics/graphics_server.h | 25 +- src/ballistica/base/graphics/graphics_vr.cc | 54 +- src/ballistica/base/graphics/graphics_vr.h | 3 + .../base/graphics/mesh/image_mesh.h | 2 +- .../base/graphics/mesh/mesh_buffer_base.h | 9 +- .../graphics/mesh/mesh_data_client_handle.h | 6 +- .../graphics/mesh/mesh_indexed_object_split.h | 2 +- .../mesh/mesh_indexed_static_dynamic.h | 4 +- .../base/graphics/renderer/render_pass.cc | 18 +- .../base/graphics/renderer/render_pass.h | 45 +- .../base/graphics/support/net_graph.cc | 4 +- .../base/graphics/text/text_group.cc | 14 +- .../base/graphics/text/text_group.h | 14 +- src/ballistica/base/ui/dev_console.cc | 633 +++++++++++------- src/ballistica/base/ui/dev_console.h | 20 +- src/ballistica/base/ui/ui.cc | 11 +- .../scene_v1/node/explosion_node.cc | 2 +- src/ballistica/scene_v1/node/shield_node.cc | 2 +- src/ballistica/scene_v1/node/spaz_node.cc | 10 +- src/ballistica/scene_v1/node/text_node.cc | 6 +- src/ballistica/shared/ballistica.cc | 2 +- src/ballistica/ui_v1/support/root_ui.cc | 12 +- src/ballistica/ui_v1/widget/text_widget.cc | 2 +- src/tools/pcommandbatch/pcommandbatch.c | 12 +- 36 files changed, 944 insertions(+), 758 deletions(-) diff --git a/.efrocachemap b/.efrocachemap index 9785c6fd..63a65228 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -1108,10 +1108,6 @@ "build/assets/ba_data/textures/agentIconColorMask.pvr": "075f61aae95df3456dc37dd598e73c93", "build/assets/ba_data/textures/agentIconColorMask_preview.png": "0f93c1b587d4da394a706ea975c02801", "build/assets/ba_data/textures/agentIcon_preview.png": "4dd9bed5d6b0d9fd06ad3c7245bd0af3", - "build/assets/ba_data/textures/aliBSRemoteIOSQR.dds": "36f0109aab733ac8c564134a5c6b8565", - "build/assets/ba_data/textures/aliBSRemoteIOSQR.ktx": "154b455d458339bae37f4f83ed3bf9ba", - "build/assets/ba_data/textures/aliBSRemoteIOSQR.pvr": "17c9acb519e98485cd063375aab43b3a", - "build/assets/ba_data/textures/aliBSRemoteIOSQR_preview.png": "a6babeb7c3cc08e781c743d15e80f44d", "build/assets/ba_data/textures/aliColor.dds": "7f87ef5a6d6465a09f9ed651bbc47040", "build/assets/ba_data/textures/aliColor.ktx": "cfb95bf0ac3f489c2b715613a901d405", "build/assets/ba_data/textures/aliColor.pvr": "098d12386d71cdbf1d8b8f8ea6658ba8", @@ -1120,10 +1116,6 @@ "build/assets/ba_data/textures/aliColorMask.pvr": "44160498f3290b08a0c8619b46f38d62", "build/assets/ba_data/textures/aliColorMask_preview.png": "47fa53145d34727c863a47830e378c4a", "build/assets/ba_data/textures/aliColor_preview.png": "5a23819c762d483bf9fc7b12ad29acce", - "build/assets/ba_data/textures/aliControllerQR.dds": "9436ee9bd470325835d92538b68eddf6", - "build/assets/ba_data/textures/aliControllerQR.ktx": "acda0b3c72369ddc403e832105021dd8", - "build/assets/ba_data/textures/aliControllerQR.pvr": "1483008a770dcb7a315a293bfa6c3aaf", - "build/assets/ba_data/textures/aliControllerQR_preview.png": "c8e05aeea062254af18319b09753a376", "build/assets/ba_data/textures/aliIcon.dds": "edfacc0e398df035a6c02297dfbfd7a9", "build/assets/ba_data/textures/aliIcon.ktx": "a5c386a4977d6d4538c6fc176e69b116", "build/assets/ba_data/textures/aliIcon.pvr": "9d2dad0e469eaec3de216f9cd43a6de3", @@ -4064,26 +4056,26 @@ "build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1", "build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae", "build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599", - "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "e8a40affea4d63bc4ca150adfeb973db", - "build/prefab/full/linux_arm64_gui/release/ballisticakit": "fb00781c9574d0ca777eb5ced699dc18", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "d53b0c174af88e8a483896fdfd411579", - "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "bb6fd9371937ebe3f25d253d3046269e", - "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "f71e0d97424b7bf4b1ad57876ca4f01f", - "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "6c2ba3735f33f1fd3804bd89a71c75bc", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "cff1c33bb6725fb06020a256ac8e6b16", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "d9d6dbe7c5396a3adb8468fbecbf2b8c", - "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "2dcddcc4a939a290fd8974d575fa3761", - "build/prefab/full/mac_arm64_gui/release/ballisticakit": "cd7f47495207a86d2f72ea0749b69db8", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "e223f88277dafee40cd0e631ee4fa02d", - "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "1b8a5eac67370bed2a29f81525fbc6eb", - "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "91debaa22c5ce91586cfdad646a72afe", - "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "84c8c568e4daeef372806cdc96f4ed48", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "ebf0e8e22d53790b85ceb9f5c507db35", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "ba136eb04e177e264d459443bcde879f", - "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "fdc1b63de28ebd369b78b2bbeb3c6290", - "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "126e2eec53a5f7a00d95039ad506b9b4", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "7db3922abdbf3045ef814f235d514cdb", - "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "b5a1ff440599ccf09bd543d64a1d7aba", + "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "e7171e1db64d2c0fdebbaeb45d99422e", + "build/prefab/full/linux_arm64_gui/release/ballisticakit": "4f6ed2673aa7716c211c94baeb611da3", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "629d63c3627b863e817a98b891b38325", + "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "b6315ff0d68b436500e48de435b69c77", + "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "aa98cf408c857767bcbb41ce2b63ce76", + "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "fa56d6e2beb16a44eff88dd9ca3e0b3e", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "3f026a96404b41c4369bd40694eae4de", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "9713455275e8d7b6bc98fa85fbc1e3ee", + "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "051d1a2636fe1b5dadb1f9806b9040a3", + "build/prefab/full/mac_arm64_gui/release/ballisticakit": "ff117aec63d1413c9f48bac4fd20c9a5", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "0502bb185cf85e224628b3be5e18750a", + "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "8999ff0a5601c423e2fa10b59425bfa2", + "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "f2d0d08db00ee44a5c98023ea8521bcc", + "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "35e1d1017b406d9ed31b2b901a1d0dbe", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "6346c88ec18632ac3ad63beae6122569", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "a08613797c5064a0b2302b9468dc88e9", + "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "f3d4f9dc7162d7f736c32f8a8ead5477", + "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "dbddd278a058fb61b8ca5301a3ae4a09", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "aca30445a8fc28b69a2bce57bd651dc3", + "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "1ba63aa89b4b45d893499a491e3047cd", "build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "1e786451b0abe1451f17b908c2d8abb3", "build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "80db3e75458db18efe1657f8ce686996", "build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "1e786451b0abe1451f17b908c2d8abb3", @@ -4092,22 +4084,22 @@ "build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "c36dc72d78f9df240ae9f640dee470c2", "build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "a29bc1b96b2422dce9154ef8a404a8e6", "build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "c36dc72d78f9df240ae9f640dee470c2", - "build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "8f3b213feb6207ab470a7318de8e5cc9", - "build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "1b24bf754c66d424be3f3809b2523c61", - "build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "8f3b213feb6207ab470a7318de8e5cc9", - "build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "1b24bf754c66d424be3f3809b2523c61", - "build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "93ff05ad705918cf0c47e5946021a2e5", - "build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "61ee5217ce8cfc2d471ffc5d1d8d4ad8", - "build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "d57603910e6c8d153b05a5515ec99ab2", - "build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "61ee5217ce8cfc2d471ffc5d1d8d4ad8", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "2312b4a091f482d64c22f71ca971efe8", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "0d5cb925a29f8185d615d6b954674c6b", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "eb53d93675b81c631d43f2283b59a9ae", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "f15e465066504b1bfadc6fef97bfa6d4", - "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "bad42242aa1c98b5e6c7318da8b0fa01", - "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "55366eb80cbd1b22c2636d29b780b6f6", - "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "c6870a6302ae49bac39f53b390797d8f", - "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "29ff7769db971f92b49917c3d61de3ec", + "build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "d1e2aef8e1ba4fac62908efd3b8079c4", + "build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "4dd471e8559a31c1425cd344646261b5", + "build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "d1e2aef8e1ba4fac62908efd3b8079c4", + "build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "4dd471e8559a31c1425cd344646261b5", + "build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "0bff76811b9640d20c7104b8dabf27e8", + "build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "b6e72c87d43dbf2a93e9a0b74952677b", + "build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "3c8593e81564012a7638a20c0dc0267b", + "build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "b6e72c87d43dbf2a93e9a0b74952677b", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "a6b742a577b1a2a5b99ef4acc4949735", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "3019670a3df31b6ed2bbd5d3a847afbb", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "85335e293ae1433afdf40a83e346d379", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "172855f5f89e9bd36efe7bacad3d5fc9", + "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "6fa16da3c74bc305a550697b7b453b21", + "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "dc2d4d3655e8cd65d83e355e731441a8", + "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "24a6884294c6c6da095e24f0dfa0faf4", + "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "68f39e024d3ca6bef9a0dc593ba139ab", "src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c", "src/assets/ba_data/python/babase/_mgen/enums.py": "f8cd3af311ac63147882590123b78318", "src/ballistica/base/mgen/pyembed/binding_base.inc": "c81b2b1f3a14b4cd20a7b93416fe893a", diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b68b826..92d36bf8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -### 1.7.28 (build 21337, api 8, 2023-09-11) +### 1.7.28 (build 21342, api 8, 2023-09-13) - Renamed Console to DevConsole, and added an option under advanced settings to always show a 'dev' button onscreen which can be used to toggle it. The @@ -16,6 +16,8 @@ console is probably still a better way to go for most people but this makes at least simple things possible without an internet connection for most Android users. +- Pressing esc when the DevConsole is in its small form now dismisses it + instead of toggling it to its large form. - Added some high level functionality for copying and deleting feature-sets to the `spinoff` tool. For example, to create your own `poo` feature-set based on the existing `template_fs` one, do `tools/spinoff fset-copy template_fs poo`. diff --git a/src/assets/.asset_manifest_private.json b/src/assets/.asset_manifest_private.json index 4c874ca4..c383200f 100644 --- a/src/assets/.asset_manifest_private.json +++ b/src/assets/.asset_manifest_private.json @@ -1129,10 +1129,6 @@ "ba_data/textures/agentIconColorMask.pvr", "ba_data/textures/agentIconColorMask_preview.png", "ba_data/textures/agentIcon_preview.png", - "ba_data/textures/aliBSRemoteIOSQR.dds", - "ba_data/textures/aliBSRemoteIOSQR.ktx", - "ba_data/textures/aliBSRemoteIOSQR.pvr", - "ba_data/textures/aliBSRemoteIOSQR_preview.png", "ba_data/textures/aliColor.dds", "ba_data/textures/aliColor.ktx", "ba_data/textures/aliColor.pvr", @@ -1141,10 +1137,6 @@ "ba_data/textures/aliColorMask.pvr", "ba_data/textures/aliColorMask_preview.png", "ba_data/textures/aliColor_preview.png", - "ba_data/textures/aliControllerQR.dds", - "ba_data/textures/aliControllerQR.ktx", - "ba_data/textures/aliControllerQR.pvr", - "ba_data/textures/aliControllerQR_preview.png", "ba_data/textures/aliIcon.dds", "ba_data/textures/aliIcon.ktx", "ba_data/textures/aliIcon.pvr", diff --git a/src/assets/Makefile b/src/assets/Makefile index 77353683..946ce5c0 100644 --- a/src/assets/Makefile +++ b/src/assets/Makefile @@ -5624,10 +5624,8 @@ TEX2D_DDS_TARGETS = \ $(BUILD_DIR)/ba_data/textures/agentColorMask.dds \ $(BUILD_DIR)/ba_data/textures/agentIcon.dds \ $(BUILD_DIR)/ba_data/textures/agentIconColorMask.dds \ - $(BUILD_DIR)/ba_data/textures/aliBSRemoteIOSQR.dds \ $(BUILD_DIR)/ba_data/textures/aliColor.dds \ $(BUILD_DIR)/ba_data/textures/aliColorMask.dds \ - $(BUILD_DIR)/ba_data/textures/aliControllerQR.dds \ $(BUILD_DIR)/ba_data/textures/aliIcon.dds \ $(BUILD_DIR)/ba_data/textures/aliIconColorMask.dds \ $(BUILD_DIR)/ba_data/textures/aliSplash.dds \ @@ -6029,10 +6027,8 @@ TEX2D_PVR_TARGETS = \ $(BUILD_DIR)/ba_data/textures/agentColorMask.pvr \ $(BUILD_DIR)/ba_data/textures/agentIcon.pvr \ $(BUILD_DIR)/ba_data/textures/agentIconColorMask.pvr \ - $(BUILD_DIR)/ba_data/textures/aliBSRemoteIOSQR.pvr \ $(BUILD_DIR)/ba_data/textures/aliColor.pvr \ $(BUILD_DIR)/ba_data/textures/aliColorMask.pvr \ - $(BUILD_DIR)/ba_data/textures/aliControllerQR.pvr \ $(BUILD_DIR)/ba_data/textures/aliIcon.pvr \ $(BUILD_DIR)/ba_data/textures/aliIconColorMask.pvr \ $(BUILD_DIR)/ba_data/textures/aliSplash.pvr \ @@ -6434,10 +6430,8 @@ TEX2D_KTX_TARGETS = \ $(BUILD_DIR)/ba_data/textures/agentColorMask.ktx \ $(BUILD_DIR)/ba_data/textures/agentIcon.ktx \ $(BUILD_DIR)/ba_data/textures/agentIconColorMask.ktx \ - $(BUILD_DIR)/ba_data/textures/aliBSRemoteIOSQR.ktx \ $(BUILD_DIR)/ba_data/textures/aliColor.ktx \ $(BUILD_DIR)/ba_data/textures/aliColorMask.ktx \ - $(BUILD_DIR)/ba_data/textures/aliControllerQR.ktx \ $(BUILD_DIR)/ba_data/textures/aliIcon.ktx \ $(BUILD_DIR)/ba_data/textures/aliIconColorMask.ktx \ $(BUILD_DIR)/ba_data/textures/aliSplash.ktx \ @@ -6839,10 +6833,8 @@ TEX2D_PREVIEW_PNG_TARGETS = \ $(BUILD_DIR)/ba_data/textures/agentColor_preview.png \ $(BUILD_DIR)/ba_data/textures/agentIconColorMask_preview.png \ $(BUILD_DIR)/ba_data/textures/agentIcon_preview.png \ - $(BUILD_DIR)/ba_data/textures/aliBSRemoteIOSQR_preview.png \ $(BUILD_DIR)/ba_data/textures/aliColorMask_preview.png \ $(BUILD_DIR)/ba_data/textures/aliColor_preview.png \ - $(BUILD_DIR)/ba_data/textures/aliControllerQR_preview.png \ $(BUILD_DIR)/ba_data/textures/aliIconColorMask_preview.png \ $(BUILD_DIR)/ba_data/textures/aliIcon_preview.png \ $(BUILD_DIR)/ba_data/textures/aliSplash_preview.png \ diff --git a/src/assets/ba_data/python/baenv.py b/src/assets/ba_data/python/baenv.py index 31e6c7d9..3a5cd63b 100644 --- a/src/assets/ba_data/python/baenv.py +++ b/src/assets/ba_data/python/baenv.py @@ -52,7 +52,7 @@ if TYPE_CHECKING: # Build number and version of the ballistica binary we expect to be # using. -TARGET_BALLISTICA_BUILD = 21337 +TARGET_BALLISTICA_BUILD = 21342 TARGET_BALLISTICA_VERSION = '1.7.28' diff --git a/src/assets/ba_data/python/bauiv1lib/helpui.py b/src/assets/ba_data/python/bauiv1lib/helpui.py index 4c404992..6a7ed437 100644 --- a/src/assets/ba_data/python/bauiv1lib/helpui.py +++ b/src/assets/ba_data/python/bauiv1lib/helpui.py @@ -196,210 +196,158 @@ class HelpWindow(bui.Window): texture=logo_tex, ) - force_test = False app = bui.app assert app.classic is not None - if ( - app.classic.platform == 'android' - and app.classic.subplatform == 'alibaba' - ) or force_test: - v -= 120.0 - txtv = ( - '\xe8\xbf\x99\xe6\x98\xaf\xe4\xb8\x80\xe4\xb8\xaa\xe5\x8f\xaf' - '\xe4\xbb\xa5\xe5\x92\x8c\xe5\xae\xb6\xe4\xba\xba\xe6\x9c\x8b' - '\xe5\x8f\x8b\xe4\xb8\x80\xe8\xb5\xb7\xe7\x8e\xa9\xe7\x9a\x84' - '\xe6\xb8\xb8\xe6\x88\x8f,\xe5\x90\x8c\xe6\x97\xb6\xe6\x94\xaf' - '\xe6\x8c\x81\xe8\x81\x94 \xe2\x80\xa8\xe7\xbd\x91\xe5\xaf\xb9' - '\xe6\x88\x98\xe3\x80\x82\n' - '\xe5\xa6\x82\xe6\xb2\xa1\xe6\x9c\x89\xe6\xb8\xb8\xe6\x88\x8f' - '\xe6\x89\x8b\xe6\x9f\x84,\xe5\x8f\xaf\xe4\xbb\xa5\xe4\xbd\xbf' - '\xe7\x94\xa8\xe7\xa7\xbb\xe5\x8a\xa8\xe8\xae\xbe\xe5\xa4\x87' - '\xe6\x89\xab\xe7\xa0\x81\xe4\xb8\x8b\xe8\xbd\xbd\xe2\x80\x9c' - '\xe9\x98\xbf\xe9\x87\x8c\xc2' - '\xa0TV\xc2\xa0\xe5\x8a\xa9\xe6\x89' - '\x8b\xe2\x80\x9d\xe7\x94\xa8 \xe6\x9d\xa5\xe4\xbb\xa3\xe6\x9b' - '\xbf\xe5\xa4\x96\xe8\xae\xbe\xe3\x80\x82\n' - '\xe6\x9c\x80\xe5\xa4\x9a\xe6\x94\xaf\xe6\x8c\x81\xe6\x8e\xa5' - '\xe5\x85\xa5\xc2\xa08\xc2\xa0\xe4\xb8\xaa\xe5\xa4\x96\xe8' - '\xae\xbe' - ) - bui.textwidget( - parent=self._subcontainer, - size=(0, 0), - h_align='center', - v_align='center', - maxwidth=self._sub_width * 0.9, - position=(self._sub_width * 0.5, v - 180), - text=txtv, - ) - bui.imagewidget( - parent=self._subcontainer, - position=(self._sub_width - 320, v - 120), - size=(200, 200), - texture=bui.gettexture('aliControllerQR'), - ) - bui.imagewidget( - parent=self._subcontainer, - position=(90, v - 130), - size=(210, 210), - texture=bui.gettexture('multiplayerExamples'), - ) - v -= 120.0 + v -= spacing * 50.0 + txt = bui.Lstr(resource=self._r + '.someDaysText').evaluate() + bui.textwidget( + parent=self._subcontainer, + position=(h, v), + size=(0, 0), + scale=1.2, + maxwidth=self._sub_width * 0.9, + text=txt, + h_align='center', + color=paragraph, + v_align='center', + flatness=1.0, + ) + v -= spacing * 25.0 + getres(self._r + '.someDaysExtraSpace') + txt_scale = 0.66 + txt = bui.Lstr(resource=self._r + '.orPunchingSomethingText').evaluate() + bui.textwidget( + parent=self._subcontainer, + position=(h, v), + size=(0, 0), + scale=txt_scale, + maxwidth=self._sub_width * 0.9, + text=txt, + h_align='center', + color=paragraph, + v_align='center', + flatness=1.0, + ) + v -= spacing * 27.0 + getres(self._r + '.orPunchingSomethingExtraSpace') + txt_scale = 1.0 + txt = bui.Lstr( + resource=self._r + '.canHelpText', + subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))], + ).evaluate() + bui.textwidget( + parent=self._subcontainer, + position=(h, v), + size=(0, 0), + scale=txt_scale, + flatness=1.0, + text=txt, + h_align='center', + color=paragraph, + v_align='center', + ) + + v -= spacing * 70.0 + txt_scale = 1.0 + txt = bui.Lstr(resource=self._r + '.toGetTheMostText').evaluate() + bui.textwidget( + parent=self._subcontainer, + position=(h, v), + size=(0, 0), + scale=txt_scale, + maxwidth=self._sub_width * 0.9, + text=txt, + h_align='center', + color=header, + v_align='center', + flatness=1.0, + ) + + v -= spacing * 40.0 + txt_scale = 0.74 + txt = bui.Lstr(resource=self._r + '.friendsText').evaluate() + hval2 = h - 220 + bui.textwidget( + parent=self._subcontainer, + position=(hval2, v), + size=(0, 0), + scale=txt_scale, + maxwidth=100, + text=txt, + h_align='right', + color=header, + v_align='center', + flatness=1.0, + ) + + txt = bui.Lstr( + resource=self._r + '.friendsGoodText', + subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))], + ).evaluate() + txt_scale = 0.7 + bui.textwidget( + parent=self._subcontainer, + position=(hval2 + 10, v + 8), + size=(0, 0), + scale=txt_scale, + maxwidth=500, + text=txt, + h_align='left', + color=paragraph, + flatness=1.0, + ) + + app = bui.app + + v -= spacing * 45.0 + txt = ( + bui.Lstr(resource=self._r + '.devicesText').evaluate() + if app.env.vr + else bui.Lstr(resource=self._r + '.controllersText').evaluate() + ) + txt_scale = 0.74 + hval2 = h - 220 + bui.textwidget( + parent=self._subcontainer, + position=(hval2, v), + size=(0, 0), + scale=txt_scale, + maxwidth=100, + text=txt, + h_align='right', + v_align='center', + color=header, + flatness=1.0, + ) + + txt_scale = 0.7 + if not app.env.vr: + infotxt = '.controllersInfoText' + txt = bui.Lstr( + resource=self._r + infotxt, + fallback_resource=self._r + '.controllersInfoText', + subs=[ + ('${APP_NAME}', bui.Lstr(resource='titleText')), + ('${REMOTE_APP_NAME}', bui.get_remote_app_name()), + ], + ).evaluate() else: - v -= spacing * 50.0 - txt = bui.Lstr(resource=self._r + '.someDaysText').evaluate() - bui.textwidget( - parent=self._subcontainer, - position=(h, v), - size=(0, 0), - scale=1.2, - maxwidth=self._sub_width * 0.9, - text=txt, - h_align='center', - color=paragraph, - v_align='center', - flatness=1.0, - ) - v -= spacing * 25.0 + getres(self._r + '.someDaysExtraSpace') - txt_scale = 0.66 txt = bui.Lstr( - resource=self._r + '.orPunchingSomethingText' - ).evaluate() - bui.textwidget( - parent=self._subcontainer, - position=(h, v), - size=(0, 0), - scale=txt_scale, - maxwidth=self._sub_width * 0.9, - text=txt, - h_align='center', - color=paragraph, - v_align='center', - flatness=1.0, - ) - v -= spacing * 27.0 + getres( - self._r + '.orPunchingSomethingExtraSpace' - ) - txt_scale = 1.0 - txt = bui.Lstr( - resource=self._r + '.canHelpText', + resource=self._r + '.devicesInfoText', subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))], ).evaluate() - bui.textwidget( - parent=self._subcontainer, - position=(h, v), - size=(0, 0), - scale=txt_scale, - flatness=1.0, - text=txt, - h_align='center', - color=paragraph, - v_align='center', - ) - v -= spacing * 70.0 - txt_scale = 1.0 - txt = bui.Lstr(resource=self._r + '.toGetTheMostText').evaluate() - bui.textwidget( - parent=self._subcontainer, - position=(h, v), - size=(0, 0), - scale=txt_scale, - maxwidth=self._sub_width * 0.9, - text=txt, - h_align='center', - color=header, - v_align='center', - flatness=1.0, - ) - - v -= spacing * 40.0 - txt_scale = 0.74 - txt = bui.Lstr(resource=self._r + '.friendsText').evaluate() - hval2 = h - 220 - bui.textwidget( - parent=self._subcontainer, - position=(hval2, v), - size=(0, 0), - scale=txt_scale, - maxwidth=100, - text=txt, - h_align='right', - color=header, - v_align='center', - flatness=1.0, - ) - - txt = bui.Lstr( - resource=self._r + '.friendsGoodText', - subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))], - ).evaluate() - txt_scale = 0.7 - bui.textwidget( - parent=self._subcontainer, - position=(hval2 + 10, v + 8), - size=(0, 0), - scale=txt_scale, - maxwidth=500, - text=txt, - h_align='left', - color=paragraph, - flatness=1.0, - ) - - app = bui.app - - v -= spacing * 45.0 - txt = ( - bui.Lstr(resource=self._r + '.devicesText').evaluate() - if app.env.vr - else bui.Lstr(resource=self._r + '.controllersText').evaluate() - ) - txt_scale = 0.74 - hval2 = h - 220 - bui.textwidget( - parent=self._subcontainer, - position=(hval2, v), - size=(0, 0), - scale=txt_scale, - maxwidth=100, - text=txt, - h_align='right', - v_align='center', - color=header, - flatness=1.0, - ) - - txt_scale = 0.7 - if not app.env.vr: - infotxt = '.controllersInfoText' - txt = bui.Lstr( - resource=self._r + infotxt, - fallback_resource=self._r + '.controllersInfoText', - subs=[ - ('${APP_NAME}', bui.Lstr(resource='titleText')), - ('${REMOTE_APP_NAME}', bui.get_remote_app_name()), - ], - ).evaluate() - else: - txt = bui.Lstr( - resource=self._r + '.devicesInfoText', - subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))], - ).evaluate() - - bui.textwidget( - parent=self._subcontainer, - position=(hval2 + 10, v + 8), - size=(0, 0), - scale=txt_scale, - maxwidth=500, - max_height=105, - text=txt, - h_align='left', - color=paragraph, - flatness=1.0, - ) + bui.textwidget( + parent=self._subcontainer, + position=(hval2 + 10, v + 8), + size=(0, 0), + scale=txt_scale, + maxwidth=500, + max_height=105, + text=txt, + h_align='left', + color=paragraph, + flatness=1.0, + ) v -= spacing * 150.0 diff --git a/src/ballistica/base/app_mode/app_mode_empty.cc b/src/ballistica/base/app_mode/app_mode_empty.cc index 415e6af9..5373698a 100644 --- a/src/ballistica/base/app_mode/app_mode_empty.cc +++ b/src/ballistica/base/app_mode/app_mode_empty.cc @@ -37,7 +37,7 @@ void AppModeEmpty::DrawWorld(base::FrameDef* frame_def) { // Draw some lovely spinning text. if (!hello_text_group_.Exists()) { hello_text_group_ = Object::New(); - hello_text_group_->set_text("Potato!"); + hello_text_group_->SetText("Potato!"); } auto& grp(*hello_text_group_); auto* pass = frame_def->overlay_pass(); diff --git a/src/ballistica/base/graphics/component/post_process_component.h b/src/ballistica/base/graphics/component/post_process_component.h index 39435599..516bcd86 100644 --- a/src/ballistica/base/graphics/component/post_process_component.h +++ b/src/ballistica/base/graphics/component/post_process_component.h @@ -11,7 +11,7 @@ class PostProcessComponent : public RenderComponent { public: explicit PostProcessComponent(RenderPass* pass) : RenderComponent(pass), normal_distort_(0.0f), eyes_(false) {} - void setNormalDistort(float d) { + void SetNormalDistort(float d) { EnsureConfiguring(); normal_distort_ = d; } diff --git a/src/ballistica/base/graphics/component/render_component.h b/src/ballistica/base/graphics/component/render_component.h index f16953fa..bd59acce 100644 --- a/src/ballistica/base/graphics/component/render_component.h +++ b/src/ballistica/base/graphics/component/render_component.h @@ -162,12 +162,12 @@ class RenderComponent { } void Submit() { if (state_ != State::kSubmitted) { - // if we were drawing, make note that we're done + // If we were drawing, make note that we're done. if (state_ == State::kDrawing) { #if BA_DEBUG_BUILD assert(pass_->frame_def()->defining_component()); pass_->frame_def()->set_defining_component(false); -#endif // BA_DEBUG_BUILD +#endif } state_ = State::kSubmitted; } diff --git a/src/ballistica/base/graphics/graphics.cc b/src/ballistica/base/graphics/graphics.cc index 848068a7..31146db5 100644 --- a/src/ballistica/base/graphics/graphics.cc +++ b/src/ballistica/base/graphics/graphics.cc @@ -357,7 +357,8 @@ class Graphics::ScreenMessageEntry { }; // Draw controls and things that lie on top of the action. -void Graphics::DrawMiscOverlays(RenderPass* pass) { +void Graphics::DrawMiscOverlays(FrameDef* frame_def) { + RenderPass* pass = frame_def->overlay_pass(); assert(g_base && g_base->InLogicThread()); // Every now and then, update our stats. @@ -382,7 +383,7 @@ void Graphics::DrawMiscOverlays(RenderPass* pass) { if (!fps_text_group_.Exists()) { fps_text_group_ = Object::New(); } - fps_text_group_->set_text(fps_string_); + fps_text_group_->SetText(fps_string_); } SimpleComponent c(pass); c.SetTransparent(true); @@ -415,7 +416,7 @@ void Graphics::DrawMiscOverlays(RenderPass* pass) { if (!ping_text_group_.Exists()) { ping_text_group_ = Object::New(); } - ping_text_group_->set_text(ping_string_); + ping_text_group_->SetText(ping_string_); } SimpleComponent c(pass); c.SetTransparent(true); @@ -431,12 +432,13 @@ void Graphics::DrawMiscOverlays(RenderPass* pass) { for (int e = 0; e < text_elem_count; e++) { c.SetTexture(ping_text_group_->GetElementTexture(e)); c.SetFlatness(1.0f); - c.PushTransform(); - c.Translate(14.0f + (show_fps_ ? 30.0f : 0.0f), 0.1f, - kScreenMessageZDepth); - c.Scale(0.7f, 0.7f); - c.DrawMesh(ping_text_group_->GetElementMesh(e)); - c.PopTransform(); + { + auto xf = c.ScopedTransform(); + c.Translate(14.0f + (show_fps_ ? 30.0f : 0.0f), 0.1f, + kScreenMessageZDepth); + c.Scale(0.7f, 0.7f); + c.DrawMesh(ping_text_group_->GetElementMesh(e)); + } } c.Submit(); } @@ -450,7 +452,7 @@ void Graphics::DrawMiscOverlays(RenderPass* pass) { if (!net_info_text_group_.Exists()) { net_info_text_group_ = Object::New(); } - net_info_text_group_->set_text(net_info_string_); + net_info_text_group_->SetText(net_info_string_); } SimpleComponent c(pass); c.SetTransparent(true); @@ -459,11 +461,12 @@ void Graphics::DrawMiscOverlays(RenderPass* pass) { for (int e = 0; e < text_elem_count; e++) { c.SetTexture(net_info_text_group_->GetElementTexture(e)); c.SetFlatness(1.0f); - c.PushTransform(); - c.Translate(4.0f, (show_fps_ ? 66.0f : 40.0f), kScreenMessageZDepth); - c.Scale(0.7f, 0.7f); - c.DrawMesh(net_info_text_group_->GetElementMesh(e)); - c.PopTransform(); + { + auto xf = c.ScopedTransform(); + c.Translate(4.0f, (show_fps_ ? 66.0f : 40.0f), kScreenMessageZDepth); + c.Scale(0.7f, 0.7f); + c.DrawMesh(net_info_text_group_->GetElementMesh(e)); + } } c.Submit(); } @@ -603,33 +606,35 @@ void Graphics::DrawMiscOverlays(RenderPass* pass) { } c.SetColor(r * fade, g * fade, b * fade, a); - c.PushTransform(); - if (i->v_smoothed == 0.0f) { - i->v_smoothed = v + v_extra; - } else { - float smoothing = 0.8f; - i->v_smoothed = - smoothing * i->v_smoothed + (1.0f - smoothing) * (v + v_extra); - } - c.Translate(screen_width * 0.5f, i->v_smoothed, - vr ? 60 : kScreenMessageZDepth); - if (vr) { - // Let's drop down a bit in vr mode. - c.Translate(0, -10.0f, 0); - c.Scale((str_width + 60) * scale * s_extra, - (str_height + 20) * scale * s_extra); + { + auto xf = c.ScopedTransform(); - // Align our bottom with where we just scaled from. - c.Translate(0, 0.5f, 0); - } else { - c.Scale((str_width + 110) * scale * s_extra, - (str_height + 40) * scale * s_extra); + if (i->v_smoothed == 0.0f) { + i->v_smoothed = v + v_extra; + } else { + float smoothing = 0.8f; + i->v_smoothed = smoothing * i->v_smoothed + + (1.0f - smoothing) * (v + v_extra); + } + c.Translate(screen_width * 0.5f, i->v_smoothed, + vr ? 60 : kScreenMessageZDepth); + if (vr) { + // Let's drop down a bit in vr mode. + c.Translate(0, -10.0f, 0); + c.Scale((str_width + 60) * scale * s_extra, + (str_height + 20) * scale * s_extra); - // Align our bottom with where we just scaled from. - c.Translate(0, 0.5f, 0); + // Align our bottom with where we just scaled from. + c.Translate(0, 0.5f, 0); + } else { + c.Scale((str_width + 110) * scale * s_extra, + (str_height + 40) * scale * s_extra); + + // Align our bottom with where we just scaled from. + c.Translate(0, 0.5f, 0); + } + c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1)); } - c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1)); - c.PopTransform(); v += scale * (36 + str_height); if (v > g_base->graphics->screen_virtual_height() + 30) { @@ -698,13 +703,14 @@ void Graphics::DrawMiscOverlays(RenderPass* pass) { c.SetColor(1, 1, 1, a); } c.SetFlatness(i->GetText().GetElementMaxFlatness(e)); - c.PushTransform(); - c.Translate(screen_width * 0.5f, i->v_smoothed, - vr ? 150 : kScreenMessageZDepth); - c.Scale(scale * s_extra, scale * s_extra); - c.Translate(0, 20); - c.DrawMesh(i->GetText().GetElementMesh(e)); - c.PopTransform(); + { + auto xf = c.ScopedTransform(); + c.Translate(screen_width * 0.5f, i->v_smoothed, + vr ? 150 : kScreenMessageZDepth); + c.Scale(scale * s_extra, scale * s_extra); + c.Translate(0, 20); + c.DrawMesh(i->GetText().GetElementMesh(e)); + } } v += scale * (36 + str_height); @@ -798,12 +804,13 @@ void Graphics::DrawMiscOverlays(RenderPass* pass) { g_base->assets->SysTexture(SysTextureID::kCharacterIconMask)); } c2.SetColor(1, 1, 1, a); - c2.PushTransform(); - c2.Translate(h - 14, v_base + 10 + i->v_smoothed, - kScreenMessageZDepth); - c2.Scale(22.0f * s_extra, 22.0f * s_extra); - c2.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1)); - c2.PopTransform(); + { + auto xf = c2.ScopedTransform(); + c2.Translate(h - 14, v_base + 10 + i->v_smoothed, + kScreenMessageZDepth); + c2.Scale(22.0f * s_extra, 22.0f * s_extra); + c2.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1)); + } c2.Submit(); } @@ -830,11 +837,12 @@ void Graphics::DrawMiscOverlays(RenderPass* pass) { 1.0f * a); c.SetFlatness(i->GetText().GetElementMaxFlatness(e)); c.SetMaskUV2Texture(i->GetText().GetElementMaskUV2Texture(e)); - c.PushTransform(); - c.Translate(h, v_base + 2 + i->v_smoothed, kScreenMessageZDepth); - c.Scale(0.6f * s_extra, 0.6f * s_extra); - c.DrawMesh(i->GetText().GetElementMesh(e)); - c.PopTransform(); + { + auto xf = c.ScopedTransform(); + c.Translate(h, v_base + 2 + i->v_smoothed, kScreenMessageZDepth); + c.Scale(0.6f * s_extra, 0.6f * s_extra); + c.DrawMesh(i->GetText().GetElementMesh(e)); + } } assert(!i->translation_dirty); v -= g_base->text_graphics->GetStringHeight(i->s_translated.c_str()) @@ -1171,12 +1179,12 @@ void Graphics::BuildAndPushFrameDef() { g_base->input->Draw(frame_def); RenderPass* overlay_pass = frame_def->overlay_pass(); - DrawMiscOverlays(overlay_pass); + DrawMiscOverlays(frame_def); // Let UI draw dev console and whatever else. DrawDevUI(frame_def); - DrawCursor(overlay_pass, app_time_millisecs); + DrawCursor(frame_def); // Draw our light/shadow images to the screen if desired. DrawDebugBuffers(overlay_pass); @@ -1224,7 +1232,7 @@ void Graphics::BuildAndPushFrameDef() { frame_def->set_mesh_data_destroys(mesh_data_destroys_); mesh_data_destroys_.clear(); - g_base->graphics_server->SetFrameDef(frame_def); + g_base->graphics_server->EnqueueFrameDef(frame_def); // Clean up frame_defs awaiting deletion. ClearFrameDefDeleteList(); @@ -1249,13 +1257,14 @@ void Graphics::DrawBoxingGlovesTest(FrameDef* frame_def) { // Blit. if (explicit_bool(true)) { PostProcessComponent c(frame_def->blit_pass()); - c.setNormalDistort(0.07f); - c.PushTransform(); - c.Translate(0, 7, -3.3f); - c.Scale(10, 10, 10); - c.Rotate(a, 0, 0, 1); - c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kBoxingGlove)); - c.PopTransform(); + c.SetNormalDistort(0.07f); + { + auto xf = c.ScopedTransform(); + c.Translate(0, 7, -3.3f); + c.Scale(10, 10, 10); + c.Rotate(a, 0, 0, 1); + c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kBoxingGlove)); + } c.Submit(); } @@ -1265,12 +1274,13 @@ void Graphics::DrawBoxingGlovesTest(FrameDef* frame_def) { c.SetTexture(g_base->assets->SysTexture(SysTextureID::kBoxingGlove)); c.SetReflection(ReflectionType::kSoft); c.SetReflectionScale(0.4f, 0.4f, 0.4f); - c.PushTransform(); - c.Translate(0.0f, 3.7f, -3.3f); - c.Scale(10.0f, 10.0f, 10.0f); - c.Rotate(a, 0.0f, 0.0f, 1.0f); - c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kBoxingGlove)); - c.PopTransform(); + { + auto xf = c.ScopedTransform(); + c.Translate(0.0f, 3.7f, -3.3f); + c.Scale(10.0f, 10.0f, 10.0f); + c.Rotate(a, 0.0f, 0.0f, 1.0f); + c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kBoxingGlove)); + } c.Submit(); } @@ -1279,12 +1289,13 @@ void Graphics::DrawBoxingGlovesTest(FrameDef* frame_def) { SimpleComponent c(frame_def->light_shadow_pass()); c.SetColor(0.16f, 0.11f, 0.1f, 1.0f); c.SetTransparent(true); - c.PushTransform(); - c.Translate(0.0f, 3.7f, -3.3f); - c.Scale(10.0f, 10.0f, 10.0f); - c.Rotate(a, 0.0f, 0.0f, 1.0f); - c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kBoxingGlove)); - c.PopTransform(); + { + auto xf = c.ScopedTransform(); + c.Translate(0.0f, 3.7f, -3.3f); + c.Scale(10.0f, 10.0f, 10.0f); + c.Rotate(a, 0.0f, 0.0f, 1.0f); + c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kBoxingGlove)); + } c.Submit(); } } @@ -1295,21 +1306,23 @@ void Graphics::DrawDebugBuffers(RenderPass* pass) { { SpecialComponent c(pass, SpecialComponent::Source::kLightBuffer); float csize = 100; - c.PushTransform(); - c.Translate(70, 400, kDebugImgZDepth); - c.Scale(csize, csize); - c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1)); - c.PopTransform(); + { + auto xf = c.ScopedTransform(); + c.Translate(70, 400, kDebugImgZDepth); + c.Scale(csize, csize); + c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1)); + } c.Submit(); } { SpecialComponent c(pass, SpecialComponent::Source::kLightShadowBuffer); float csize = 100; - c.PushTransform(); - c.Translate(70, 250, kDebugImgZDepth); - c.Scale(csize, csize); - c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1)); - c.PopTransform(); + { + auto xf = c.ScopedTransform(); + c.Translate(70, 250, kDebugImgZDepth); + c.Scale(csize, csize); + c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1)); + } c.Submit(); } } @@ -1364,7 +1377,9 @@ void Graphics::DrawFades(FrameDef* frame_def, millisecs_t real_time) { fade_ = 1.0f - (static_cast(real_time - fade_start_) / static_cast(fade_time_)); - if (fade_ <= 0) fade_ = 0.00001f; + if (fade_ <= 0) { + fade_ = 0.00001f; + } } else { fade_ = 0; if (!was_done && fade_end_call_.Exists()) { @@ -1386,60 +1401,8 @@ void Graphics::DrawFades(FrameDef* frame_def, millisecs_t real_time) { / static_cast(kProgressBarFadeTime)) * (1.0f - a); } - // TODO(ericf): move this to GraphicsVR. - if (g_core->IsVRMode()) { -#if BA_VR_BUILD - SimpleComponent c(frame_def->vr_cover_pass()); - c.SetTransparent(false); - Vector3f cam_pt = {0.0f, 0.0f, 0.0f}; - Vector3f cam_target_pt = {0.0f, 0.0f, 0.0f}; - cam_pt = - Vector3f(frame_def->cam_original().x, frame_def->cam_original().y, - frame_def->cam_original().z); - // In vr follow-mode the cam point gets tweaked. - // - // FIXME: should probably just do this on the camera end. - if (frame_def->camera_mode() == CameraMode::kOrbit) { - // fudge this one up a bit; looks better that way.. - cam_target_pt = Vector3f(frame_def->cam_target_original().x, - frame_def->cam_target_original().y + 6.0f, - frame_def->cam_target_original().z); - } else { - cam_target_pt = Vector3f(frame_def->cam_target_original().x, - frame_def->cam_target_original().y, - frame_def->cam_target_original().z); - } - Vector3f diff = cam_target_pt - cam_pt; - diff.Normalize(); - Vector3f side = Vector3f::Cross(diff, Vector3f(0.0f, 1.0f, 0.0f)); - Vector3f up = Vector3f::Cross(diff, side); - c.SetColor(0, 0, 0); - c.PushTransform(); - // we start in vr-overlay screen space; get back to world.. - c.Translate(cam_pt.x, cam_pt.y, cam_pt.z); - c.MultMatrix(Matrix44fOrient(diff, up).m); - // at the very end we stay turned around so we get 100% black - if (a < 0.98f) { - c.Translate(0, 0, 40.0f * a); - c.Rotate(180, 1, 0, 0); - } - float inv_a = 1.0f - a; - float s = 100.0f * inv_a + 5.0f * a; - c.Scale(s, s, s); - c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kVRFade)); - c.PopTransform(); - c.Submit(); -#else // BA_VR_BUILD - throw Exception(); -#endif - } else { - SimpleComponent c(overlay_pass); - c.SetTransparent(a < 1.0f); - c.SetColor(0, 0, 0, a); - c.DrawMesh(screen_mesh_.Get()); - c.Submit(); - } + DoDrawFade(frame_def, a); // If we're doing a progress-bar fade, throw in the fading progress bar. if (real_time - progress_bar_end_time_ < kProgressBarFadeTime / 2) { @@ -1452,9 +1415,25 @@ void Graphics::DrawFades(FrameDef* frame_def, millisecs_t real_time) { } } -void Graphics::DrawCursor(RenderPass* pass, millisecs_t real_time) { +void Graphics::DoDrawFade(FrameDef* frame_def, float amt) { + SimpleComponent c(frame_def->overlay_front_pass()); + c.SetTransparent(amt < 1.0f); + c.SetColor(0, 0, 0, amt); + { + // Draw this at the front of this overlay pass; should never really + // need stuff covering this methinks. + auto xf = c.ScopedTransform(); + c.Translate(0.0f, 0.0f, 1.0f); + c.DrawMesh(screen_mesh_.Get()); + } + c.Submit(); +} + +void Graphics::DrawCursor(FrameDef* frame_def) { assert(g_base->InLogicThread()); + millisecs_t real_time = frame_def->real_time(); + bool can_show_cursor = g_core->platform->IsRunningOnDesktop(); bool should_show_cursor = camera_->manual() || g_base->input->IsCursorVisible(); @@ -1481,20 +1460,21 @@ void Graphics::DrawCursor(RenderPass* pass, millisecs_t real_time) { } else { // Draw software cursor. if (can_show_cursor && should_show_cursor) { - SimpleComponent c(pass); + SimpleComponent c(frame_def->overlay_front_pass()); c.SetTransparent(true); float csize = 50.0f; c.SetTexture(g_base->assets->SysTexture(SysTextureID::kCursor)); - c.PushTransform(); + { + auto xf = c.ScopedTransform(); - // Note: we don't plug in known cursor position values here; we tell the - // renderer to insert the latest values on its end; this lessens cursor - // lag substantially. - c.CursorTranslate(); - c.Translate(csize * 0.44f, csize * -0.44f, kCursorZDepth); - c.Scale(csize, csize); - c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1)); - c.PopTransform(); + // Note: we don't plug in known cursor position values here; we tell the + // renderer to insert the latest values on its end; this lessens cursor + // lag substantially. + c.CursorTranslate(); + c.Translate(csize * 0.44f, csize * -0.44f, kCursorZDepth); + c.Scale(csize, csize); + c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1)); + } c.Submit(); } } @@ -1898,7 +1878,7 @@ auto Graphics::ScreenMessageEntry::GetText() -> TextGroup& { mesh_dirty = true; } if (mesh_dirty) { - s_mesh_->set_text( + s_mesh_->SetText( s_translated, align_left ? TextMesh::HAlign::kLeft : TextMesh::HAlign::kCenter, TextMesh::VAlign::kBottom); diff --git a/src/ballistica/base/graphics/graphics.h b/src/ballistica/base/graphics/graphics.h index 9c10307d..889ccdaf 100644 --- a/src/ballistica/base/graphics/graphics.h +++ b/src/ballistica/base/graphics/graphics.h @@ -44,7 +44,8 @@ const float kBackingDepth1{0.0f}; const float kShadowNeutral{0.5f}; -const float kCursorZDepth{-0.1f}; +// Cursor depth within the front-overlay (not related to above depths). +const float kCursorZDepth{0.9f}; // Client class for graphics operations (used from the logic thread). class Graphics { @@ -317,11 +318,14 @@ class Graphics { camera_gyro_explicitly_disabled_ = disabled; } + protected: + virtual void DoDrawFade(FrameDef* frame_def, float amt); + private: class ScreenMessageEntry; void DrawBoxingGlovesTest(FrameDef* frame_def); void DrawBlotches(FrameDef* frame_def); - void DrawCursor(RenderPass* pass, millisecs_t real_time); + void DrawCursor(FrameDef* frame_def); void DrawFades(FrameDef* frame_def, millisecs_t real_time); void DrawDebugBuffers(RenderPass* pass); @@ -331,7 +335,7 @@ class Graphics { float size, float r, float g, float b, float a); auto GetEmptyFrameDef() -> FrameDef*; void InitInternalComponents(FrameDef* frame_def); - void DrawMiscOverlays(RenderPass* pass); + void DrawMiscOverlays(FrameDef* frame_def); void DrawLoadDot(RenderPass* pass); void ClearFrameDefDeleteList(); void DrawProgressBar(RenderPass* pass, float opacity); diff --git a/src/ballistica/base/graphics/graphics_server.cc b/src/ballistica/base/graphics/graphics_server.cc index e262296e..01bed987 100644 --- a/src/ballistica/base/graphics/graphics_server.cc +++ b/src/ballistica/base/graphics/graphics_server.cc @@ -47,13 +47,12 @@ void GraphicsServer::OnMainThreadStartApp() { } } -void GraphicsServer::SetFrameDef(FrameDef* framedef) { - // Note: we're just setting the framedef directly here - // even though this gets called from the logic thread. - // Ideally it would seem we should push these to our thread - // event list, but currently we spin-lock waiting for new - // frames to appear which would prevent that from working; - // we would need to change that code. +void GraphicsServer::EnqueueFrameDef(FrameDef* framedef) { + // Note: we're just setting the framedef directly here even though this + // gets called from the logic thread. Ideally it would seem we should push + // these to our thread event list, but currently we may spin-lock waiting + // for new frames to appear which would prevent that from working; we + // would need to change that code. { std::scoped_lock llock(frame_def_mutex_); assert(frame_def_ == nullptr); @@ -69,8 +68,8 @@ auto GraphicsServer::GetRenderFrameDef() -> FrameDef* { return nullptr; } - // If the app says it's minimized, don't do anything. - // (on iOS we'll get shut down if we make GL calls in this state, etc) + // If the app says it's minimized, don't do anything (on iOS we'll get + // shut down if we make GL calls in this state, etc). if (g_base->app_adapter->app_paused()) { return nullptr; } @@ -78,9 +77,7 @@ auto GraphicsServer::GetRenderFrameDef() -> FrameDef* { // Do some incremental loading every time we try to render. g_base->assets->RunPendingGraphicsLoads(); - // Spin and wait for a short bit for a frame_def to appear. If it does, we - // grab it, render it, and also message the logic thread to start generating - // another one. + // Spin and wait for a short bit for a frame_def to appear. while (true) { FrameDef* frame_def{}; { @@ -92,8 +89,8 @@ auto GraphicsServer::GetRenderFrameDef() -> FrameDef* { } if (frame_def) { // As soon as we start working on rendering a frame, ask the logic - // thread to start working on the next one for us. Keeps things nice and - // pipelined. + // thread to start working on the next one for us. Keeps things nice + // and pipelined. g_base->logic->event_loop()->PushCall([] { g_base->logic->Draw(); }); return frame_def; } @@ -150,8 +147,8 @@ void GraphicsServer::PreprocessRenderFrameDef(FrameDef* frame_def) { } } -// Does the default drawing to the screen, either from the left or right stereo -// eye or in mono. +// Does the default drawing to the screen, either from the left or right +// stereo eye or in mono. void GraphicsServer::DrawRenderFrameDef(FrameDef* frame_def, int eye) { assert(renderer_); if (renderer_) { @@ -175,15 +172,12 @@ void GraphicsServer::TryRender() { assert(g_base->InGraphicsThread()); if (FrameDef* frame_def = GetRenderFrameDef()) { - // Apply settings such as tv-mode passed along on the frame-def. + // Apply settings such as tv-mode that were passed along on the + // frame-def. ApplyFrameDefSettings(frame_def); - // Note: we always run mesh updates contained in the framedef - // even if we don't actually render it. - // (Hmm this seems flaky; will TryRender always get called - // for each FrameDef?... perhaps we should separate mesh updates - // from FrameDefs? Or change our logic so that frame-defs *always* get - // rendered. + // Note: we run mesh-updates on each frame-def that comes through even + // if we don't actually render the frame. RunFrameDefMeshUpdates(frame_def); // Only actually render if we have a screen and aren't in a hold. diff --git a/src/ballistica/base/graphics/graphics_server.h b/src/ballistica/base/graphics/graphics_server.h index 10fd4fcb..646a2d99 100644 --- a/src/ballistica/base/graphics/graphics_server.h +++ b/src/ballistica/base/graphics/graphics_server.h @@ -15,18 +15,17 @@ namespace ballistica::base { -// Runs in the main thread and renders frame_defs shipped to it by the -// Graphics +/// A server that runs in the graphics thread and renders frame_defs shipped +/// to it by the logic thread. class GraphicsServer { public: GraphicsServer(); void OnMainThreadStartApp(); - /// Should be called to inform ballistica of screen size changes; this will be - /// applied to the server and then sent to the logic thread to apply to - /// various - // app systems (ui, etc.). + /// Should be called to inform ballistica of screen size changes; this + /// will be applied to the server and then sent to the logic thread to + /// apply to various app systems (ui, etc.). void SetScreenResolution(float h, float v); void PushSetScreenGammaCall(float gamma); @@ -42,14 +41,14 @@ class GraphicsServer { const std::vector*>& components); void SetRenderHold(); - // Used by the logic thread to pass frame-defs to the graphics server - // for rendering. - void SetFrameDef(FrameDef* framedef); + /// Used by the logic thread to pass frame-defs to the graphics server for + /// rendering. + void EnqueueFrameDef(FrameDef* framedef); - // returns the next frame_def needing to be rendered, waiting for it to arrive - // if necessary. this can return nullptr if no frame_defs come in within a - // reasonable amount of time. a frame_def here *must* be rendered and disposed - // of using the RenderFrameDef* calls + // Returns the next frame_def to be rendered, waiting for it to arrive if + // necessary. this can return nullptr if no frame_defs come in within a + // reasonable amount of time. a frame_def here *must* be rendered and + // disposed of using the RenderFrameDef* calls. auto GetRenderFrameDef() -> FrameDef*; void ApplyFrameDefSettings(FrameDef* frame_def); diff --git a/src/ballistica/base/graphics/graphics_vr.cc b/src/ballistica/base/graphics/graphics_vr.cc index d53f92d8..34739141 100644 --- a/src/ballistica/base/graphics/graphics_vr.cc +++ b/src/ballistica/base/graphics/graphics_vr.cc @@ -37,6 +37,49 @@ static auto ValueTestBool(bool* storage, double* absval, double* deltaval) return static_cast(*storage); } +void GraphicsVR::DoDrawFade(FrameDef* frame_def, float amt) { + SimpleComponent c(frame_def->vr_cover_pass()); + c.SetTransparent(false); + Vector3f cam_pt = {0.0f, 0.0f, 0.0f}; + Vector3f cam_target_pt = {0.0f, 0.0f, 0.0f}; + cam_pt = Vector3f(frame_def->cam_original().x, frame_def->cam_original().y, + frame_def->cam_original().z); + + // In vr follow-mode the cam point gets tweaked. + // + // FIXME: should probably just do this on the camera end. + if (frame_def->camera_mode() == CameraMode::kOrbit) { + // fudge this one up a bit; looks better that way.. + cam_target_pt = Vector3f(frame_def->cam_target_original().x, + frame_def->cam_target_original().y + 6.0f, + frame_def->cam_target_original().z); + } else { + cam_target_pt = Vector3f(frame_def->cam_target_original().x, + frame_def->cam_target_original().y, + frame_def->cam_target_original().z); + } + Vector3f diff = cam_target_pt - cam_pt; + diff.Normalize(); + Vector3f side = Vector3f::Cross(diff, Vector3f(0.0f, 1.0f, 0.0f)); + Vector3f up = Vector3f::Cross(diff, side); + c.SetColor(0, 0, 0); + c.PushTransform(); + // We start in vr-overlay screen space; get back to world. + c.Translate(cam_pt.x, cam_pt.y, cam_pt.z); + c.MultMatrix(Matrix44fOrient(diff, up).m); + // At the very end we stay turned around so we get 100% black. + if (amt < 0.98f) { + c.Translate(0, 0, 40.0f * amt); + c.Rotate(180, 1, 0, 0); + } + float inv_a = 1.0f - amt; + float s = 100.0f * inv_a + 5.0f * amt; + c.Scale(s, s, s); + c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kVRFade)); + c.PopTransform(); + c.Submit(); +} + auto GraphicsVR::ValueTest(const std::string& arg, double* absval, double* deltaval, double* outval) -> bool { if (arg == "vrOverlayScale") { @@ -165,15 +208,15 @@ void GraphicsVR::CalcVROverlayMatrices(FrameDef* frame_def) { vr_overlay_matrix = CalcVROverlayMatrix(cam_pt, cam_target_pt); - // We also always calc a completely fixed matrix for some elements that - // should *never* move such as score-screens. + // We also always calc a completely fixed matrix for some elements + // that should *never* move such as score-screens. cam_target_pt.y = fixed_y; cam_target_pt.z = fixed_z; vr_overlay_matrix_fixed = CalcVROverlayMatrix(cam_pt, cam_target_pt); } - // Calc a screen-matrix that gives us a drawing area of - // kBaseVirtualResX by kBaseVirtualResY. + // Calc a screen-matrix that gives us a drawing area of kBaseVirtualResX + // by kBaseVirtualResY. frame_def->set_vr_overlay_screen_matrix( Matrix44fTranslate(-0.5f * kBaseVirtualResX, -0.5f * kBaseVirtualResY, 0.0f) @@ -225,9 +268,11 @@ auto GraphicsVR::CalcVROverlayMatrix(const Vector3f& cam_pt, base_scale)) * m; } + void GraphicsVR::DrawVROverlay(FrameDef* frame_def) { // In vr mode we have draw our overlay-flat texture in to space // as part of our regular overlay pass. + // // NOTE: this assumes nothing after this point gets drawn into // the overlay-flat pass (otherwise it may get skipped). // This should be a safe assumption since this is pretty much just for @@ -246,6 +291,7 @@ void GraphicsVR::DrawVROverlay(FrameDef* frame_def) { c.Submit(); } } + void GraphicsVR::DrawOverlayBounds(RenderPass* pass) { // We can optionally draw a guide to show the edges of the overlay pass if (draw_overlay_bounds_) { diff --git a/src/ballistica/base/graphics/graphics_vr.h b/src/ballistica/base/graphics/graphics_vr.h index 62ccd218..a365c743 100644 --- a/src/ballistica/base/graphics/graphics_vr.h +++ b/src/ballistica/base/graphics/graphics_vr.h @@ -63,6 +63,9 @@ class GraphicsVR : public Graphics { vr_hands_state_ = state; } + protected: + void DoDrawFade(FrameDef* frame_def, float amt) override; + private: void CalcVROverlayMatrices(FrameDef* frame_def); auto CalcVROverlayMatrix(const Vector3f& cam_pt, diff --git a/src/ballistica/base/graphics/mesh/image_mesh.h b/src/ballistica/base/graphics/mesh/image_mesh.h index aa267d48..136cd6fc 100644 --- a/src/ballistica/base/graphics/mesh/image_mesh.h +++ b/src/ballistica/base/graphics/mesh/image_mesh.h @@ -7,7 +7,7 @@ namespace ballistica::base { -// a mesh set up to draw images +// A mesh set up to draw images. class ImageMesh : public MeshIndexedSimpleSplit { public: ImageMesh(); diff --git a/src/ballistica/base/graphics/mesh/mesh_buffer_base.h b/src/ballistica/base/graphics/mesh/mesh_buffer_base.h index a3637655..34ce772e 100644 --- a/src/ballistica/base/graphics/mesh/mesh_buffer_base.h +++ b/src/ballistica/base/graphics/mesh/mesh_buffer_base.h @@ -7,10 +7,11 @@ namespace ballistica::base { -// Buffers used by the logic thread to pass indices/vertices/etc. to meshes in -// the graphics thread. Note that it is safe to create these in other threads; -// you just need to turn off thread-checks until you pass ownership to the game -// thread. (or just avoid creating references outside of the logic thread) +// Buffers used by the logic thread to pass indices/vertices/etc. to meshes +// in the graphics thread. Note that it is safe to create these in other +// threads; you just need to turn off thread-checks until you pass ownership +// to the game thread. (or just avoid creating references outside of the +// logic thread). class MeshBufferBase : public Object { public: uint32_t state; // which dynamicState value on the mesh this corresponds to diff --git a/src/ballistica/base/graphics/mesh/mesh_data_client_handle.h b/src/ballistica/base/graphics/mesh/mesh_data_client_handle.h index af6a1c88..37eedd90 100644 --- a/src/ballistica/base/graphics/mesh/mesh_data_client_handle.h +++ b/src/ballistica/base/graphics/mesh/mesh_data_client_handle.h @@ -8,9 +8,9 @@ namespace ballistica::base { -// Client-side (game-thread) handle to server-side (graphics-thread) mesh data. -// Server-side data will be created when this object is instantiated and -// cleared when this object goes down. +// Client-side (logic-thread) handle to server-side (graphics-thread) mesh +// data. Server-side data will be created when this object is instantiated +// and cleared when this object goes down. class MeshDataClientHandle : public Object { public: explicit MeshDataClientHandle(MeshData* d); diff --git a/src/ballistica/base/graphics/mesh/mesh_indexed_object_split.h b/src/ballistica/base/graphics/mesh/mesh_indexed_object_split.h index 5a3eaeb4..1baa3b56 100644 --- a/src/ballistica/base/graphics/mesh/mesh_indexed_object_split.h +++ b/src/ballistica/base/graphics/mesh/mesh_indexed_object_split.h @@ -7,7 +7,7 @@ namespace ballistica::base { -// a mesh with static indices and UVs and dynamic positions and normals +/// A mesh with static indices and UVs and dynamic positions and normals. class MeshIndexedObjectSplit : public MeshIndexedStaticDynamic class MeshIndexedStaticDynamic : public MeshIndexedBase { public: diff --git a/src/ballistica/base/graphics/renderer/render_pass.cc b/src/ballistica/base/graphics/renderer/render_pass.cc index f1642c40..b98349ae 100644 --- a/src/ballistica/base/graphics/renderer/render_pass.cc +++ b/src/ballistica/base/graphics/renderer/render_pass.cc @@ -49,14 +49,14 @@ void RenderPass::Render(RenderTarget* render_target, bool transparent) { switch (type()) { case Type::kBeautyPass: { g_base->graphics_server->SetCamera(cam_pos_, cam_target_, cam_up_); - // If this changes, make sure to change - // it before _drawCameraBuffer() too. + // If this changes, make sure to change it before _drawCameraBuffer() + // too. // FIXME: // If we're drawing our cam into its own buffer we could technically // use its full depth range ...otherwise we need to share with the // other onscreen elements (but maybe its good to use the limited - // range regardless to make sure we can) + // range regardless to make sure we can get by that way). renderer->SetDepthRange(kBackingDepth3, kBackingDepth4); SetFrustum(cam_near_clip_, cam_far_clip_); @@ -139,9 +139,9 @@ void RenderPass::Render(RenderTarget* render_target, bool transparent) { -amt * w, (1.0f + amt) * w, -amt * h, (1.0f + amt) * h, -1, 1); } else { g_base->graphics_server->SetCamera(cam_pos_, cam_target_, cam_up_); - // We set the same depth ranges as the overlay-3d pass since - // we're essentially doing the same thing. See explanation in the - // overlay-3d case above the one difference is that we split the + // We set the same depth ranges as the overlay-3d pass since we're + // essentially doing the same thing. See explanation in the + // overlay-3d case above. The one difference is that we split the // range between our fixed overlay and our regular overlay passes // (we want fixed-overlay stuff on bottom). if (renderer->has_camera_render_target()) { @@ -175,7 +175,7 @@ void RenderPass::Render(RenderTarget* render_target, bool transparent) { } } } else { - // Nn non-vr mode both our overlays are just ortho projected. + // In non-vr mode both our overlays are just ortho projected. g_base->graphics_server->ModelViewReset(); if (type() == Type::kOverlayFrontPass) { renderer->SetDepthRange(kBackingDepth1, kBackingDepth1B); @@ -230,8 +230,8 @@ void RenderPass::Render(RenderTarget* render_target, bool transparent) { const Vector3f& soffs = renderer->shadow_offset(); // Well, this is slightly terrifying; '-soffs' is causing crashes - // here but multing by -1.000001f works. - // (generally just on android 4.3 on atom processors) + // here but multing by -1.000001f works (generally just on Android + // 4.3 on atom processors). g_base->graphics_server->Translate(Vector3f( -1.000001f * soffs.x, -1.000001f * soffs.y, -1.000001f * soffs.z)); } diff --git a/src/ballistica/base/graphics/renderer/render_pass.h b/src/ballistica/base/graphics/renderer/render_pass.h index 3c7fa7f0..d52f3817 100644 --- a/src/ballistica/base/graphics/renderer/render_pass.h +++ b/src/ballistica/base/graphics/renderer/render_pass.h @@ -11,23 +11,46 @@ namespace ballistica::base { -// A drawing context for one pass. This can be a render to the screen, a shadow -// pass, a window, etc. +// A drawing context for one pass. This can be a render to the screen, a +// shadow pass, a window, etc. class RenderPass { public: enum class ReflectionSubPass { kRegular, kMirrored }; enum class Type { + // A pass whose results are projected onto the scene for lighting and + // shadow effects. Values lighter than kShadowNeutral will show up as + // light and darker than neutral will show up as shadowing. This version + // should be used by anything wanting to draw with both shadows and + // lighting cast on it. Note that there is no z-depth used in shadow + // calculations, so objects casting shadows should not show shadows or + // else they will shadow themselves. kLightShadowPass, + // A pass whose results are projected onto the scene for lighting and + // shadow effects. Values lighter than kShadowNeutral will show up as + // light and darker than neutral will show up as shadowing. This pass is + // intended to only contain lights however. Objects that cast shadows + // generally should use this light texture when drawing themselves; if + // they use the kLightShadowPass texture, they will shadow themselves. kLightPass, + // The pass where normal foreground scene geometry is drawn into. kBeautyPass, + // Background geometry is drawn into this; it has a separate depth range + // so that far off mountains can properly occlude each other and whatnot + // without sacrificing depth fidelity of the regular beauty pass. kBeautyPassBG, + // Geometry used to blit the camera buffer on-screen for final display. + // This geometry can make use of shaders for effects such as + // depth-of-field or can distort the texture lookup UVs for distortion + // shock-waves or other effects. kBlitPass, - // Standard 2d overlay stuff. May be drawn in 2d or on a plane in 3d - // space (in vr). In VR, each of these elements are drawn individually - // and can thus have their own depth. also in VR this overlay repositions - // itself per level; use kOverlayFixedPass for items that shouldn't. - // this overlay may be obscured by UI. Use OVERLAY_FRONT_PASS if you need - // things to show up in front of UI. + // Standard 2d overlay stuff such as UI. May be drawn in 2d or on a + // plane in 3d space (in vr). In VR, each of these elements are drawn + // individually and can thus have their own depth. also in VR, this + // overlay may be repositions based on the camera/map/etc; use + // kOverlayFixedPass for items that shouldn't do this (for example, + // elements visible across map transitions). Be aware that things here + // may be obscured by UI depending on depth/etc. Use OVERLAY_FRONT_PASS + // if you need things to always show up in front of UI. kOverlayPass, // Just like kOverlayPass but guaranteed to draw in front of UI. kOverlayFrontPass, @@ -40,7 +63,9 @@ class RenderPass { /// Only used in VR - stuff that needs to cover absolutely everything /// else (like the 3d wipe fade). kVRCoverPass, - // Only used in VR - overlay elements that should always be fixed in space. + // Only used in VR - overlay elements that should always be fixed in + // space. Use this for stuff that may be visible across map transitions + // or other events that can cause the regular overlay to move around. kOverlayFixedPass }; @@ -49,7 +74,7 @@ class RenderPass { auto type() const -> Type { return type_; } - // The physical size of the drawing surface. + // The physical size of the drawing surface (pixels). auto physical_width() const -> float { return physical_width_; } auto physical_height() const -> float { return physical_height_; } diff --git a/src/ballistica/base/graphics/support/net_graph.cc b/src/ballistica/base/graphics/support/net_graph.cc index 5f1b08d1..6c44fefc 100644 --- a/src/ballistica/base/graphics/support/net_graph.cc +++ b/src/ballistica/base/graphics/support/net_graph.cc @@ -152,8 +152,8 @@ void NetGraph::Draw(RenderPass* pass, double time, double x, double y, double w, snprintf(val_str, sizeof(val_str), "%.3f", impl_->smoothed ? impl_->v_smoothed : val); } - impl_->max_vel_text.set_text(val_str, TextMesh::HAlign::kLeft, - TextMesh::VAlign::kTop); + impl_->max_vel_text.SetText(val_str, TextMesh::HAlign::kLeft, + TextMesh::VAlign::kTop); SimpleComponent c2(pass); c2.SetTransparent(true); diff --git a/src/ballistica/base/graphics/text/text_group.cc b/src/ballistica/base/graphics/text/text_group.cc index 3dbd994c..71f85955 100644 --- a/src/ballistica/base/graphics/text/text_group.cc +++ b/src/ballistica/base/graphics/text/text_group.cc @@ -8,9 +8,9 @@ namespace ballistica::base { -void TextGroup::set_text(const std::string& text, TextMesh::HAlign alignment_h, - TextMesh::VAlign alignment_v, bool big, - float resolution_scale) { +void TextGroup::SetText(const std::string& text, TextMesh::HAlign alignment_h, + TextMesh::VAlign alignment_v, bool big, + float resolution_scale) { text_ = text; // In order to *actually* draw big, all our letters @@ -18,8 +18,8 @@ void TextGroup::set_text(const std::string& text, TextMesh::HAlign alignment_h, big_ = (big && TextGraphics::HaveBigChars(text)); // If we had an OS texture for custom drawing, release it. - // (it should stick around for a while; we'll be able to re-grab - // the same one if we havn't changed) + // It should stick around for a while; we'll be able to re-grab + // the same one if we havn't changed. os_texture_.Clear(); // If we're drawing big we always just need 1 font page (the big one). @@ -89,7 +89,9 @@ void TextGroup::set_text(const std::string& text, TextMesh::HAlign alignment_h, // For the few we can't color, we don't want to be able to // flatten them either. - if (!entry->can_color) entry->max_flatness = 0.0f; + if (!entry->can_color) { + entry->max_flatness = 0.0f; + } // For OS-rendered text we fill out a text-packer will all the spans // we'll need. we then hand that over to the OS to draw and create diff --git a/src/ballistica/base/graphics/text/text_group.h b/src/ballistica/base/graphics/text/text_group.h index 260d6f98..750bfd18 100644 --- a/src/ballistica/base/graphics/text/text_group.h +++ b/src/ballistica/base/graphics/text/text_group.h @@ -14,9 +14,9 @@ namespace ballistica::base { -// encapsulates the multiple meshes and textures necessary to -// draw arbitrary text. To actually draw the text, iterate over the meshes -// and textures this class provides to you, drawing each in the same manner +// Encapsulates the multiple meshes and textures necessary to draw arbitrary +// text. To actually draw the text, iterate over the meshes and textures +// this class provides to you, drawing each in the same manner. class TextGroup : public Object { public: // the number of meshes needing to be drawn for this text @@ -55,10 +55,10 @@ class TextGroup : public Object { ? SysTextureID::kSoftRect2 : SysTextureID::kSoftRect); } - void set_text(const std::string& text, - TextMesh::HAlign alignment_h = TextMesh::HAlign::kLeft, - TextMesh::VAlign alignment_v = TextMesh::VAlign::kNone, - bool big = false, float resolution_scale = 1.0f); + void SetText(const std::string& text, + TextMesh::HAlign alignment_h = TextMesh::HAlign::kLeft, + TextMesh::VAlign alignment_v = TextMesh::VAlign::kNone, + bool big = false, float resolution_scale = 1.0f); auto text() const -> const std::string& { return text_; } void GetCaratPts(const std::string& text_in, TextMesh::HAlign alignment_h, TextMesh::VAlign alignment_v, int carat_pos, float* carat_x, diff --git a/src/ballistica/base/ui/dev_console.cc b/src/ballistica/base/ui/dev_console.cc index 53ae57f9..d3ca2134 100644 --- a/src/ballistica/base/ui/dev_console.cc +++ b/src/ballistica/base/ui/dev_console.cc @@ -23,7 +23,6 @@ namespace ballistica::base { // How much of the screen the console covers when it is at full size. const float kDevConsoleSize = 0.9f; -const float kDevConsoleZDepth = 0.0f; const int kDevConsoleLineLimit = 80; const int kDevConsoleStringBreakUpSize = 1950; const int kDevConsoleActivateKey1 = SDLK_BACKQUOTE; @@ -33,20 +32,65 @@ const double kTransitionSeconds = 0.1; enum class DevButtonAttach_ { kLeft, kCenter, kRight }; -class DevConsole::Button_ { +static auto XOffs(DevButtonAttach_ attach) -> float { + switch (attach) { + case DevButtonAttach_::kLeft: + return 0.0f; + case DevButtonAttach_::kRight: + return g_base->graphics->screen_virtual_width(); + case DevButtonAttach_::kCenter: + return g_base->graphics->screen_virtual_width() * 0.5f; + } + assert(false); + return 0.0f; +} + +static void DrawBasicButton(RenderPass* pass, TextGroup* tgrp, float tscale, + float bottom, float x, float y, float width, + float height, const Vector3f& fgcolor, + const Vector3f& bgcolor) { + SimpleComponent c(pass); + c.SetTransparent(true); + c.SetColor(bgcolor.x, bgcolor.y, bgcolor.z, 1.0f); + { + auto xf = c.ScopedTransform(); + c.Translate(x + width * 0.5f, y + bottom + height * 0.5f, + kDevConsoleZDepth); + // Draw our backing. + { + auto xf = c.ScopedTransform(); + c.Scale(width, height); + c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1)); + } + // Draw our text. + c.SetColor(fgcolor.x, fgcolor.y, fgcolor.z, 1.0f); + c.SetFlatness(1.0f); + int elem_count = tgrp->GetElementCount(); + for (int e = 0; e < elem_count; e++) { + c.SetTexture(tgrp->GetElementTexture(e)); + { + auto xf = c.ScopedTransform(); + float sc{0.6f * tscale}; + c.Scale(sc, sc, 1.0f); + c.DrawMesh(tgrp->GetElementMesh(e)); + } + } + } + c.Submit(); +} + +/// Super-simple widget type for populating dev-console +/// (we don't want to depend on any of our full UI feature-sets). +class DevConsole::Widget_ { + public: + virtual ~Widget_() = default; + virtual auto HandleMouseDown(float mx, float my) -> bool = 0; + virtual void HandleMouseUp(float mx, float my) = 0; + virtual void Draw(RenderPass* pass, float bottom) = 0; +}; + +class DevConsole::Button_ : public DevConsole::Widget_ { public: - template - Button_(const std::string& label, float text_scale, DevButtonAttach_ attach, - float x, float y, float width, float height, const F& lambda) - : label{label}, - attach{attach}, - x{x}, - y{y}, - width{width}, - height{height}, - call{NewLambdaRunnable(lambda)}, - text_scale{text_scale} {} - std::string label; DevButtonAttach_ attach; float x; float y; @@ -55,27 +99,28 @@ class DevConsole::Button_ { bool pressed{}; Object::Ref call; TextGroup text_group; - bool text_group_built_{}; float text_scale; - auto InUs(float mx, float my) -> bool { - mx -= XOffs(); - return (mx >= x && mx <= (x + width) && my >= y && my <= (y + height)); - } - auto XOffs() -> float { - switch (attach) { - case DevButtonAttach_::kLeft: - return 0.0f; - case DevButtonAttach_::kRight: - return g_base->graphics->screen_virtual_width(); - case DevButtonAttach_::kCenter: - return g_base->graphics->screen_virtual_width() * 0.5f; - } - assert(false); - return 0.0f; + template + Button_(const std::string& label, float text_scale, DevButtonAttach_ attach, + float x, float y, float width, float height, const F& lambda) + : attach{attach}, + x{x}, + y{y}, + width{width}, + height{height}, + call{NewLambdaRunnable(lambda)}, + text_scale{text_scale} { + text_group.SetText(label, TextMesh::HAlign::kCenter, + TextMesh::VAlign::kCenter); } - auto HandleMouseDown(float mx, float my) -> bool { + auto InUs(float mx, float my) -> bool { + mx -= XOffs(attach); + return (mx >= x && mx <= (x + width) && my >= y && my <= (y + height)); + } + + auto HandleMouseDown(float mx, float my) -> bool override { if (InUs(mx, my)) { pressed = true; return true; @@ -83,56 +128,156 @@ class DevConsole::Button_ { return false; } - void HandleMouseUp(float mx, float my) { - pressed = false; - if (InUs(mx, my)) { - if (call.Exists()) { - call.Get()->Run(); + void HandleMouseUp(float mx, float my) override { + if (pressed) { + pressed = false; + if (InUs(mx, my)) { + if (call.Exists()) { + call.Get()->Run(); + } } } } - void Draw(RenderPass* pass, float bottom) { - if (!text_group_built_) { - text_group.set_text(label, TextMesh::HAlign::kCenter, - TextMesh::VAlign::kCenter); + void Draw(RenderPass* pass, float bottom) override { + DrawBasicButton( + pass, &text_group, text_scale, bottom, x + XOffs(attach), y, width, + height, + pressed ? Vector3f{0.0f, 0.0f, 0.0f} : Vector3f{0.8f, 0.7f, 0.8f}, + pressed ? Vector3f{0.8f, 0.7f, 0.8f} : Vector3f{0.25, 0.2f, 0.3f}); + } +}; + +class DevConsole::ToggleButton_ : public DevConsole::Widget_ { + public: + DevButtonAttach_ attach; + float x; + float y; + float width; + float height; + bool pressed{}; + bool on{}; + Object::Ref on_call; + Object::Ref off_call; + TextGroup text_group; + float text_scale; + + template + ToggleButton_(const std::string& label, float text_scale, + DevButtonAttach_ attach, float x, float y, float width, + float height, const F& on_call, const G& off_call) + : attach{attach}, + x{x}, + y{y}, + width{width}, + height{height}, + on_call{NewLambdaRunnable(on_call)}, + off_call{NewLambdaRunnable(off_call)}, + text_scale{text_scale} { + text_group.SetText(label, TextMesh::HAlign::kCenter, + TextMesh::VAlign::kCenter); + } + + auto InUs(float mx, float my) -> bool { + mx -= XOffs(attach); + return (mx >= x && mx <= (x + width) && my >= y && my <= (y + height)); + } + + auto HandleMouseDown(float mx, float my) -> bool override { + if (InUs(mx, my)) { + pressed = true; + return true; } - SimpleComponent c(pass); - c.SetTransparent(true); + return false; + } + + void HandleMouseUp(float mx, float my) override { if (pressed) { - c.SetColor(0.8f, 0.7f, 0.8f, 1.0f); - } else { - c.SetColor(0.25f, 0.2f, 0.3f, 1.0f); - } - { - auto xf = c.ScopedTransform(); - c.Translate(x + XOffs() + width * 0.5f, y + bottom + height * 0.5f, - kDevConsoleZDepth); - // Draw our backing. - { - auto xf = c.ScopedTransform(); - c.Scale(width, height); - c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1)); - } - // Draw our text. - if (pressed) { - c.SetColor(0.0f, 0.0f, 0.0f, 1.0f); - } else { - c.SetColor(0.8f, 0.7f, 0.8f, 1.0f); - } - c.SetFlatness(1.0f); - int elem_count = text_group.GetElementCount(); - for (int e = 0; e < elem_count; e++) { - c.SetTexture(text_group.GetElementTexture(e)); - { - auto xf = c.ScopedTransform(); - float sc{0.6f * text_scale}; - c.Scale(sc, sc, 1.0f); - c.DrawMesh(text_group.GetElementMesh(e)); + pressed = false; + if (InUs(mx, my)) { + on = !on; + auto&& call = on ? on_call : off_call; + if (call.Exists()) { + call.Get()->Run(); } } } - c.Submit(); + } + + void Draw(RenderPass* pass, float bottom) override { + DrawBasicButton(pass, &text_group, text_scale, bottom, x + XOffs(attach), y, + width, height, + pressed ? Vector3f{1.0f, 1.0f, 1.0f} + : on ? Vector3f{1.0f, 1.0f, 1.0f} + : Vector3f{0.8f, 0.7f, 0.8f}, + pressed ? Vector3f{0.5f, 0.2f, 1.0f} + : on ? Vector3f{0.5f, 0.4f, 0.6f} + : Vector3f{0.25, 0.2f, 0.3f}); + } +}; + +class DevConsole::TabButton_ : public DevConsole::Widget_ { + public: + DevButtonAttach_ attach; + float x; + float y; + float width; + float height; + bool pressed{}; + bool selected{}; + Object::Ref call; + TextGroup text_group; + float text_scale; + + template + TabButton_(const std::string& label, bool selected, float text_scale, + DevButtonAttach_ attach, float x, float y, float width, + float height, const F& call) + : attach{attach}, + x{x}, + y{y}, + selected{selected}, + width{width}, + height{height}, + call{NewLambdaRunnable(call)}, + text_scale{text_scale} { + text_group.SetText(label, TextMesh::HAlign::kCenter, + TextMesh::VAlign::kCenter); + } + + auto InUs(float mx, float my) -> bool { + mx -= XOffs(attach); + return (mx >= x && mx <= (x + width) && my >= y && my <= (y + height)); + } + + auto HandleMouseDown(float mx, float my) -> bool override { + if (InUs(mx, my) && !selected) { + pressed = true; + return true; + } + return false; + } + + void HandleMouseUp(float mx, float my) override { + if (pressed) { + pressed = false; + if (InUs(mx, my)) { + if (call.Exists()) { + call.Get()->Run(); + } + } + } + } + + void Draw(RenderPass* pass, float bottom) override { + DrawBasicButton(pass, &text_group, text_scale, bottom, x + XOffs(attach), y, + width, height, + pressed ? Vector3f{1.0f, 1.0f, 1.0f} + : selected ? Vector3f{1.0f, 1.0f, 1.0f} + : Vector3f{0.8f, 0.7f, 0.8f}, + pressed ? Vector3f{0.5f, 0.2f, 1.0f} + : selected ? Vector3f{0.5f, 0.4f, 0.6f} + : Vector3f{0.25, 0.2f, 0.3f}); } }; @@ -144,7 +289,7 @@ class DevConsole::Line_ { auto GetText() -> TextGroup& { if (!s_mesh_.Exists()) { s_mesh_ = Object::New(); - s_mesh_->set_text(s); + s_mesh_->SetText(s); } return *s_mesh_; } @@ -164,32 +309,45 @@ DevConsole::DevConsole() { title += " (test)"; } - title_text_group_.set_text(title); - built_text_group_.set_text("Built: " __DATE__ " " __TIME__); - prompt_text_group_.set_text(">"); + title_text_group_.SetText(title); + built_text_group_.SetText("Built: " __DATE__ " " __TIME__); + prompt_text_group_.SetText(">"); - // NOTE: Once we can adjust UI scale on the fly we'll have to update - // this to recalc accordingly. - float bs = PythonConsoleBaseScale_(); - buttons_.emplace_back("Exec", 0.75f * bs, DevButtonAttach_::kRight, - -33.0f * bs, 15.95f * bs, 32.0f * bs, 13.0f * bs, - [this] { Exec(); }); - - // buttons_.emplace_back("TestButton", 1.0f, DevButtonAttach_::kLeft, 100.0f, - // 100.0f, 100.0f, 30.0f, [] { printf("B1 PRESSED!\n"); - // }); - - // buttons_.emplace_back("TestButton2", 1.0f, DevButtonAttach_::kCenter, - // -50.0f, - // 120.0f, 100.0f, 30.0f, [] { printf("B2 PRESSED!\n"); - // }); - - // buttons_.emplace_back("TestButton3", 0.8f, DevButtonAttach_::kRight, - // -200.0f, - // 140.0f, 100.0f, 30.0f, [] { printf("B3 PRESSED!\n"); - // }); + Refresh(); } +void DevConsole::Refresh() { + BA_PRECONDITION(g_base->InLogicThread()); + buttons_.clear(); + tab_buttons_.clear(); + RefreshTabsButtons_(); + + if (active_tab_ == "Python") { + float bs = PythonConsoleBaseScale_(); + buttons_.emplace_back(std::make_unique( + "Exec", 0.75f * bs, DevButtonAttach_::kRight, -33.0f * bs, 15.95f * bs, + 32.0f * bs, 13.0f * bs, [this] { Exec(); })); + } +} + +void DevConsole::RefreshTabsButtons_() { + float bs = PythonConsoleBaseScale_(); + float bwidth = 90.0f * bs; + float bheight = 26.0f * bs; + float bscale = 0.8f * bs; + float total_width = tabs_.size() * bwidth; + float x = total_width * -0.5f; + + for (auto&& tab : tabs_) { + tab_buttons_.emplace_back(std::make_unique( + tab, active_tab_ == tab, bscale, DevButtonAttach_::kCenter, x, -bheight, + bwidth, bheight, [this, tab] { + active_tab_ = tab; + Refresh(); + })); + x += bwidth; + } +} DevConsole::~DevConsole() = default; auto DevConsole::HandleMouseDown(int button, float x, float y) -> bool { @@ -202,8 +360,13 @@ auto DevConsole::HandleMouseDown(int button, float x, float y) -> bool { // Pass to any buttons (in bottom-local space). if (button == 1) { + for (auto&& button : tab_buttons_) { + if (button->HandleMouseDown(x, y - bottom)) { + return true; + } + } for (auto&& button : buttons_) { - if (button.HandleMouseDown(x, y - bottom)) { + if (button->HandleMouseDown(x, y - bottom)) { return true; } } @@ -225,8 +388,11 @@ void DevConsole::HandleMouseUp(int button, float x, float y) { float bottom{Bottom_()}; if (button == 1) { + for (auto&& button : tab_buttons_) { + button->HandleMouseUp(x, y - bottom); + } for (auto&& button : buttons_) { - button.HandleMouseUp(x, y - bottom); + button->HandleMouseUp(x, y - bottom); } } @@ -311,7 +477,7 @@ auto DevConsole::HandleKeyPress(const SDL_Keysym* keysym) -> bool { // The rest of these presses we only handle while active. switch (keysym->sym) { case SDLK_ESCAPE: - ToggleState(); + Dismiss(); break; case SDLK_BACKSPACE: case SDLK_DELETE: { @@ -530,11 +696,12 @@ auto DevConsole::Bottom_() const -> float { return bottom; } -void DevConsole::Draw(RenderPass* pass) { +void DevConsole::Draw(FrameDef* frame_def) { float bs = PythonConsoleBaseScale_(); + RenderPass* pass = frame_def->overlay_front_pass(); - // If we're not yet transitioning in for the first time OR have - // completed transitioning out, do nothing. + // If we're not yet transitioning in for the first time OR have completed + // transitioning out, do nothing. if (transition_start_ <= 0.0 || state_ == State_::kInactive && ((g_base->logic->display_time() - transition_start_) @@ -543,155 +710,169 @@ void DevConsole::Draw(RenderPass* pass) { } float bottom = Bottom_(); + { bg_mesh_.SetPositionAndSize(0, bottom, kDevConsoleZDepth, pass->virtual_width(), (pass->virtual_height() - bottom)); stripe_mesh_.SetPositionAndSize(0, bottom + 15.0f * bs, kDevConsoleZDepth, pass->virtual_width(), 15.0f * bs); - shadow_mesh_.SetPositionAndSize(0, bottom - 7.0f * bs, kDevConsoleZDepth, - pass->virtual_width(), 7.0f * bs); + border_mesh_.SetPositionAndSize(0, bottom - 3.0f * bs, kDevConsoleZDepth, + pass->virtual_width(), 3.0f * bs); SimpleComponent c(pass); c.SetTransparent(true); c.SetColor(0, 0, 0.1f, 0.9f); c.DrawMesh(&bg_mesh_); c.Submit(); - c.SetColor(1.0f, 1.0f, 1.0f, 0.1f); - c.DrawMesh(&stripe_mesh_); - c.Submit(); - c.SetColor(0, 0, 0, 0.1f); - c.DrawMesh(&shadow_mesh_); - c.Submit(); - } - if (input_text_dirty_) { - input_text_group_.set_text(input_string_); - input_text_dirty_ = false; - last_input_text_change_time_ = pass->frame_def()->real_time(); - } - { - SimpleComponent c(pass); - c.SetFlatness(1.0f); - c.SetTransparent(true); - c.SetColor(0.5f, 0.5f, 0.7f, 0.8f); - int elem_count = built_text_group_.GetElementCount(); - for (int e = 0; e < elem_count; e++) { - c.SetTexture(built_text_group_.GetElementTexture(e)); - { - auto xf = c.ScopedTransform(); - c.Translate(pass->virtual_width() - 115.0f * bs, bottom + 4.0f, - kDevConsoleZDepth); - c.Scale(0.35f * bs, 0.35f * bs, 1.0f); - c.DrawMesh(built_text_group_.GetElementMesh(e)); - } - } - elem_count = title_text_group_.GetElementCount(); - for (int e = 0; e < elem_count; e++) { - c.SetTexture(title_text_group_.GetElementTexture(e)); - { - auto xf = c.ScopedTransform(); - c.Translate(10.0f * bs, bottom + 4.0f, kDevConsoleZDepth); - c.Scale(0.35f * bs, 0.35f * bs, 1.0f); - c.DrawMesh(title_text_group_.GetElementMesh(e)); - } - } - elem_count = prompt_text_group_.GetElementCount(); - for (int e = 0; e < elem_count; e++) { - c.SetTexture(prompt_text_group_.GetElementTexture(e)); - c.SetColor(1, 1, 1, 1); - { - auto xf = c.ScopedTransform(); - c.Translate(5.0f * bs, bottom + 14.5f * bs, kDevConsoleZDepth); - c.Scale(0.5f * bs, 0.5f * bs, 1.0f); - c.DrawMesh(prompt_text_group_.GetElementMesh(e)); - } - } - elem_count = input_text_group_.GetElementCount(); - for (int e = 0; e < elem_count; e++) { - c.SetTexture(input_text_group_.GetElementTexture(e)); - { - auto xf = c.ScopedTransform(); - c.Translate(15.0f * bs, bottom + 14.5f * bs, kDevConsoleZDepth); - c.Scale(0.5f * bs, 0.5f * bs, 1.0f); - c.DrawMesh(input_text_group_.GetElementMesh(e)); - } + if (active_tab_ == "Python") { + c.SetColor(1.0f, 1.0f, 1.0f, 0.1f); + c.DrawMesh(&stripe_mesh_); + c.Submit(); } + c.SetColor(0.25f, 0.2f, 0.3f, 1.0f); + c.DrawMesh(&border_mesh_); c.Submit(); } - // Carat. - millisecs_t real_time = pass->frame_def()->real_time(); - if (real_time % 200 < 100 - || (real_time - last_input_text_change_time_ < 100)) { - SimpleComponent c(pass); - c.SetTransparent(true); - c.SetColor(1, 1, 1, 0.7f); + if (active_tab_ == "Python") { + if (input_text_dirty_) { + input_text_group_.SetText(input_string_); + input_text_dirty_ = false; + last_input_text_change_time_ = pass->frame_def()->real_time(); + } { - auto xf = c.ScopedTransform(); - c.Translate( - (19.0f + g_base->text_graphics->GetStringWidth(input_string_) * 0.5f) - * bs, - bottom + 22.5f * bs, kDevConsoleZDepth); - c.Scale(6.0f * bs, 12.0f * bs, 1.0f); - c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1)); + SimpleComponent c(pass); + c.SetFlatness(1.0f); + c.SetTransparent(true); + c.SetColor(0.5f, 0.5f, 0.7f, 0.8f); + int elem_count = built_text_group_.GetElementCount(); + for (int e = 0; e < elem_count; e++) { + c.SetTexture(built_text_group_.GetElementTexture(e)); + { + auto xf = c.ScopedTransform(); + c.Translate(pass->virtual_width() - 115.0f * bs, bottom + 4.0f, + kDevConsoleZDepth); + c.Scale(0.35f * bs, 0.35f * bs, 1.0f); + c.DrawMesh(built_text_group_.GetElementMesh(e)); + } + } + elem_count = title_text_group_.GetElementCount(); + for (int e = 0; e < elem_count; e++) { + c.SetTexture(title_text_group_.GetElementTexture(e)); + { + auto xf = c.ScopedTransform(); + c.Translate(10.0f * bs, bottom + 4.0f, kDevConsoleZDepth); + c.Scale(0.35f * bs, 0.35f * bs, 1.0f); + c.DrawMesh(title_text_group_.GetElementMesh(e)); + } + } + elem_count = prompt_text_group_.GetElementCount(); + for (int e = 0; e < elem_count; e++) { + c.SetTexture(prompt_text_group_.GetElementTexture(e)); + c.SetColor(1, 1, 1, 1); + { + auto xf = c.ScopedTransform(); + c.Translate(5.0f * bs, bottom + 14.5f * bs, kDevConsoleZDepth); + c.Scale(0.5f * bs, 0.5f * bs, 1.0f); + c.DrawMesh(prompt_text_group_.GetElementMesh(e)); + } + } + elem_count = input_text_group_.GetElementCount(); + for (int e = 0; e < elem_count; e++) { + c.SetTexture(input_text_group_.GetElementTexture(e)); + { + auto xf = c.ScopedTransform(); + c.Translate(15.0f * bs, bottom + 14.5f * bs, kDevConsoleZDepth); + c.Scale(0.5f * bs, 0.5f * bs, 1.0f); + c.DrawMesh(input_text_group_.GetElementMesh(e)); + } + } + c.Submit(); + } + + // Carat. + millisecs_t real_time = pass->frame_def()->real_time(); + if (real_time % 200 < 100 + || (real_time - last_input_text_change_time_ < 100)) { + SimpleComponent c(pass); + c.SetTransparent(true); + c.SetColor(1, 1, 1, 0.7f); + { + auto xf = c.ScopedTransform(); + c.Translate( + (19.0f + + g_base->text_graphics->GetStringWidth(input_string_) * 0.5f) + * bs, + bottom + 22.5f * bs, kDevConsoleZDepth); + c.Scale(6.0f * bs, 12.0f * bs, 1.0f); + c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1)); + } + c.Submit(); + } + + // Draw output lines. + { + float draw_scale = 0.6f; + float v_inc = 18.0f; + SimpleComponent c(pass); + c.SetTransparent(true); + c.SetColor(1, 1, 1, 1); + c.SetFlatness(1.0f); + float h = 0.5f + * (g_base->graphics->screen_virtual_width() + - (kDevConsoleStringBreakUpSize * draw_scale)); + float v = bottom + 32.0f * bs; + if (!last_line_.empty()) { + if (last_line_mesh_dirty_) { + if (!last_line_mesh_group_.Exists()) { + last_line_mesh_group_ = Object::New(); + } + last_line_mesh_group_->SetText(last_line_); + last_line_mesh_dirty_ = false; + } + int elem_count = last_line_mesh_group_->GetElementCount(); + for (int e = 0; e < elem_count; e++) { + c.SetTexture(last_line_mesh_group_->GetElementTexture(e)); + { + auto xf = c.ScopedTransform(); + c.Translate(h, v + 2, kDevConsoleZDepth); + c.Scale(draw_scale, draw_scale); + c.DrawMesh(last_line_mesh_group_->GetElementMesh(e)); + } + } + v += v_inc; + } + for (auto i = lines_.rbegin(); i != lines_.rend(); i++) { + int elem_count = i->GetText().GetElementCount(); + for (int e = 0; e < elem_count; e++) { + c.SetTexture(i->GetText().GetElementTexture(e)); + { + auto xf = c.ScopedTransform(); + c.Translate(h, v + 2, kDevConsoleZDepth); + c.Scale(draw_scale, draw_scale); + c.DrawMesh(i->GetText().GetElementMesh(e)); + } + } + v += v_inc; + if (v > pass->virtual_height() + v_inc) { + break; + } + } + c.Submit(); } - c.Submit(); } - // Draw output lines. + // Tab Buttons. { - float draw_scale = 0.6f; - float v_inc = 18.0f; - SimpleComponent c(pass); - c.SetTransparent(true); - c.SetColor(1, 1, 1, 1); - c.SetFlatness(1.0f); - float h = 0.5f - * (g_base->graphics->screen_virtual_width() - - (kDevConsoleStringBreakUpSize * draw_scale)); - float v = bottom + 32.0f * bs; - if (!last_line_.empty()) { - if (last_line_mesh_dirty_) { - if (!last_line_mesh_group_.Exists()) { - last_line_mesh_group_ = Object::New(); - } - last_line_mesh_group_->set_text(last_line_); - last_line_mesh_dirty_ = false; - } - int elem_count = last_line_mesh_group_->GetElementCount(); - for (int e = 0; e < elem_count; e++) { - c.SetTexture(last_line_mesh_group_->GetElementTexture(e)); - { - auto xf = c.ScopedTransform(); - c.Translate(h, v + 2, kDevConsoleZDepth); - c.Scale(draw_scale, draw_scale); - c.DrawMesh(last_line_mesh_group_->GetElementMesh(e)); - } - } - v += v_inc; + for (auto&& button : tab_buttons_) { + button->Draw(pass, bottom); } - for (auto i = lines_.rbegin(); i != lines_.rend(); i++) { - int elem_count = i->GetText().GetElementCount(); - for (int e = 0; e < elem_count; e++) { - c.SetTexture(i->GetText().GetElementTexture(e)); - { - auto xf = c.ScopedTransform(); - c.Translate(h, v + 2, kDevConsoleZDepth); - c.Scale(draw_scale, draw_scale); - c.DrawMesh(i->GetText().GetElementMesh(e)); - } - } - v += v_inc; - if (v > pass->virtual_height() + v_inc) { - break; - } - } - c.Submit(); } // Buttons. { for (auto&& button : buttons_) { - button.Draw(pass, bottom); + button->Draw(pass, bottom); } } } @@ -706,6 +887,8 @@ auto DevConsole::PythonConsoleBaseScale_() const -> float { case UIScale::kLast: return 2.0f; } + FatalError("Unhandled scale."); + return 1.0f; } } // namespace ballistica::base diff --git a/src/ballistica/base/ui/dev_console.h b/src/ballistica/base/ui/dev_console.h index a017551e..a3881107 100644 --- a/src/ballistica/base/ui/dev_console.h +++ b/src/ballistica/base/ui/dev_console.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "ballistica/base/graphics/renderer/renderer.h" #include "ballistica/shared/foundation/object.h" @@ -13,6 +14,9 @@ namespace ballistica::base { +/// Where on the overlay-front-pass we draw. +const float kDevConsoleZDepth = 0.0f; + class DevConsole { public: DevConsole(); @@ -31,7 +35,7 @@ class DevConsole { /// Print text to the console. void Print(const std::string& s_in); - void Draw(RenderPass* pass); + void Draw(FrameDef* frame_def); /// Called when the console should start accepting Python command input. void EnableInput(); @@ -47,18 +51,27 @@ class DevConsole { auto HandleMouseDown(int button, float x, float y) -> bool; void HandleMouseUp(int button, float x, float y); void Exec(); + void Refresh(); private: + class Widget_; class Button_; + class ToggleButton_; + class TabButton_; class Line_; enum class State_ { kInactive, kMini, kFull }; + auto Bottom_() const -> float; auto PythonConsoleBaseScale_() const -> float; void SubmitCommand_(const std::string& command); void InvokeStringEditor_(); + void RefreshTabsButtons_(); + + std::list tabs_{"Python", "AppModes", "Logging", "Graphics"}; + std::string active_tab_{"Python"}; ImageMesh bg_mesh_; ImageMesh stripe_mesh_; - ImageMesh shadow_mesh_; + ImageMesh border_mesh_; TextGroup built_text_group_; TextGroup title_text_group_; TextGroup prompt_text_group_; @@ -78,7 +91,8 @@ class DevConsole { bool last_line_mesh_dirty_{true}; bool python_console_pressed_{}; PythonRef string_edit_adapter_; - std::list buttons_; + std::vector > buttons_; + std::vector > tab_buttons_; }; } // namespace ballistica::base diff --git a/src/ballistica/base/ui/ui.cc b/src/ballistica/base/ui/ui.cc index 0eafba90..e612a853 100644 --- a/src/ballistica/base/ui/ui.cc +++ b/src/ballistica/base/ui/ui.cc @@ -163,13 +163,14 @@ void UI::HandleMouseUp(int button, float x, float y) { if (dev_console_) { dev_console_->HandleMouseUp(button, x, y); } + if (dev_console_button_pressed_ && button == 1) { + dev_console_button_pressed_ = false; if (InDevConsoleButton_(x, y)) { if (dev_console_) { dev_console_->ToggleState(); } } - dev_console_button_pressed_ = false; } if (g_base->HaveUIV1()) { @@ -386,7 +387,7 @@ void UI::Draw(FrameDef* frame_def) { void UI::DrawDev(FrameDef* frame_def) { // Draw dev console. if (dev_console_) { - dev_console_->Draw(frame_def->overlay_pass()); + dev_console_->Draw(frame_def); } // Draw dev console button. @@ -422,14 +423,14 @@ auto UI::InDevConsoleButton_(float x, float y) const -> bool { void UI::DrawDevConsoleButton_(FrameDef* frame_def) { if (!dev_console_button_txt_.Exists()) { dev_console_button_txt_ = Object::New(); - dev_console_button_txt_->set_text("dev"); + dev_console_button_txt_->SetText("dev"); } auto& grp(*dev_console_button_txt_); float vwidth = g_base->graphics->screen_virtual_width(); float vheight = g_base->graphics->screen_virtual_height(); float bsz = DevConsoleButtonSize_(); - SimpleComponent c(frame_def->overlay_pass()); + SimpleComponent c(frame_def->overlay_front_pass()); c.SetTransparent(true); c.SetTexture(g_base->assets->SysTexture(SysTextureID::kCircleShadow)); if (dev_console_button_pressed_) { @@ -439,7 +440,7 @@ void UI::DrawDevConsoleButton_(FrameDef* frame_def) { } { auto xf = c.ScopedTransform(); - c.Translate(vwidth - bsz * 0.5f, vheight * 0.5f, kCursorZDepth - 0.01f); + c.Translate(vwidth - bsz * 0.5f, vheight * 0.5f, kDevConsoleZDepth + 0.01f); c.Scale(bsz, bsz, 1.0f); c.DrawMeshAsset(g_base->assets->SysMesh(SysMeshID::kImage1x1)); { diff --git a/src/ballistica/scene_v1/node/explosion_node.cc b/src/ballistica/scene_v1/node/explosion_node.cc index 3cabd8b8..008c7b22 100644 --- a/src/ballistica/scene_v1/node/explosion_node.cc +++ b/src/ballistica/scene_v1/node/explosion_node.cc @@ -136,7 +136,7 @@ void ExplosionNode::Draw(base::FrameDef* frame_def) { float s = 1.0f; if (high_quality) { base::PostProcessComponent c(frame_def->blit_pass()); - c.setNormalDistort(0.5f * amt); + c.SetNormalDistort(0.5f * amt); c.PushTransform(); c.Translate(position_[0], position_[1], position_[2]); c.Scale(1.0f + s * 0.8f * 0.025f * age, diff --git a/src/ballistica/scene_v1/node/shield_node.cc b/src/ballistica/scene_v1/node/shield_node.cc index 5018b4d1..c1cf5cee 100644 --- a/src/ballistica/scene_v1/node/shield_node.cc +++ b/src/ballistica/scene_v1/node/shield_node.cc @@ -268,7 +268,7 @@ void ShieldNode::Draw(base::FrameDef* frame_def) { } if (frame_def->has_depth_texture()) { base::PostProcessComponent c2(frame_def->blit_pass()); - c2.setNormalDistort(distort); + c2.SetNormalDistort(distort); c2.PushTransform(); c2.MultMatrix((om * m).m); c2.Scale(s, s, s); diff --git a/src/ballistica/scene_v1/node/spaz_node.cc b/src/ballistica/scene_v1/node/spaz_node.cc index 2f4b71e2..7cd1cdd3 100644 --- a/src/ballistica/scene_v1/node/spaz_node.cc +++ b/src/ballistica/scene_v1/node/spaz_node.cc @@ -4783,7 +4783,7 @@ void SpazNode::Draw(base::FrameDef* frame_def) { snprintf(buffer, sizeof(buffer), "%d", static_cast(diff)); if (curse_timer_txt_ != buffer) { curse_timer_txt_ = buffer; - curse_timer_text_group_.set_text(curse_timer_txt_); + curse_timer_text_group_.SetText(curse_timer_txt_); } float r, g, b; if (render_frame_count % 6 < 3) { @@ -4911,7 +4911,7 @@ void SpazNode::Draw(base::FrameDef* frame_def) { { // text if (counter_mesh_text_ != counter_text_) { counter_mesh_text_ = counter_text_; - counter_text_group_.set_text(counter_mesh_text_); + counter_text_group_.SetText(counter_mesh_text_); } base::SimpleComponent c(frame_def->overlay_3d_pass()); c.SetTransparent(true); @@ -4940,9 +4940,9 @@ void SpazNode::Draw(base::FrameDef* frame_def) { if (explicit_bool(true)) { if (name_mesh_txt_ != name_) { name_mesh_txt_ = name_; - name_text_group_.set_text(name_mesh_txt_, - base::TextMesh::HAlign::kCenter, - base::TextMesh::VAlign::kCenter); + name_text_group_.SetText(name_mesh_txt_, + base::TextMesh::HAlign::kCenter, + base::TextMesh::VAlign::kCenter); } base::SimpleComponent c(frame_def->overlay_3d_pass()); c.SetTransparent(true); diff --git a/src/ballistica/scene_v1/node/text_node.cc b/src/ballistica/scene_v1/node/text_node.cc index 44f0ec66..ca2c34ad 100644 --- a/src/ballistica/scene_v1/node/text_node.cc +++ b/src/ballistica/scene_v1/node/text_node.cc @@ -417,8 +417,8 @@ void TextNode::Draw(base::FrameDef* frame_def) { break; } - // update if need be - text_group_.set_text(text_translated_, h_align, v_align, true, 2.5f); + // Update if need be. + text_group_.SetText(text_translated_, h_align, v_align, true, 2.5f); text_group_dirty_ = false; } @@ -589,7 +589,7 @@ void TextNode::Draw(base::FrameDef* frame_def) { } // Update if need be. - text_group_.set_text(text_translated_, h_align, v_align); + text_group_.SetText(text_translated_, h_align, v_align); text_group_dirty_ = false; } float z = vr_2d_text diff --git a/src/ballistica/shared/ballistica.cc b/src/ballistica/shared/ballistica.cc index 1033b62f..c1fe3eb4 100644 --- a/src/ballistica/shared/ballistica.cc +++ b/src/ballistica/shared/ballistica.cc @@ -39,7 +39,7 @@ auto main(int argc, char** argv) -> int { namespace ballistica { // These are set automatically via script; don't modify them here. -const int kEngineBuildNumber = 21337; +const int kEngineBuildNumber = 21342; const char* kEngineVersion = "1.7.28"; const int kEngineApiVersion = 8; diff --git a/src/ballistica/ui_v1/support/root_ui.cc b/src/ballistica/ui_v1/support/root_ui.cc index 5e58f9db..ff1d09ce 100644 --- a/src/ballistica/ui_v1/support/root_ui.cc +++ b/src/ballistica/ui_v1/support/root_ui.cc @@ -265,9 +265,9 @@ void RootUI::Draw(base::FrameDef* frame_def) { party_button_text_group_ = Object::New(); } if (party_button_name != party_button_text_group_->text()) { - party_button_text_group_->set_text( - party_button_name, base::TextMesh::HAlign::kCenter, - base::TextMesh::VAlign::kTop); + party_button_text_group_->SetText(party_button_name, + base::TextMesh::HAlign::kCenter, + base::TextMesh::VAlign::kTop); } int text_elem_count = party_button_text_group_->GetElementCount(); for (int e = 0; e < text_elem_count; e++) { @@ -301,7 +301,7 @@ void RootUI::Draw(base::FrameDef* frame_def) { if (!party_size_text_group_.Exists()) { party_size_text_group_ = Object::New(); } - party_size_text_group_->set_text( + party_size_text_group_->SetText( std::to_string(party_size_text_group_num_)); // ..we also may want to update our 'someone joined' message if @@ -311,12 +311,12 @@ void RootUI::Draw(base::FrameDef* frame_def) { start_a_game_text_group_ = Object::New(); } if (party_size == 2) { // (includes us as host) - start_a_game_text_group_->set_text( + start_a_game_text_group_->SetText( g_base->assets->GetResourceString( "joinedPartyInstructionsText"), base::TextMesh::HAlign::kRight, base::TextMesh::VAlign::kTop); } else if (party_size > 2) { - start_a_game_text_group_->set_text( + start_a_game_text_group_->SetText( std::to_string(party_size - 1) + " friends have joined your party.\nGo to 'Play' to start " "a game.", diff --git a/src/ballistica/ui_v1/widget/text_widget.cc b/src/ballistica/ui_v1/widget/text_widget.cc index bf87b833..78af0a85 100644 --- a/src/ballistica/ui_v1/widget/text_widget.cc +++ b/src/ballistica/ui_v1/widget/text_widget.cc @@ -298,7 +298,7 @@ void TextWidget::Draw(base::RenderPass* pass, bool draw_transparent) { text_group_ = Object::New(); } if (text_group_dirty_) { - text_group_->set_text(text_translated_, align_h, align_v, big_, res_scale_); + text_group_->SetText(text_translated_, align_h, align_v, big_, res_scale_); text_width_ = g_base->text_graphics->GetStringWidth(text_translated_, big_); // FIXME: doesnt support big. diff --git a/src/tools/pcommandbatch/pcommandbatch.c b/src/tools/pcommandbatch/pcommandbatch.c index 20975fdf..c353e6f3 100644 --- a/src/tools/pcommandbatch/pcommandbatch.c +++ b/src/tools/pcommandbatch/pcommandbatch.c @@ -1,7 +1,7 @@ // Released under the MIT License. See LICENSE for details. // An ultra-simple client app to forward commands to a pcommand server. This -// lets us run *lots* of small pcommands very fast. Normally the limiting +// lets us run *lots* of small pcommands very fast. Often the limiting // factor in such cases is the startup time of Python which this mostly // eliminates. See tools/efrotools/pcommandbatch.py for more info. @@ -380,12 +380,20 @@ int calc_paths_(struct Context_* ctx) { // might be to have a single 'controller' server instance that spins up // worker instances as needed. Though such a fancy setup might be // overkill. - ctx->instance_num = rand() % 6; + // ctx->instance_num = rand() % 6; // I was wondering if using pid would lead to a more even distribution, // but it didn't make a significant difference in my tests. And I worry // there would be some odd corner case where pid isn't going up evenly, so // sticking with rand() for now. ctx->instance_num = ctx->pid % 6; + + // Actually I think this might be a good technique. This should deliver a + // few consecutive requests to a single server instance so it should + // reduce wasted spinup time when just a command or two is run, but it + // should still scale up to use all 6 instances when lots of commands go + // through. (tests show this to be the same speed as the others in that + // latter case). + ctx->instance_num = (ctx->pid / 4) % 6; return 0; }