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