From cf5b61c87a76d1c6465be1f0c636f39f242f1fae Mon Sep 17 00:00:00 2001 From: KP Date: Sat, 27 Jul 2024 21:07:41 -0500 Subject: [PATCH] Bugfixes n sector picking n more --- Data/resources/shaders/.kp3d/map_f.glsl | 4 + Data/resources/textures/.kp3d/crosshair.png | Bin 160 -> 144 bytes Data/sandbox-log.txt | 424 ++++++++------------ KP3Dii/src/KP3D_Map.cpp | 166 +++++--- KP3Dii/src/KP3D_Map.h | 26 +- KP3Dii/src/KP3D_Renderer3D.cpp | 62 ++- KP3Dii/src/KP3D_Renderer3D.h | 5 +- KP3Dii/src/KP3D_StaticMesh.cpp | 27 +- KP3Dii/src/KP3D_StaticMesh.h | 9 +- Sandbox/src/Editor.cpp | 218 ++++++---- Sandbox/src/Editor.h | 2 + Sandbox/src/Sandbox.cpp | 6 + Sandbox/src/Sandbox.h | 1 + 13 files changed, 510 insertions(+), 440 deletions(-) diff --git a/Data/resources/shaders/.kp3d/map_f.glsl b/Data/resources/shaders/.kp3d/map_f.glsl index 60d66b0..bbe7096 100644 --- a/Data/resources/shaders/.kp3d/map_f.glsl +++ b/Data/resources/shaders/.kp3d/map_f.glsl @@ -2,6 +2,8 @@ uniform vec3 u_campos; +uniform vec3 u_highlight; + in vec3 v_position; in vec3 v_normal; in vec3 v_proj_normal; @@ -63,6 +65,8 @@ void main() v_output = mix(v_output, texv, 0.66); + v_output.rgb *= u_highlight; + /* diff --git a/Data/resources/textures/.kp3d/crosshair.png b/Data/resources/textures/.kp3d/crosshair.png index 801fb03356b26ddd1a7c34aa4673ed227dbad9b1..d863835327db4b4b8a1ee6b61f6d1c6dfb881dc0 100644 GIT binary patch delta 113 zcmZ3$IDt{IGr-TCmrII^fq{Y7)59eQNV9`52OE$)5)^)UqN0ZTAqED%LyV#tUJXD& zRZkbk5Q*?)2e$u>45wI_)iiwB7$jMl49s>(6f(q`%CQ?7Ffg=MNWWa1B0il KpUXO@geCwU4jJwM delta 129 zcmbQhxPVcyGr-TCmrII^fq{Y7)59eQNb`X(2OE%-_t3pKQBfoOFi_wy@&|^zzx}?JVD|?B3f(yT8SlG2v1u3<@bM1|aPu%Au+*l&R a#>Q|dT_XOX6aRUj0Sun5elF{r5}E)`044bV diff --git a/Data/sandbox-log.txt b/Data/sandbox-log.txt index 6f5a254..90c27f4 100644 --- a/Data/sandbox-log.txt +++ b/Data/sandbox-log.txt @@ -1,269 +1,167 @@ -[05:25:18 PM] Info: Starting... +[09:06:03 PM] Info: Starting... KP3D version 2 =============================== Copyright (C) kpworld.xyz 2018-2024 Contact me! @kp_cftsz -[05:25:18 PM] Info: Initializing SDL -[05:25:18 PM] Info: Initializing OpenGL -[05:25:18 PM] Info: OpenGL version: 4.6.0 NVIDIA 536.23 -[05:25:18 PM] Info: Initializing GLEW -[05:25:18 PM] Info: Initializing SDL_mixer -[05:25:18 PM] Info: Reticulating splines... -[05:25:18 PM] Info: Ready! -[05:25:18 PM] Info: SECTOR HIERARCHY -[05:25:18 PM] Info: Sector 3 (area: 1) -[05:25:18 PM] Info: Parent: -[05:25:18 PM] Info: - 1 -[05:25:18 PM] Info: Children: -[05:25:18 PM] Info: - [NO CHILDREN] -[05:25:18 PM] Info: ----- -[05:25:18 PM] Info: Sector 4 (area: 1) -[05:25:18 PM] Info: Parent: -[05:25:18 PM] Info: - 2 -[05:25:18 PM] Info: Children: -[05:25:18 PM] Info: - [NO CHILDREN] -[05:25:18 PM] Info: ----- -[05:25:18 PM] Info: Sector 6 (area: 6) -[05:25:18 PM] Info: Parent: -[05:25:18 PM] Info: - 1 -[05:25:18 PM] Info: Children: -[05:25:18 PM] Info: - [NO CHILDREN] -[05:25:18 PM] Info: ----- -[05:25:18 PM] Info: Sector 2 (area: 19) -[05:25:18 PM] Info: Parent: -[05:25:18 PM] Info: - 1 -[05:25:18 PM] Info: Children: -[05:25:18 PM] Info: - 4 -[05:25:18 PM] Info: ----- -[05:25:18 PM] Info: Sector 5 (area: 34) -[05:25:18 PM] Info: Parent: -[05:25:18 PM] Info: - [NO PARENT] -[05:25:18 PM] Info: Children: -[05:25:18 PM] Info: - [NO CHILDREN] -[05:25:18 PM] Info: ----- -[05:25:18 PM] Info: Sector 1 (area: 105.5) -[05:25:18 PM] Info: Parent: -[05:25:18 PM] Info: - [NO PARENT] -[05:25:18 PM] Info: Children: -[05:25:18 PM] Info: - 3 -[05:25:18 PM] Info: - 6 -[05:25:18 PM] Info: - 2 -[05:25:18 PM] Info: ----- -[05:25:30 PM] Info: SECTOR HIERARCHY -[05:25:30 PM] Info: Sector 3 (area: 1) -[05:25:30 PM] Info: Parent: -[05:25:30 PM] Info: - 1 -[05:25:30 PM] Info: Children: -[05:25:30 PM] Info: - [NO CHILDREN] -[05:25:30 PM] Info: ----- -[05:25:30 PM] Info: Sector 4 (area: 1) -[05:25:30 PM] Info: Parent: -[05:25:30 PM] Info: - 2 -[05:25:30 PM] Info: Children: -[05:25:30 PM] Info: - [NO CHILDREN] -[05:25:30 PM] Info: ----- -[05:25:30 PM] Info: Sector 6 (area: 6) -[05:25:30 PM] Info: Parent: -[05:25:30 PM] Info: - 1 -[05:25:30 PM] Info: Children: -[05:25:30 PM] Info: - [NO CHILDREN] -[05:25:30 PM] Info: ----- -[05:25:30 PM] Info: Sector 7 (area: 15) -[05:25:30 PM] Info: Parent: -[05:25:30 PM] Info: - [NO PARENT] -[05:25:30 PM] Info: Children: -[05:25:30 PM] Info: - [NO CHILDREN] -[05:25:30 PM] Info: ----- -[05:25:30 PM] Info: Sector 2 (area: 19) -[05:25:30 PM] Info: Parent: -[05:25:30 PM] Info: - 1 -[05:25:30 PM] Info: Children: -[05:25:30 PM] Info: - 4 -[05:25:30 PM] Info: ----- -[05:25:30 PM] Info: Sector 5 (area: 34) -[05:25:30 PM] Info: Parent: -[05:25:30 PM] Info: - [NO PARENT] -[05:25:30 PM] Info: Children: -[05:25:30 PM] Info: - [NO CHILDREN] -[05:25:30 PM] Info: ----- -[05:25:30 PM] Info: Sector 1 (area: 105.5) -[05:25:30 PM] Info: Parent: -[05:25:30 PM] Info: - [NO PARENT] -[05:25:30 PM] Info: Children: -[05:25:30 PM] Info: - 3 -[05:25:30 PM] Info: - 6 -[05:25:30 PM] Info: - 2 -[05:25:30 PM] Info: ----- -[05:25:35 PM] Info: SECTOR HIERARCHY -[05:25:35 PM] Info: Sector 3 (area: 1) -[05:25:35 PM] Info: Parent: -[05:25:35 PM] Info: - 1 -[05:25:35 PM] Info: Children: -[05:25:35 PM] Info: - [NO CHILDREN] -[05:25:35 PM] Info: ----- -[05:25:35 PM] Info: Sector 4 (area: 1) -[05:25:35 PM] Info: Parent: -[05:25:35 PM] Info: - 2 -[05:25:35 PM] Info: Children: -[05:25:35 PM] Info: - [NO CHILDREN] -[05:25:35 PM] Info: ----- -[05:25:35 PM] Info: Sector 8 (area: 3) -[05:25:35 PM] Info: Parent: -[05:25:35 PM] Info: - [NO PARENT] -[05:25:35 PM] Info: Children: -[05:25:35 PM] Info: - [NO CHILDREN] -[05:25:35 PM] Info: ----- -[05:25:35 PM] Info: Sector 6 (area: 6) -[05:25:35 PM] Info: Parent: -[05:25:35 PM] Info: - 1 -[05:25:35 PM] Info: Children: -[05:25:35 PM] Info: - [NO CHILDREN] -[05:25:35 PM] Info: ----- -[05:25:35 PM] Info: Sector 7 (area: 15) -[05:25:35 PM] Info: Parent: -[05:25:35 PM] Info: - [NO PARENT] -[05:25:35 PM] Info: Children: -[05:25:35 PM] Info: - [NO CHILDREN] -[05:25:35 PM] Info: ----- -[05:25:35 PM] Info: Sector 2 (area: 19) -[05:25:35 PM] Info: Parent: -[05:25:35 PM] Info: - 1 -[05:25:35 PM] Info: Children: -[05:25:35 PM] Info: - 4 -[05:25:35 PM] Info: ----- -[05:25:35 PM] Info: Sector 5 (area: 34) -[05:25:35 PM] Info: Parent: -[05:25:35 PM] Info: - [NO PARENT] -[05:25:35 PM] Info: Children: -[05:25:35 PM] Info: - [NO CHILDREN] -[05:25:35 PM] Info: ----- -[05:25:35 PM] Info: Sector 1 (area: 105.5) -[05:25:35 PM] Info: Parent: -[05:25:35 PM] Info: - [NO PARENT] -[05:25:35 PM] Info: Children: -[05:25:35 PM] Info: - 3 -[05:25:35 PM] Info: - 6 -[05:25:35 PM] Info: - 2 -[05:25:35 PM] Info: ----- -[05:25:47 PM] Info: SECTOR HIERARCHY -[05:25:47 PM] Info: Sector 3 (area: 1) -[05:25:47 PM] Info: Parent: -[05:25:47 PM] Info: - 1 -[05:25:47 PM] Info: Children: -[05:25:47 PM] Info: - [NO CHILDREN] -[05:25:47 PM] Info: ----- -[05:25:47 PM] Info: Sector 4 (area: 1) -[05:25:47 PM] Info: Parent: -[05:25:47 PM] Info: - 2 -[05:25:47 PM] Info: Children: -[05:25:47 PM] Info: - [NO CHILDREN] -[05:25:47 PM] Info: ----- -[05:25:47 PM] Info: Sector 8 (area: 3) -[05:25:47 PM] Info: Parent: -[05:25:47 PM] Info: - [NO PARENT] -[05:25:47 PM] Info: Children: -[05:25:47 PM] Info: - [NO CHILDREN] -[05:25:47 PM] Info: ----- -[05:25:47 PM] Info: Sector 6 (area: 6) -[05:25:47 PM] Info: Parent: -[05:25:47 PM] Info: - 1 -[05:25:47 PM] Info: Children: -[05:25:47 PM] Info: - [NO CHILDREN] -[05:25:47 PM] Info: ----- -[05:25:47 PM] Info: Sector 9 (area: 8) -[05:25:47 PM] Info: Parent: -[05:25:47 PM] Info: - [NO PARENT] -[05:25:47 PM] Info: Children: -[05:25:47 PM] Info: - [NO CHILDREN] -[05:25:47 PM] Info: ----- -[05:25:47 PM] Info: Sector 7 (area: 15) -[05:25:47 PM] Info: Parent: -[05:25:47 PM] Info: - [NO PARENT] -[05:25:47 PM] Info: Children: -[05:25:47 PM] Info: - [NO CHILDREN] -[05:25:47 PM] Info: ----- -[05:25:47 PM] Info: Sector 2 (area: 19) -[05:25:47 PM] Info: Parent: -[05:25:47 PM] Info: - 1 -[05:25:47 PM] Info: Children: -[05:25:47 PM] Info: - 4 -[05:25:47 PM] Info: ----- -[05:25:47 PM] Info: Sector 5 (area: 34) -[05:25:47 PM] Info: Parent: -[05:25:47 PM] Info: - [NO PARENT] -[05:25:47 PM] Info: Children: -[05:25:47 PM] Info: - [NO CHILDREN] -[05:25:47 PM] Info: ----- -[05:25:47 PM] Info: Sector 1 (area: 105.5) -[05:25:47 PM] Info: Parent: -[05:25:47 PM] Info: - [NO PARENT] -[05:25:47 PM] Info: Children: -[05:25:47 PM] Info: - 3 -[05:25:47 PM] Info: - 6 -[05:25:47 PM] Info: - 2 -[05:25:47 PM] Info: ----- -[05:25:56 PM] Info: SECTOR HIERARCHY -[05:25:56 PM] Info: Sector 3 (area: 1) -[05:25:56 PM] Info: Parent: -[05:25:56 PM] Info: - 1 -[05:25:56 PM] Info: Children: -[05:25:56 PM] Info: - [NO CHILDREN] -[05:25:56 PM] Info: ----- -[05:25:56 PM] Info: Sector 4 (area: 1) -[05:25:56 PM] Info: Parent: -[05:25:56 PM] Info: - 2 -[05:25:56 PM] Info: Children: -[05:25:56 PM] Info: - [NO CHILDREN] -[05:25:56 PM] Info: ----- -[05:25:56 PM] Info: Sector 8 (area: 3) -[05:25:56 PM] Info: Parent: -[05:25:56 PM] Info: - [NO PARENT] -[05:25:56 PM] Info: Children: -[05:25:56 PM] Info: - [NO CHILDREN] -[05:25:56 PM] Info: ----- -[05:25:56 PM] Info: Sector 10 (area: 4) -[05:25:56 PM] Info: Parent: -[05:25:56 PM] Info: - [NO PARENT] -[05:25:56 PM] Info: Children: -[05:25:56 PM] Info: - [NO CHILDREN] -[05:25:56 PM] Info: ----- -[05:25:56 PM] Info: Sector 6 (area: 6) -[05:25:56 PM] Info: Parent: -[05:25:56 PM] Info: - 1 -[05:25:56 PM] Info: Children: -[05:25:56 PM] Info: - [NO CHILDREN] -[05:25:56 PM] Info: ----- -[05:25:56 PM] Info: Sector 9 (area: 8) -[05:25:56 PM] Info: Parent: -[05:25:56 PM] Info: - [NO PARENT] -[05:25:56 PM] Info: Children: -[05:25:56 PM] Info: - [NO CHILDREN] -[05:25:56 PM] Info: ----- -[05:25:56 PM] Info: Sector 7 (area: 15) -[05:25:56 PM] Info: Parent: -[05:25:56 PM] Info: - [NO PARENT] -[05:25:56 PM] Info: Children: -[05:25:56 PM] Info: - [NO CHILDREN] -[05:25:56 PM] Info: ----- -[05:25:56 PM] Info: Sector 2 (area: 19) -[05:25:56 PM] Info: Parent: -[05:25:56 PM] Info: - 1 -[05:25:56 PM] Info: Children: -[05:25:56 PM] Info: - 4 -[05:25:56 PM] Info: ----- -[05:25:56 PM] Info: Sector 5 (area: 34) -[05:25:56 PM] Info: Parent: -[05:25:56 PM] Info: - [NO PARENT] -[05:25:56 PM] Info: Children: -[05:25:56 PM] Info: - [NO CHILDREN] -[05:25:56 PM] Info: ----- -[05:25:56 PM] Info: Sector 1 (area: 105.5) -[05:25:56 PM] Info: Parent: -[05:25:56 PM] Info: - [NO PARENT] -[05:25:56 PM] Info: Children: -[05:25:56 PM] Info: - 3 -[05:25:56 PM] Info: - 6 -[05:25:56 PM] Info: - 2 -[05:25:56 PM] Info: ----- +[09:06:03 PM] Info: Initializing SDL +[09:06:03 PM] Info: Initializing OpenGL +[09:06:03 PM] Info: OpenGL version: 4.6.0 NVIDIA 536.23 +[09:06:03 PM] Info: Initializing GLEW +[09:06:03 PM] Info: Initializing SDL_mixer +[09:06:03 PM] Info: Reticulating splines... +[09:06:03 PM] Info: Ready! +[09:06:03 PM] Info: Finalize mesh with 45 batches +[09:06:10 PM] Info: Finalize mesh with 48 batches +[09:06:19 PM] Info: Finalize mesh with 55 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:24 PM] Info: Finalize mesh with 56 batches +[09:06:25 PM] Info: Finalize mesh with 56 batches +[09:06:25 PM] Info: Finalize mesh with 56 batches +[09:06:25 PM] Info: Finalize mesh with 56 batches +[09:06:25 PM] Info: Finalize mesh with 56 batches +[09:06:25 PM] Info: Finalize mesh with 56 batches +[09:06:25 PM] Info: Finalize mesh with 56 batches +[09:06:25 PM] Info: Finalize mesh with 56 batches +[09:06:25 PM] Info: Finalize mesh with 56 batches +[09:06:25 PM] Info: Finalize mesh with 56 batches +[09:06:26 PM] Info: Finalize mesh with 56 batches +[09:06:26 PM] Info: Finalize mesh with 56 batches +[09:06:26 PM] Info: Finalize mesh with 56 batches +[09:06:26 PM] Info: Finalize mesh with 56 batches +[09:06:28 PM] Info: Finalize mesh with 56 batches +[09:06:28 PM] Info: Finalize mesh with 56 batches +[09:06:28 PM] Info: Finalize mesh with 56 batches +[09:06:28 PM] Info: Finalize mesh with 56 batches +[09:06:28 PM] Info: Finalize mesh with 56 batches +[09:06:28 PM] Info: Finalize mesh with 56 batches +[09:06:28 PM] Info: Finalize mesh with 56 batches +[09:06:28 PM] Info: Finalize mesh with 56 batches +[09:06:28 PM] Info: Finalize mesh with 56 batches +[09:06:28 PM] Info: Finalize mesh with 56 batches +[09:06:28 PM] Info: Finalize mesh with 56 batches +[09:06:28 PM] Info: Finalize mesh with 56 batches +[09:06:28 PM] Info: Finalize mesh with 56 batches +[09:06:28 PM] Info: Finalize mesh with 56 batches +[09:06:28 PM] Info: Finalize mesh with 56 batches +[09:06:28 PM] Info: Finalize mesh with 56 batches +[09:06:28 PM] Info: Finalize mesh with 56 batches +[09:06:29 PM] Info: Finalize mesh with 56 batches +[09:06:29 PM] Info: Finalize mesh with 56 batches +[09:06:29 PM] Info: Finalize mesh with 56 batches +[09:06:29 PM] Info: Finalize mesh with 56 batches +[09:06:36 PM] Info: Finalize mesh with 56 batches +[09:06:36 PM] Info: Finalize mesh with 56 batches +[09:06:36 PM] Info: Finalize mesh with 56 batches +[09:06:36 PM] Info: Finalize mesh with 56 batches +[09:06:36 PM] Info: Finalize mesh with 56 batches +[09:06:36 PM] Info: Finalize mesh with 56 batches +[09:06:36 PM] Info: Finalize mesh with 56 batches +[09:06:36 PM] Info: Finalize mesh with 56 batches +[09:06:36 PM] Info: Finalize mesh with 56 batches +[09:06:36 PM] Info: Finalize mesh with 56 batches +[09:06:36 PM] Info: Finalize mesh with 56 batches +[09:06:36 PM] Info: Finalize mesh with 56 batches +[09:06:36 PM] Info: Finalize mesh with 56 batches +[09:06:36 PM] Info: Finalize mesh with 56 batches +[09:06:36 PM] Info: Finalize mesh with 56 batches +[09:06:37 PM] Info: Finalize mesh with 56 batches +[09:06:37 PM] Info: Finalize mesh with 56 batches +[09:06:37 PM] Info: Finalize mesh with 56 batches +[09:06:37 PM] Info: Finalize mesh with 56 batches +[09:06:37 PM] Info: Finalize mesh with 56 batches +[09:06:37 PM] Info: Finalize mesh with 56 batches +[09:06:37 PM] Info: Finalize mesh with 56 batches +[09:06:37 PM] Info: Finalize mesh with 56 batches +[09:06:37 PM] Info: Finalize mesh with 56 batches +[09:06:37 PM] Info: Finalize mesh with 56 batches +[09:06:53 PM] Info: Finalize mesh with 56 batches +[09:06:53 PM] Info: Finalize mesh with 56 batches +[09:06:53 PM] Info: Finalize mesh with 56 batches +[09:06:53 PM] Info: Finalize mesh with 56 batches +[09:06:53 PM] Info: Finalize mesh with 56 batches +[09:06:53 PM] Info: Finalize mesh with 56 batches +[09:06:53 PM] Info: Finalize mesh with 56 batches +[09:06:53 PM] Info: Finalize mesh with 56 batches +[09:06:53 PM] Info: Finalize mesh with 56 batches +[09:06:53 PM] Info: Finalize mesh with 56 batches +[09:06:53 PM] Info: Finalize mesh with 56 batches +[09:06:53 PM] Info: Finalize mesh with 56 batches +[09:06:53 PM] Info: Finalize mesh with 56 batches +[09:06:54 PM] Info: Finalize mesh with 56 batches +[09:06:54 PM] Info: Finalize mesh with 56 batches +[09:06:54 PM] Info: Finalize mesh with 56 batches +[09:06:54 PM] Info: Finalize mesh with 56 batches +[09:06:54 PM] Info: Finalize mesh with 56 batches +[09:06:54 PM] Info: Finalize mesh with 56 batches +[09:06:54 PM] Info: Finalize mesh with 56 batches +[09:06:54 PM] Info: Finalize mesh with 56 batches +[09:06:54 PM] Info: Finalize mesh with 56 batches +[09:06:54 PM] Info: Finalize mesh with 56 batches +[09:06:54 PM] Info: Finalize mesh with 56 batches +[09:06:56 PM] Info: Finalize mesh with 56 batches +[09:06:56 PM] Info: Finalize mesh with 56 batches +[09:06:56 PM] Info: Finalize mesh with 56 batches +[09:06:56 PM] Info: Finalize mesh with 56 batches +[09:06:56 PM] Info: Finalize mesh with 56 batches +[09:06:56 PM] Info: Finalize mesh with 54 batches +[09:06:56 PM] Info: Finalize mesh with 54 batches +[09:06:56 PM] Info: Finalize mesh with 54 batches +[09:06:56 PM] Info: Finalize mesh with 54 batches +[09:06:56 PM] Info: Finalize mesh with 54 batches +[09:06:56 PM] Info: Finalize mesh with 54 batches +[09:06:56 PM] Info: Finalize mesh with 54 batches +[09:06:56 PM] Info: Finalize mesh with 54 batches +[09:06:56 PM] Info: Finalize mesh with 54 batches +[09:06:56 PM] Info: Finalize mesh with 54 batches +[09:06:56 PM] Info: Finalize mesh with 54 batches +[09:06:56 PM] Info: Finalize mesh with 54 batches +[09:06:56 PM] Info: Finalize mesh with 54 batches +[09:06:56 PM] Info: Finalize mesh with 54 batches +[09:06:56 PM] Info: Finalize mesh with 54 batches +[09:06:56 PM] Info: Finalize mesh with 54 batches +[09:06:56 PM] Info: Finalize mesh with 54 batches +[09:06:56 PM] Info: Finalize mesh with 54 batches +[09:06:56 PM] Info: Finalize mesh with 54 batches +[09:06:56 PM] Info: Finalize mesh with 54 batches +[09:07:03 PM] Info: Finalize mesh with 54 batches +[09:07:03 PM] Info: Finalize mesh with 54 batches +[0 \ No newline at end of file diff --git a/KP3Dii/src/KP3D_Map.cpp b/KP3Dii/src/KP3D_Map.cpp index ffeb9b0..d6b81a9 100644 --- a/KP3Dii/src/KP3D_Map.cpp +++ b/KP3Dii/src/KP3D_Map.cpp @@ -47,10 +47,30 @@ bool SectorContains(const kp3d::Sector& outer, const kp3d::Sector& inner) return completely_inside || (count > 0 && partial_count < 4); // stupid } +// Callback used by the renderer and editor +// kind of ugly the way this works... +kp3d::uint ShouldHighlight(const kp3d::RenderBatch3D& batch) +{ + if (!kp3d::editor_hovered_batch) + return 0xFFFFFFFF; + if (&batch != kp3d::editor_hovered_batch) + return 0xFFFFFFFF; + kp3d::BatchSectorInfo info = std::any_cast(batch.userdata); + // if (info.wall) + // return 0xFF5555FF; + // else if (info.flat) + // return 0xFFFF55FF; + // else + if (info.sector) + return 0x5555FFFF; +} + } namespace kp3d { +RenderBatch3D* editor_hovered_batch = nullptr; + Map::Map() { } @@ -165,8 +185,9 @@ void Map::BuildFlat(Sector& sector, Flat& flat, bool invert) flat.triangulated_data.push_back(vtxa); flat.triangulated_data.push_back(vtxb); flat.triangulated_data.push_back(vtxc); + BatchSectorInfo info = {BatchSectorInfo::BATCH_FLAT, §or, &flat, nullptr}; if (flat.texture) - m_mesh.AddBatch(flat.texture, { vtxa, vtxb, vtxc }, !invert); + m_mesh.AddBatch(flat.texture, { vtxa, vtxb, vtxc }, !invert, std::make_any(info)); } } @@ -176,7 +197,7 @@ void Map::BuildFlat(Sector& sector, Flat& flat, bool invert) * To do this we perform a similar approach to BuildFlat, but because the walls aren't strictly along one axis we have to * "flatten" them to perform the math to triangulate them. This is done by projecting the 3D points to 2D. */ -void Map::BuildQuad(Sector& sector, Flat& flat_top, Flat& flat_bottom, const Texture* texture, Vec3 pos_a, Vec3 pos_b, bool flip, bool flip_u, bool flip_v, XYf uv_offset) +void Map::BuildQuad(Sector& sector, Wall& wall, Flat& flat_top, Flat& flat_bottom, const Texture* texture, Vec3 pos_a, Vec3 pos_b, bool flip, bool flip_u, bool flip_v, XYf uv_offset) { if (!texture) return; @@ -251,8 +272,9 @@ void Map::BuildQuad(Sector& sector, Flat& flat_top, Flat& flat_bottom, const Tex Vertex3D vtxa = Vertex3D(fva, Vec2(au * tw, av * th)); Vertex3D vtxb = Vertex3D(fvb, Vec2(bu * tw, bv * th)); Vertex3D vtxc = Vertex3D(fvc, Vec2(cu * tw, cv * th)); + BatchSectorInfo info = {BatchSectorInfo::BATCH_WALL, §or, nullptr, &wall}; if (texture) - m_mesh.AddBatch(texture, { vtxa, vtxb, vtxc }, flip); + m_mesh.AddBatch(texture, {vtxa, vtxb, vtxc}, flip, std::make_any(info)); } } } @@ -261,15 +283,15 @@ void Map::BuildWall(Sector& sector, Wall& wall) { Vec3 a = {wall.start.x, 0.0f, wall.start.y}; Vec3 b = {wall.end.x, 0.0f, wall.end.y}; - BuildQuad(sector, sector.floor, sector.ceiling, wall.textures[TEX_FRONT], a, b, false, false, false, wall.uv_offset[TEX_FRONT]); + BuildQuad(sector, wall, sector.floor, sector.ceiling, wall.textures[TEX_FRONT], a, b, false, false, false, wall.uv_offset[TEX_FRONT]); if (wall.flags & Wall::FLAG_OPENING) { // Build upper and lower walls for sectors connected to other sectors (or sectors within sectors) bool flip = wall.portal->floor.base_height < sector.floor.base_height; - BuildQuad(sector, sector.floor, wall.portal->floor, wall.textures[TEX_LOWER], a, b, flip, false, false, wall.uv_offset[TEX_LOWER]); + BuildQuad(sector, wall, sector.floor, wall.portal->floor, wall.textures[TEX_LOWER], a, b, flip, false, false, wall.uv_offset[TEX_LOWER]); flip = wall.portal->ceiling.base_height < sector.ceiling.base_height; - BuildQuad(sector, sector.ceiling, wall.portal->ceiling, wall.textures[TEX_UPPER], a, b, !flip, false, false, wall.uv_offset[TEX_UPPER]); + BuildQuad(sector, wall, sector.ceiling, wall.portal->ceiling, wall.textures[TEX_UPPER], a, b, !flip, false, false, wall.uv_offset[TEX_UPPER]); } } @@ -280,8 +302,11 @@ void Map::JoinSectors(Sector& sector) for (int i = 0; i < sector.walls.size(); i++) { Wall& ld = sector.walls[i]; - for (Sector& s: sectors) + if (ld.flags & Wall::FLAG_TOUCHED) + continue; + for (const auto& sp: sectors) { + Sector& s = *sp; if (s.id == sector.id) continue; @@ -296,6 +321,8 @@ void Map::JoinSectors(Sector& sector) for (Wall& l : s.walls) { + //if (l.flags & Wall::FLAG_TOUCHED) + // continue; bool good = false; bool start_cmp = PosCmp({l.start.x, 0.0f, l.start.y}, {pos_a.x, 0.0f, pos_a.z}, e) || PosCmp({l.start.x, 0.0f, l.start.y}, {pos_b.x, 0.0f, pos_b.z}, e); @@ -354,7 +381,7 @@ void Map::JoinSectors(Sector& sector) w1.end.x = l.start.x; w1.end.y = l.start.y; w1.textures[TEX_FRONT] = nullptr; - w1.flags = Wall::FLAG_OPENING; + // w1.flags = Wall::FLAG_OPENING; w1.portal = &s; w1.flags = Wall::FLAG_TOUCHED; InsertLine(sector.walls, i + 1, w1); @@ -427,6 +454,7 @@ void Map::Init() { sectors.clear(); m_mesh.Reset(); + sectors.reserve(10000); BuildSkybox("skybox_16.jpg"); BuildGrid(); @@ -454,19 +482,19 @@ void Map::Init() XYf points6[] = {{1, 4}, {3, 4}, {3, 7}, {1, 7}}; auto build_sector = [&](Texture* wall, Texture* floor, Texture* ceil, float floor_height, float ceil_height, int id, XYf* points, size_t num_points, bool inverted = false) { - Sector s; - s.ceiling.texture = ceil; - s.floor.texture = floor; - s.floor.floor = true; - s.floor.base_height = floor_height; - s.ceiling.base_height = ceil_height; - s.id = id; - s.parent_id = 0; - s.inverted = inverted; + std::shared_ptr s = std::make_unique(); + s->ceiling.texture = ceil; + s->floor.texture = floor; + s->floor.floor = true; + s->floor.base_height = floor_height; + s->ceiling.base_height = ceil_height; + s->id = id; + s->parent_id = 0; + s->inverted = inverted; float scl = 1.0f; for (size_t i = 0; i < num_points; i++) - s.walls.push_back(Wall{ {wall,wall,wall}, {{0, 0}}, points[i], points[(i + 1) % num_points], Wall::NO_FLAGS, (uint)i }); - original_sectors.push_back(s); + s->walls.push_back(Wall{ {wall,wall,wall}, {{0, 0}}, points[i], points[(i + 1) % num_points], Wall::NO_FLAGS, (uint)i }); + sectors.push_back(s); }; build_sector(&tex3, &tex, &tex2, -1.0f, 5.0f, 1, points, std::size(points)); build_sector(&tex4, &tex2, &tex2, -1.5f, 4.0f, 2, points2, std::size(points2)); @@ -482,36 +510,42 @@ void Map::Rebuild(NormalGenType gen_normals) { m_mesh.Reset(); - sectors.clear(); - for (Sector& s : original_sectors) - { - sectors.push_back(s); - } + //sectors.clear(); + //for (Sector& s : original_sectors) + //{ + // s.original = &s; + // sectors.push_back(s); + //} // Correct sectors with counter-clockwise linedef order using the shoelace formula, // also while we're at it grab the sector areas (will be useful later) and reset old data. int i = 0; - for (Sector& s: sectors) + for (const auto& sp: sectors) { + Sector& s = *sp; // Since we're regenerating the map, we don't want to re-use this data, it may be old. s.children.clear(); + s.floor.triangulated_data.clear(); + s.floor.steiner_points.clear(); + s.ceiling.triangulated_data.clear(); + s.ceiling.steiner_points.clear(); s.area = 0.0f; s.flags = Sector::NO_FLAGS; s.parent_id = 0; - s.id = ++i; + // s.id = ++i; // Now perform the swap + save the area float area = 0.0f; for (Wall& l: s.walls) { - bool touched = l.flags & Wall::FLAG_TOUCHED; - bool no_collisions = l.flags & Wall::FLAG_NO_COLLISION; - l.flags = Wall::NO_FLAGS; - if (touched) - l.flags |= Wall::FLAG_TOUCHED; - if (no_collisions) - l.flags |= Wall::FLAG_NO_COLLISION; - l.portal = nullptr; + //bool touched = l.flags & Wall::FLAG_TOUCHED; + //bool no_collisions = l.flags & Wall::FLAG_NO_COLLISION; + //l.flags = Wall::NO_FLAGS; + //if (touched) + // l.flags |= Wall::FLAG_TOUCHED; + //if (no_collisions) + // l.flags |= Wall::FLAG_NO_COLLISION; + //l.portal = nullptr; area += l.start.x * l.end.y; area -= l.end.x * l.start.y; @@ -527,11 +561,13 @@ void Map::Rebuild(NormalGenType gen_normals) } // Now perform the process of "parenting" sectors; this essentially takes in our flat list of sectors and creates a hierarchy. - std::sort(sectors.begin(), sectors.end(), [](const Sector& a, const Sector& b) { return a.area < b.area; }); - for (Sector& sector: sectors) + std::sort(sectors.begin(), sectors.end(), [](const auto& a, const auto& b) { return a->area < b->area; }); + for (const auto& sp: sectors) { - for (Sector& potential_parent: sectors) + Sector& sector = *sp; + for (const auto& spp: sectors) { + Sector& potential_parent = *spp; if (sector.id == potential_parent.id) continue; if (SectorContains(potential_parent, sector)) @@ -543,7 +579,7 @@ void Map::Rebuild(NormalGenType gen_normals) } } -#if 1 +#if 0 // Debug: Print out the sector hierachy KP3D_LOG_INFO("SECTOR HIERARCHY"); for (Sector& s: sectors) @@ -561,8 +597,9 @@ void Map::Rebuild(NormalGenType gen_normals) #endif // Preproc (really just part of the test map building process again) - for (Sector& s: sectors) + for (const auto& sp: sectors) { + Sector& s = *sp; // Build up "steiner points" for terrain only // We'll do this along a grid for now; it should be noted that this will be expected to be part of the sector data later int num_steiners_along_xy = 50; @@ -590,26 +627,26 @@ void Map::Rebuild(NormalGenType gen_normals) if (s.id == 1 || s.id == 5) { - float yv0 = PerlinNoise2D(steiner_point.x, steiner_point.y, 1.0, 10.0); - float yv1 = -PerlinNoise2D(steiner_point.x, steiner_point.y, 0.5, 9.0); - s.floor.steiner_points.push_back({ steiner_point.x, yv0, steiner_point.y }); - s.ceiling.steiner_points.push_back({ steiner_point.x, yv1, steiner_point.y }); + //float yv0 = PerlinNoise2D(steiner_point.x, steiner_point.y, 1.0, 10.0); + //float yv1 = -PerlinNoise2D(steiner_point.x, steiner_point.y, 0.5, 9.0); + //s.floor.steiner_points.push_back({ steiner_point.x, yv0, steiner_point.y }); + //s.ceiling.steiner_points.push_back({ steiner_point.x, yv1, steiner_point.y }); } } } } // Build level geometry - for (Sector& s: sectors) - JoinSectors(s); - for (Sector& s: sectors) + for (const auto& s: sectors) + JoinSectors(*s); + for (const auto& s: sectors) { - BuildFlat(s, s.floor, false); - BuildFlat(s, s.ceiling, true); + BuildFlat(*s, s->floor, false); + BuildFlat(*s, s->ceiling, true); } - for (Sector& s: sectors) - for (Wall& ld: s.walls) - BuildWall(s, ld); + for (const auto& s: sectors) + for (Wall& ld: s->walls) + BuildWall(*s, ld); // Invert the map on the Z axis; not doing this for any other reason besides compatibility with KP3D 1.0 for (RenderBatch3D& b : m_mesh.GetBatchesRef()) @@ -624,7 +661,25 @@ void Map::Rebuild(NormalGenType gen_normals) } // Finalize the mesh - m_mesh.Finalize(gen_normals); + m_mesh.Finalize( + gen_normals, + [](const RenderBatch3D& a, const RenderBatch3D& b) -> bool + { + return a.texture->GetGLID() < b.texture->GetGLID() && + std::any_cast(a.userdata).type < std::any_cast(b.userdata).type; + }, + [](const RenderBatch3D& a, const RenderBatch3D& b) -> bool + { + const auto& au = std::any_cast(a.userdata); + const auto& bu = std::any_cast(b.userdata); + + return a.texture->GetGLID() != b.texture->GetGLID() || + au.sector != bu.sector || + au.flat != bu.flat || + au.wall != bu.wall; + } + ); + KP3D_LOG_INFO("Finalize mesh with {} batches", m_mesh.GetBatchesRef().size()); } void Map::Update() @@ -638,7 +693,7 @@ void Map::Render() // Map kp3d::Renderer3D::PushShader(kp3d::Renderer3D::GetMapShader()); - kp3d::Renderer3D::DrawMesh(m_mesh, m_transform); + kp3d::Renderer3D::DrawMesh(m_mesh, m_transform, true, ShouldHighlight); kp3d::Renderer3D::PopShader(); // Debug dots @@ -754,4 +809,9 @@ void Map::RenderGrid() Renderer3D::PopShader(); } +StaticMesh& Map::GetMeshRef() +{ + return m_mesh; +} + } // namespace kp3d diff --git a/KP3Dii/src/KP3D_Map.h b/KP3Dii/src/KP3D_Map.h index 3f4c882..782ced5 100644 --- a/KP3Dii/src/KP3D_Map.h +++ b/KP3Dii/src/KP3D_Map.h @@ -40,6 +40,7 @@ struct Wall uint uid; Sector* portal = nullptr; + //int portal = 0; }; struct Flat @@ -85,6 +86,8 @@ struct Sector float area = 0.0f; + Sector* original; + }; struct Skybox @@ -94,6 +97,20 @@ struct Skybox Transform transform; }; +// Information we can associate with render batches to find out what parts of the map a piece of geometry represents +struct BatchSectorInfo +{ + enum + { + BATCH_SECTOR, + BATCH_FLAT, + BATCH_WALL + } type; + kp3d::Sector* sector = nullptr; + kp3d::Flat* flat = nullptr; + kp3d::Wall* wall = nullptr; +}; + class Map { public: @@ -104,7 +121,7 @@ public: ErrCode SaveToFile(const std::string& path); void BuildFlat(Sector& sector, Flat& flat, bool invert); - void BuildQuad(Sector& sector, Flat& flat_top, Flat& flat_bottom, const Texture* texture, Vec3 pos_a, Vec3 pos_b, bool flip, bool flip_u, bool flip_v, XYf uv_offset); + void BuildQuad(Sector& sector, Wall& wall, Flat& flat_top, Flat& flat_bottom, const Texture* texture, Vec3 pos_a, Vec3 pos_b, bool flip, bool flip_u, bool flip_v, XYf uv_offset); void BuildWall(Sector& sector, Wall& wall); void JoinSectors(Sector& sector); @@ -121,10 +138,11 @@ public: void BuildGrid(); void RenderGrid(); + StaticMesh& GetMeshRef(); + public: bool join_disabled = false; - std::vector original_sectors; - std::vector sectors; + std::vector> sectors; bool render_wireframe = true; float texture_scale = 128.0f; Vec3 grid_box[6]; @@ -143,4 +161,6 @@ private: }; +extern RenderBatch3D* editor_hovered_batch; // hack + } diff --git a/KP3Dii/src/KP3D_Renderer3D.cpp b/KP3Dii/src/KP3D_Renderer3D.cpp index 3e90a02..4852274 100644 --- a/KP3Dii/src/KP3D_Renderer3D.cpp +++ b/KP3Dii/src/KP3D_Renderer3D.cpp @@ -165,18 +165,8 @@ void Renderer3D::End() r3d_state->active = false; } -void Renderer3D::DrawMesh(StaticMesh& mesh, const Mat4& m, bool bind_shader) +void Renderer3D::DrawMesh(StaticMesh& mesh, const Mat4& m, bool bind_shader, uint (*func_highlight)(const RenderBatch3D&)) { - if (bind_shader) - r3d_state->shader->Bind(); - r3d_state->shader->SetUniform("u_mvp", m); - r3d_state->shader->SetUniform("u_campos", r3d_state->v->position); - r3d_state->shader->SetUniform("u_camdir", r3d_state->v->forward); - r3d_state->shader->SetUniform("u_time", r3d_state->time); - - // TODO: Remove this: - r3d_state->shader->SetUniform("u_transmat", Mat4().InitIdentity()); - glBindVertexArray(mesh.m_gl_vao_id); // The reason the blending shit works like this here is @@ -186,12 +176,27 @@ void Renderer3D::DrawMesh(StaticMesh& mesh, const Mat4& m, bool bind_shader) glAlphaFunc(GL_GREATER, 0.1f); glEnable(GL_ALPHA_TEST); - if (mesh.skinnable) + for (const RenderBatch3D& batch: mesh.m_batches) { - } + if (bind_shader) + r3d_state->shader->Bind(); + r3d_state->shader->SetUniform("u_mvp", m); + r3d_state->shader->SetUniform("u_campos", r3d_state->v->position); + r3d_state->shader->SetUniform("u_camdir", r3d_state->v->forward); + r3d_state->shader->SetUniform("u_time", r3d_state->time); + + // Optional highlight function used by the editor + if (func_highlight) + { + std::array arr = ColorToFloats(func_highlight(batch)); + Vec3 color = { arr[0], arr[1], arr[2] }; + r3d_state->shader->SetUniform("u_highlight", color); + } + else + { + r3d_state->shader->SetUniform("u_highlight", Vec3(1.0f, 1.0f, 1.0f)); + } - for (const auto& batch: mesh.m_batches) - { bool indexed = !batch.index_data.empty(); bool skinned = !batch.bone_data.empty(); @@ -205,7 +210,6 @@ void Renderer3D::DrawMesh(StaticMesh& mesh, const Mat4& m, bool bind_shader) glEnableVertexAttribArray(2); if (skinned) { - // glBindBuffer(GL_ARRAY_BUFFER, batch.gl_bbo_id); glEnableVertexAttribArray(3); glEnableVertexAttribArray(4); } @@ -234,8 +238,6 @@ void Renderer3D::DrawMesh(StaticMesh& mesh, const Mat4& m, bool bind_shader) ); } - // if (!skinned) - //{ if (!batch.index_data.empty()) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, batch.gl_ibo_id); @@ -245,12 +247,6 @@ void Renderer3D::DrawMesh(StaticMesh& mesh, const Mat4& m, bool bind_shader) { glDrawArrays(GL_TRIANGLES, 0, batch.vertex_data.size()); } - //} - // else - //{ - // // glDrawElementsBaseVertex(GL_TRIANGLES, batch.index_data.size(), GL_UNSIGNED_INT, (void*)(sizeof(uint) * - //base_index), base_vertex) - //} if (skinned) { @@ -268,9 +264,9 @@ void Renderer3D::DrawMesh(StaticMesh& mesh, const Mat4& m, bool bind_shader) glBindVertexArray(0); } -void Renderer3D::DrawMesh(StaticMesh& mesh, Transform& m, bool bind_shader) +void Renderer3D::DrawMesh(StaticMesh& mesh, Transform& m, bool bind_shader, uint (*func_highlight)(const RenderBatch3D&)) { - DrawMesh(mesh, m.GetProjectedTransformationMatrix(*r3d_state->v, *r3d_state->p), bind_shader); + DrawMesh(mesh, m.GetProjectedTransformationMatrix(*r3d_state->v, *r3d_state->p), bind_shader, func_highlight); } void Renderer3D::DrawBillboard(const Texture& texture, const Vec3& position, Vec2 size, bool both_axes, float yaw) @@ -364,26 +360,20 @@ void Renderer3D::DrawModel(Model& model, const Mat4& m) if (!mesh) continue; - // float* data = new float[MAX_BONES*16]; for (int i = 0; i < transforms.size(); i++) { if (i >= MAX_BONES) continue; - // for (int j = 0; j < 16; j++) - // data[i * 16 + j] = transforms[i].mat.data()[j]; std::string u = "u_bones[" + std::to_string(i) + "]"; - // r3d_state->shader->SetUniform(u, transforms[i]); glUniformMatrix4fv( glGetUniformLocation(r3d_state->shader->GetGLID(), u.c_str()), 1, GL_FALSE, transforms[i].mat.data() ); - // glUniformMatrix4fv(glGetUniformLocation(r3d_state->shader->GetGLID(), "u_bones"), MAX_BONES, GL_TRUE, data); } if (mesh->skinnable) r3d_state->shader->SetUniform("u_has_bones", 1); DrawMesh(*mesh, m); if (mesh->skinnable) r3d_state->shader->SetUniform("u_has_bones", 0); - // delete[] data; } } @@ -403,10 +393,10 @@ void Renderer3D::DrawLine(const Vec3& start, const Vec3& end, float thickness, u float angle = atan2(start.z - end.z, start.x - end.x) - ToRadians(90.0f); - Vec3 v0 = { start.x - cosf(angle) * thickness, start.y, start.z - sinf(angle) * thickness }; - Vec3 v1 = { start.x + cosf(angle) * thickness, start.y, start.z + sinf(angle) * thickness }; - Vec3 v2 = { end.x + cosf(angle) * thickness, end.y, end.z + sinf(angle) * thickness }; - Vec3 v3 = { end.x - cosf(angle) * thickness, end.y, end.z - sinf(angle) * thickness }; + Vec3 v0 = {start.x - cosf(angle) * thickness, start.y, start.z - sinf(angle) * thickness}; + Vec3 v1 = {start.x + cosf(angle) * thickness, start.y, start.z + sinf(angle) * thickness}; + Vec3 v2 = {end.x + cosf(angle) * thickness, end.y, end.z + sinf(angle) * thickness}; + Vec3 v3 = {end.x - cosf(angle) * thickness, end.y, end.z - sinf(angle) * thickness}; LR_PushVertex(v0.x, v0.y, v0.z, in_floats[R], in_floats[G], in_floats[B], in_floats[A], 0.0f, 0.0f); LR_PushVertex(v1.x, v1.y, v1.z, in_floats[R], in_floats[G], in_floats[B], in_floats[A], 1.0f, 0.0f); diff --git a/KP3Dii/src/KP3D_Renderer3D.h b/KP3Dii/src/KP3D_Renderer3D.h index 68dc2b3..4b71c60 100644 --- a/KP3Dii/src/KP3D_Renderer3D.h +++ b/KP3Dii/src/KP3D_Renderer3D.h @@ -15,6 +15,7 @@ class StaticMesh; class Texture; class Shader; class Model; +struct RenderBatch3D; class Renderer3D { @@ -22,8 +23,8 @@ public: static void Begin(const Camera& v, const Mat4& p); static void End(); - static void DrawMesh(StaticMesh& mesh, const Mat4& m, bool bind_shader = true); - static void DrawMesh(StaticMesh& mesh, Transform& m, bool bind_shader = true); + static void DrawMesh(StaticMesh& mesh, const Mat4& m, bool bind_shader = true, uint (*func_highlight)(const RenderBatch3D&) = nullptr); + static void DrawMesh(StaticMesh& mesh, Transform& m, bool bind_shader = true, uint (*func_highlight)(const RenderBatch3D&) = nullptr); static void DrawBillboard(const Texture& texture, const Vec3& position, Vec2 size, bool both_axes = false, float yaw = 90.0f); static void DrawSmartBillboard( const std::vector& textures, diff --git a/KP3Dii/src/KP3D_StaticMesh.cpp b/KP3Dii/src/KP3D_StaticMesh.cpp index 24f3303..da2e436 100644 --- a/KP3Dii/src/KP3D_StaticMesh.cpp +++ b/KP3Dii/src/KP3D_StaticMesh.cpp @@ -78,7 +78,7 @@ StaticMesh::~StaticMesh() glDeleteVertexArrays(1, &m_gl_vao_id); } -void StaticMesh::AddBatch(const Texture* texture, const std::vector& vertex_data, bool flip) +void StaticMesh::AddBatch(const Texture* texture, const std::vector& vertex_data, bool flip, std::any user_data) { // "flipping" the vertex data basically means changing the order of the vertices so it faces // a different direction than it did previously, useful for making sure stuff works with culling @@ -102,6 +102,7 @@ void StaticMesh::AddBatch(const Texture* texture, const std::vector& v // Clean me/move me somewhere else auto& current = m_batches.back(); + current.userdata = user_data; for (size_t j = 0; j < current.vertex_data.size(); j += 3) { Vertex3D& v0 = current.vertex_data[j + 0]; @@ -169,15 +170,19 @@ void StaticMesh::AddSkinnedBatch( } } - m_batches.push_back({0, texture, vertex_data, 0, flipped_data, 0, bone_data}); + m_batches.push_back({0, texture, vertex_data, 0, flipped_data, bone_data}); } -// This code probably isn't good... // Take the batches, order them by texture ID, and have one draw call per texture use. // I might make another version of this which sets up texture atlases so that way you don't // have to have a new VBO for every batch. You'd be rendering one VBO with different // texture coordinates. -void StaticMesh::Finalize(NormalGenType gen_normals) +// +// Also, you may optionally provide "sort" and "criteria" callbacks to control how the mesh +// will get batched. By default, batching will be performed based on texture ID, but you can +// set up any conditions. +// +void StaticMesh::Finalize(NormalGenType gen_normals, BatchComparison sort, BatchComparison criteria) { std::vector total_vertices; @@ -185,7 +190,7 @@ void StaticMesh::Finalize(NormalGenType gen_normals) std::sort( m_batches.begin(), m_batches.end(), - [](const RenderBatch3D& a, const RenderBatch3D& b) { return a.texture->GetGLID() < b.texture->GetGLID(); } + sort ? sort : [](const RenderBatch3D& a, const RenderBatch3D& b) { return a.texture->GetGLID() < b.texture->GetGLID(); } ); for (size_t i = 0; i < m_batches.size(); i++) @@ -200,8 +205,16 @@ void StaticMesh::Finalize(NormalGenType gen_normals) // If their texture has switched (or there isn't another one), split the draw call if (auto next = std::next(m_batches.begin() + i, 1); next < m_batches.end()) { - if (next->texture->GetGLID() != current.texture->GetGLID()) - setup = true; + if (criteria) + { + if (criteria(current, *next)) + setup = true; + } + else + { + if (next->texture->GetGLID() != current.texture->GetGLID()) + setup = true; + } } else { diff --git a/KP3Dii/src/KP3D_StaticMesh.h b/KP3Dii/src/KP3D_StaticMesh.h index 84cacca..13a2495 100644 --- a/KP3Dii/src/KP3D_StaticMesh.h +++ b/KP3Dii/src/KP3D_StaticMesh.h @@ -3,6 +3,7 @@ #include #include +#include #include "KP3D_Common.h" #include "KP3D_Math.h" @@ -56,9 +57,9 @@ struct RenderBatch3D std::vector vertex_data; GLuint gl_ibo_id = 0; std::vector index_data; - GLuint gl_bbo_id = 0; std::vector bone_data; bool flipped = false; + std::any userdata; }; enum NormalGenType @@ -68,13 +69,15 @@ enum NormalGenType GEN_SMOOTH_NORMALS }; +using BatchComparison = bool (*)(const RenderBatch3D&, const RenderBatch3D&); + class StaticMesh { public: StaticMesh(); ~StaticMesh(); - void AddBatch(const Texture* texture, const std::vector& vertex_data, bool flip = false); + void AddBatch(const Texture* texture, const std::vector& vertex_data, bool flip = false, std::any user_data = {}); void AddIndexedBatch(const Texture* texture, const std::vector& vertex_data, const std::vector& index_data); void AddSkinnedBatch( const Texture* texture, @@ -83,7 +86,7 @@ public: const std::vector& bone_data, bool flip = true ); - void Finalize(NormalGenType gen_normals = GEN_NORMALS); + void Finalize(NormalGenType gen_normals = GEN_NORMALS, BatchComparison sort = nullptr, BatchComparison criteria = nullptr); void Reset(); std::vector& GetBatchesRef(); diff --git a/Sandbox/src/Editor.cpp b/Sandbox/src/Editor.cpp index 1217356..dea9dac 100644 --- a/Sandbox/src/Editor.cpp +++ b/Sandbox/src/Editor.cpp @@ -6,6 +6,7 @@ #include "KP3D_Raycast.h" #include "KP3D_Math.h" #include "KP3D_Geometry.h" +#include "KP3D_Console.h" #include "Sandbox.h" @@ -52,90 +53,68 @@ void Editor::Update() if (m_mode == MODE_BUILD) { - if (sandbox->IsMouseButtonDown(kp3d::MOUSE_BUTTON_LEFT)) + UpdateModeBuild(); + return; + } + + // Raycast through everything on the map + using namespace kp3d; + struct Target + { + Vec3 position; + float distance; + RenderBatch3D* b; + }; + std::vector targets; + for (RenderBatch3D& b: sandbox->map.GetMeshRef().GetBatchesRef()) + { + for (size_t i = 0; i < b.vertex_data.size(); i += 3) { - points.push_back(m_stem_pos); - - if (points.size() >= 3 && kp3d::PosCmp(points.back(), points.front(), 1.0f / 128.0f))// points.back() == points.front()) + Vec3 pos; + Triangle tri = {b.vertex_data[i].position, b.vertex_data[i + 1].position, b.vertex_data[i + 2].position}; + auto ray = GetRayFromCamera(sandbox->camera); + bool raycast = RayIntersectsTriangle(ray[0], ray[1], &tri, pos); + if (raycast) { - kp3d::Sector s; - s.ceiling.texture = &m_block; - s.floor.texture = &m_block; - s.floor.floor = true; - s.floor.base_height = 0.0f; - s.ceiling.base_height = 2.0f; - s.id = sandbox->map.sectors.size() + 1; - s.parent_id = 0; - s.inverted = false; - for (int i = 0; i < points.size() - 1; i++) - { - kp3d::Wall wall; - wall.start = { points[i].x, -points[i].z }; - wall.end = { points[i + 1].x, -points[i + 1].z }; - wall.uid = i; - for (int j = 0; j < 3; j++) - wall.textures[j] = &m_block; - - s.walls.push_back(wall); - } - - sandbox->map.original_sectors.push_back(s); - sandbox->map.Rebuild(kp3d::GEN_NORMALS); - - points.clear(); + float dist = sqrtf( + pow(pos.x - sandbox->camera.position.x, 2) + + pow(pos.y - sandbox->camera.position.y, 2) + + pow(pos.z - sandbox->camera.position.z, 2) + ); + targets.push_back({pos, dist, &b}); } - - sandbox->MouseButtonReset(kp3d::MOUSE_BUTTON_LEFT); } - static kp3d::Vec3 start_pos; - static bool has_start_pos = false; - if (sandbox->IsMouseButtonDown(kp3d::MOUSE_BUTTON_RIGHT)) + if (!targets.empty()) { - if (!has_start_pos) - { - start_pos = m_stem_pos; - has_start_pos = true; - } - points.clear(); - points.emplace_back(m_stem_pos.x, start_pos.y, m_stem_pos.z); - points.emplace_back(start_pos.x, start_pos.y, m_stem_pos.z); - points.emplace_back(start_pos.x, start_pos.y, start_pos.z); - points.emplace_back(m_stem_pos.x, start_pos.y, start_pos.z); - points.emplace_back(m_stem_pos.x, start_pos.y, m_stem_pos.z); - std::reverse(points.begin(), points.end()); + std::sort(targets.begin(), targets.end(), [&](const Target& a, const Target& b) { return a.distance > b.distance; }); + const Target& target = targets.back(); + editor_hovered_batch = target.b; } else + editor_hovered_batch = nullptr; + } + + if (editor_hovered_batch) + { + auto info = std::any_cast(editor_hovered_batch->userdata); + if (info.flat) { - if (has_start_pos) + if (sandbox->IsKeyDown(KEY_PAGEUP)) { - kp3d::Sector s; - s.ceiling.texture = &m_block; - s.floor.texture = &m_block; - s.floor.floor = true; - s.floor.base_height = 0.0f; - s.ceiling.base_height = 2.0f; - s.id = sandbox->map.sectors.size() + 1; - s.parent_id = 0; - s.inverted = false; - for (int i = 0; i < points.size() - 1; i++) - { - kp3d::Wall wall; - wall.start = { points[i].x, -points[i].z }; - wall.end = { points[i + 1].x, -points[i + 1].z }; - wall.uid = i; - for (int j = 0; j < 3; j++) - wall.textures[j] = &m_block; - - s.walls.push_back(wall); - } - - sandbox->map.original_sectors.push_back(s); - sandbox->map.Rebuild(kp3d::GEN_NORMALS); - points.clear(); - has_start_pos = false; + info.flat->base_height += 0.1f; + sandbox->map.Rebuild(GEN_NORMALS); + } + if (sandbox->IsKeyDown(KEY_PAGEDOWN)) + { + info.flat->base_height -= 0.1f; + sandbox->map.Rebuild(GEN_NORMALS); } } + + + } + } void Editor::RenderMap() @@ -163,12 +142,15 @@ void Editor::RenderMap() pos.z = Align(pos.z, 1.0f); RenderStem(pos); m_stem_pos = pos; - } void Editor::RenderStem(kp3d::Vec3 position) { using namespace kp3d; + + if (m_mode != MODE_BUILD) + return; + Vec2 size = {1.0f, (float) m_stem.GetHeight() / (float) m_stem.GetWidth()}; const Camera* camera = Renderer3D::GetPrimaryCamera(); kp3d::Vec3 player_distance = position - camera->position; @@ -188,6 +170,93 @@ void Editor::RenderStem(kp3d::Vec3 position) Renderer3D::DrawBillboard(m_stem, {position.x, position.y + size.y * 0.5f, position.z}, size); } +void Editor::UpdateModeBuild() +{ + if (sandbox->IsMouseButtonDown(kp3d::MOUSE_BUTTON_LEFT)) + { + points.push_back(m_stem_pos); + + if (points.size() >= 3 && kp3d::PosCmp(points.back(), points.front(), 1.0f / 128.0f))// points.back() == points.front()) + { + std::shared_ptr s = std::make_shared(); + s->ceiling.texture = &m_block; + s->floor.texture = &m_block; + s->floor.floor = true; + s->floor.base_height = 0.0f; + s->ceiling.base_height = 2.0f; + s->id = sandbox->map.sectors.size() + 1; + s->parent_id = 0; + s->inverted = false; + for (int i = 0; i < points.size() - 1; i++) + { + kp3d::Wall wall; + wall.start = { points[i].x, -points[i].z }; + wall.end = { points[i + 1].x, -points[i + 1].z }; + wall.uid = i; + for (int j = 0; j < 3; j++) + wall.textures[j] = &m_block; + + s->walls.push_back(wall); + } + + sandbox->map.sectors.push_back(s); + sandbox->map.Rebuild(kp3d::GEN_NORMALS); + + points.clear(); + } + + sandbox->MouseButtonReset(kp3d::MOUSE_BUTTON_LEFT); + } + static kp3d::Vec3 start_pos; + static bool has_start_pos = false; + if (sandbox->IsMouseButtonDown(kp3d::MOUSE_BUTTON_RIGHT)) + { + if (!has_start_pos) + { + start_pos = m_stem_pos; + has_start_pos = true; + } + points.clear(); + points.emplace_back(m_stem_pos.x, start_pos.y, m_stem_pos.z); + points.emplace_back(start_pos.x, start_pos.y, m_stem_pos.z); + points.emplace_back(start_pos.x, start_pos.y, start_pos.z); + points.emplace_back(m_stem_pos.x, start_pos.y, start_pos.z); + points.emplace_back(m_stem_pos.x, start_pos.y, m_stem_pos.z); + std::reverse(points.begin(), points.end()); + } + else + { + if (has_start_pos) + { + std::shared_ptr s = std::make_shared(); + s->ceiling.texture = &m_block; + s->floor.texture = &m_block; + s->floor.floor = true; + s->floor.base_height = 0.0f; + s->ceiling.base_height = 2.0f; + s->id = sandbox->map.sectors.size() + 1; + s->parent_id = 0; + s->inverted = false; + for (int i = 0; i < points.size() - 1; i++) + { + kp3d::Wall wall; + wall.start = { points[i].x, -points[i].z }; + wall.end = { points[i + 1].x, -points[i + 1].z }; + wall.uid = i; + for (int j = 0; j < 3; j++) + wall.textures[j] = &m_block; + + s->walls.push_back(wall); + } + + sandbox->map.sectors.push_back(s); + sandbox->map.Rebuild(kp3d::GEN_NORMALS); + points.clear(); + has_start_pos = false; + } + } +} + void Editor::RenderUI() { // Menu bar @@ -199,11 +268,14 @@ void Editor::RenderUI() } if (ImGui::BeginMenu("Edit")) { + if (ImGui::MenuItem("Undo")) {} + if (ImGui::MenuItem("Redo")) {} ImGui::EndMenu(); } if (ImGui::BeginMenu("View")) { ImGui::Checkbox("Info overlay", &show_info_overlay); + ImGui::Checkbox("Console", &kp3d::console::open); ImGui::EndMenu(); } ImGui::EndMainMenuBar(); diff --git a/Sandbox/src/Editor.h b/Sandbox/src/Editor.h index 339522d..3b0dbb2 100644 --- a/Sandbox/src/Editor.h +++ b/Sandbox/src/Editor.h @@ -21,6 +21,8 @@ public: void RenderMap(); void RenderStem(kp3d::Vec3 position); + void UpdateModeBuild(); + void RenderModeBuild(); void RenderModeSectorEdit(); diff --git a/Sandbox/src/Sandbox.cpp b/Sandbox/src/Sandbox.cpp index 89697f3..483312f 100644 --- a/Sandbox/src/Sandbox.cpp +++ b/Sandbox/src/Sandbox.cpp @@ -16,6 +16,7 @@ Sandbox::Sandbox(const std::string& path): kp3d::Game(path, "sandbox-cfg.json", "sandbox-log.txt") { tex.Load("logo.png"); + crosshair.Load(".kp3d/crosshair.png"); m_projection.InitPerspective(70.0f, (float) GetWidth() / (float) GetHeight()); map.Init(); @@ -134,6 +135,11 @@ void Sandbox::Render() kp3d::Renderer2D::Begin(); for (auto& p : points) kp3d::Renderer2D::DrawTexture(tex, p.x, p.y, 50, 50); + kp3d::Renderer2D::DrawTexture( + crosshair, + (float) GetWidth() * 0.5f - (float) crosshair.GetWidth() * 0.5f, + (float) GetHeight() * 0.5f - (float) crosshair.GetHeight() * 0.5f + ); kp3d::Renderer2D::End(); if (m_mode == MODE_EDIT) diff --git a/Sandbox/src/Sandbox.h b/Sandbox/src/Sandbox.h index 9e06939..d56b325 100644 --- a/Sandbox/src/Sandbox.h +++ b/Sandbox/src/Sandbox.h @@ -32,6 +32,7 @@ public: kp3d::Map map; Editor editor; kp3d::Camera camera; + kp3d::Texture crosshair; private: // KP3D essentials