diff --git a/build.gradle b/build.gradle index f98fb36..69f1f93 100644 --- a/build.gradle +++ b/build.gradle @@ -3,12 +3,13 @@ plugins { id 'application' id 'java' } -project.ext.lwjglVersion = "3.3.6" +project.ext.lwjglVersion = "3.4.1" project.ext.jomlVersion = "1.10.8" project.ext.jomlprimitivesVersion = "1.10.0" project.ext.lwjgl3awtVersion = "0.1.8" project.ext.steamworks4jVersion = "1.9.0" project.ext.steamworks4jserverVersion = "1.9.0" +project.ext.imguiVersion = "1.92.0" switch (OperatingSystem.current()) { case OperatingSystem.LINUX: @@ -43,7 +44,6 @@ dependencies { implementation 'org.tinylog:tinylog-impl:2.7.0' implementation "org.lwjgl:lwjgl" implementation "org.lwjgl:lwjgl-assimp" - implementation "org.lwjgl:lwjgl-cuda" implementation "org.lwjgl:lwjgl-fmod" implementation "org.lwjgl:lwjgl-freetype" implementation "org.lwjgl:lwjgl-glfw" @@ -57,7 +57,6 @@ dependencies { implementation "org.lwjgl:lwjgl-rpmalloc" implementation "org.lwjgl:lwjgl-shaderc" implementation "org.lwjgl:lwjgl-stb" - implementation "org.lwjgl:lwjgl-tootle" implementation "org.lwjgl:lwjgl-vma" implementation "org.lwjgl:lwjgl-vulkan" implementation "org.lwjgl:lwjgl::$lwjglNatives" @@ -74,7 +73,6 @@ dependencies { runtimeOnly "org.lwjgl:lwjgl-remotery:${lwjglVersion}:${lwjglNatives}" implementation "org.lwjgl:lwjgl-shaderc::$lwjglNatives" implementation "org.lwjgl:lwjgl-stb::$lwjglNatives" - implementation "org.lwjgl:lwjgl-tootle::$lwjglNatives" implementation "org.lwjgl:lwjgl-vma::$lwjglNatives" if (lwjglNatives == "natives-macos" || lwjglNatives == "natives-macos-arm64") implementation "org.lwjgl:lwjgl-vulkan::$lwjglNatives" implementation "org.joml:joml:${jomlVersion}" @@ -84,4 +82,13 @@ dependencies { implementation "com.code-disaster.steamworks4j:steamworks4j-server:${steamworks4jserverVersion}" implementation 'com.google.code.gson:gson:2.14.0' implementation "org.jcommander:jcommander:3.0" + ['', '-opengl', '-glfw'].each { + implementation "org.lwjgl:lwjgl$it:$lwjglVersion" + implementation "org.lwjgl:lwjgl$it::natives-windows" + } + + implementation "io.github.spair:imgui-java-binding:$imguiVersion" + implementation "io.github.spair:imgui-java-lwjgl3:$imguiVersion" + + implementation "io.github.spair:imgui-java-natives-windows:$imguiVersion" } \ No newline at end of file diff --git a/resources/EngineResources/GuiShaders/gui_frag.glsl b/resources/EngineResources/GuiShaders/gui_frag.glsl new file mode 100644 index 0000000..8319e46 --- /dev/null +++ b/resources/EngineResources/GuiShaders/gui_frag.glsl @@ -0,0 +1,12 @@ +#version 450 + +layout (location = 0) in vec2 inTextCoords; +layout (location = 1) in vec4 inColor; + +layout (binding = 0) uniform sampler2D fontsSampler; + +layout (location = 0) out vec4 outFragColor; + +void main() { + outFragColor = inColor * texture(fontsSampler, inTextCoords); +} diff --git a/resources/EngineResources/GuiShaders/gui_vertex.glsl b/resources/EngineResources/GuiShaders/gui_vertex.glsl new file mode 100644 index 0000000..dd0eb04 --- /dev/null +++ b/resources/EngineResources/GuiShaders/gui_vertex.glsl @@ -0,0 +1,23 @@ +#version 450 + +layout (location = 0) in vec2 inPos; +layout (location = 1) in vec2 inTextCoords; +layout (location = 2) in vec4 inColor; + +layout(push_constant) uniform PushConstants{ + vec2 scale; +} pushConstants; + +layout (location = 0) out vec2 outTextCoords; +layout (location = 1) out vec4 outColor; + +out gl_PerVertex +{ + vec4 gl_Position; +}; + +void main() { + outTextCoords = inTextCoords; + outColor = inColor; + gl_Position = vec4(inPos * pushConstants.scale + vec2(-1.0,1.0),0.0,1.0); +} diff --git a/resources/EngineResources/Texture/Billy.png b/resources/EngineResources/Texture/Billy.png new file mode 100644 index 0000000..04b08c6 Binary files /dev/null and b/resources/EngineResources/Texture/Billy.png differ diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Display/Render.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Display/Render.java index f2ebd1b..bae024f 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Display/Render.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Display/Render.java @@ -3,6 +3,8 @@ package net.halbear.Terrain4J.EngineCore.Display; import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance; import net.halbear.Terrain4J.EngineCore.Logic.InitData; import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext; +import net.halbear.Terrain4J.EngineCore.Vulkan.GUI.GuiRenderer; +import net.halbear.Terrain4J.EngineCore.Vulkan.GUI.GuiTexture; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.TextureCache; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.PostProcessing.PostProcess; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.*; @@ -42,13 +44,12 @@ public class Render { private final SceneRenderer sceneRender; private final PostProcess PostProcessor; private final SwapChainRender swapChainRender; + private final GuiRenderer GuiRender; private int CurrentFrame; private final VulkanContext RendererContext; private boolean Resize = false; private List Materials = new ArrayList<>(); private List Models = new ArrayList<>(); - private List VoxelModels = new ArrayList<>(); - private final MaterialsCache materialsCache; private TextureCache textureCache; @@ -77,6 +78,7 @@ public class Render { } sceneRender = new SceneRender(RendererContext); PostProcessor = new PostProcess(RendererContext,sceneRender.GetAttachmentColour()); + GuiRender = new GuiRenderer(engineInstance, RendererContext, GraphicsQueue, PostProcessor.GetAttachment()); swapChainRender = new SwapChainRender(RendererContext,PostProcessor.GetAttachment()); textureCache = new TextureCache(); materialsCache = new MaterialsCache(); @@ -103,13 +105,18 @@ public class Render { modelsCache.loadModels(RendererContext, Models, CommandPools[0], GraphicsQueue); Logger.debug("Loaded {} models", Models.size()); - VoxelModels.addAll(initData.voxelModels()); - Logger.debug("Loading {} Voxel models", VoxelModels.size()); - modelsCache.loadVoxelModels(RendererContext, VoxelModels, CommandPools[0], GraphicsQueue); - Logger.debug("Loaded {} Voxel models", VoxelModels.size()); + List guiTextures = initData.GuiTextures(); + if(guiTextures != null){ + initData.GuiTextures().forEach(texture -> textureCache.AddTexture(RendererContext, texture.TexturePath(), texture.TexturePath(), VK_FORMAT_R8G8B8A8_SRGB)); + } + sceneRender.LoadMaterials(RendererContext,materialsCache,textureCache); + GuiRender.LoadTextures(RendererContext,initData.GuiTextures(),textureCache); } + public GuiRenderer GetGUIRenderer(){return GuiRender;} + public long GetGuiTexture(long ID){return GuiRender.GetVkDescriptorImage(ID);} + private void RecordingStart(CommandPool commandPool, CommandBuffer commandBuffer){ commandPool.Reset(RendererContext); commandBuffer.BeginRecording(); @@ -125,6 +132,7 @@ public class Render { sceneRender.cleanup(RendererContext); PostProcessor.CleanUp(RendererContext); swapChainRender.CleanUp(RendererContext); + GuiRender.CleanUp(RendererContext); Logger.debug("Dynamic Renderer Cleaned up"); Arrays.asList(RenderCompleteSemaphores).forEach(i->i.cleanup(RendererContext)); Logger.debug("Render Semaphores cleaned up"); @@ -151,8 +159,9 @@ public class Render { sceneRender.Render(engineInstance,RendererContext,CommandBuffer, modelsCache,materialsCache,CurrentFrame); PostProcessor.Render(RendererContext,CommandBuffer,sceneRender.GetAttachmentColour()); + GuiRender.Render(RendererContext,CommandBuffer,CurrentFrame,PostProcessor.GetAttachment()); - int ImageIndex;// = swapChain.FetchNextImage(RendererContext.GetDevice(), PresentCompleteSemaphores[CurrentFrame]); + int ImageIndex; if (Resize || (ImageIndex = swapChain.FetchNextImage(RendererContext.GetDevice(), PresentCompleteSemaphores[CurrentFrame])) < 0){ resize(engineInstance); return; @@ -188,6 +197,7 @@ public class Render { engineInstance.scene().GetProjection().Resize(extend.width(),extend.height()); sceneRender.Resize(engineInstance,RendererContext); PostProcessor.Resize(RendererContext,sceneRender.GetAttachmentColour()); + GuiRender.Resize(RendererContext,PostProcessor.GetAttachment()); swapChainRender.Resize(RendererContext,PostProcessor.GetAttachment()); } diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Input/KeyboardInput.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Input/KeyboardInput.java index 7f4650e..ef7dc08 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Input/KeyboardInput.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Input/KeyboardInput.java @@ -1,7 +1,6 @@ package net.halbear.Terrain4J.EngineCore.Input; import org.lwjgl.glfw.GLFWCharCallbackI; -import org.lwjgl.glfw.GLFWKeyCallback; import org.lwjgl.glfw.GLFWKeyCallbackI; import java.util.ArrayList; @@ -11,14 +10,18 @@ import java.util.Map; import static org.lwjgl.glfw.GLFW.*; -public class KeyboardInput { +public class KeyboardInput implements GLFWKeyCallbackI { private long window; + private final Map SinglePressKeyMap; + private List Callbacks; public List keysPressed = new ArrayList<>(); public List keysSinglePressed = new ArrayList<>(); public KeyboardInput(long Window){ window = Window; + SinglePressKeyMap = new HashMap<>(); + Callbacks = new ArrayList<>(); glfwSetKeyCallback(window, this::KeyCallback); } public void input() { @@ -34,6 +37,19 @@ public class KeyboardInput { } if (keysSinglePressed.contains(key)&& action == GLFW_RELEASE) keysSinglePressed.remove(keysSinglePressed.indexOf(key)); } + + + @Override + public void invoke(long Window, int key, int scancode, int action, int mods) { + SinglePressKeyMap.put(key, action == GLFW_PRESS); + int CallBackCount = Callbacks.size(); + for (int i = 0; i < CallBackCount; i++) { + Callbacks.get(i).invoke(Window, key, scancode, action, mods); + } + } + public void AddKeyCallBack(GLFWKeyCallbackI callbackI){ + Callbacks.add(callbackI); + } public boolean keyPressed(int keyCode) { if (keysPressed.contains(keyCode)) return true; else return false; @@ -55,4 +71,5 @@ public class KeyboardInput { public void setCharCallBack(GLFWCharCallbackI charCallback) { glfwSetCharCallback(window, charCallback); } + } diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/GameLogic.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/GameLogic.java index d015130..8a96ab3 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/GameLogic.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/GameLogic.java @@ -3,6 +3,9 @@ package net.halbear.Terrain4J.EngineCore.Logic; public interface GameLogic { void cleanup(); InitData Initialise(EngineInstance engineInstance); + + void RenderThreadInput(EngineInstance engineInstance, long FrameDiffNanoSeconds); + void Input(EngineInstance engineInstance, long FrameDiffNanoSeconds); void CameraInput(EngineInstance engineInstance, long FrameDiffNanoSeconds); void Update(EngineInstance engineInstance, long FrameDiffNanoSeconds); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/InitData.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/InitData.java index 9806620..b95bb29 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/InitData.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/InitData.java @@ -1,10 +1,10 @@ package net.halbear.Terrain4J.EngineCore.Logic; +import net.halbear.Terrain4J.EngineCore.Vulkan.GUI.GuiTexture; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.MaterialData; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.ModelData; -import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.CompatibleVoxelMesh; import java.util.List; -public record InitData(List Models, List voxelModels, List Materials) { +public record InitData(List Models, List Materials, List GuiTextures) { } diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/InitVoxelData.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/InitVoxelData.java deleted file mode 100644 index 7f4bffa..0000000 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/InitVoxelData.java +++ /dev/null @@ -1,9 +0,0 @@ -package net.halbear.Terrain4J.EngineCore.Logic; - -import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.MaterialData; -import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.CompatibleVoxelMesh; - -import java.util.List; - -public record InitVoxelData(List Models, List Materials) { -} diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/GameCore.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/GameCore.java index 9e46529..fcb5deb 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/GameCore.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/GameCore.java @@ -1,5 +1,9 @@ package net.halbear.Terrain4J.EngineCore.Main; +import imgui.ImGui; +import imgui.ImGuiIO; +import imgui.ImVec2; +import imgui.flag.ImGuiCond; import net.halbear.Terrain4J.EngineCore.Display.Window; import net.halbear.Terrain4J.EngineCore.Input.KeyboardInput; import net.halbear.Terrain4J.EngineCore.Input.MouseListener; @@ -8,13 +12,11 @@ import net.halbear.Terrain4J.EngineCore.Logic.Rendering.ModelLoader; import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor; import net.halbear.Terrain4J.EngineCore.Main.Scene.Camera; import net.halbear.Terrain4J.EngineCore.Main.Scene.Scene; -import net.halbear.Terrain4J.EngineCore.Main.Util.Maths.T4Math; +import net.halbear.Terrain4J.EngineCore.Vulkan.GUI.GuiTexture; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.MaterialData; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.ModelData; -import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.CompatibleVoxelMesh; import org.joml.Vector2f; import org.joml.Vector3f; -import org.tinylog.Logger; import java.util.ArrayList; import java.util.List; @@ -34,6 +36,8 @@ public class GameCore implements GameLogic { private List CubeActors = new ArrayList<>(); private Vector2f LastMousePos = new Vector2f(0,0); private int Ticks = 0; + private int GUI_MODE = 0; + private GuiTexture guiTexture; @Override public void cleanup() { @@ -42,35 +46,24 @@ public class GameCore implements GameLogic { @Override public InitData Initialise(EngineInstance engineInstance) { - - CompatibleVoxelMesh GrassCube = new CompatibleVoxelMesh("GrassBlock") - .CreateMeshFace(CompatibleVoxelMesh.FaceDirection.North, "resources/EngineResources/Texture/VoxelTextures/VoxelTexture1.png") - .CreateMeshFace(CompatibleVoxelMesh.FaceDirection.East, "resources/EngineResources/Texture/VoxelTextures/VoxelTexture14.png") - .CreateMeshFace(CompatibleVoxelMesh.FaceDirection.South, "resources/EngineResources/Texture/VoxelTextures/VoxelTexture13.png") - .CreateMeshFace(CompatibleVoxelMesh.FaceDirection.West, "resources/EngineResources/Texture/VoxelTextures/VoxelTexture12.png") - .CreateMeshFace(CompatibleVoxelMesh.FaceDirection.Up, "resources/EngineResources/Texture/VoxelTextures/VoxelTexture15.png") - .CreateMeshFace(CompatibleVoxelMesh.FaceDirection.Down, "resources/EngineResources/Texture/VoxelTextures/VoxelTexture0.png").CompileMesh(); - - InitVoxelData Voxels = CompatibleVoxelMesh.GetVoxelModelsGenerated(); - List VoxelModels = Voxels.Models(); - for(int i = 0; i < VoxelModels.size(); i++){ - Logger.debug("Voxel -> [{}]",VoxelModels.get(i).ID()); - } Scene scene = engineInstance.scene(); List models = new ArrayList<>(); //ModelData SponzaData = ModelLoader.LoadModel("resources/models/Unit02/evangelion_unit-02.json"); //List SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Unit02/evangelion_unit-02_mat.json"); - ModelData SponzaData = ModelLoader.LoadModel("resources/models/Sponza/Sponza.json"); - List SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Sponza/Sponza_mat.json"); - scene.AddActor(new Actor("Sponza", SponzaData.ID(), new Vector3f(0,0,-5f))); + //ModelData SponzaData = ModelLoader.LoadModel("resources/models/Cafe/exterior.json"); + //List SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Cafe/exterior_mat.json"); + // ModelData SponzaData1 = ModelLoader.LoadModel("resources/models/Cafe/interior.json"); + // List SponzaMaterial1= ModelLoader.LoadMaterials("resources/models/Cafe/interior_mat.json"); + //scene.AddActor(new Actor("Sponza1", SponzaData.ID(), new Vector3f(0,0,-5f))); + //scene.AddActor(new Actor("Sponza2", SponzaData1.ID(), new Vector3f(0,0,-5f))); models.add(ModelLoader.LoadModel("resources/models/Metro/OBJ/MetroLeadCar.json")); models.add(ModelLoader.LoadModel("resources/models/melona/melona.json")); models.add(ModelLoader.LoadModel("resources/models/Alice/Welsh040Alice.json")); models.add(ModelLoader.LoadModel("resources/models/Sloop/SloopOBJ.json")); models.add(ModelLoader.LoadModel("resources/models/Corvette/corvetteclass.json")); - for(int i = 0; i < 50000; i++) { + for(int i = 0; i < 5000; i++) { CubeActors.add(new Actor("AdvancedModel" + i, models.get((int)Math.round(Math.min(Math.max(Math.random() *(Math.random() * models.size() - 1),0),models.size() - 1))).ID(), new Vector3f((float)(-200 + Math.random() * 400), (float)(-50 + Math.random() * 100), (float)(250 + Math.random() * -500)))); angles.add((float)(Math.random() * 360)); rotatingAngles.add(new Vector3f((float)(Math.random()*2), (float)(Math.random()*2), (float)(Math.random()*2))); @@ -84,15 +77,21 @@ public class GameCore implements GameLogic { materials.addAll(ModelLoader.LoadMaterials("resources/models/melona/melona_mat.json")); materials.addAll(ModelLoader.LoadMaterials("resources/models/Alice/Welsh040Alice_mat.json")); materials.addAll(ModelLoader.LoadMaterials("resources/models/Sloop/SloopOBJ_mat.json")); - materials.addAll(SponzaMaterial); - materials.addAll(Voxels.Materials()); - models.add(SponzaData); + // materials.addAll(SponzaMaterial); + //materials.addAll(SponzaMaterial1); + //models.add(SponzaData); + //models.add(SponzaData1); Camera camera = scene.GetCamera(); camera.SetPosition(40.0f, 155.0f, -42.0f); camera.SetPosition(0,0,0); camera.SetRotation((float) Math.toRadians(10.0f), (float) Math.toRadians(-90.0f),0); camera.SetRotation(0,0,0); - return new InitData(models,VoxelModels,materials); + + guiTexture = new GuiTexture("resources/EngineResources/Texture/DefaultTexture.png"); + List guiTextures = new ArrayList<>(); + guiTextures.add(guiTexture); + + return new InitData(models,materials,guiTextures); } @Override @@ -119,6 +118,11 @@ public class GameCore implements GameLogic { } } + @Override + public void RenderThreadInput(EngineInstance engineInstance, long FrameDiffNanoSeconds) { + HandleGui(engineInstance); + } + @Override public void Input(EngineInstance engineInstance, long FrameDiffNanoSeconds) { Scene scene = engineInstance.scene(); @@ -127,6 +131,15 @@ public class GameCore implements GameLogic { KeyboardInput input = window.getKeyboardInput(); float MovementDist = (float)(FrameDiffNanoSeconds / 1000000L) * MOVEMENT_SPEED; Camera camera = scene.GetCamera(); + if(input.keyPressed(GLFW_KEY_1)){ + GUI_MODE = 0; + } + if(input.keyPressed(GLFW_KEY_2)){ + GUI_MODE = 1; + } + if(input.keyPressed(GLFW_KEY_3)){ + GUI_MODE = 2; + } if(input.keyPressed(GLFW_KEY_W)){ camera.MoveForward(MovementDist); } @@ -145,6 +158,39 @@ public class GameCore implements GameLogic { if(input.keyPressed(GLFW_KEY_LEFT_SHIFT)){ camera.MoveDown(MovementDist); } + if(input.keyPressed(GLFW_KEY_LEFT_CONTROL)){ + camera.Sprint(true); + } else camera.Sprint(false); + } + + private boolean HandleGui(EngineInstance engineInstance){ + ImGuiIO imGuiIO = ImGui.getIO(); + MouseListener mouseListener = engineInstance.window().getMouseInput(); + Vector2f mousePosition = mouseListener.getCurrentPos(); + imGuiIO.addMousePosEvent(mousePosition.x,mousePosition.y); + imGuiIO.addMouseButtonEvent(0,mouseListener.isLeftButtonPressed()); + imGuiIO.addMouseButtonEvent(1,mouseListener.isRightButtonPressed()); + + if(GUI_MODE == 0){ + ImGui.newFrame(); + ImGui.showDemoWindow(); + ImGui.endFrame(); + ImGui.render(); + } else if (GUI_MODE == 1){ + ImGui.newFrame(); + ImGui.setNextWindowPos(0,0, ImGuiCond.Always); + ImGui.setNextWindowSize(500,500); + ImGui.begin("Test Window"); + ImGui.image(guiTexture.ID(),new ImVec2(300,300)); + ImGui.end(); + ImGui.endFrame(); + ImGui.render(); + } else if (GUI_MODE == 2){ + ImGui.newFrame(); + ImGui.endFrame(); + ImGui.render(); + } + return imGuiIO.getWantCaptureKeyboard(); } @Override diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/Camera.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/Camera.java index 865da27..8dba0d1 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/Camera.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/Camera.java @@ -10,6 +10,7 @@ public class Camera { private final Vector3f Rotation; private final Vector3f Up; private final Matrix4f ViewMatrix; + private boolean Sprint; public Camera(){ Direction = new Vector3f(); @@ -19,6 +20,11 @@ public class Camera { Up = new Vector3f(); ViewMatrix = new Matrix4f(); } + + public void Sprint(boolean sprint){ + this.Sprint = sprint; + } + public void SetRotation(float x, float y, float z){Rotation.set(x,y,z); Recalculate();} public void AddRotation(float x, float y, float z){Rotation.add(x,y,z); Recalculate();} @@ -41,31 +47,37 @@ public class Camera { } public void MoveForward(float Distance){ + if(Sprint) Distance *=2; ViewMatrix.positiveZ(Direction).negate().mul(Distance); Position.add(Direction); Recalculate(); } public void MoveBackward(float Distance){ + if(Sprint) Distance *=2; ViewMatrix.positiveZ(Direction).negate().mul(Distance); Position.sub(Direction); Recalculate(); } public void MoveUp(float Distance){ + if(Sprint) Distance *=2; ViewMatrix.positiveY(Up).negate().mul(Distance); Position.sub(Up); Recalculate(); } public void MoveDown(float Distance){ + if(Sprint) Distance *=2; ViewMatrix.positiveY(Up).negate().mul(Distance); Position.add(Up); Recalculate(); } public void MoveLeft(float Distance){ + if(Sprint) Distance *=2; ViewMatrix.positiveX(Right).negate().mul(Distance); Position.add(Right); Recalculate(); } public void MoveRight(float Distance){ + if(Sprint) Distance *=2; ViewMatrix.positiveX(Right).negate().mul(Distance); Position.sub(Right); Recalculate(); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Threads/RenderThread.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Threads/RenderThread.java index b55d620..3355778 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Threads/RenderThread.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Threads/RenderThread.java @@ -25,6 +25,7 @@ public class RenderThread extends EngineThread { } @Override public void FrameEvent(long now, long InitialTime){ + gameLogic.RenderThreadInput(PrimaryRuntime.GetEngineInstance(), (now-InitialTime)); gameLogic.Update(PrimaryRuntime.GetEngineInstance(), (now - InitialTime)); render.render(PrimaryRuntime.GetEngineInstance()); } diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/GUI/GuiRenderer.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/GUI/GuiRenderer.java new file mode 100644 index 0000000..685ea51 --- /dev/null +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/GUI/GuiRenderer.java @@ -0,0 +1,318 @@ +package net.halbear.Terrain4J.EngineCore.Vulkan.GUI; + +import imgui.ImDrawData; +import imgui.ImGui; +import imgui.ImGuiIO; +import imgui.ImVec4; +import imgui.glfw.ImGuiImplGlfw; +import imgui.type.ImInt; +import net.halbear.Terrain4J.EngineCore.Input.KeyboardInput; +import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig; +import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance; +import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext; +import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.DefaultPipeline; +import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.*; +import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Pipeline; +import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.PipelineBuildInfo; +import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.PushConstantsRange; +import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.PostProcessing.PostProcess; +import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.*; +import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.CommandBuffer; +import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.CommandPool; +import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.Device; +import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.Queues.Queue; +import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanBuffer; +import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils; +import org.lwjgl.system.MemoryStack; +import org.lwjgl.system.MemoryUtil; +import org.lwjgl.util.shaderc.Shaderc; +import org.lwjgl.vulkan.*; +import org.tinylog.Logger; + +import java.nio.ByteBuffer; +import java.nio.FloatBuffer; +import java.nio.LongBuffer; +import java.util.*; + +import static org.lwjgl.util.vma.Vma.VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT; +import static org.lwjgl.util.vma.Vma.VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE; +import static org.lwjgl.vulkan.VK13.*; + +public class GuiRenderer { + private static final String DESCRIPTOR_ID_TEXTURE = "GUI_DESC_ID_TEXT"; + private static final String GUI_FRAGMENT_SHADER_GLSL = "resources/EngineResources/GuiShaders/gui_frag.glsl"; + private static final String GUI_FRAGMENT_SHADER_SPV = GUI_FRAGMENT_SHADER_GLSL + ".spv"; + private static final String GUI_VERTEX_SHADER_GLSL = "resources/EngineResources/GuiShaders/gui_vertex.glsl"; + private static final String GUI_VERTEX_SHADER_SPV = GUI_VERTEX_SHADER_GLSL + ".spv"; + + private final VulkanBuffer[] IndexBuffers; + private final VulkanBuffer[] VertexBuffers; + private final Texture FontsTexture; + private final TextureSampler FontsTextureSampler; + private final Map GuiTexturesMap; + private final Pipeline pipeline; + private final DescriptorSetLayout TextDescriptorSetLayout; + private VkRenderingAttachmentInfo.Buffer AttachmentInfoColour; + private VkRenderingInfo RenderingInfo; + + public long GetVkDescriptorImage(long ID){ + return GuiTexturesMap.get(ID); + } + + public GuiRenderer(EngineInstance engineInstance, VulkanContext VkCtx, Queue queue, Attachment dstAttachment){ + AttachmentInfoColour = CreateColourAttachmentInfo(dstAttachment); + RenderingInfo = CreateRenderInfo(dstAttachment,AttachmentInfoColour); + ShaderModule[] shadermodules = CreateShaderModules(VkCtx); + TextDescriptorSetLayout = new DescriptorSetLayout(VkCtx,new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,0,1,VK_SHADER_STAGE_FRAGMENT_BIT)); + pipeline = CreatePipeline(VkCtx, shadermodules, new DescriptorSetLayout[]{TextDescriptorSetLayout}); + Arrays.asList(shadermodules).forEach(s->s.CleanUp(VkCtx)); + + VertexBuffers = new VulkanBuffer[VulkanUtils.MAX_IN_FLIGHT]; + IndexBuffers = new VulkanBuffer[VulkanUtils.MAX_IN_FLIGHT]; + + FontsTexture = InitGUI(VkCtx,queue); + var textureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_BORDER_COLOR_INT_OPAQUE_BLACK,1,true); + FontsTextureSampler = new TextureSampler(VkCtx,textureSamplerInfo); + Device device = VkCtx.GetDevice(); + DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator(); + DescriptorSet descriptorSet = descriptorAllocator.AddDescriptorSets(device,DESCRIPTOR_ID_TEXTURE,1,TextDescriptorSetLayout)[0]; + descriptorSet.SetImage(device,FontsTexture.GetImageView(),FontsTextureSampler,TextDescriptorSetLayout.GetLayoutInfo().Binding()); + ImGui.getIO().getFonts().setTexID(descriptorSet.GetVkDescriptorSet()); + + KeyboardInput keyboardInput=engineInstance.window().getKeyboardInput(); + keyboardInput.setCharCallBack(new GuiUtils.CharacterCallBack()); + keyboardInput.AddKeyCallBack(new GuiUtils.KeyCallBack()); + + GuiTexturesMap = new HashMap<>(); + } + + private static VkRenderingAttachmentInfo.Buffer CreateColourAttachmentInfo(Attachment dstAttachment){ + return VkRenderingAttachmentInfo.calloc(1) + .sType$Default() + .imageView(dstAttachment.GetVkImageView().GetVulkanImageView()) + .imageLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) + .loadOp(VK_ATTACHMENT_LOAD_OP_LOAD) + .storeOp(VK_ATTACHMENT_STORE_OP_STORE); + } + + private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] shaderModules, DescriptorSetLayout[] descriptorSetLayouts){ + var VertexBufferStructure = new GuiVertexBufferStruct(); + var BuildInfo = new PipelineBuildInfo(shaderModules, VertexBufferStructure.GetVertexInput(), + PostProcess.COLOUR_FORMAT) + .SetPushConstantRanges( + new PushConstantsRange[]{ + new PushConstantsRange(VK_SHADER_STAGE_VERTEX_BIT,0,VulkanUtils.VEC2_SIZE) + }) + .SetDescriptorSetLayouts(descriptorSetLayouts) + .BlendingIsUsed(true); + var pipeline = new DefaultPipeline(VkCtx, BuildInfo); + VertexBufferStructure.CleanUp(); + return pipeline; + } + + private static VkRenderingInfo CreateRenderInfo(Attachment ColourAttachment, VkRenderingAttachmentInfo.Buffer ColourAttachmentInfo){ + VkRenderingInfo renderingInfo; + try(var MemStack = MemoryStack.stackPush()){ + Image image = ColourAttachment.GetVkImage(); + VkExtent2D extent2D = VkExtent2D.calloc(MemStack).width(image.GetWidth()).height(image.GetHeight()); + var RenderArea = VkRect2D.calloc(MemStack).extent(extent2D); + renderingInfo = VkRenderingInfo.calloc() + .sType$Default() + .renderArea(RenderArea) + .layerCount(1) + .pColorAttachments(ColourAttachmentInfo); + } + return renderingInfo; + } + + private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx){ + if(EngineConfig.getInstance().RecompileShaders()){ + ShaderCompiler.CompileGLSLShaderOnChange(GUI_VERTEX_SHADER_GLSL, Shaderc.shaderc_glsl_vertex_shader); + ShaderCompiler.CompileGLSLShaderOnChange(GUI_FRAGMENT_SHADER_GLSL, Shaderc.shaderc_glsl_fragment_shader); + } + return new ShaderModule[]{ + new ShaderModule(VkCtx, VK_SHADER_STAGE_VERTEX_BIT, GUI_VERTEX_SHADER_SPV, null), + new ShaderModule(VkCtx, VK_SHADER_STAGE_FRAGMENT_BIT, GUI_FRAGMENT_SHADER_SPV, null) + }; + } + + public void LoadTextures(VulkanContext VkCtx, List GuiTextures, TextureCache textureCache){ + if(GuiTextures == null){ + return; + } + DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator(); + int TextureCount = GuiTextures.size(); + Device device = VkCtx.GetDevice(); + for(int i = 0; i < TextureCount; i++){ + var guiTexture = GuiTextures.get(i); + String descriptorID = guiTexture.TexturePath(); + DescriptorSet descriptorSet = descriptorAllocator.AddDescriptorSets(device, descriptorID, 1, TextDescriptorSetLayout)[0]; + Texture texture = textureCache.GetTexture(guiTexture.TexturePath()); + descriptorSet.SetImage(device,texture.GetImageView(),FontsTextureSampler,TextDescriptorSetLayout.GetLayoutInfo().Binding()); + //Logger.debug("TEXTURE ID -> [{}] DESCRIPTOR SET -> [{}] TEXTURE -> [{}] IMAGE PATH -> [{}] TEXTURE SAMPLER ->[{}]",guiTexture.ID(),descriptorSet.GetVkDescriptorSet(),texture,guiTexture.TexturePath(),FontsTextureSampler); + GuiTexturesMap.put(guiTexture.ID(),descriptorSet.GetVkDescriptorSet()); + } + } + + private static Texture InitGUI(VulkanContext VkCtx, Queue queue){ + ImGui.createContext(); + ImGuiIO imGuiIO = ImGui.getIO(); + imGuiIO.setIniFilename(null); + VkExtent2D SwapChainExtent = VkCtx.GetSwapChain().GetSwapChainExtent(); + imGuiIO.setDisplaySize(SwapChainExtent.width(), SwapChainExtent.height()); + imGuiIO.setDisplayFramebufferScale(1.0f,1.0f); + + ImInt textureWidth = new ImInt(); + ImInt textureHeight = new ImInt(); + ByteBuffer buffer = imGuiIO.getFonts().getTexDataAsRGBA32(textureWidth,textureHeight); + ImageSrc imageSrc = new ImageSrc(buffer,textureWidth.get(),textureHeight.get(),4); + Texture FontsTexture = new Texture(VkCtx, "GUI_TEXTURE",imageSrc,VK_FORMAT_R8G8B8A8_SRGB); + + var commandPool = new CommandPool(VkCtx, queue.GetQueueFamilyIndex(), false); + var commandBuffer = new CommandBuffer(VkCtx, commandPool, true, true); + commandBuffer.BeginRecording(); + FontsTexture.RecordTextureTransition(commandBuffer); + commandBuffer.EndRecording(); + commandBuffer.SubmitAndWait(VkCtx, queue); + commandBuffer.cleanup(VkCtx,commandPool); + commandPool.cleanup(VkCtx); + return FontsTexture; + } + + public void Render(VulkanContext VkCtx, CommandBuffer commandBuffer, int CurrentFrame, Attachment dstAttachment){ + try(var MemStack = MemoryStack.stackPush()){ + UpdateBuffers(VkCtx, CurrentFrame); + if(VertexBuffers[CurrentFrame] == null){ + return; + } + Image dstImage = dstAttachment.GetVkImage(); + int Width = dstImage.GetWidth(); + int Height = dstImage.GetHeight(); + + VkCommandBuffer CommandHandle = commandBuffer.GetVulkanCommandBuffer(); + + vkCmdBeginRendering(CommandHandle, RenderingInfo); + vkCmdBindPipeline(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.GetVulkanPipeline()); + + var Viewport = VkViewport.calloc(1,MemStack) + .x(0) + .y(Height) + .height(-Height) + .width(Width) + .minDepth(0.0f) + .maxDepth(1.0f); + vkCmdSetViewport(CommandHandle,0,Viewport); + + LongBuffer VertexBuff = MemStack.mallocLong(1); + VertexBuff.put(0,VertexBuffers[CurrentFrame].GetBuffer()); + LongBuffer Offsets = MemStack.mallocLong(1); + Offsets.put(0,0L); + vkCmdBindVertexBuffers(CommandHandle,0,VertexBuff,Offsets); + vkCmdBindIndexBuffer(CommandHandle,IndexBuffers[CurrentFrame].GetBuffer(),0,VK_INDEX_TYPE_UINT16); + + ImGuiIO imGuiIO = ImGui.getIO(); + FloatBuffer PushConstantBuffer = MemStack.mallocFloat(2); + PushConstantBuffer.put(0,2.0f/imGuiIO.getDisplaySizeX()); + PushConstantBuffer.put(1,-2.0f/imGuiIO.getDisplaySizeY()); + vkCmdPushConstants(CommandHandle,pipeline.GetVulkanPipelineLayout(),VK_SHADER_STAGE_VERTEX_BIT,0,PushConstantBuffer); + + LongBuffer DescriptorSets = MemStack.mallocLong(1); + + ImVec4 imVec4 = new ImVec4(); + VkRect2D.Buffer rect = VkRect2D.calloc(1,MemStack); + ImDrawData imDrawData = ImGui.getDrawData(); + int CmdListCount = imDrawData.getCmdListsCount(); + int OffsetIndex = 0; + int OffsetVertex = 0; + for(int i = 0; i < CmdListCount; i++){ + int CommandBufferSize = imDrawData.getCmdListCmdBufferSize(i); + for(int j = 0; j < CommandBufferSize; j++){ + long TextureID = imDrawData.getCmdListCmdBufferTextureId(i,j); + Long TextureDescriptorSet = GuiTexturesMap.get(TextureID); + if(TextureDescriptorSet == null){ + TextureDescriptorSet = TextureID; + } + DescriptorSets.put(0,TextureDescriptorSet); + vkCmdBindDescriptorSets(CommandHandle,VK_PIPELINE_BIND_POINT_GRAPHICS,pipeline.GetVulkanPipelineLayout(),0,DescriptorSets,null); + + imDrawData.getCmdListCmdBufferClipRect(imVec4,i,j); + rect.offset(it->it.x((int)Math.max(imVec4.x,0)).y((int)Math.max(imVec4.y,1))); + rect.extent(it->it.width((int)(imVec4.z - imVec4.x)).height((int)(imVec4.w - imVec4.y))); + vkCmdSetScissor(CommandHandle,0,rect); + int ElementCount = imDrawData.getCmdListCmdBufferElemCount(i,j); + vkCmdDrawIndexed(CommandHandle,ElementCount,1, + OffsetIndex + imDrawData.getCmdListCmdBufferIdxOffset(i,j), + OffsetVertex + imDrawData.getCmdListCmdBufferVtxOffset(i,j),0); + } + OffsetIndex += imDrawData.getCmdListIdxBufferSize(i); + OffsetVertex += imDrawData.getCmdListVtxBufferSize(i); + } + vkCmdEndRendering(CommandHandle); + } + } + + private void UpdateBuffers(VulkanContext VkCtx, int Index){ + ImDrawData imDrawData = ImGui.getDrawData(); + + if(imDrawData.ptr == 0) return; + int VertexBufferSize = imDrawData.getTotalVtxCount() * GuiVertexBufferStruct.VERTEX_SIZE; + int IndexBufferSize = imDrawData.getTotalIdxCount() * VulkanUtils.SHORT_LENGTH; + if(VertexBufferSize == 0 || IndexBufferSize == 0) return; + var VertexBuff = VertexBuffers[Index]; + if(VertexBuff == null || VertexBufferSize > VertexBuff.GetRequestedSize()){ + if(VertexBuff != null){ + VertexBuff.cleanup(VkCtx); + } + VertexBuff = new VulkanBuffer(VkCtx, VertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, + VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); + VertexBuffers[Index] = VertexBuff; + } + + var IndiciesBuffer = IndexBuffers[Index]; + if(IndiciesBuffer == null || IndexBufferSize > IndiciesBuffer.GetRequestedSize()){ + if(IndiciesBuffer != null){ + IndiciesBuffer.cleanup(VkCtx); + } + IndiciesBuffer = new VulkanBuffer(VkCtx,IndexBufferSize,VK_BUFFER_USAGE_INDEX_BUFFER_BIT,VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, + VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); + IndexBuffers[Index] = IndiciesBuffer; + } + + ByteBuffer dstVertexBuffer = MemoryUtil.memByteBuffer(VertexBuff.MapMemory(VkCtx),VertexBufferSize); + ByteBuffer dstIndexBuffer = MemoryUtil.memByteBuffer(IndiciesBuffer.MapMemory(VkCtx),IndexBufferSize); + + int CommandListCount = imDrawData.getCmdListsCount(); + for(int i = 0; i < CommandListCount; i++){ + ByteBuffer ImGuiVertexBuffer = imDrawData.getCmdListVtxBufferData(i); + dstVertexBuffer.put(ImGuiVertexBuffer); + ByteBuffer ImGuiIndicesBuffer = imDrawData.getCmdListIdxBufferData(i); + dstIndexBuffer.put(ImGuiIndicesBuffer); + } + VertexBuff.Flush(VkCtx); + IndiciesBuffer.Flush(VkCtx); + VertexBuff.UnMapMemory(VkCtx); + IndiciesBuffer.UnMapMemory(VkCtx); + } + + public void Resize(VulkanContext VkCtx, Attachment dstAttachment){ + ImGuiIO imGuiIO = ImGui.getIO(); + VkExtent2D SwapChainExtent = VkCtx.GetSwapChain().GetSwapChainExtent(); + imGuiIO.setDisplaySize(SwapChainExtent.width(),SwapChainExtent.height()); + + RenderingInfo.free(); + AttachmentInfoColour.free(); + AttachmentInfoColour = CreateColourAttachmentInfo(dstAttachment); + RenderingInfo = CreateRenderInfo(dstAttachment,AttachmentInfoColour); + } + + public void CleanUp(VulkanContext VkCtx){ + FontsTextureSampler.CleanUp(VkCtx); + FontsTexture.CleanUp(VkCtx); + TextDescriptorSetLayout.CleanUp(VkCtx); + pipeline.CleanUp(VkCtx); + Arrays.stream(VertexBuffers).filter(Objects::nonNull).forEach(b->b.cleanup(VkCtx)); + Arrays.stream(IndexBuffers).filter(Objects::nonNull).forEach(b->b.cleanup(VkCtx)); + RenderingInfo.free(); + AttachmentInfoColour.free(); + } +} diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/GUI/GuiTexture.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/GUI/GuiTexture.java new file mode 100644 index 0000000..5b54dd6 --- /dev/null +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/GUI/GuiTexture.java @@ -0,0 +1,17 @@ +package net.halbear.Terrain4J.EngineCore.Vulkan.GUI; + +import java.security.SecureRandom; + +public record GuiTexture(long ID, String TexturePath) { + public GuiTexture(String texturePath){ + this(GetID(),texturePath); + } + private static long GetID(){ + SecureRandom secureRandom = new SecureRandom(); + long ID = Math.abs(secureRandom.nextLong()); + if(ID == 0){ + ID += 1; + } + return ID; + } +} diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/GUI/GuiUtils.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/GUI/GuiUtils.java new file mode 100644 index 0000000..6aad4c2 --- /dev/null +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/GUI/GuiUtils.java @@ -0,0 +1,149 @@ +package net.halbear.Terrain4J.EngineCore.Vulkan.GUI; + +import imgui.ImGui; +import imgui.ImGuiIO; +import imgui.flag.ImGuiKey; +import org.lwjgl.glfw.GLFWCharCallbackI; +import org.lwjgl.glfw.GLFWKeyCallbackI; + +import static org.lwjgl.glfw.GLFW.*; + +public class GuiUtils { + public GuiUtils(){ + + } + + private static int GetImGuiKey(int key) { + return switch (key) { + case GLFW_KEY_TAB -> ImGuiKey.Tab; + case GLFW_KEY_LEFT -> ImGuiKey.LeftArrow; + case GLFW_KEY_RIGHT -> ImGuiKey.RightArrow; + case GLFW_KEY_UP -> ImGuiKey.UpArrow; + case GLFW_KEY_DOWN -> ImGuiKey.DownArrow; + case GLFW_KEY_PAGE_UP -> ImGuiKey.PageUp; + case GLFW_KEY_PAGE_DOWN -> ImGuiKey.PageDown; + case GLFW_KEY_HOME -> ImGuiKey.Home; + case GLFW_KEY_END -> ImGuiKey.End; + case GLFW_KEY_INSERT -> ImGuiKey.Insert; + case GLFW_KEY_DELETE -> ImGuiKey.Delete; + case GLFW_KEY_BACKSPACE -> ImGuiKey.Backspace; + case GLFW_KEY_SPACE -> ImGuiKey.Space; + case GLFW_KEY_ENTER -> ImGuiKey.Enter; + case GLFW_KEY_ESCAPE -> ImGuiKey.Escape; + case GLFW_KEY_APOSTROPHE -> ImGuiKey.Apostrophe; + case GLFW_KEY_COMMA -> ImGuiKey.Comma; + case GLFW_KEY_MINUS -> ImGuiKey.Minus; + case GLFW_KEY_PERIOD -> ImGuiKey.Period; + case GLFW_KEY_SLASH -> ImGuiKey.Slash; + case GLFW_KEY_SEMICOLON -> ImGuiKey.Semicolon; + case GLFW_KEY_EQUAL -> ImGuiKey.Equal; + case GLFW_KEY_LEFT_BRACKET -> ImGuiKey.LeftBracket; + case GLFW_KEY_BACKSLASH -> ImGuiKey.Backslash; + case GLFW_KEY_RIGHT_BRACKET -> ImGuiKey.RightBracket; + case GLFW_KEY_GRAVE_ACCENT -> ImGuiKey.GraveAccent; + case GLFW_KEY_CAPS_LOCK -> ImGuiKey.CapsLock; + case GLFW_KEY_SCROLL_LOCK -> ImGuiKey.ScrollLock; + case GLFW_KEY_NUM_LOCK -> ImGuiKey.NumLock; + case GLFW_KEY_PRINT_SCREEN -> ImGuiKey.PrintScreen; + case GLFW_KEY_PAUSE -> ImGuiKey.Pause; + case GLFW_KEY_KP_0 -> ImGuiKey.Keypad0; + case GLFW_KEY_KP_1 -> ImGuiKey.Keypad1; + case GLFW_KEY_KP_2 -> ImGuiKey.Keypad2; + case GLFW_KEY_KP_3 -> ImGuiKey.Keypad3; + case GLFW_KEY_KP_4 -> ImGuiKey.Keypad4; + case GLFW_KEY_KP_5 -> ImGuiKey.Keypad5; + case GLFW_KEY_KP_6 -> ImGuiKey.Keypad6; + case GLFW_KEY_KP_7 -> ImGuiKey.Keypad7; + case GLFW_KEY_KP_8 -> ImGuiKey.Keypad8; + case GLFW_KEY_KP_9 -> ImGuiKey.Keypad9; + case GLFW_KEY_KP_DECIMAL -> ImGuiKey.KeypadDecimal; + case GLFW_KEY_KP_DIVIDE -> ImGuiKey.KeypadDivide; + case GLFW_KEY_KP_MULTIPLY -> ImGuiKey.KeypadMultiply; + case GLFW_KEY_KP_SUBTRACT -> ImGuiKey.KeypadSubtract; + case GLFW_KEY_KP_ADD -> ImGuiKey.KeypadAdd; + case GLFW_KEY_KP_ENTER -> ImGuiKey.KeypadEnter; + case GLFW_KEY_KP_EQUAL -> ImGuiKey.KeypadEqual; + case GLFW_KEY_LEFT_SHIFT -> ImGuiKey.LeftShift; + case GLFW_KEY_LEFT_CONTROL -> ImGuiKey.LeftCtrl; + case GLFW_KEY_LEFT_ALT -> ImGuiKey.LeftAlt; + case GLFW_KEY_LEFT_SUPER -> ImGuiKey.LeftSuper; + case GLFW_KEY_RIGHT_SHIFT -> ImGuiKey.RightShift; + case GLFW_KEY_RIGHT_CONTROL -> ImGuiKey.RightCtrl; + case GLFW_KEY_RIGHT_ALT -> ImGuiKey.RightAlt; + case GLFW_KEY_RIGHT_SUPER -> ImGuiKey.RightSuper; + case GLFW_KEY_MENU -> ImGuiKey.Menu; + case GLFW_KEY_0 -> ImGuiKey._0; + case GLFW_KEY_1 -> ImGuiKey._1; + case GLFW_KEY_2 -> ImGuiKey._2; + case GLFW_KEY_3 -> ImGuiKey._3; + case GLFW_KEY_4 -> ImGuiKey._4; + case GLFW_KEY_5 -> ImGuiKey._5; + case GLFW_KEY_6 -> ImGuiKey._6; + case GLFW_KEY_7 -> ImGuiKey._7; + case GLFW_KEY_8 -> ImGuiKey._8; + case GLFW_KEY_9 -> ImGuiKey._9; + case GLFW_KEY_A -> ImGuiKey.A; + case GLFW_KEY_B -> ImGuiKey.B; + case GLFW_KEY_C -> ImGuiKey.C; + case GLFW_KEY_D -> ImGuiKey.D; + case GLFW_KEY_E -> ImGuiKey.E; + case GLFW_KEY_F -> ImGuiKey.F; + case GLFW_KEY_G -> ImGuiKey.G; + case GLFW_KEY_H -> ImGuiKey.H; + case GLFW_KEY_I -> ImGuiKey.I; + case GLFW_KEY_J -> ImGuiKey.J; + case GLFW_KEY_K -> ImGuiKey.K; + case GLFW_KEY_L -> ImGuiKey.L; + case GLFW_KEY_M -> ImGuiKey.M; + case GLFW_KEY_N -> ImGuiKey.N; + case GLFW_KEY_O -> ImGuiKey.O; + case GLFW_KEY_P -> ImGuiKey.P; + case GLFW_KEY_Q -> ImGuiKey.Q; + case GLFW_KEY_R -> ImGuiKey.R; + case GLFW_KEY_S -> ImGuiKey.S; + case GLFW_KEY_T -> ImGuiKey.T; + case GLFW_KEY_U -> ImGuiKey.U; + case GLFW_KEY_V -> ImGuiKey.V; + case GLFW_KEY_W -> ImGuiKey.W; + case GLFW_KEY_X -> ImGuiKey.X; + case GLFW_KEY_Y -> ImGuiKey.Y; + case GLFW_KEY_Z -> ImGuiKey.Z; + case GLFW_KEY_F1 -> ImGuiKey.F1; + case GLFW_KEY_F2 -> ImGuiKey.F2; + case GLFW_KEY_F3 -> ImGuiKey.F3; + case GLFW_KEY_F4 -> ImGuiKey.F4; + case GLFW_KEY_F5 -> ImGuiKey.F5; + case GLFW_KEY_F6 -> ImGuiKey.F6; + case GLFW_KEY_F7 -> ImGuiKey.F7; + case GLFW_KEY_F8 -> ImGuiKey.F8; + case GLFW_KEY_F9 -> ImGuiKey.F9; + case GLFW_KEY_F10 -> ImGuiKey.F10; + case GLFW_KEY_F11 -> ImGuiKey.F11; + case GLFW_KEY_F12 -> ImGuiKey.F12; + default -> ImGuiKey.None; + }; + } + + public static class CharacterCallBack implements GLFWCharCallbackI{ + @Override + public void invoke(long WindowHandle, int c){ + ImGuiIO imGuiIO = ImGui.getIO(); + if(!imGuiIO.getWantCaptureKeyboard()) return; + imGuiIO.addInputCharacter(c); + } + } + + public static class KeyCallBack implements GLFWKeyCallbackI{ + @Override + public void invoke(long WindowHandle, int Key, int ScanCode, int Action, int Mods){ + ImGuiIO imGuiIO = ImGui.getIO(); + if(!imGuiIO.getWantCaptureKeyboard()) return; + if(Action == GLFW_PRESS){ + imGuiIO.addKeyEvent(GetImGuiKey(Key),true); + } else if(Action == GLFW_RELEASE){ + imGuiIO.addKeyEvent(GetImGuiKey(Key),false); + } + + } + } +} diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/GUI/GuiVertexBufferStruct.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/GUI/GuiVertexBufferStruct.java new file mode 100644 index 0000000..74b4c01 --- /dev/null +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/GUI/GuiVertexBufferStruct.java @@ -0,0 +1,64 @@ +package net.halbear.Terrain4J.EngineCore.Vulkan.GUI; + +import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils; +import org.lwjgl.vulkan.VkPipelineVertexInputStateCreateInfo; +import org.lwjgl.vulkan.VkVertexInputAttributeDescription; +import org.lwjgl.vulkan.VkVertexInputBindingDescription; + +import static org.lwjgl.vulkan.VK10.*; + +public class GuiVertexBufferStruct { + + public static final int VERTEX_SIZE = VulkanUtils.FLOAT_SIZE * 5; + private static final int NUMBER_OF_ATTRIBUTES = 3; + + private final VkPipelineVertexInputStateCreateInfo VertexInput; + private final VkVertexInputAttributeDescription.Buffer VertexInputAttributes; + private final VkVertexInputBindingDescription.Buffer VertexInputBindings; + + public GuiVertexBufferStruct(){ + VertexInputAttributes = VkVertexInputAttributeDescription.calloc(NUMBER_OF_ATTRIBUTES); + VertexInputBindings = VkVertexInputBindingDescription.calloc(1); + VertexInput = VkPipelineVertexInputStateCreateInfo.calloc(); + int i = 0; + int offset = 0; + VertexInputAttributes.get(i) // Position + .binding(0) + .location(i) + .format(VK_FORMAT_R32G32_SFLOAT) + .offset(offset); + i++; + offset+= VulkanUtils.FLOAT_SIZE * 2; // Texture Coords Attribute + VertexInputAttributes.get(i) + .binding(0) + .location(i) + .format(VK_FORMAT_R32G32_SFLOAT) + .offset(offset); + i++; + offset+= VulkanUtils.FLOAT_SIZE * 2; // Colour Attribute + VertexInputAttributes.get(i) + .binding(0) + .location(i) + .format(VK_FORMAT_R8G8B8A8_UNORM) + .offset(offset); + + VertexInputBindings.get(0) + .binding(0) + .stride(VERTEX_SIZE) + .inputRate(VK_VERTEX_INPUT_RATE_VERTEX); + VertexInput + .sType(VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO) + .pVertexBindingDescriptions(VertexInputBindings) + .pVertexAttributeDescriptions(VertexInputAttributes); + } + + public VkPipelineVertexInputStateCreateInfo GetVertexInput(){ + return VertexInput; + } + + public void CleanUp(){ + VertexInputAttributes.free(); + VertexInputBindings.free(); + VertexInput.free(); + } +} diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/GraphUtils.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/GraphUtils.java index c2c15ad..f2b1a05 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/GraphUtils.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/GraphUtils.java @@ -35,7 +35,6 @@ public class GraphUtils { } newImage = new ImageSrc(image, width.get(0), height.get(0), channels.get(0)); } - Logger.debug("Loaded Buffer [{}]",image); return newImage ; } } diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/TextureCache.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/TextureCache.java index 8859b5c..19a4581 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/TextureCache.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/TextureCache.java @@ -92,7 +92,10 @@ public class TextureCache { TextureMap.forEach((key,value)->value.CleanUpStgBuffer(VkCtx)); Logger.debug("Recorded Texture Transition"); } - + public Texture GetTexture(String TexturePath){ + Logger.debug("Fetching Texture -> [{}]",TexturePath.trim()); + return TextureMap.get(TexturePath.trim()); + } public IndexedLinkedHashMap GetTextureCache(){return TextureMap;} public List GetTextureList(){return new ArrayList<>(TextureMap.values());} public int GetPosition(String ID){ diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/VoxelPipeline.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/VoxelPipeline.java deleted file mode 100644 index a0dac07..0000000 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/VoxelPipeline.java +++ /dev/null @@ -1,174 +0,0 @@ -package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline; - -import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext; -import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.DescriptorSetLayout; -import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.Device; -import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils; -import org.lwjgl.system.MemoryStack; -import org.lwjgl.vulkan.*; -import org.tinylog.Logger; - -import java.nio.LongBuffer; - -import static org.lwjgl.vulkan.VK10.*; - -public class VoxelPipeline implements Pipeline{ - private final long VulkanPipeline; - private final long VulkanPipelineLayout; - - public VoxelPipeline(VulkanContext VkCtx, PipelineBuildInfo BuildInfo){ - Device device = VkCtx.GetDevice(); - try(var MemStack = MemoryStack.stackPush()) { - LongBuffer longPtr = MemStack.mallocLong(1); - VkPushConstantRange.Buffer VkPushConstRangeBuffer = null; - PushConstantsRange[] PushConstRanges = BuildInfo.GetPushConstantRanges(); - int PushConstCount = PushConstRanges.length != 0 ? PushConstRanges.length : 0; - if (PushConstCount > 0) { - VkPushConstRangeBuffer = VkPushConstantRange.calloc(PushConstCount, MemStack); - for (int i = 0; i < PushConstCount; i++) { - PushConstantsRange pushConstantsRange = PushConstRanges[i]; - VkPushConstRangeBuffer.get(i) - .stageFlags(pushConstantsRange.Stage()) - .offset(pushConstantsRange.Offset()) - .size(pushConstantsRange.Size()); - } - } - DescriptorSetLayout[] descriptorSetLayouts = BuildInfo.GetDescriptorSetLayouts(); - int LayoutCount = descriptorSetLayouts != null ? descriptorSetLayouts.length : 0; - LongBuffer ppLayout = MemStack.mallocLong(LayoutCount); - for (int i = 0; i < LayoutCount; i++) { - ppLayout.put(i, descriptorSetLayouts[i].GetVkDescriptorLayout()); - } - - var PipelineLayoutCreateInfoPtr = VkPipelineLayoutCreateInfo.calloc(MemStack) - .sType$Default() - .pSetLayouts(ppLayout) - .pPushConstantRanges(VkPushConstRangeBuffer); - - VulkanUtils.vkCheck(vkCreatePipelineLayout(device.FetchVulkanDevice(), PipelineLayoutCreateInfoPtr, null, longPtr) - , "Unable to create new pipeline layout"); - VulkanPipelineLayout = longPtr.get(0); - VulkanPipeline = CreateVoxelPipeline(VkCtx,device.FetchVulkanDevice(), 0, VulkanPipelineLayout,MemStack); - } - } - - public static long CreatePipelineLayout(VkDevice device,LongBuffer DescriptorSetLayout, MemoryStack MemStack){ - VkDescriptorSetLayoutBinding.Buffer BindingBuffer = VkDescriptorSetLayoutBinding.calloc(2,MemStack); - BindingBuffer.get(0) - .binding(0) - .descriptorType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) - .descriptorCount(1) - .stageFlags(VK_SHADER_STAGE_VERTEX_BIT); - BindingBuffer.get(1) - .binding(1) - .descriptorType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) - .descriptorCount(1) - .stageFlags(VK_SHADER_STAGE_FRAGMENT_BIT); - VkDescriptorSetLayoutCreateInfo LayoutInfo = VkDescriptorSetLayoutCreateInfo.calloc(MemStack) - .sType$Default() - .pBindings(BindingBuffer); - - LongBuffer LongPtr = MemStack.mallocLong(1); - VulkanUtils.vkCheck(vkCreateDescriptorSetLayout(device, LayoutInfo, - null, LongPtr),"Could not create new Descriptor Set Layout"); - Long pDescriptorSetLayout = LongPtr.get(0); - DescriptorSetLayout.put(0,pDescriptorSetLayout); - LongBuffer LayoutPointer = MemStack.longs(pDescriptorSetLayout); - VkPipelineLayoutCreateInfo PipelineLayoutInfo = VkPipelineLayoutCreateInfo.calloc(MemStack) - .sType$Default() - .pSetLayouts(LayoutPointer); - VulkanUtils.vkCheck(vkCreatePipelineLayout(device, PipelineLayoutInfo, - null, LongPtr),"Could not create Pipeline Layout"); - return LongPtr.get(0); - } - - public static long CreateVoxelPipeline(VulkanContext VkCtx,VkDevice device, long RenderPass, long PipelineLayout, MemoryStack MemStack) { - LongBuffer longPtr = MemStack.mallocLong(1); - VkVertexInputBindingDescription.Buffer BindingDescriptionBuffer = VkVertexInputBindingDescription.calloc(1, MemStack) - .binding(0) - .stride(5) - .inputRate(VK_VERTEX_INPUT_RATE_VERTEX); - VkVertexInputAttributeDescription.Buffer AttributeDescriptionsBuffer = VkVertexInputAttributeDescription.calloc(2, MemStack); - - AttributeDescriptionsBuffer.get(0) - .location(0) - .binding(0) - .format(VK_FORMAT_R8G8B8_UINT) - .offset(0); - AttributeDescriptionsBuffer.get(1) - .location(1) - .binding(0) - .format(VK_FORMAT_R8G8_UINT); - VkPipelineVertexInputStateCreateInfo VertexInputInfo = VkPipelineVertexInputStateCreateInfo.calloc(MemStack) - .sType(VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO) - .pVertexBindingDescriptions(BindingDescriptionBuffer) - .pVertexAttributeDescriptions(AttributeDescriptionsBuffer); - var AssemblyStateCreateInfo = VkPipelineInputAssemblyStateCreateInfo.calloc(MemStack) - .sType(VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO) - .topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST).primitiveRestartEnable(false); - var ViewportCreateStateInfo = VkPipelineViewportStateCreateInfo.calloc(MemStack) - .sType$Default() - .viewportCount(1) - .scissorCount(1); - var RasterizationStateCreateInfo = VkPipelineRasterizationStateCreateInfo.calloc(MemStack) - .sType(VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO) - .depthClampEnable(false) - .rasterizerDiscardEnable(false) - .polygonMode(VK_POLYGON_MODE_FILL) - .cullMode(VK_CULL_MODE_BACK_BIT) - .frontFace(VK_FRONT_FACE_CLOCKWISE) - .lineWidth(1.0f) - .depthBiasEnable(false); - var MultisampleStateCreateInfo = VkPipelineMultisampleStateCreateInfo.calloc(MemStack) - .sType$Default() - .sampleShadingEnable(false) - .rasterizationSamples(VK_SAMPLE_COUNT_1_BIT); - VkPipelineColorBlendAttachmentState.Buffer ColourBlendAttachment = VkPipelineColorBlendAttachmentState.calloc(1, MemStack) - .colorWriteMask(VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT) - .blendEnable(false); - VkPipelineColorBlendStateCreateInfo ColourBlending = VkPipelineColorBlendStateCreateInfo.calloc(MemStack) - .sType(VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO) - .logicOpEnable(false) - .pAttachments(ColourBlendAttachment); - - VkGraphicsPipelineCreateInfo.Buffer PipelineInfo = VkGraphicsPipelineCreateInfo.calloc(1) - .sType(VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO) - .pVertexInputState(VertexInputInfo) - .pInputAssemblyState(AssemblyStateCreateInfo) - .pViewportState(ViewportCreateStateInfo) - .pRasterizationState(RasterizationStateCreateInfo) - .pMultisampleState(MultisampleStateCreateInfo) - .pColorBlendState(ColourBlending) - .layout(PipelineLayout) - .renderPass(RenderPass) - .subpass(0); - VulkanUtils.vkCheck(vkCreateGraphicsPipelines(device, - VkCtx.GetVkPipelineCache().GetVkPipelineCache(), PipelineInfo, - null, longPtr),"Could not create new pipeline"); - - // Clean up allocation structs - PipelineInfo.free(); ColourBlending.free(); ColourBlendAttachment.free(); - MultisampleStateCreateInfo.free(); RasterizationStateCreateInfo.free(); ViewportCreateStateInfo.free(); - AssemblyStateCreateInfo.free(); VertexInputInfo.free(); AssemblyStateCreateInfo.free(); - BindingDescriptionBuffer.free(); - - return longPtr.get(0); - } - @Override - public long GetVulkanPipeline() { - return VulkanPipeline; - } - - @Override - public long GetVulkanPipelineLayout() { - return VulkanPipelineLayout; - } - - @Override - public void CleanUp(VulkanContext VkCtx) { - Logger.debug("destroying Pipeline"); - VkDevice vkDevice = VkCtx.GetDevice().FetchVulkanDevice(); - vkDestroyPipelineLayout(vkDevice,VulkanPipelineLayout,null); - vkDestroyPipeline(vkDevice,VulkanPipeline,null); - } -} diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/VkModel/CompatibleVoxelMesh.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/VkModel/CompatibleVoxelMesh.java deleted file mode 100644 index 08e003f..0000000 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/VkModel/CompatibleVoxelMesh.java +++ /dev/null @@ -1,225 +0,0 @@ -package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel; - -import net.halbear.Terrain4J.EngineCore.Display.Render; -import net.halbear.Terrain4J.EngineCore.Logic.InitVoxelData; - -import org.joml.Vector4f; -import org.lwjgl.system.MemoryUtil; -import org.tinylog.Logger; - -import java.nio.FloatBuffer; -import java.nio.IntBuffer; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - - -public class CompatibleVoxelMesh { - private static final int VERTEX_STRIDE = 6; - public static List voxelModels = new ArrayList<>(); - public static List TexturePaths = new ArrayList<>(); - private Render renderInstance; - private float[] VertexArray; - private int[] IndicesArray; - private final String ID; - private boolean[] Faces = new boolean[]{false,false,false,false,false,false}; - private int[] Textureindex = new int[6]; - private Vector4f[] DiffuseColours = new Vector4f[]{new Vector4f(0.6f, 0.6f, 0.6f, 1.0f),new Vector4f(0.5f, 0.5f, 0.5f, 1.0f),new Vector4f(0.4f, 0.4f, 0.4f, 1.0f),new Vector4f(0.5f, 0.5f, 0.5f, 1.0f),new Vector4f(0.7f, 0.7f, 0.7f, 1.0f),new Vector4f(0.3f, 0.3f, 0.3f, 1.0f)}; - - static{ - TexturePaths.add("resources/EngineResources/Texture/DefaultTexture.png"); - } - - public enum FaceDirection{ - North(0), - South(2), - East(1), - West(3), - Up(4), - Down(5); - - private final int value; - - FaceDirection(int value) { - this.value = value; - } - - // 3. Add a getter method to access the number - public int getValue() { - return value; - } - } - - public record VoxelModelInitData(VoxelModelData voxelModel, List materialData){} - public record VoxelModelData(String ID, List meshes, FloatBuffer vertexBuffer, IntBuffer indexBuffer){} - public record VoxelMeshData(String ID, FloatBuffer vertexBuffer, IntBuffer indexBuffer, int VertexCount, int IndexCount){} - - public CompatibleVoxelMesh(String VoxelID){ - VertexArray = new float[6 * 20]; - IndicesArray = new int[6 * 6]; - ID = VoxelID; - } - public CompatibleVoxelMesh(Render rendererInstance, String VoxelID){ - renderInstance = rendererInstance; - VertexArray = new float[6 * 20]; - IndicesArray = new int[6 * 6]; - ID = VoxelID; - } - public CompatibleVoxelMesh SetSideTexture(int SideNumber, String TextureID){ - int index = TexturePaths.indexOf(TextureID); - if(index < 0){ - TexturePaths.add(TextureID); - index = TexturePaths.indexOf(TextureID); - } - Textureindex[SideNumber] = index; - return this; - } - - public CompatibleVoxelMesh CreateMeshFace(FaceDirection faceDirection, String TextureID){ - int side = faceDirection.getValue(); - Faces[side] = true; - - int index = TexturePaths.indexOf(TextureID); - if (index < 0) { - TexturePaths.add(TextureID); - index = TexturePaths.indexOf(TextureID); - } - Textureindex[side] = index; - - float[] srcFace = switch (faceDirection) { - case North -> FrontFace; - case South -> BackFace; - case East -> RightFace; - case West -> LeftFace; - case Up -> TopFace; - case Down -> BottomFace; - }; - - System.arraycopy(srcFace, 0, VertexArray, side * 20, 20); - return this; - } - - public static InitVoxelData GetVoxelModelsGenerated(){ - List models = new ArrayList<>(); - List materials = new ArrayList<>(); - for(int i = 0; i < voxelModels.size(); i++){ - models.add(voxelModels.get(i).voxelModel()); - materials.addAll(voxelModels.get(i).materialData()); - } - return new InitVoxelData(models,materials); - } - - public CompatibleVoxelMesh CompileMesh(){ - CompileMeshNoReturn(); - return this; - } - - public void CompileMeshNoReturn() { - List meshes = new ArrayList<>(); - List materials = new ArrayList<>(); - List AddedMaterials = new ArrayList<>(); - int faceCount = 0; - for (int i = 0; i < 6; i++) { - if (Faces[i]) { - faceCount++; - } - } - VoxelMeshData data = new VoxelMeshData(ID, MemoryUtil.memAllocFloat(20*faceCount), MemoryUtil.memAllocInt(6*faceCount), 4, 6); - float[] vertexArray = new float[faceCount * 20]; - faceCount = 0; - for(int i = 0; i < 6; i++){ - if(Faces[i]){ - String TextureID = "N/A_NULL"; - if(Textureindex[i] >= 0 && Textureindex[i] < TexturePaths.size()) TextureID = TexturePaths.get(Textureindex[i]); - else TextureID = "resources/EngineResources/Texture/DefaultTexture.png"; - if(!AddedMaterials.contains(TextureID)) { - materials.add(new MaterialData(TextureID, TextureID,DiffuseColours[i])); - AddedMaterials.add(TextureID); - } - for(int j = 0; j < 20; j++){ - vertexArray[(faceCount * 20) + j] = VertexArray[(i * 20) + j]; - } - if(!Objects.equals(TextureID, "N/A_NULL")){ - meshes.add(new MeshData(ID + "_" + i, TextureID,faceCount * 20, 20, faceCount * 6, 6)); - } - int offset = faceCount * 4; - data.indexBuffer.put(offset); - data.indexBuffer.put(offset + 1); - data.indexBuffer.put(offset + 2); - data.indexBuffer.put(offset + 2); - data.indexBuffer.put(offset + 3); - data.indexBuffer.put(offset); - faceCount++; - } - } - Logger.debug("Voxel with [{}] sides generated",faceCount); - data.indexBuffer.flip(); - data.vertexBuffer.put(vertexArray).flip(); - VoxelModelData model = new VoxelModelData(ID,meshes, data.vertexBuffer, data.indexBuffer); - voxelModels.add(new VoxelModelInitData(model, materials)); - } - - public float[] FetchFaceWithTexture(float TextureIndex, FaceDirection direction){ - float[] meshData = new float[20]; - this.Textureindex[direction.getValue()] = (int) TextureIndex; - switch (direction){ - case North -> { - System.arraycopy(FrontFace, 0, meshData, 0, 20); - } - case South -> { - System.arraycopy(BackFace, 0, meshData, 0, 20); - } - case East -> { - System.arraycopy(RightFace, 0, meshData, 0, 20); - } - case West -> { - System.arraycopy(LeftFace, 0, meshData, 0, 20); - } - case Up -> { - System.arraycopy(TopFace, 0, meshData, 0, 20); - } - case Down -> { - System.arraycopy(BottomFace, 0, meshData, 0, 20); - } - } - return meshData; - } - - public static final float[] FrontFace = new float[]{ - -0.5f, -0.5f, 0.5f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 1.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f - }; - public static final float[] BackFace = new float[]{ - 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, - -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, - -0.5f, 0.5f, -0.5f, 1.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f - }; - public static final float[] TopFace = new float[]{ - -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 0.0f - }; - public static final float[] BottomFace = new float[]{ - -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, - 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f - }; - public static final float[] LeftFace = new float[]{ - -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, - -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 0.0f - }; - public static final float[] RightFace = new float[]{ - 0.5f, -0.5f, 0.5f, 0.0f, 1.0f, - 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 0.0f - }; - -} diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/VkModel/MaterialsCache.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/VkModel/MaterialsCache.java index 2e1eb55..e83661d 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/VkModel/MaterialsCache.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/VkModel/MaterialsCache.java @@ -54,7 +54,6 @@ public class MaterialsCache { boolean ValidTexture = TexturePath != null && !TexturePath.isEmpty(); boolean TransparentTexture; if(ValidTexture){ - Logger.debug("Loading Texture [{}]",TexturePath); Texture newTexture = textureCache.AddTexture(VkCtx, TexturePath, TexturePath, VK_FORMAT_R8G8B8A8_SRGB); if(newTexture == null) { TransparentTexture = false; @@ -69,7 +68,6 @@ public class MaterialsCache { MaterialsMap.put(newMaterial.ID(), newMaterial); Logger.trace(Material.toString()); Material.DiffuseColour().get(Offset,data); - Logger.debug("Set Diffuse Colour -> [{}]",Material.DiffuseColour()); data.putInt(Offset + VulkanUtils.VEC4_SIZE, ValidTexture ? 1 : 0); data.putInt(Offset + VulkanUtils.VEC4_SIZE + VulkanUtils.INT_SIZE, textureCache.GetPosition(TexturePath)); //pad data because the minimum size of data in the shader layout is a multiple of Vec4, diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/VkModel/ModelsCache.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/VkModel/ModelsCache.java index 37705d6..dd134ac 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/VkModel/ModelsCache.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/VkModel/ModelsCache.java @@ -28,39 +28,6 @@ public class ModelsCache { ModelsMap = new HashMap<>(); } - public void loadVoxelModels(VulkanContext VkCtx, List Models, CommandPool commandPool, Queue queue){ - try { - List StagingBufferList = new ArrayList<>(); - var Command = new CommandBuffer(VkCtx, commandPool, true, true); - Command.BeginRecording(); - - for (CompatibleVoxelMesh.VoxelModelData modelData : Models) { - VulkanModel VKModel = new VulkanModel(modelData.ID()); - ModelsMap.put(VKModel.GetID(), VKModel); - - for (MeshData meshData : modelData.meshes()) { - TransferBuffer VerticesBuffers = CreateVoxelVerticesBuffer(VkCtx, meshData,modelData.vertexBuffer()); - TransferBuffer IndicesBuffers = CreateVoxelIndicesBuffer(VkCtx, meshData,modelData.indexBuffer()); - StagingBufferList.add(VerticesBuffers.SrcBuffer()); - StagingBufferList.add(IndicesBuffers.SrcBuffer()); - VerticesBuffers.RecordTransferCommand(Command); - IndicesBuffers.RecordTransferCommand(Command); - Logger.debug("Creating new Vulkan Mesh -> ID=[{}] MaterialID=[{}]",meshData.ID(),meshData.MaterialID()); - VulkanMesh VkMesh = new VulkanMesh(meshData.ID(), VerticesBuffers.DstBuffer(), IndicesBuffers.DstBuffer(), - meshData.IndexSize(), meshData.MaterialID()); - VKModel.GetVkMeshList().add(VkMesh); - } - } - Command.EndRecording(); - Command.SubmitAndWait(VkCtx,queue); - Command.cleanup(VkCtx,commandPool); - - StagingBufferList.forEach(b -> b.cleanup(VkCtx)); - } catch (Exception exception){ - throw new RuntimeException(exception); - } - } - public void loadModels(VulkanContext VkCtx, List Models, CommandPool commandPool, Queue queue){ try { List StagingBufferList = new ArrayList<>(); @@ -83,7 +50,6 @@ public class ModelsCache { StagingBufferList.add(IndicesBuffers.SrcBuffer()); VerticesBuffers.RecordTransferCommand(Command); IndicesBuffers.RecordTransferCommand(Command); - Logger.debug("Creating new Vulkan Mesh -> ID=[{}] MaterialID=[{}]",meshData.ID(),meshData.MaterialID()); VulkanMesh VkMesh = new VulkanMesh(meshData.ID(), VerticesBuffers.DstBuffer(), IndicesBuffers.DstBuffer(), meshData.IndexSize() / VulkanUtils.INT_SIZE, meshData.MaterialID()); VKModel.GetVkMeshList().add(VkMesh); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/DisplayToScreen/SceneRender.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/DisplayToScreen/SceneRender.java index 1b7a853..e1218d8 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/DisplayToScreen/SceneRender.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/DisplayToScreen/SceneRender.java @@ -79,7 +79,7 @@ public class SceneRender implements SceneRenderer {//dynamic rendering public SceneRender(VulkanContext vulkanContext){ ClearValueColour = VkClearValue.calloc().color( - c -> c.float32(0, R).float32(1, G).float32(2, B).float32(3, 1.0f)); + c -> c.float32(0, R).float32(1, G).float32(2, B).float32(3, 0.0f)); ClearValueDepth = VkClearValue.calloc().color(c -> c.float32(0, 0.0f)); AttachmentColour = CreateColourAttachment(vulkanContext); AttachmentDepth = CreateDepthAttachment(vulkanContext); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Util/VulkanBuffer.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Util/VulkanBuffer.java index 3af05c7..3fb1fba 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Util/VulkanBuffer.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Util/VulkanBuffer.java @@ -62,7 +62,6 @@ public class VulkanBuffer { MemoryUtil.memFree(pointerBuffer); UnMapMemory(vulkanContext); vmaDestroyBuffer(vulkanContext.GetVkMemoryAllocator().GetVmaAllocator(), Buffer, Allocation); - Logger.debug("Freed Vulkan Memory Buffer"); } public void Flush(VulkanContext VkCtx){ vmaFlushAllocation(VkCtx.GetVkMemoryAllocator().GetVmaAllocator(),Allocation,0,VK_WHOLE_SIZE); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Util/VulkanUtils.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Util/VulkanUtils.java index e9dfe30..59305b2 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Util/VulkanUtils.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Util/VulkanUtils.java @@ -32,6 +32,7 @@ public class VulkanUtils { public static final int MATRIX4X4_SIZE = 16 * FLOAT_SIZE; public static final int VEC4_SIZE = 4 * FLOAT_SIZE; public static final int VEC2_SIZE = 2 * FLOAT_SIZE; + public static final int SHORT_LENGTH = 2; public static void CopyMatrixToBuffer(VulkanContext VkCtx, VulkanBuffer VkBuffer, Matrix4f matrix, int Offset){ long MappedMemory = VkBuffer.MapMemory(VkCtx); diff --git a/src/main/resources/META-INF/native-image/net/halbear/jni-config.json b/src/main/resources/META-INF/native-image/net/halbear/jni-config.json new file mode 100644 index 0000000..17efea9 --- /dev/null +++ b/src/main/resources/META-INF/native-image/net/halbear/jni-config.json @@ -0,0 +1,307 @@ +[ + { + "name": "imgui.ImFontAtlas", + "methods": [ + { + "name": "createAlpha8Pixels", + "parameterTypes": [ + "int" + ] + }, + { + "name": "createRgba32Pixels", + "parameterTypes": [ + "int" + ] + } + ] + }, + { + "name": "imgui.ImVec2", + "fields": [ + { + "name": "x" + }, + { + "name": "y" + } + ] + }, + { + "name": "imgui.ImVec4", + "fields": [ + { + "name": "w" + }, + { + "name": "x" + }, + { + "name": "y" + }, + { + "name": "z" + } + ] + }, + { + "name": "imgui.assertion.ImAssertCallback", + "methods": [ + { + "name": "imAssert", + "parameterTypes": [ + "java.lang.String", + "int", + "java.lang.String" + ] + } + ] + }, + { + "name": "imgui.binding.ImGuiStruct", + "fields": [ + { + "name": "ptr" + } + ] + }, + { + "name": "imgui.callback.ImGuiInputTextCallback", + "methods": [ + { + "name": "accept", + "parameterTypes": [ + "long" + ] + } + ] + }, + { + "name": "imgui.callback.ImListClipperCallback", + "methods": [ + { + "name": "accept", + "parameterTypes": [ + "int" + ] + } + ] + }, + { + "name": "imgui.callback.ImPlatformFuncViewport", + "methods": [ + { + "name": "accept", + "parameterTypes": [ + "imgui.ImGuiViewport" + ] + } + ] + }, + { + "name": "imgui.callback.ImPlatformFuncViewportFloat", + "methods": [ + { + "name": "accept", + "parameterTypes": [ + "imgui.ImGuiViewport", + "float" + ] + } + ] + }, + { + "name": "imgui.callback.ImPlatformFuncViewportImVec2", + "methods": [ + { + "name": "accept", + "parameterTypes": [ + "imgui.ImGuiViewport", + "imgui.ImVec2" + ] + } + ] + }, + { + "name": "imgui.callback.ImPlatformFuncViewportString", + "methods": [ + { + "name": "accept", + "parameterTypes": [ + "imgui.ImGuiViewport", + "java.lang.String" + ] + } + ] + }, + { + "name": "imgui.callback.ImPlatformFuncViewportSuppBoolean", + "methods": [ + { + "name": "get", + "parameterTypes": [ + "imgui.ImGuiViewport" + ] + } + ] + }, + { + "name": "imgui.callback.ImPlatformFuncViewportSuppFloat", + "methods": [ + { + "name": "get", + "parameterTypes": [ + "imgui.ImGuiViewport" + ] + } + ] + }, + { + "name": "imgui.callback.ImPlatformFuncViewportSuppImVec2", + "methods": [ + { + "name": "get", + "parameterTypes": [ + "imgui.ImGuiViewport", + "imgui.ImVec2" + ] + } + ] + }, + { + "name": "imgui.callback.ImStrConsumer", + "methods": [ + { + "name": "accept", + "parameterTypes": [ + "java.lang.String" + ] + } + ] + }, + { + "name": "imgui.callback.ImStrSupplier", + "methods": [ + { + "name": "get", + "parameterTypes": [] + } + ] + }, + { + "name": "imgui.internal.ImRect", + "fields": [ + { + "name": "max" + }, + { + "name": "min" + } + ] + }, + { + "name": "imgui.type.ImString", + "methods": [ + { + "name": "resizeInternal", + "parameterTypes": [ + "int" + ] + } + ] + }, + { + "name": "imgui.type.ImString$InputData", + "fields": [ + { + "name": "isDirty" + }, + { + "name": "isResized" + }, + { + "name": "size" + } + ] + }, + { + "name": "java.lang.Boolean", + "methods": [ + { + "name": "getBoolean", + "parameterTypes": [ + "java.lang.String" + ] + } + ] + }, + { + "name": "org.lwjgl.system.CallbackI", + "methods": [ + { + "name": "callback", + "parameterTypes": [ + "long", + "long" + ] + } + ] + }, + { + "name": "org.vulkanb.Main", + "methods": [ + { + "name": "main", + "parameterTypes": [ + "java.lang.String[]" + ] + } + ] + }, + { + "name": "sun.launcher.LauncherHelper", + "fields": [ + { + "name": "isStaticMain" + }, + { + "name": "noArgMain" + } + ], + "methods": [ + { + "name": "getApplicationClass", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.management.VMManagementImpl", + "fields": [ + { + "name": "compTimeMonitoringSupport" + }, + { + "name": "currentThreadCpuTimeSupport" + }, + { + "name": "objectMonitorUsageSupport" + }, + { + "name": "otherThreadCpuTimeSupport" + }, + { + "name": "remoteDiagnosticCommandsSupport" + }, + { + "name": "synchronizerUsageSupport" + }, + { + "name": "threadAllocatedMemorySupport" + }, + { + "name": "threadContentionMonitoringSupport" + } + ] + } +] \ No newline at end of file