GUI, although images don't seem to render

This commit is contained in:
Halbear 2026-06-12 16:06:43 +01:00
parent 8ce30cae83
commit c9844fc415
26 changed files with 1032 additions and 488 deletions

View file

@ -3,12 +3,13 @@ plugins {
id 'application' id 'application'
id 'java' id 'java'
} }
project.ext.lwjglVersion = "3.3.6" project.ext.lwjglVersion = "3.4.1"
project.ext.jomlVersion = "1.10.8" project.ext.jomlVersion = "1.10.8"
project.ext.jomlprimitivesVersion = "1.10.0" project.ext.jomlprimitivesVersion = "1.10.0"
project.ext.lwjgl3awtVersion = "0.1.8" project.ext.lwjgl3awtVersion = "0.1.8"
project.ext.steamworks4jVersion = "1.9.0" project.ext.steamworks4jVersion = "1.9.0"
project.ext.steamworks4jserverVersion = "1.9.0" project.ext.steamworks4jserverVersion = "1.9.0"
project.ext.imguiVersion = "1.92.0"
switch (OperatingSystem.current()) { switch (OperatingSystem.current()) {
case OperatingSystem.LINUX: case OperatingSystem.LINUX:
@ -43,7 +44,6 @@ dependencies {
implementation 'org.tinylog:tinylog-impl:2.7.0' implementation 'org.tinylog:tinylog-impl:2.7.0'
implementation "org.lwjgl:lwjgl" implementation "org.lwjgl:lwjgl"
implementation "org.lwjgl:lwjgl-assimp" implementation "org.lwjgl:lwjgl-assimp"
implementation "org.lwjgl:lwjgl-cuda"
implementation "org.lwjgl:lwjgl-fmod" implementation "org.lwjgl:lwjgl-fmod"
implementation "org.lwjgl:lwjgl-freetype" implementation "org.lwjgl:lwjgl-freetype"
implementation "org.lwjgl:lwjgl-glfw" implementation "org.lwjgl:lwjgl-glfw"
@ -57,7 +57,6 @@ dependencies {
implementation "org.lwjgl:lwjgl-rpmalloc" implementation "org.lwjgl:lwjgl-rpmalloc"
implementation "org.lwjgl:lwjgl-shaderc" implementation "org.lwjgl:lwjgl-shaderc"
implementation "org.lwjgl:lwjgl-stb" implementation "org.lwjgl:lwjgl-stb"
implementation "org.lwjgl:lwjgl-tootle"
implementation "org.lwjgl:lwjgl-vma" implementation "org.lwjgl:lwjgl-vma"
implementation "org.lwjgl:lwjgl-vulkan" implementation "org.lwjgl:lwjgl-vulkan"
implementation "org.lwjgl:lwjgl::$lwjglNatives" implementation "org.lwjgl:lwjgl::$lwjglNatives"
@ -74,7 +73,6 @@ dependencies {
runtimeOnly "org.lwjgl:lwjgl-remotery:${lwjglVersion}:${lwjglNatives}" runtimeOnly "org.lwjgl:lwjgl-remotery:${lwjglVersion}:${lwjglNatives}"
implementation "org.lwjgl:lwjgl-shaderc::$lwjglNatives" implementation "org.lwjgl:lwjgl-shaderc::$lwjglNatives"
implementation "org.lwjgl:lwjgl-stb::$lwjglNatives" implementation "org.lwjgl:lwjgl-stb::$lwjglNatives"
implementation "org.lwjgl:lwjgl-tootle::$lwjglNatives"
implementation "org.lwjgl:lwjgl-vma::$lwjglNatives" implementation "org.lwjgl:lwjgl-vma::$lwjglNatives"
if (lwjglNatives == "natives-macos" || lwjglNatives == "natives-macos-arm64") implementation "org.lwjgl:lwjgl-vulkan::$lwjglNatives" if (lwjglNatives == "natives-macos" || lwjglNatives == "natives-macos-arm64") implementation "org.lwjgl:lwjgl-vulkan::$lwjglNatives"
implementation "org.joml:joml:${jomlVersion}" implementation "org.joml:joml:${jomlVersion}"
@ -84,4 +82,13 @@ dependencies {
implementation "com.code-disaster.steamworks4j:steamworks4j-server:${steamworks4jserverVersion}" implementation "com.code-disaster.steamworks4j:steamworks4j-server:${steamworks4jserverVersion}"
implementation 'com.google.code.gson:gson:2.14.0' implementation 'com.google.code.gson:gson:2.14.0'
implementation "org.jcommander:jcommander:3.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"
} }

View file

@ -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);
}

View file

@ -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);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 868 KiB

View file

@ -3,6 +3,8 @@ package net.halbear.Terrain4J.EngineCore.Display;
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance; import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
import net.halbear.Terrain4J.EngineCore.Logic.InitData; import net.halbear.Terrain4J.EngineCore.Logic.InitData;
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext; 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.Pipeline.Images.TextureCache;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.PostProcessing.PostProcess; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.PostProcessing.PostProcess;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.*; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.*;
@ -42,13 +44,12 @@ public class Render {
private final SceneRenderer sceneRender; private final SceneRenderer sceneRender;
private final PostProcess PostProcessor; private final PostProcess PostProcessor;
private final SwapChainRender swapChainRender; private final SwapChainRender swapChainRender;
private final GuiRenderer GuiRender;
private int CurrentFrame; private int CurrentFrame;
private final VulkanContext RendererContext; private final VulkanContext RendererContext;
private boolean Resize = false; private boolean Resize = false;
private List<MaterialData> Materials = new ArrayList<>(); private List<MaterialData> Materials = new ArrayList<>();
private List<ModelData> Models = new ArrayList<>(); private List<ModelData> Models = new ArrayList<>();
private List<CompatibleVoxelMesh.VoxelModelData> VoxelModels = new ArrayList<>();
private final MaterialsCache materialsCache; private final MaterialsCache materialsCache;
private TextureCache textureCache; private TextureCache textureCache;
@ -77,6 +78,7 @@ public class Render {
} }
sceneRender = new SceneRender(RendererContext); sceneRender = new SceneRender(RendererContext);
PostProcessor = new PostProcess(RendererContext,sceneRender.GetAttachmentColour()); PostProcessor = new PostProcess(RendererContext,sceneRender.GetAttachmentColour());
GuiRender = new GuiRenderer(engineInstance, RendererContext, GraphicsQueue, PostProcessor.GetAttachment());
swapChainRender = new SwapChainRender(RendererContext,PostProcessor.GetAttachment()); swapChainRender = new SwapChainRender(RendererContext,PostProcessor.GetAttachment());
textureCache = new TextureCache(); textureCache = new TextureCache();
materialsCache = new MaterialsCache(); materialsCache = new MaterialsCache();
@ -103,13 +105,18 @@ public class Render {
modelsCache.loadModels(RendererContext, Models, CommandPools[0], GraphicsQueue); modelsCache.loadModels(RendererContext, Models, CommandPools[0], GraphicsQueue);
Logger.debug("Loaded {} models", Models.size()); Logger.debug("Loaded {} models", Models.size());
VoxelModels.addAll(initData.voxelModels()); List<GuiTexture> guiTextures = initData.GuiTextures();
Logger.debug("Loading {} Voxel models", VoxelModels.size()); if(guiTextures != null){
modelsCache.loadVoxelModels(RendererContext, VoxelModels, CommandPools[0], GraphicsQueue); initData.GuiTextures().forEach(texture -> textureCache.AddTexture(RendererContext, texture.TexturePath(), texture.TexturePath(), VK_FORMAT_R8G8B8A8_SRGB));
Logger.debug("Loaded {} Voxel models", VoxelModels.size()); }
sceneRender.LoadMaterials(RendererContext,materialsCache,textureCache); 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){ private void RecordingStart(CommandPool commandPool, CommandBuffer commandBuffer){
commandPool.Reset(RendererContext); commandPool.Reset(RendererContext);
commandBuffer.BeginRecording(); commandBuffer.BeginRecording();
@ -125,6 +132,7 @@ public class Render {
sceneRender.cleanup(RendererContext); sceneRender.cleanup(RendererContext);
PostProcessor.CleanUp(RendererContext); PostProcessor.CleanUp(RendererContext);
swapChainRender.CleanUp(RendererContext); swapChainRender.CleanUp(RendererContext);
GuiRender.CleanUp(RendererContext);
Logger.debug("Dynamic Renderer Cleaned up"); Logger.debug("Dynamic Renderer Cleaned up");
Arrays.asList(RenderCompleteSemaphores).forEach(i->i.cleanup(RendererContext)); Arrays.asList(RenderCompleteSemaphores).forEach(i->i.cleanup(RendererContext));
Logger.debug("Render Semaphores cleaned up"); Logger.debug("Render Semaphores cleaned up");
@ -151,8 +159,9 @@ public class Render {
sceneRender.Render(engineInstance,RendererContext,CommandBuffer, modelsCache,materialsCache,CurrentFrame); sceneRender.Render(engineInstance,RendererContext,CommandBuffer, modelsCache,materialsCache,CurrentFrame);
PostProcessor.Render(RendererContext,CommandBuffer,sceneRender.GetAttachmentColour()); 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){ if (Resize || (ImageIndex = swapChain.FetchNextImage(RendererContext.GetDevice(), PresentCompleteSemaphores[CurrentFrame])) < 0){
resize(engineInstance); resize(engineInstance);
return; return;
@ -188,6 +197,7 @@ public class Render {
engineInstance.scene().GetProjection().Resize(extend.width(),extend.height()); engineInstance.scene().GetProjection().Resize(extend.width(),extend.height());
sceneRender.Resize(engineInstance,RendererContext); sceneRender.Resize(engineInstance,RendererContext);
PostProcessor.Resize(RendererContext,sceneRender.GetAttachmentColour()); PostProcessor.Resize(RendererContext,sceneRender.GetAttachmentColour());
GuiRender.Resize(RendererContext,PostProcessor.GetAttachment());
swapChainRender.Resize(RendererContext,PostProcessor.GetAttachment()); swapChainRender.Resize(RendererContext,PostProcessor.GetAttachment());
} }

View file

@ -1,7 +1,6 @@
package net.halbear.Terrain4J.EngineCore.Input; package net.halbear.Terrain4J.EngineCore.Input;
import org.lwjgl.glfw.GLFWCharCallbackI; import org.lwjgl.glfw.GLFWCharCallbackI;
import org.lwjgl.glfw.GLFWKeyCallback;
import org.lwjgl.glfw.GLFWKeyCallbackI; import org.lwjgl.glfw.GLFWKeyCallbackI;
import java.util.ArrayList; import java.util.ArrayList;
@ -11,14 +10,18 @@ import java.util.Map;
import static org.lwjgl.glfw.GLFW.*; import static org.lwjgl.glfw.GLFW.*;
public class KeyboardInput { public class KeyboardInput implements GLFWKeyCallbackI {
private long window; private long window;
private final Map<Integer, Boolean> SinglePressKeyMap;
private List<GLFWKeyCallbackI> Callbacks;
public List<Integer> keysPressed = new ArrayList<>(); public List<Integer> keysPressed = new ArrayList<>();
public List<Integer> keysSinglePressed = new ArrayList<>(); public List<Integer> keysSinglePressed = new ArrayList<>();
public KeyboardInput(long Window){ public KeyboardInput(long Window){
window = Window; window = Window;
SinglePressKeyMap = new HashMap<>();
Callbacks = new ArrayList<>();
glfwSetKeyCallback(window, this::KeyCallback); glfwSetKeyCallback(window, this::KeyCallback);
} }
public void input() { public void input() {
@ -34,6 +37,19 @@ public class KeyboardInput {
} }
if (keysSinglePressed.contains(key)&& action == GLFW_RELEASE) keysSinglePressed.remove(keysSinglePressed.indexOf(key)); 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) { public boolean keyPressed(int keyCode) {
if (keysPressed.contains(keyCode)) return true; if (keysPressed.contains(keyCode)) return true;
else return false; else return false;
@ -55,4 +71,5 @@ public class KeyboardInput {
public void setCharCallBack(GLFWCharCallbackI charCallback) { public void setCharCallBack(GLFWCharCallbackI charCallback) {
glfwSetCharCallback(window, charCallback); glfwSetCharCallback(window, charCallback);
} }
} }

View file

@ -3,6 +3,9 @@ package net.halbear.Terrain4J.EngineCore.Logic;
public interface GameLogic { public interface GameLogic {
void cleanup(); void cleanup();
InitData Initialise(EngineInstance engineInstance); InitData Initialise(EngineInstance engineInstance);
void RenderThreadInput(EngineInstance engineInstance, long FrameDiffNanoSeconds);
void Input(EngineInstance engineInstance, long FrameDiffNanoSeconds); void Input(EngineInstance engineInstance, long FrameDiffNanoSeconds);
void CameraInput(EngineInstance engineInstance, long FrameDiffNanoSeconds); void CameraInput(EngineInstance engineInstance, long FrameDiffNanoSeconds);
void Update(EngineInstance engineInstance, long FrameDiffNanoSeconds); void Update(EngineInstance engineInstance, long FrameDiffNanoSeconds);

View file

@ -1,10 +1,10 @@
package net.halbear.Terrain4J.EngineCore.Logic; 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.MaterialData;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.ModelData; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.ModelData;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.CompatibleVoxelMesh;
import java.util.List; import java.util.List;
public record InitData(List<ModelData> Models, List<CompatibleVoxelMesh.VoxelModelData> voxelModels, List<MaterialData> Materials) { public record InitData(List<ModelData> Models, List<MaterialData> Materials, List<GuiTexture> GuiTextures) {
} }

View file

@ -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<CompatibleVoxelMesh.VoxelModelData> Models, List<MaterialData> Materials) {
}

View file

@ -1,5 +1,9 @@
package net.halbear.Terrain4J.EngineCore.Main; 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.Display.Window;
import net.halbear.Terrain4J.EngineCore.Input.KeyboardInput; import net.halbear.Terrain4J.EngineCore.Input.KeyboardInput;
import net.halbear.Terrain4J.EngineCore.Input.MouseListener; 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.Actor;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Camera; import net.halbear.Terrain4J.EngineCore.Main.Scene.Camera;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Scene; 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.MaterialData;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.ModelData; 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.Vector2f;
import org.joml.Vector3f; import org.joml.Vector3f;
import org.tinylog.Logger;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -34,6 +36,8 @@ public class GameCore implements GameLogic {
private List<Actor> CubeActors = new ArrayList<>(); private List<Actor> CubeActors = new ArrayList<>();
private Vector2f LastMousePos = new Vector2f(0,0); private Vector2f LastMousePos = new Vector2f(0,0);
private int Ticks = 0; private int Ticks = 0;
private int GUI_MODE = 0;
private GuiTexture guiTexture;
@Override @Override
public void cleanup() { public void cleanup() {
@ -42,35 +46,24 @@ public class GameCore implements GameLogic {
@Override @Override
public InitData Initialise(EngineInstance engineInstance) { 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<CompatibleVoxelMesh.VoxelModelData> VoxelModels = Voxels.Models();
for(int i = 0; i < VoxelModels.size(); i++){
Logger.debug("Voxel -> [{}]",VoxelModels.get(i).ID());
}
Scene scene = engineInstance.scene(); Scene scene = engineInstance.scene();
List<ModelData> models = new ArrayList<>(); List<ModelData> models = new ArrayList<>();
//ModelData SponzaData = ModelLoader.LoadModel("resources/models/Unit02/evangelion_unit-02.json"); //ModelData SponzaData = ModelLoader.LoadModel("resources/models/Unit02/evangelion_unit-02.json");
//List<MaterialData> SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Unit02/evangelion_unit-02_mat.json"); //List<MaterialData> SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Unit02/evangelion_unit-02_mat.json");
ModelData SponzaData = ModelLoader.LoadModel("resources/models/Sponza/Sponza.json"); //ModelData SponzaData = ModelLoader.LoadModel("resources/models/Cafe/exterior.json");
List<MaterialData> SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Sponza/Sponza_mat.json"); //List<MaterialData> SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Cafe/exterior_mat.json");
scene.AddActor(new Actor("Sponza", SponzaData.ID(), new Vector3f(0,0,-5f))); // ModelData SponzaData1 = ModelLoader.LoadModel("resources/models/Cafe/interior.json");
// List<MaterialData> 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/Metro/OBJ/MetroLeadCar.json"));
models.add(ModelLoader.LoadModel("resources/models/melona/melona.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/Alice/Welsh040Alice.json"));
models.add(ModelLoader.LoadModel("resources/models/Sloop/SloopOBJ.json")); models.add(ModelLoader.LoadModel("resources/models/Sloop/SloopOBJ.json"));
models.add(ModelLoader.LoadModel("resources/models/Corvette/corvetteclass.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)))); 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)); angles.add((float)(Math.random() * 360));
rotatingAngles.add(new Vector3f((float)(Math.random()*2), (float)(Math.random()*2), (float)(Math.random()*2))); 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/melona/melona_mat.json"));
materials.addAll(ModelLoader.LoadMaterials("resources/models/Alice/Welsh040Alice_mat.json")); materials.addAll(ModelLoader.LoadMaterials("resources/models/Alice/Welsh040Alice_mat.json"));
materials.addAll(ModelLoader.LoadMaterials("resources/models/Sloop/SloopOBJ_mat.json")); materials.addAll(ModelLoader.LoadMaterials("resources/models/Sloop/SloopOBJ_mat.json"));
materials.addAll(SponzaMaterial); // materials.addAll(SponzaMaterial);
materials.addAll(Voxels.Materials()); //materials.addAll(SponzaMaterial1);
models.add(SponzaData); //models.add(SponzaData);
//models.add(SponzaData1);
Camera camera = scene.GetCamera(); Camera camera = scene.GetCamera();
camera.SetPosition(40.0f, 155.0f, -42.0f); camera.SetPosition(40.0f, 155.0f, -42.0f);
camera.SetPosition(0,0,0); camera.SetPosition(0,0,0);
camera.SetRotation((float) Math.toRadians(10.0f), (float) Math.toRadians(-90.0f),0); camera.SetRotation((float) Math.toRadians(10.0f), (float) Math.toRadians(-90.0f),0);
camera.SetRotation(0,0,0); camera.SetRotation(0,0,0);
return new InitData(models,VoxelModels,materials);
guiTexture = new GuiTexture("resources/EngineResources/Texture/DefaultTexture.png");
List<GuiTexture> guiTextures = new ArrayList<>();
guiTextures.add(guiTexture);
return new InitData(models,materials,guiTextures);
} }
@Override @Override
@ -119,6 +118,11 @@ public class GameCore implements GameLogic {
} }
} }
@Override
public void RenderThreadInput(EngineInstance engineInstance, long FrameDiffNanoSeconds) {
HandleGui(engineInstance);
}
@Override @Override
public void Input(EngineInstance engineInstance, long FrameDiffNanoSeconds) { public void Input(EngineInstance engineInstance, long FrameDiffNanoSeconds) {
Scene scene = engineInstance.scene(); Scene scene = engineInstance.scene();
@ -127,6 +131,15 @@ public class GameCore implements GameLogic {
KeyboardInput input = window.getKeyboardInput(); KeyboardInput input = window.getKeyboardInput();
float MovementDist = (float)(FrameDiffNanoSeconds / 1000000L) * MOVEMENT_SPEED; float MovementDist = (float)(FrameDiffNanoSeconds / 1000000L) * MOVEMENT_SPEED;
Camera camera = scene.GetCamera(); 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)){ if(input.keyPressed(GLFW_KEY_W)){
camera.MoveForward(MovementDist); camera.MoveForward(MovementDist);
} }
@ -145,6 +158,39 @@ public class GameCore implements GameLogic {
if(input.keyPressed(GLFW_KEY_LEFT_SHIFT)){ if(input.keyPressed(GLFW_KEY_LEFT_SHIFT)){
camera.MoveDown(MovementDist); 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 @Override

View file

@ -10,6 +10,7 @@ public class Camera {
private final Vector3f Rotation; private final Vector3f Rotation;
private final Vector3f Up; private final Vector3f Up;
private final Matrix4f ViewMatrix; private final Matrix4f ViewMatrix;
private boolean Sprint;
public Camera(){ public Camera(){
Direction = new Vector3f(); Direction = new Vector3f();
@ -19,6 +20,11 @@ public class Camera {
Up = new Vector3f(); Up = new Vector3f();
ViewMatrix = new Matrix4f(); 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 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();} 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){ public void MoveForward(float Distance){
if(Sprint) Distance *=2;
ViewMatrix.positiveZ(Direction).negate().mul(Distance); ViewMatrix.positiveZ(Direction).negate().mul(Distance);
Position.add(Direction); Position.add(Direction);
Recalculate(); Recalculate();
} }
public void MoveBackward(float Distance){ public void MoveBackward(float Distance){
if(Sprint) Distance *=2;
ViewMatrix.positiveZ(Direction).negate().mul(Distance); ViewMatrix.positiveZ(Direction).negate().mul(Distance);
Position.sub(Direction); Position.sub(Direction);
Recalculate(); Recalculate();
} }
public void MoveUp(float Distance){ public void MoveUp(float Distance){
if(Sprint) Distance *=2;
ViewMatrix.positiveY(Up).negate().mul(Distance); ViewMatrix.positiveY(Up).negate().mul(Distance);
Position.sub(Up); Position.sub(Up);
Recalculate(); Recalculate();
} }
public void MoveDown(float Distance){ public void MoveDown(float Distance){
if(Sprint) Distance *=2;
ViewMatrix.positiveY(Up).negate().mul(Distance); ViewMatrix.positiveY(Up).negate().mul(Distance);
Position.add(Up); Position.add(Up);
Recalculate(); Recalculate();
} }
public void MoveLeft(float Distance){ public void MoveLeft(float Distance){
if(Sprint) Distance *=2;
ViewMatrix.positiveX(Right).negate().mul(Distance); ViewMatrix.positiveX(Right).negate().mul(Distance);
Position.add(Right); Position.add(Right);
Recalculate(); Recalculate();
} }
public void MoveRight(float Distance){ public void MoveRight(float Distance){
if(Sprint) Distance *=2;
ViewMatrix.positiveX(Right).negate().mul(Distance); ViewMatrix.positiveX(Right).negate().mul(Distance);
Position.sub(Right); Position.sub(Right);
Recalculate(); Recalculate();

View file

@ -25,6 +25,7 @@ public class RenderThread extends EngineThread {
} }
@Override @Override
public void FrameEvent(long now, long InitialTime){ public void FrameEvent(long now, long InitialTime){
gameLogic.RenderThreadInput(PrimaryRuntime.GetEngineInstance(), (now-InitialTime));
gameLogic.Update(PrimaryRuntime.GetEngineInstance(), (now - InitialTime)); gameLogic.Update(PrimaryRuntime.GetEngineInstance(), (now - InitialTime));
render.render(PrimaryRuntime.GetEngineInstance()); render.render(PrimaryRuntime.GetEngineInstance());
} }

View file

@ -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<Long,Long> 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<GuiTexture> 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();
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}
}
}

View file

@ -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();
}
}

View file

@ -35,7 +35,6 @@ public class GraphUtils {
} }
newImage = new ImageSrc(image, width.get(0), height.get(0), channels.get(0)); newImage = new ImageSrc(image, width.get(0), height.get(0), channels.get(0));
} }
Logger.debug("Loaded Buffer [{}]",image);
return newImage ; return newImage ;
} }
} }

View file

@ -92,7 +92,10 @@ public class TextureCache {
TextureMap.forEach((key,value)->value.CleanUpStgBuffer(VkCtx)); TextureMap.forEach((key,value)->value.CleanUpStgBuffer(VkCtx));
Logger.debug("Recorded Texture Transition"); Logger.debug("Recorded Texture Transition");
} }
public Texture GetTexture(String TexturePath){
Logger.debug("Fetching Texture -> [{}]",TexturePath.trim());
return TextureMap.get(TexturePath.trim());
}
public IndexedLinkedHashMap<String, Texture> GetTextureCache(){return TextureMap;} public IndexedLinkedHashMap<String, Texture> GetTextureCache(){return TextureMap;}
public List<Texture> GetTextureList(){return new ArrayList<>(TextureMap.values());} public List<Texture> GetTextureList(){return new ArrayList<>(TextureMap.values());}
public int GetPosition(String ID){ public int GetPosition(String ID){

View file

@ -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);
}
}

View file

@ -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<VoxelModelInitData> voxelModels = new ArrayList<>();
public static List<String> 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> materialData){}
public record VoxelModelData(String ID, List<MeshData> 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<VoxelModelData> models = new ArrayList<>();
List<MaterialData> 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<MeshData> meshes = new ArrayList<>();
List<MaterialData> materials = new ArrayList<>();
List<String> 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
};
}

View file

@ -54,7 +54,6 @@ public class MaterialsCache {
boolean ValidTexture = TexturePath != null && !TexturePath.isEmpty(); boolean ValidTexture = TexturePath != null && !TexturePath.isEmpty();
boolean TransparentTexture; boolean TransparentTexture;
if(ValidTexture){ if(ValidTexture){
Logger.debug("Loading Texture [{}]",TexturePath);
Texture newTexture = textureCache.AddTexture(VkCtx, TexturePath, TexturePath, VK_FORMAT_R8G8B8A8_SRGB); Texture newTexture = textureCache.AddTexture(VkCtx, TexturePath, TexturePath, VK_FORMAT_R8G8B8A8_SRGB);
if(newTexture == null) { if(newTexture == null) {
TransparentTexture = false; TransparentTexture = false;
@ -69,7 +68,6 @@ public class MaterialsCache {
MaterialsMap.put(newMaterial.ID(), newMaterial); MaterialsMap.put(newMaterial.ID(), newMaterial);
Logger.trace(Material.toString()); Logger.trace(Material.toString());
Material.DiffuseColour().get(Offset,data); 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, ValidTexture ? 1 : 0);
data.putInt(Offset + VulkanUtils.VEC4_SIZE + VulkanUtils.INT_SIZE, textureCache.GetPosition(TexturePath)); 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, //pad data because the minimum size of data in the shader layout is a multiple of Vec4,

View file

@ -28,39 +28,6 @@ public class ModelsCache {
ModelsMap = new HashMap<>(); ModelsMap = new HashMap<>();
} }
public void loadVoxelModels(VulkanContext VkCtx, List<CompatibleVoxelMesh.VoxelModelData> Models, CommandPool commandPool, Queue queue){
try {
List<VulkanBuffer> 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<ModelData> Models, CommandPool commandPool, Queue queue){ public void loadModels(VulkanContext VkCtx, List<ModelData> Models, CommandPool commandPool, Queue queue){
try { try {
List<VulkanBuffer> StagingBufferList = new ArrayList<>(); List<VulkanBuffer> StagingBufferList = new ArrayList<>();
@ -83,7 +50,6 @@ public class ModelsCache {
StagingBufferList.add(IndicesBuffers.SrcBuffer()); StagingBufferList.add(IndicesBuffers.SrcBuffer());
VerticesBuffers.RecordTransferCommand(Command); VerticesBuffers.RecordTransferCommand(Command);
IndicesBuffers.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(), VulkanMesh VkMesh = new VulkanMesh(meshData.ID(), VerticesBuffers.DstBuffer(), IndicesBuffers.DstBuffer(),
meshData.IndexSize() / VulkanUtils.INT_SIZE, meshData.MaterialID()); meshData.IndexSize() / VulkanUtils.INT_SIZE, meshData.MaterialID());
VKModel.GetVkMeshList().add(VkMesh); VKModel.GetVkMeshList().add(VkMesh);

View file

@ -79,7 +79,7 @@ public class SceneRender implements SceneRenderer {//dynamic rendering
public SceneRender(VulkanContext vulkanContext){ public SceneRender(VulkanContext vulkanContext){
ClearValueColour = VkClearValue.calloc().color( 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)); ClearValueDepth = VkClearValue.calloc().color(c -> c.float32(0, 0.0f));
AttachmentColour = CreateColourAttachment(vulkanContext); AttachmentColour = CreateColourAttachment(vulkanContext);
AttachmentDepth = CreateDepthAttachment(vulkanContext); AttachmentDepth = CreateDepthAttachment(vulkanContext);

View file

@ -62,7 +62,6 @@ public class VulkanBuffer {
MemoryUtil.memFree(pointerBuffer); MemoryUtil.memFree(pointerBuffer);
UnMapMemory(vulkanContext); UnMapMemory(vulkanContext);
vmaDestroyBuffer(vulkanContext.GetVkMemoryAllocator().GetVmaAllocator(), Buffer, Allocation); vmaDestroyBuffer(vulkanContext.GetVkMemoryAllocator().GetVmaAllocator(), Buffer, Allocation);
Logger.debug("Freed Vulkan Memory Buffer");
} }
public void Flush(VulkanContext VkCtx){ public void Flush(VulkanContext VkCtx){
vmaFlushAllocation(VkCtx.GetVkMemoryAllocator().GetVmaAllocator(),Allocation,0,VK_WHOLE_SIZE); vmaFlushAllocation(VkCtx.GetVkMemoryAllocator().GetVmaAllocator(),Allocation,0,VK_WHOLE_SIZE);

View file

@ -32,6 +32,7 @@ public class VulkanUtils {
public static final int MATRIX4X4_SIZE = 16 * FLOAT_SIZE; public static final int MATRIX4X4_SIZE = 16 * FLOAT_SIZE;
public static final int VEC4_SIZE = 4 * FLOAT_SIZE; public static final int VEC4_SIZE = 4 * FLOAT_SIZE;
public static final int VEC2_SIZE = 2 * 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){ public static void CopyMatrixToBuffer(VulkanContext VkCtx, VulkanBuffer VkBuffer, Matrix4f matrix, int Offset){
long MappedMemory = VkBuffer.MapMemory(VkCtx); long MappedMemory = VkBuffer.MapMemory(VkCtx);

View file

@ -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"
}
]
}
]