From 01b7d524eed4041a1ae8345838696d60a2427d78 Mon Sep 17 00:00:00 2001 From: Halbear Date: Fri, 30 Jan 2026 09:29:52 +0000 Subject: [PATCH] starting vertex rendering --- .../Rendering/VertexBufferStructure.java | 47 ++++++++++ .../DisplayToScreen/SceneRender.java | 1 + .../EngineCore/Vulkan/Util/VulkanBuffer.java | 85 +++++++++++++++++++ .../EngineCore/Vulkan/Util/VulkanUtils.java | 26 +++++- 4 files changed, 155 insertions(+), 4 deletions(-) create mode 100644 src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/VertexBufferStructure.java create mode 100644 src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Util/VulkanBuffer.java 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 new file mode 100644 index 0000000..f1e043c --- /dev/null +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/VertexBufferStructure.java @@ -0,0 +1,47 @@ +package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering; + +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.VK_FORMAT_R32G32B32_SFLOAT; +import static org.lwjgl.vulkan.VK10.VK_VERTEX_INPUT_RATE_VERTEX; + +public class VertexBufferStructure { + private final int NUMBER_OF_ATTRIBUTES = 1; + private final int POSITION_COMPONENTS = 3; + + private final VkPipelineVertexInputStateCreateInfo VertexInput; + private final VkVertexInputAttributeDescription.Buffer VertexInputAttributes; + private final VkVertexInputBindingDescription.Buffer VertexInputBindings; + + public VertexBufferStructure(){ + VertexInputAttributes = VkVertexInputAttributeDescription.calloc(NUMBER_OF_ATTRIBUTES); + VertexInputBindings = VkVertexInputBindingDescription.calloc(1); + VertexInput = VkPipelineVertexInputStateCreateInfo.calloc(); + + int i =0; + int Offset = 0; + VertexInputAttributes.get(i) + .binding(0) + .location(i) + .format(VK_FORMAT_R32G32B32_SFLOAT) + .offset(Offset); + VertexInputBindings.get(0) + .binding(0) + .stride(POSITION_COMPONENTS * VulkanUtils.FLOAT_SIZE) + .inputRate(VK_VERTEX_INPUT_RATE_VERTEX); + VertexInput + .sType$Default() + .pVertexAttributeDescriptions(VertexInputAttributes) + .pVertexBindingDescriptions(VertexInputBindings); + } + public void cleanup(){ + VertexInput.free(); + VertexInputAttributes.free(); + } + public VkPipelineVertexInputStateCreateInfo getVertexInput(){ + return VertexInput; + } +} 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 fa0e89d..cd81dea 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 @@ -61,6 +61,7 @@ public class SceneRender { //dynamic rendering; } public void Render(VulkanContext vulkanContext, CommandBuffer commandBuffer, int ImageIndex){ + UpdateColours(vulkanContext); try(var MemStack = MemoryStack.stackPush()){ SwapChain swapChain = vulkanContext.GetSwapChain(); long SwapChainImage = swapChain.GetVulkanImageView(ImageIndex).GetVulkanImage(); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Util/VulkanBuffer.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Util/VulkanBuffer.java new file mode 100644 index 0000000..0aea89c --- /dev/null +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Util/VulkanBuffer.java @@ -0,0 +1,85 @@ +package net.halbear.Terrain4J.EngineCore.Vulkan.Util; + +import net.halbear.Terrain4J.EngineCore.Logic.VulkanContext; +import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.Device; +import org.lwjgl.PointerBuffer; +import org.lwjgl.system.MemoryStack; +import org.lwjgl.system.MemoryUtil; +import org.lwjgl.vulkan.VkBufferCreateInfo; +import org.lwjgl.vulkan.VkDevice; +import org.lwjgl.vulkan.VkMemoryAllocateInfo; +import org.lwjgl.vulkan.VkMemoryRequirements; +import org.tinylog.Logger; + +import java.nio.LongBuffer; + +import static net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils.vkCheck; +import static org.lwjgl.system.MemoryUtil.NULL; +import static org.lwjgl.vulkan.VK10.*; + +public class VulkanBuffer { + private final long AllocationSize; + private final long Buffer; + private final long Memory; + private final PointerBuffer pointerBuffer; + private final long RequestedSize; + private long MappedMemory; + + public VulkanBuffer(VulkanContext vulkanContext, long Size, int Usage, int RequestMask){ + RequestedSize = Size; + MappedMemory = NULL; + try(var MemStack = MemoryStack.stackPush()){ + Device device = vulkanContext.GetDevice(); + var BufferCreationInfo = VkBufferCreateInfo.calloc(MemStack) + .sType$Default() + .size(Size) + .usage(Usage) + .sharingMode(VK_SHARING_MODE_EXCLUSIVE); + LongBuffer LongPointer = MemStack.mallocLong(1); + vkCheck(vkCreateBuffer(device.FetchVulkanDevice(), BufferCreationInfo, null, LongPointer),"Failed to create Vulkan Buffer"); + Buffer = LongPointer.get(0); + + var MemoryRequirements = VkMemoryRequirements.calloc(MemStack); + vkGetBufferMemoryRequirements(device.FetchVulkanDevice(), Buffer, MemoryRequirements); + + var MemoryAllocation = VkMemoryAllocateInfo.calloc(MemStack) + .sType$Default() + .allocationSize(MemoryRequirements.size()) + .memoryTypeIndex(VulkanUtils.MemoryTypeFromProperties(vulkanContext, MemoryRequirements.memoryTypeBits(), RequestMask)); + + vkCheck(vkAllocateMemory(device.FetchVulkanDevice(),MemoryAllocation,null,LongPointer),"Failed to allocate memory for Vulkan"); + AllocationSize = MemoryAllocation.allocationSize(); + Memory = LongPointer.get(0); + pointerBuffer = MemoryUtil.memAllocPointer(1); + + vkCheck(vkBindBufferMemory(device.FetchVulkanDevice(),Buffer,Memory,0),"Failed to Bind Vulkan Memory Buffer"); + } + } + public void cleanup(VulkanContext vulkanContext){ + MemoryUtil.memFree(pointerBuffer); + VkDevice vulkanDevice = vulkanContext.GetDevice().FetchVulkanDevice(); + vkDestroyBuffer(vulkanDevice,Buffer, null); + vkFreeMemory(vulkanDevice, Memory, null); + Logger.debug("Freed Vulkan Memory Buffer"); + } + + public long GetBuffer(){ + return Buffer; + } + public long GetRequestedSize(){ + return RequestedSize; + } + public long MapMemory(VulkanContext vulkanContext){ + if(MappedMemory == NULL){ + vkCheck(vkMapMemory(vulkanContext.GetDevice().FetchVulkanDevice(), Memory,0,AllocationSize,0,pointerBuffer),"Failed to map Vulkan Buffer"); + MappedMemory = pointerBuffer.get(0); + } + return MappedMemory; + } + public void UnMapMemory(VulkanContext vulkanContext){ + if(MappedMemory != NULL){ + vkUnmapMemory(vulkanContext.GetDevice().FetchVulkanDevice(), Memory); + MappedMemory = NULL; + } + } +} 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 c44d4fb..b162dd3 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 @@ -1,10 +1,8 @@ package net.halbear.Terrain4J.EngineCore.Vulkan.Util; +import net.halbear.Terrain4J.EngineCore.Logic.VulkanContext; import org.lwjgl.system.MemoryStack; -import org.lwjgl.vulkan.VkCommandBuffer; -import org.lwjgl.vulkan.VkDependencyInfo; -import org.lwjgl.vulkan.VkImageMemoryBarrier; -import org.lwjgl.vulkan.VkImageMemoryBarrier2; +import org.lwjgl.vulkan.*; import org.tinylog.Logger; import java.util.Locale; @@ -15,6 +13,26 @@ import static org.lwjgl.vulkan.VK13.vkCmdPipelineBarrier2; public class VulkanUtils { public static final int MAX_IN_FLIGHT = 2; public enum OSType {WINDOWS, MACOS, LINUX, UNSUPPORTED} + + public static final int FLOAT_SIZE = 4; + public static final int INT_SIZE = 4; + + public static int MemoryTypeFromProperties(VulkanContext vulkanContext, int TypeBits, int ReqMask){ + int result = -1; + VkMemoryType.Buffer MemoryTypes = vulkanContext.GetPhysicalDevice().GetMemoryProperties().memoryTypes(); + for(int i = 0; i < VK_MAX_MEMORY_TYPES; i++){ + if((TypeBits & 1) == 1 && (MemoryTypes.get(i).propertyFlags() & ReqMask)==ReqMask){ + result = i; + break; + } + TypeBits >>= 1; + } + if(result < 0){ + throw new RuntimeException("Failed to find MemoryType"); + } + return result; + } + public static OSType getOS() { OSType result; String os = System.getProperty("os.name", "generic").toLowerCase(Locale.ENGLISH);