From 84020a922b99f70de2e4b122d53fbb1daaa18054 Mon Sep 17 00:00:00 2001 From: Halbear Date: Mon, 18 May 2026 14:55:43 +0100 Subject: [PATCH] Working towards 3D rendering --- .../Terrain4J/EngineCore/Display/Render.java | 36 +++++- .../EngineCore/Logic/EngineConfig.java | 16 ++- .../EngineCore/Logic/EngineInstance.java | 2 +- .../EngineCore/Logic/VulkanContext.java | 8 +- .../EngineCore/Main/PrimaryRuntime.java | 1 + .../Terrain4J/EngineCore/Main/Scene.java | 8 -- .../EngineCore/Main/Scene/Actor.java | 54 ++++++++ .../EngineCore/Main/Scene/Scene.java | 27 ++++ .../EngineCore/Threads/MainThread.java | 3 - .../EngineCore/Vulkan/Rendering/Image.java | 8 -- .../Rendering/Pipeline/Images/Attachment.java | 38 ++++++ .../Rendering/Pipeline/Images/Image.java | 116 ++++++++++++++++++ .../Vulkan/Rendering/Pipeline/Pipeline.java | 35 +++++- .../Rendering/Pipeline/PipelineBuildInfo.java | 19 +++ .../Pipeline/PushConstantsRange.java | 4 + .../Rendering/Projection/Project3D.java | 33 +++++ .../Rendering/VertexBufferStructure.java | 16 ++- .../Vulkan/Rendering/VkModel/MeshData.java | 2 +- .../Vulkan/Rendering/VkModel/ModelsCache.java | 9 +- .../DisplayToScreen/SceneRender.java | 85 +++++++++++-- .../EngineCore/Vulkan/Util/VulkanUtils.java | 1 + terrain4j.properties | 7 +- 22 files changed, 486 insertions(+), 42 deletions(-) delete mode 100644 src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene.java create mode 100644 src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/Actor.java create mode 100644 src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/Scene.java delete mode 100644 src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Image.java create mode 100644 src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/Attachment.java create mode 100644 src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/Image.java create mode 100644 src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/PushConstantsRange.java create mode 100644 src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Projection/Project3D.java 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 6e6f94b..99a932d 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Display/Render.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Display/Render.java @@ -16,6 +16,7 @@ import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.SwapCha import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils; import org.lwjgl.system.MemoryStack; import org.lwjgl.vulkan.VkCommandBufferSubmitInfo; +import org.lwjgl.vulkan.VkExtent2D; import org.lwjgl.vulkan.VkSemaphoreSubmitInfo; import org.tinylog.Logger; @@ -39,6 +40,7 @@ public class Render { private final SceneRender sceneRender; private int CurrentFrame; private final VulkanContext RendererContext; + private boolean Resize = false; public Render(EngineInstance engineInstance) { RendererContext = new VulkanContext(engineInstance.window()); @@ -62,6 +64,7 @@ public class Render { } sceneRender = new SceneRender(RendererContext); modelsCache = new ModelsCache(); + Resize = false; } public void Initialise(InitData initData){ @@ -105,16 +108,41 @@ public class Render { var CommandPool = CommandPools[CurrentFrame]; var CommandBuffer = CommandBuffers[CurrentFrame]; RecordingStart(CommandPool, CommandBuffer); - int ImageIndex = swapChain.FetchNextImage(RendererContext.GetDevice(), PresentCompleteSemaphores[CurrentFrame]); - if (ImageIndex < 0){ + int ImageIndex;// = swapChain.FetchNextImage(RendererContext.GetDevice(), PresentCompleteSemaphores[CurrentFrame]); + if (Resize || (ImageIndex = swapChain.FetchNextImage(RendererContext.GetDevice(), PresentCompleteSemaphores[CurrentFrame])) < 0){ + resize(engineInstance); return; } - sceneRender.Render(RendererContext,CommandBuffer, modelsCache,ImageIndex); + sceneRender.Render(engineInstance,RendererContext,CommandBuffer, modelsCache,ImageIndex); RecordingStop(CommandBuffer); Submit(CommandBuffer, CurrentFrame, ImageIndex); - swapChain.PresentImage(PresentQueue, RenderCompleteSemaphores[ImageIndex],ImageIndex); + Resize = swapChain.PresentImage(PresentQueue, RenderCompleteSemaphores[ImageIndex],ImageIndex); CurrentFrame = (CurrentFrame + 1) % VulkanUtils.MAX_IN_FLIGHT; } + + private void resize(EngineInstance engineInstance){ + Window window = engineInstance.window(); + if(window.getWidth() == 0 && window.getHeight() == 0){ + return; + } + Resize = false; + RendererContext.GetDevice().waitIdle(); + RendererContext.Resize(window); + + Arrays.asList(RenderCompleteSemaphores).forEach(i->i.cleanup(RendererContext)); + Arrays.asList(PresentCompleteSemaphores).forEach(i->i.cleanup(RendererContext)); + for(int i = 0; i < VulkanUtils.MAX_IN_FLIGHT; i++){ + PresentCompleteSemaphores[i] = new Semaphore(RendererContext); + } + for(int i = 0; i < RendererContext.GetSwapChain().GetImageCount(); i++){ + RenderCompleteSemaphores[i] = new Semaphore(RendererContext); + } + + VkExtent2D extend = RendererContext.GetSwapChain().GetSwapChainExtent(); + engineInstance.scene().GetProjection().Resize(extend.width(),extend.height()); + sceneRender.Resize(RendererContext); + } + private void ResetFence(int currentFrame){ var fence = Fences[currentFrame]; fence.Reset(RendererContext); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/EngineConfig.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/EngineConfig.java index 1b60456..93f09a4 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/EngineConfig.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/EngineConfig.java @@ -9,6 +9,8 @@ import java.nio.file.Paths; import java.util.Properties; public class EngineConfig { + public static final double DegToRad = Math.PI/180.0; + public static final double RadToDeg = 180.0/Math.PI; private static final long DEFAULT_ACCURACY = 0; private static final int DEFAULT_TICKRATE = 60; private static final int DEFAULT_WIDTH = 640; @@ -43,6 +45,10 @@ public class EngineConfig { private int RequestedImages; private String IconPath = "/WindowResources/Icon/"; private String IconName = "ProgramIcon.png"; + private float FOV = 60f; + private float zFarPlane; + private float zNearPlane; + private EngineConfig() { var EngineConfigVar = new Properties(); @@ -102,6 +108,9 @@ public class EngineConfig { RequestedImages = Integer.parseInt(EngineConfigVar.getOrDefault("RequestedImages", 3).toString()); ShaderDebug =Boolean.parseBoolean(EngineConfigVar.getOrDefault("Debug_Shaders", false).toString()); RecompileShaders =Boolean.parseBoolean(EngineConfigVar.getOrDefault("ShaderRecompiling", true).toString()); + FOV = (float)(DegToRad * Float.parseFloat(EngineConfigVar.getOrDefault("field_of_view", 60.0f).toString())); + zNearPlane = (Float.parseFloat(EngineConfigVar.getOrDefault("z_near_plane", 1.0f).toString())); + zFarPlane = (Float.parseFloat(EngineConfigVar.getOrDefault("z_far_plane", 100.0f).toString())); Logger.debug("\n\nsuccessfully loaded configuration: \n{}\n\n",EngineConfigVar.toString()); } else if(!ConfigFile.exists()){ @@ -125,6 +134,9 @@ public class EngineConfig { EngineConfigVar.setProperty("ShaderRecompiling","true"); EngineConfigVar.setProperty("throttle_accuracy","100000"); EngineConfigVar.setProperty("throttle_on_unfocus","true"); + EngineConfigVar.setProperty("field_of_view","60"); + EngineConfigVar.setProperty("z_near_plane","1"); + EngineConfigVar.setProperty("z_far_plane","100"); EngineConfigVar.store(new FileWriter(path.toAbsolutePath().toString() + "/" + FILENAME), "created new properties file"); Logger.debug("Wrote New Config File [{}]", ConfigFile.getAbsolutePath()); } catch (IOException excp2) { @@ -158,7 +170,9 @@ public class EngineConfig { public boolean RecompileShaders(){ return RecompileShaders; } - + public float GetFOV(){return FOV;} + public float GetZFarPlane(){return zFarPlane;} + public float GetZNearPlane(){return zNearPlane;} public boolean VkValidated(){ return vkValidated; } diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/EngineInstance.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/EngineInstance.java index 597e33d..87ab35c 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/EngineInstance.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/EngineInstance.java @@ -1,6 +1,6 @@ package net.halbear.Terrain4J.EngineCore.Logic; -import net.halbear.Terrain4J.EngineCore.Main.Scene; +import net.halbear.Terrain4J.EngineCore.Main.Scene.Scene; import net.halbear.Terrain4J.EngineCore.Display.Window; public record EngineInstance(Window window, Scene scene) { diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/VulkanContext.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/VulkanContext.java index cfd270c..650914d 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/VulkanContext.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/VulkanContext.java @@ -28,7 +28,13 @@ public class VulkanContext { VulkanLayersOpen+=5; VkPipelineCache = new PipelineCache(device); } - + public void Resize(Window window){ + swapChain.cleanup(device); + surface.cleanup(Instance); + var EngCfg = EngineConfig.getInstance(); + surface = new Surface(Instance,PhysDevice,window); + swapChain = new SwapChain(window, device, surface, EngCfg.GetRequestedImages(),EngCfg.GetVSYNC()); + } public void cleanup(){ swapChain.cleanup(device); surface.cleanup(Instance); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/PrimaryRuntime.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/PrimaryRuntime.java index 9b74f4c..c65bc51 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/PrimaryRuntime.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/PrimaryRuntime.java @@ -2,6 +2,7 @@ package net.halbear.Terrain4J.EngineCore.Main; import net.halbear.Terrain4J.EngineCore.Display.Window; import net.halbear.Terrain4J.EngineCore.Logic.*; +import net.halbear.Terrain4J.EngineCore.Main.Scene.Scene; import net.halbear.Terrain4J.EngineCore.Threads.FastTickThread; import net.halbear.Terrain4J.EngineCore.Threads.MainThread; import net.halbear.Terrain4J.EngineCore.Threads.RenderThread; diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene.java deleted file mode 100644 index 39c5a13..0000000 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene.java +++ /dev/null @@ -1,8 +0,0 @@ -package net.halbear.Terrain4J.EngineCore.Main; - -import net.halbear.Terrain4J.EngineCore.Display.Window; - -public class Scene { - public Scene(Window window) { - } -} diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/Actor.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/Actor.java new file mode 100644 index 0000000..c05992f --- /dev/null +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/Actor.java @@ -0,0 +1,54 @@ +package net.halbear.Terrain4J.EngineCore.Main.Scene; + +import org.joml.Matrix4f; +import org.joml.Quaternionf; +import org.joml.Vector3f; + +public class Actor{ + private final String ID; + private final String ModelID; + private final Matrix4f ModelMatrix; + private final Vector3f Position; + private final Quaternionf Rotation; + private float Scale; + + public Actor(String ID, String ModelID, Vector3f Position){ + this.ID = ID; + this.ModelID = ModelID; + this.Position = Position; + Scale = 1f; + Rotation = new Quaternionf(); + ModelMatrix = new Matrix4f(); + UpdateModelMatrix(); + } + + public void ResetRotation(){ + Rotation.x = 0; + Rotation.y = 0; + Rotation.z = 0; + Rotation.w = 1.0f; + } + + public final void SetPosition(float x, float y, float z){ + Position.x = x; + Position.y = y; + Position.z = z; + UpdateModelMatrix(); + } + + public void SetScale(float Scale){ + this.Scale = Scale; + UpdateModelMatrix(); + } + + public void UpdateModelMatrix(){ + ModelMatrix.translationRotateScale(Position, Rotation, Scale); + } + + public String GetID(){return ID;} + public String GetModelID(){return ModelID;} + public Matrix4f GetModelMatrix(){return ModelMatrix;} + public Vector3f GetPosition(){ return Position;} + public Quaternionf GetRotation(){return Rotation;} + public float GetScale(){return Scale;} +} diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/Scene.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/Scene.java new file mode 100644 index 0000000..04b259a --- /dev/null +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/Scene.java @@ -0,0 +1,27 @@ +package net.halbear.Terrain4J.EngineCore.Main.Scene; + +import net.halbear.Terrain4J.EngineCore.Display.Window; +import net.halbear.Terrain4J.EngineCore.Logic.*; +import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Projection.Project3D; + +import java.util.ArrayList; +import java.util.List; + +public class Scene { + + private final List Actors; + private final Project3D Projection; + + public Scene(Window window) { + Actors = new ArrayList<>(); + var EngConfig = EngineConfig.getInstance(); + Projection = new Project3D(EngConfig.GetFOV(),EngConfig.GetZNearPlane(), EngConfig.GetZFarPlane(), + window.getWidth(), window.getHeight()); + } + + public void AddActor(Actor NewActor){Actors.add(NewActor);} + public List GetActors(){return Actors;} + public Project3D GetProjection(){return Projection;} + public void RemoveAllActors(){Actors.clear();} + public void RemoveActor(Actor actor){Actors.removeIf(Actor->Actor.GetID().equals(actor.GetID()));} +} diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Threads/MainThread.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Threads/MainThread.java index be818fb..293232d 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Threads/MainThread.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Threads/MainThread.java @@ -1,12 +1,9 @@ package net.halbear.Terrain4J.EngineCore.Threads; -import net.halbear.Terrain4J.EngineCore.Display.Window; import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig; import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance; import net.halbear.Terrain4J.EngineCore.Logic.GameLogic; -import net.halbear.Terrain4J.EngineCore.Logic.InitData; import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime; -import net.halbear.Terrain4J.EngineCore.Main.Scene; import org.tinylog.Logger; public class MainThread extends EngineThread { diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Image.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Image.java deleted file mode 100644 index 13bbb9e..0000000 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Image.java +++ /dev/null @@ -1,8 +0,0 @@ -package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering; - -public class Image { - - public static class ImageData{ - - } -} diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/Attachment.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/Attachment.java new file mode 100644 index 0000000..ecfc7ac --- /dev/null +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/Attachment.java @@ -0,0 +1,38 @@ +package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images; + +import net.halbear.Terrain4J.EngineCore.Logic.VulkanContext; +import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.ImageView; + +import static org.lwjgl.vulkan.VK13.*; +public class Attachment { + private final Image VkImage; + private final ImageView VkImageView; + private boolean DepthAttachment; + + public Attachment(VulkanContext VkCtx, int Width, int Height, int Format, int Usage){ + var ImageData = new Image.ImageData().Width(Width).Height(Height).Format(Format) + .Usage(Usage | VK_IMAGE_USAGE_SAMPLED_BIT); + VkImage = new Image(VkCtx, ImageData); + + int AspectMask = 0; + if((Usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) > 0){ + AspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + DepthAttachment = false; + } + if((Usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) > 0){ + AspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + DepthAttachment = true; + } + var ImageViewData = new ImageView.ImageViewData().Format(VkImage.GetFormat()).AspectMask(AspectMask); + VkImageView = new ImageView(VkCtx.GetDevice(), VkImage.getVulkanImage(), ImageViewData); + } + + public Image GetVkImage(){return VkImage;} + public ImageView GetVkImageView(){return VkImageView;} + public boolean IsDepthAttached(){return DepthAttachment;} + + public void CleanUp(VulkanContext VkCtx){ + VkImageView.cleanup(VkCtx.GetDevice()); + VkImage.CleanUp(VkCtx); + } +} diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/Image.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/Image.java new file mode 100644 index 0000000..80a78b5 --- /dev/null +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/Image.java @@ -0,0 +1,116 @@ +package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images; + +import net.halbear.Terrain4J.EngineCore.Logic.VulkanContext; +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.VkImageCreateInfo; +import org.lwjgl.vulkan.VkMemoryAllocateInfo; +import org.lwjgl.vulkan.VkMemoryRequirements; + +import java.nio.LongBuffer; + +import static org.lwjgl.vulkan.VK10.*; +import static org.lwjgl.vulkan.VK13.VK_FORMAT_R8G8B8A8_SRGB; + +public class Image { + + private final int Format; + private final int MipLevels; + private final long VulkanImage; + private final long VulkanMemory; + + public Image(VulkanContext VkCtx, ImageData imageData){ + try(var MemStack = MemoryStack.stackPush()){ + this.Format = imageData.Format; + this.MipLevels = imageData.MipMapLevels; + + VkImageCreateInfo vkImageCreateInfo = VkImageCreateInfo.calloc(MemStack) + .sType$Default() + .imageType(VK_IMAGE_TYPE_2D) + .format(Format) + .extent(it -> it + .width(imageData.Width) + .height(imageData.Height) + .depth(1)) + .mipLevels(MipLevels) + .arrayLayers(imageData.ArrayLayers) + .samples(imageData.SampleCount) + .initialLayout(VK_IMAGE_LAYOUT_UNDEFINED) + .sharingMode(VK_SHARING_MODE_EXCLUSIVE) + .tiling(VK_IMAGE_TILING_OPTIMAL) + .usage(imageData.Usage); + Device device = VkCtx.GetDevice(); + LongBuffer LongPtr = MemStack.mallocLong(1); + VulkanUtils.vkCheck(vkCreateImage(device.FetchVulkanDevice(),vkImageCreateInfo,null,LongPtr), + "Failed to create Vulkan Image"); + VulkanImage = LongPtr.get(0); + VkMemoryRequirements memoryRequirements = VkMemoryRequirements.calloc(MemStack); + vkGetImageMemoryRequirements(device.FetchVulkanDevice(), VulkanImage, memoryRequirements); + + var MemoryAllocation = VkMemoryAllocateInfo.calloc(MemStack) + .sType$Default() + .allocationSize(memoryRequirements.size()) + .memoryTypeIndex(VulkanUtils.MemoryTypeFromProperties(VkCtx, memoryRequirements.memoryTypeBits(),0)); + //allocate + VulkanUtils.vkCheck(vkAllocateMemory(device.FetchVulkanDevice(),MemoryAllocation,null,LongPtr) + ,"Failed to allocate Memory for Vulkan Image"); + VulkanMemory = LongPtr.get(0); + //bind + VulkanUtils.vkCheck(vkBindImageMemory(device.FetchVulkanDevice(),VulkanImage,VulkanMemory,0) + ,"Failed to bind memory for Vulkan Image"); + } + } + public void CleanUp(VulkanContext VkCtx){ + vkDestroyImage(VkCtx.GetDevice().FetchVulkanDevice(), VulkanImage,null); + vkFreeMemory(VkCtx.GetDevice().FetchVulkanDevice(), VulkanMemory,null); + } + public int GetFormat(){return Format;} + public int GetMipLevels(){return MipLevels;} + public long getVulkanImage(){return VulkanImage;} + + public static class ImageData{ + private int ArrayLayers; + private int Format; + private int Height; + private int Width; + private int MipMapLevels; + private int SampleCount; + private int Usage; + + public ImageData(){ + Format = VK_FORMAT_R8G8B8A8_SRGB; + MipMapLevels = 1; + SampleCount = 1; + ArrayLayers = 1; + } + public ImageData ArrayLayers(int ArrayLayers){ + this.ArrayLayers = ArrayLayers; + return this; + } + public ImageData Format(int Format){ + this.Format = Format; + return this; + } + public ImageData Height(int Height){ + this.Height = Height; + return this; + } + public ImageData Width(int Width){ + this.Width = Width; + return this; + } + public ImageData MipMapLevels(int MipLevel){ + this.MipMapLevels = MipLevel; + return this; + } + public ImageData SampleCount(int Samples){ + this.SampleCount = Samples; + return this; + } + public ImageData Usage(int Usage){ + this.Usage = Usage; + return this; + } + } +} diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Pipeline.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Pipeline.java index c68d82b..1955186 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Pipeline.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Pipeline.java @@ -67,12 +67,42 @@ public class Pipeline { .pAttachments(BlendAttributeState); IntBuffer ColourFormats = MemStack.mallocInt(1); ColourFormats.put(0,BuildInfo.GetColourFormat()); + + VkPipelineDepthStencilStateCreateInfo DepthStencil = null; + if(BuildInfo.GetDepthFormat() != VK_FORMAT_UNDEFINED){ + DepthStencil = VkPipelineDepthStencilStateCreateInfo.calloc(MemStack) + .sType$Default() + .depthTestEnable(true) + .depthWriteEnable(true) + .depthCompareOp(VK_COMPARE_OP_LESS_OR_EQUAL) + .depthBoundsTestEnable(false) + .stencilTestEnable(false); + } + var RendererCreateInfo = VkPipelineRenderingCreateInfo.calloc(MemStack) .sType$Default() .colorAttachmentCount(1) .pColorAttachmentFormats(ColourFormats); + + if(DepthStencil != null){RendererCreateInfo.depthAttachmentFormat(BuildInfo.GetDepthFormat());} + + 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()); + } + } var PipelineLayoutCreateInfoPtr = VkPipelineLayoutCreateInfo.calloc(MemStack) - .sType$Default(); + .sType$Default() + .pPushConstantRanges(VkPushConstRangeBuffer); + VulkanUtils.vkCheck(vkCreatePipelineLayout(device.FetchVulkanDevice(), PipelineLayoutCreateInfoPtr,null,longPtr) ,"Unable to create new pipeline layout"); VulkanPipelineLayout = longPtr.get(0); @@ -90,6 +120,9 @@ public class Pipeline { .pDynamicState(VulkanPipelineDynamicStateCreateInfo) .layout(VulkanPipelineLayout) .pNext(RendererCreateInfo); + + if(DepthStencil != null){PipelineCreateInfo.pDepthStencilState(DepthStencil);} + VulkanUtils.vkCheck(vkCreateGraphicsPipelines(device.FetchVulkanDevice(), VkCtx.GetVkPipelineCache().GetVkPipelineCache(), PipelineCreateInfo, null, longPtr),"Could not create new pipeline"); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/PipelineBuildInfo.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/PipelineBuildInfo.java index 178e892..382171e 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/PipelineBuildInfo.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/PipelineBuildInfo.java @@ -2,16 +2,35 @@ package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.ShaderModule; import org.lwjgl.vulkan.VkPipelineVertexInputStateCreateInfo; +import org.lwjgl.vulkan.VkPushConstantRange; + +import static org.lwjgl.vulkan.VK10.VK_FORMAT_UNDEFINED; public class PipelineBuildInfo { private final int ColourFormat; private final ShaderModule[] ShaderModules; private final VkPipelineVertexInputStateCreateInfo VertexInput; + private int DepthFormat; + private PushConstantsRange[] PushConstRanges; + public PipelineBuildInfo(ShaderModule[] shaderModules, VkPipelineVertexInputStateCreateInfo VertexInput, int ColourFormat){ this.ColourFormat = ColourFormat; this.ShaderModules = shaderModules; this.VertexInput = VertexInput; + DepthFormat = VK_FORMAT_UNDEFINED; } + + public PipelineBuildInfo SetDepthFormat(int DepthFormat){ + this.DepthFormat = DepthFormat; + return this; + } + public PipelineBuildInfo SetPushConstantRanges(PushConstantsRange[] PushConstRanges){ + this.PushConstRanges = PushConstRanges; + return this; + } + + public PushConstantsRange[] GetPushConstantRanges(){return PushConstRanges;} + public int GetDepthFormat(){return DepthFormat;} public int GetColourFormat(){return ColourFormat;} public ShaderModule[] GetShaderModules(){return ShaderModules;} public VkPipelineVertexInputStateCreateInfo GetVertexInputStateCreateInfo(){return VertexInput;} diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/PushConstantsRange.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/PushConstantsRange.java new file mode 100644 index 0000000..cb8a562 --- /dev/null +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/PushConstantsRange.java @@ -0,0 +1,4 @@ +package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline; + +public record PushConstantsRange(int Stage, int Offset, int Size) { +} diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Projection/Project3D.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Projection/Project3D.java new file mode 100644 index 0000000..5d7bfd7 --- /dev/null +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Projection/Project3D.java @@ -0,0 +1,33 @@ +package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Projection; + +import org.joml.Matrix4f; + +public class Project3D { + private final float FOV; // IT IS IN RADIANS!! REMEEEEMMMBER RADIANS!!!! PI/180!!!!! + // there is a universal DegToRad conversion variable one can use in EngineConfig if they need to convert it + private final Matrix4f ProjectionMatrix; + private final float ZFarPlane; + private final float ZNearPlane; + + public Project3D(float FOV, float zNear, float zFar, int Width, int Height){ + this.FOV = FOV; + this.ZFarPlane = zFar; + this.ZNearPlane = zNear; + ProjectionMatrix = new Matrix4f(); + Resize(Width, Height); + } + + public float GetFOV(){ + return FOV; + } + public float GetFarZ(){ + return ZFarPlane; + } + public float GetNearZ(){ + return ZNearPlane; + } + public void Resize(int Width, int Height){ + ProjectionMatrix.identity(); + ProjectionMatrix.perspective(FOV, (float)Width/(float)Height, ZNearPlane, ZFarPlane, true); + } +} diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/VertexBufferStructure.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/VertexBufferStructure.java index 6a3ac0c..d4a6e84 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/VertexBufferStructure.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/VertexBufferStructure.java @@ -9,7 +9,8 @@ import static org.lwjgl.vulkan.VK13.VK_FORMAT_R32G32B32_SFLOAT; import static org.lwjgl.vulkan.VK13.VK_VERTEX_INPUT_RATE_VERTEX; public class VertexBufferStructure { - private final int NUMBER_OF_ATTRIBUTES = 1; + public static final int TEXT_COORD_COMPONENTS = 2; + private static final int NUMBER_OF_ATTRIBUTES = 2; private final int POSITION_COMPONENTS = 3; private final VkPipelineVertexInputStateCreateInfo VertexInput; @@ -23,14 +24,25 @@ public class VertexBufferStructure { int i =0; int Offset = 0; + //vertex position VertexInputAttributes.get(i) .binding(0) .location(i) .format(VK_FORMAT_R32G32B32_SFLOAT) .offset(Offset); + i++; + Offset += POSITION_COMPONENTS * VulkanUtils.FLOAT_SIZE; + //texture coordinates + VertexInputAttributes.get(i) + .binding(0) + .location(i) + .format(VK_FORMAT_R32G32B32_SFLOAT) + .offset(Offset); + + int Stride = Offset + TEXT_COORD_COMPONENTS * VulkanUtils.FLOAT_SIZE; VertexInputBindings.get(0) .binding(0) - .stride(POSITION_COMPONENTS * VulkanUtils.FLOAT_SIZE) + .stride(Stride) .inputRate(VK_VERTEX_INPUT_RATE_VERTEX); VertexInput .sType$Default() diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/VkModel/MeshData.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/VkModel/MeshData.java index f67cdd9..cb83b9e 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/VkModel/MeshData.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/VkModel/MeshData.java @@ -1,4 +1,4 @@ package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel; -public record MeshData(String ID, float[] Positions, int[] Indices) { +public record MeshData(String ID, float[] Positions, float[] textureCoords, int[] Indices) { } 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 e8ea385..c6178ff 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 @@ -54,7 +54,11 @@ public class ModelsCache { private static TransferBuffer CreateVerticesBuffer(VulkanContext VkCtx, MeshData meshData){ float[] Positions = meshData.Positions(); - int ElementCount = Positions.length; + float[] TextureCoords = meshData.textureCoords(); + if(TextureCoords == null || TextureCoords.length == 0){ + TextureCoords = new float[(Positions.length/3) * 2]; + } + int ElementCount = Positions.length + TextureCoords.length; int BufferSize = ElementCount * VulkanUtils.FLOAT_SIZE; var SrcBuffer = new VulkanBuffer(VkCtx,BufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); @@ -66,9 +70,12 @@ public class ModelsCache { int Rows = Positions.length / 3; for(int Row = 0; Row < Rows; Row++){ int StartPos = Row * 3; + int StartTexCoordPos = Row * 2; data.put(Positions[StartPos]); data.put(Positions[StartPos+1]); data.put(Positions[StartPos+2]); + data.put(TextureCoords[StartTexCoordPos]); + data.put(TextureCoords[StartTexCoordPos + 1]); } SrcBuffer.UnMapMemory(VkCtx); return new TransferBuffer(SrcBuffer,DstBuffer); 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 8334544..10e0a85 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 @@ -1,11 +1,11 @@ package net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen; -import net.halbear.Terrain4J.EngineCore.Display.Render; import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig; import net.halbear.Terrain4J.EngineCore.Logic.VulkanContext; +import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.Attachment; 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.PipelineCache; +import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.PushConstantsRange; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.ShaderCompiler; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.ShaderModule; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VertexBufferStructure; @@ -15,10 +15,11 @@ import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.VulkanModel; import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.CommandBuffer; 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.LongBuffer; import java.util.Arrays; @@ -26,7 +27,12 @@ import static org.lwjgl.vulkan.KHRSwapchain.VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; import static org.lwjgl.vulkan.KHRSynchronization2.VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR; import static org.lwjgl.vulkan.VK13.*; -public class SceneRender { //dynamic rendering; +public class SceneRender {//dynamic rendering + private static final int DEPTH_FORMAT = VK_FORMAT_D16_UNORM; + private final VkClearValue ClearValueDepth; + private final ByteBuffer PushConstBuffer; + private Attachment[] AttDepth; + private VkRenderingAttachmentInfo[] AttInfoDepth; private VkClearValue ClearValueColour; private VkRenderingAttachmentInfo.Buffer[] AttachmentInfoColour; private VkRenderingInfo[] RenderInfo; @@ -44,14 +50,47 @@ public class SceneRender { //dynamic rendering; private final Pipeline VkPipeline; public SceneRender(VulkanContext vulkanContext){ + ClearValueDepth = VkClearValue.calloc().color(c->c.float32(0,1.0f)); + AttDepth = createDepthAttachments(vulkanContext); + AttInfoDepth = createDepthAttachmentsInfo(vulkanContext, AttDepth, ClearValueDepth); ClearValueColour = VkClearValue.calloc().color(c->c.float32(0,R).float32(1,G).float32(2,B).float32(3,1.0f)); AttachmentInfoColour = CreateColourAttachmentsInfo(vulkanContext,ClearValueColour); - RenderInfo = CreateRenderInfo(vulkanContext, AttachmentInfoColour); - + RenderInfo = CreateRenderInfo(vulkanContext, AttachmentInfoColour, AttInfoDepth); + PushConstBuffer = MemoryUtil.memAlloc(VulkanUtils.MATRIX4X4_SIZE * 2); ShaderModule[] shaderModules = SceneRender.CreateShaderModules(vulkanContext); VkPipeline = CreatePipeline(vulkanContext, shaderModules); Arrays.asList(shaderModules).forEach(shaderModule -> shaderModule.CleanUp(vulkanContext)); } + + private static Attachment[] createDepthAttachments(VulkanContext VkCtx){ + SwapChain swapChain = VkCtx.GetSwapChain(); + int ImageCount = swapChain.GetImageCount(); + VkExtent2D swapChainExtent = swapChain.GetSwapChainExtent(); + Attachment[] DepthAttachments = new Attachment[ImageCount]; + for(int i = 0; i < ImageCount; i++){ + DepthAttachments[i] = new Attachment(VkCtx, swapChainExtent.width(), swapChainExtent.height(), + DEPTH_FORMAT,VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT); + } + return DepthAttachments; + } + + private static VkRenderingAttachmentInfo[] createDepthAttachmentsInfo(VulkanContext VkCtx, Attachment[] DepthAttachments, VkClearValue clearValue){ + SwapChain swapChain = VkCtx.GetSwapChain(); + int ImageCount = swapChain.GetImageCount(); + var Result = new VkRenderingAttachmentInfo[ImageCount]; + for(int i = 0; i < ImageCount; i++){ + var Attachments = VkRenderingAttachmentInfo.calloc() + .sType$Default() + .imageView(DepthAttachments[i].GetVkImageView().GetVulkanImageView()) + .imageLayout(VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL) + .loadOp(VK_ATTACHMENT_LOAD_OP_CLEAR) + .storeOp(VK_ATTACHMENT_STORE_OP_DONT_CARE) + .clearValue(clearValue); + Result[i] = Attachments; + } + return Result; + } + private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx){ if(EngineConfig.getInstance().RecompileShaders()){ ShaderCompiler.CompileGLSLShaderOnChange(VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader); @@ -62,14 +101,21 @@ public class SceneRender { //dynamic rendering; new ShaderModule(VkCtx, VK_SHADER_STAGE_FRAGMENT_BIT, FRAGMENT_SHADER_FILE_SPV) }; } + private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] ShaderModules){ var vertexBufferStructure = new VertexBufferStructure(); var BuildInfo = new PipelineBuildInfo(ShaderModules,vertexBufferStructure.getVertexInput(), - VkCtx.GetSurface().GetSurfaceFormat().ImageFormat()); + VkCtx.GetSurface().GetSurfaceFormat().ImageFormat()) + .SetDepthFormat(DEPTH_FORMAT) + .SetPushConstantRanges( + new PushConstantsRange[]{ + new PushConstantsRange(VK_SHADER_STAGE_VERTEX_BIT,0,VulkanUtils.MATRIX4X4_SIZE * 2) + }); var pipeline = new Pipeline(VkCtx, BuildInfo); vertexBufferStructure.cleanup(); return pipeline; } + public void UpdateColours(VulkanContext vulkanContext){ if (Gb){ if (G < 1.0f && Math.random() <0.5) G+=0.0005f; @@ -94,7 +140,7 @@ public class SceneRender { //dynamic rendering; } ClearValueColour = VkClearValue.calloc().color(c->c.float32(0,R).float32(1,G).float32(2,B).float32(3,1.0f)); AttachmentInfoColour = CreateColourAttachmentsInfo(vulkanContext,ClearValueColour); - RenderInfo = CreateRenderInfo(vulkanContext, AttachmentInfoColour); + RenderInfo = CreateRenderInfo(vulkanContext, AttachmentInfoColour, AttInfoDepth); } public void Render(VulkanContext vulkanContext, CommandBuffer commandBuffer,ModelsCache modelsCache, int ImageIndex){ @@ -108,7 +154,15 @@ public class SceneRender { //dynamic rendering; VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_2_NONE, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_ASPECT_COLOR_BIT); + VulkanUtils.ImageBarrier(MemStack, CommandHandle, AttDepth[ImageIndex].GetVkImage().getVulkanImage(), + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, + VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT, + VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT, + VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, + VK_IMAGE_ASPECT_DEPTH_BIT); + vkCmdBeginRendering(CommandHandle, RenderInfo[ImageIndex]); + vkCmdBindPipeline(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkPipeline.GetVulkanPipeline()); VkExtent2D swapChainExtent = swapChain.GetSwapChainExtent(); @@ -129,8 +183,11 @@ public class SceneRender { //dynamic rendering; LongBuffer offsets = MemStack.mallocLong(1).put(0,0L); LongBuffer vertexBuffer = MemStack.mallocLong(1); + + //Fetch Actor Code to be written Later var VulkanModels = modelsCache.GetModelMap().values(); for(VulkanModel VkModel : VulkanModels){ + for(VulkanMesh mesh : VkModel.GetVkMeshList()){ vertexBuffer.put(0,mesh.VerticesBuffer().GetBuffer()); vkCmdBindVertexBuffers(CommandHandle,0,vertexBuffer,offsets); @@ -148,19 +205,22 @@ public class SceneRender { //dynamic rendering; } } - private static VkRenderingInfo[] CreateRenderInfo(VulkanContext vulkanContext, VkRenderingAttachmentInfo.Buffer[] ColourAttachments){ + private static VkRenderingInfo[] CreateRenderInfo(VulkanContext vulkanContext, VkRenderingAttachmentInfo.Buffer[] ColourAttachments, VkRenderingAttachmentInfo[] DepthAttachments){ SwapChain swapChain = vulkanContext.GetSwapChain(); int ImageCount = swapChain.GetImageCount(); var Result = new VkRenderingInfo[ImageCount]; + try(var MemStack = MemoryStack.stackPush()){ VkExtent2D Extent = swapChain.GetSwapChainExtent(); var RenderArea = VkRect2D.calloc(MemStack).extent(Extent); + for(int i = 0; i < ImageCount; i++){ var RenderInfo = VkRenderingInfo.calloc() .sType$Default() .renderArea(RenderArea) .layerCount(1) - .pColorAttachments(ColourAttachments[i]); + .pColorAttachments(ColourAttachments[i]) + .pDepthAttachment(DepthAttachments[i]); Result[i] = RenderInfo; } } @@ -185,6 +245,11 @@ public class SceneRender { //dynamic rendering; VkPipeline.CleanUp(VkCtx); Arrays.asList(RenderInfo).forEach(VkRenderingInfo::free); Arrays.asList(AttachmentInfoColour).forEach(VkRenderingAttachmentInfo.Buffer::free); + Arrays.asList(AttInfoDepth).forEach(VkRenderingAttachmentInfo::free); + Arrays.asList(AttachmentInfoColour).forEach(VkRenderingAttachmentInfo.Buffer::free); + Arrays.asList(AttDepth).forEach(Attachment->Attachment.CleanUp(VkCtx)); + MemoryUtil.memFree(PushConstBuffer); + ClearValueDepth.free(); ClearValueColour.free(); } 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 3436aee..16abc64 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 @@ -15,6 +15,7 @@ public class VulkanUtils { public static final int FLOAT_SIZE = 4; public static final int INT_SIZE = 4; + public static final int MATRIX4X4_SIZE = 16 * FLOAT_SIZE; public static int MemoryTypeFromProperties(VulkanContext vulkanContext, int TypeBits, int ReqMask){ int result = -1; diff --git a/terrain4j.properties b/terrain4j.properties index b721d5a..ee92827 100644 --- a/terrain4j.properties +++ b/terrain4j.properties @@ -8,7 +8,7 @@ display_height=480 display_width=640 #Engine Core Settings -#the precision of frames, set this to 16000000 and it will limit the whole engine to 64FPS +#the precision of frames, set this to 16000000, and it will limit the whole engine to 64FPS frame_accuracy=0 throttle_on_unfocus=true throttle_accuracy=500000000 @@ -31,4 +31,9 @@ RequestedImages=3 #This is the name of the GPU you want the engine to use PhysicalDeviceName= +#3D Projection Properties +field_of_view=60.0f +z_near_plane=1.0f +z_far_plane=100.0f +