Vulkan Models, Mesh, Model caching and synchronisation
This commit is contained in:
parent
01b7d524ee
commit
1ff359487d
6 changed files with 165 additions and 0 deletions
|
|
@ -0,0 +1,4 @@
|
||||||
|
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel;
|
||||||
|
|
||||||
|
public record MeshData(String ID, float[] Positions, int[] Indices) {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public record ModelData(String ID, List<MeshData> Meshes) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,102 @@
|
||||||
|
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel;
|
||||||
|
|
||||||
|
import net.halbear.Terrain4J.EngineCore.Logic.VulkanContext;
|
||||||
|
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.GPUSynchronisation.TransferBuffer;
|
||||||
|
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.MemoryUtil;
|
||||||
|
|
||||||
|
import java.nio.FloatBuffer;
|
||||||
|
import java.nio.IntBuffer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.lwjgl.vulkan.VK10.*;
|
||||||
|
|
||||||
|
public class ModelsCache {
|
||||||
|
private final Map<String, VulkanModel> ModelsMap;
|
||||||
|
public ModelsCache(){
|
||||||
|
ModelsMap = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadModels(VulkanContext VkCtx, List<ModelData> Models, CommandPool commandPool, Queue queue){
|
||||||
|
List<VulkanBuffer> StagingBufferList = new ArrayList<>();
|
||||||
|
var Command = new CommandBuffer(VkCtx, commandPool, true, true);
|
||||||
|
Command.BeginRecording();
|
||||||
|
|
||||||
|
for(ModelData modelData : Models){
|
||||||
|
VulkanModel VKModel = new VulkanModel(modelData.ID());
|
||||||
|
ModelsMap.put(VKModel.GetID(), VKModel);
|
||||||
|
for(MeshData meshData : modelData.Meshes()){
|
||||||
|
TransferBuffer VerticesBuffers = CreateVerticesBuffer(VkCtx,meshData);
|
||||||
|
TransferBuffer IndicesBuffers = CreateIndicesBuffer(VkCtx,meshData);
|
||||||
|
StagingBufferList.add(VerticesBuffers.SrcBuffer());
|
||||||
|
StagingBufferList.add(IndicesBuffers.SrcBuffer());
|
||||||
|
VerticesBuffers.RecordTransferCommand(Command);
|
||||||
|
IndicesBuffers.RecordTransferCommand(Command);
|
||||||
|
VulkanMesh VkMesh = new VulkanMesh(meshData.ID(), VerticesBuffers.DstBuffer(),IndicesBuffers.DstBuffer(),
|
||||||
|
meshData.Indices().length);
|
||||||
|
VKModel.GetVkMeshList().add(VkMesh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Command.EndRecording();
|
||||||
|
Command.SubmitAndWait(VkCtx,queue);
|
||||||
|
Command.cleanup(VkCtx,commandPool);
|
||||||
|
|
||||||
|
StagingBufferList.forEach(b -> b.cleanup(VkCtx));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TransferBuffer CreateVerticesBuffer(VulkanContext VkCtx, MeshData meshData){
|
||||||
|
float[] Positions = meshData.Positions();
|
||||||
|
int ElementCount = Positions.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);
|
||||||
|
var DstBuffer = new VulkanBuffer(VkCtx, BufferSize,
|
||||||
|
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||||
|
|
||||||
|
long MappedMemory = SrcBuffer.MapMemory(VkCtx);
|
||||||
|
FloatBuffer data = MemoryUtil.memFloatBuffer(MappedMemory, (int) SrcBuffer.GetRequestedSize());
|
||||||
|
int Rows = Positions.length / 3;
|
||||||
|
for(int Row = 0; Row < Rows; Row++){
|
||||||
|
int StartPos = Row * 3;
|
||||||
|
data.put(Positions[StartPos]);
|
||||||
|
data.put(Positions[StartPos+1]);
|
||||||
|
data.put(Positions[StartPos+2]);
|
||||||
|
}
|
||||||
|
SrcBuffer.UnMapMemory(VkCtx);
|
||||||
|
return new TransferBuffer(SrcBuffer,DstBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TransferBuffer CreateIndicesBuffer(VulkanContext VkCtx, MeshData meshData){
|
||||||
|
int[] Indices = meshData.Indices();
|
||||||
|
int IndexCount = Indices.length;
|
||||||
|
int BufferSize = IndexCount * VulkanUtils.INT_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);
|
||||||
|
var DstBuffer = new VulkanBuffer(VkCtx, BufferSize,
|
||||||
|
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||||
|
long MappedMemory = SrcBuffer.MapMemory(VkCtx);
|
||||||
|
IntBuffer data = MemoryUtil.memIntBuffer(MappedMemory,(int) SrcBuffer.GetRequestedSize());
|
||||||
|
data.put(Indices);
|
||||||
|
SrcBuffer.UnMapMemory(VkCtx);
|
||||||
|
return new TransferBuffer(SrcBuffer,DstBuffer);
|
||||||
|
}
|
||||||
|
public VulkanModel GetModel(String modelName){
|
||||||
|
return ModelsMap.get(modelName);
|
||||||
|
}
|
||||||
|
public Map<String, VulkanModel> GetModelMap(){
|
||||||
|
return ModelsMap;
|
||||||
|
}
|
||||||
|
public void CleanUp(VulkanContext VkCtx){
|
||||||
|
ModelsMap.forEach((key,Value)->Value.CleanUp(VkCtx));
|
||||||
|
ModelsMap.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel;
|
||||||
|
|
||||||
|
import net.halbear.Terrain4J.EngineCore.Logic.VulkanContext;
|
||||||
|
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanBuffer;
|
||||||
|
|
||||||
|
public record VulkanMesh(String ID, VulkanBuffer VerticesBuffer,VulkanBuffer IndicesBuffer,int IndicesCount) {
|
||||||
|
public void Cleanup(VulkanContext VkCtx){
|
||||||
|
VerticesBuffer.cleanup(VkCtx);
|
||||||
|
IndicesBuffer.cleanup(VkCtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel;
|
||||||
|
|
||||||
|
import net.halbear.Terrain4J.EngineCore.Logic.VulkanContext;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class VulkanModel {
|
||||||
|
private final String ID;
|
||||||
|
private final List<VulkanMesh> VulkanMeshList;
|
||||||
|
|
||||||
|
public VulkanModel(String id){
|
||||||
|
this.ID = id;
|
||||||
|
VulkanMeshList = new ArrayList<>();
|
||||||
|
}
|
||||||
|
public void CleanUp(VulkanContext VkCtx){
|
||||||
|
VulkanMeshList.forEach(mesh -> mesh.Cleanup(VkCtx));
|
||||||
|
}
|
||||||
|
public String GetID(){return ID;}
|
||||||
|
public List<VulkanMesh> GetVkMeshList(){return this.VulkanMeshList;}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
package net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.GPUSynchronisation;
|
||||||
|
|
||||||
|
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.CommandBuffer;
|
||||||
|
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanBuffer;
|
||||||
|
import org.lwjgl.system.MemoryStack;
|
||||||
|
import org.lwjgl.vulkan.VkBufferCopy;
|
||||||
|
|
||||||
|
import static org.lwjgl.vulkan.VK10.vkCmdCopyBuffer;
|
||||||
|
|
||||||
|
public record TransferBuffer(VulkanBuffer SrcBuffer, VulkanBuffer DstBuffer) {
|
||||||
|
public void RecordTransferCommand(CommandBuffer commandBuffer){
|
||||||
|
try(var MemStack = MemoryStack.stackPush()){
|
||||||
|
VkBufferCopy.Buffer CopyRegion = VkBufferCopy.calloc(1,MemStack)
|
||||||
|
.srcOffset(0).dstOffset(0).size(SrcBuffer.GetRequestedSize());
|
||||||
|
vkCmdCopyBuffer(commandBuffer.GetVulkanCommandBuffer(),SrcBuffer.GetBuffer(),DstBuffer.GetBuffer(),CopyRegion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue