Working towards 3D rendering
This commit is contained in:
parent
71d3cd400b
commit
84020a922b
22 changed files with 486 additions and 42 deletions
|
|
@ -16,6 +16,7 @@ import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.SwapCha
|
||||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
|
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
|
||||||
import org.lwjgl.system.MemoryStack;
|
import org.lwjgl.system.MemoryStack;
|
||||||
import org.lwjgl.vulkan.VkCommandBufferSubmitInfo;
|
import org.lwjgl.vulkan.VkCommandBufferSubmitInfo;
|
||||||
|
import org.lwjgl.vulkan.VkExtent2D;
|
||||||
import org.lwjgl.vulkan.VkSemaphoreSubmitInfo;
|
import org.lwjgl.vulkan.VkSemaphoreSubmitInfo;
|
||||||
import org.tinylog.Logger;
|
import org.tinylog.Logger;
|
||||||
|
|
||||||
|
|
@ -39,6 +40,7 @@ public class Render {
|
||||||
private final SceneRender sceneRender;
|
private final SceneRender sceneRender;
|
||||||
private int CurrentFrame;
|
private int CurrentFrame;
|
||||||
private final VulkanContext RendererContext;
|
private final VulkanContext RendererContext;
|
||||||
|
private boolean Resize = false;
|
||||||
|
|
||||||
public Render(EngineInstance engineInstance) {
|
public Render(EngineInstance engineInstance) {
|
||||||
RendererContext = new VulkanContext(engineInstance.window());
|
RendererContext = new VulkanContext(engineInstance.window());
|
||||||
|
|
@ -62,6 +64,7 @@ public class Render {
|
||||||
}
|
}
|
||||||
sceneRender = new SceneRender(RendererContext);
|
sceneRender = new SceneRender(RendererContext);
|
||||||
modelsCache = new ModelsCache();
|
modelsCache = new ModelsCache();
|
||||||
|
Resize = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Initialise(InitData initData){
|
public void Initialise(InitData initData){
|
||||||
|
|
@ -105,16 +108,41 @@ public class Render {
|
||||||
var CommandPool = CommandPools[CurrentFrame];
|
var CommandPool = CommandPools[CurrentFrame];
|
||||||
var CommandBuffer = CommandBuffers[CurrentFrame];
|
var CommandBuffer = CommandBuffers[CurrentFrame];
|
||||||
RecordingStart(CommandPool, CommandBuffer);
|
RecordingStart(CommandPool, CommandBuffer);
|
||||||
int ImageIndex = swapChain.FetchNextImage(RendererContext.GetDevice(), PresentCompleteSemaphores[CurrentFrame]);
|
int ImageIndex;// = swapChain.FetchNextImage(RendererContext.GetDevice(), PresentCompleteSemaphores[CurrentFrame]);
|
||||||
if (ImageIndex < 0){
|
if (Resize || (ImageIndex = swapChain.FetchNextImage(RendererContext.GetDevice(), PresentCompleteSemaphores[CurrentFrame])) < 0){
|
||||||
|
resize(engineInstance);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sceneRender.Render(RendererContext,CommandBuffer, modelsCache,ImageIndex);
|
sceneRender.Render(engineInstance,RendererContext,CommandBuffer, modelsCache,ImageIndex);
|
||||||
RecordingStop(CommandBuffer);
|
RecordingStop(CommandBuffer);
|
||||||
Submit(CommandBuffer, CurrentFrame, ImageIndex);
|
Submit(CommandBuffer, CurrentFrame, ImageIndex);
|
||||||
swapChain.PresentImage(PresentQueue, RenderCompleteSemaphores[ImageIndex],ImageIndex);
|
Resize = swapChain.PresentImage(PresentQueue, RenderCompleteSemaphores[ImageIndex],ImageIndex);
|
||||||
CurrentFrame = (CurrentFrame + 1) % VulkanUtils.MAX_IN_FLIGHT;
|
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){
|
private void ResetFence(int currentFrame){
|
||||||
var fence = Fences[currentFrame];
|
var fence = Fences[currentFrame];
|
||||||
fence.Reset(RendererContext);
|
fence.Reset(RendererContext);
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ import java.nio.file.Paths;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
public class EngineConfig {
|
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 long DEFAULT_ACCURACY = 0;
|
||||||
private static final int DEFAULT_TICKRATE = 60;
|
private static final int DEFAULT_TICKRATE = 60;
|
||||||
private static final int DEFAULT_WIDTH = 640;
|
private static final int DEFAULT_WIDTH = 640;
|
||||||
|
|
@ -43,6 +45,10 @@ public class EngineConfig {
|
||||||
private int RequestedImages;
|
private int RequestedImages;
|
||||||
private String IconPath = "/WindowResources/Icon/";
|
private String IconPath = "/WindowResources/Icon/";
|
||||||
private String IconName = "ProgramIcon.png";
|
private String IconName = "ProgramIcon.png";
|
||||||
|
private float FOV = 60f;
|
||||||
|
private float zFarPlane;
|
||||||
|
private float zNearPlane;
|
||||||
|
|
||||||
|
|
||||||
private EngineConfig() {
|
private EngineConfig() {
|
||||||
var EngineConfigVar = new Properties();
|
var EngineConfigVar = new Properties();
|
||||||
|
|
@ -102,6 +108,9 @@ public class EngineConfig {
|
||||||
RequestedImages = Integer.parseInt(EngineConfigVar.getOrDefault("RequestedImages", 3).toString());
|
RequestedImages = Integer.parseInt(EngineConfigVar.getOrDefault("RequestedImages", 3).toString());
|
||||||
ShaderDebug =Boolean.parseBoolean(EngineConfigVar.getOrDefault("Debug_Shaders", false).toString());
|
ShaderDebug =Boolean.parseBoolean(EngineConfigVar.getOrDefault("Debug_Shaders", false).toString());
|
||||||
RecompileShaders =Boolean.parseBoolean(EngineConfigVar.getOrDefault("ShaderRecompiling", true).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());
|
Logger.debug("\n\nsuccessfully loaded configuration: \n{}\n\n",EngineConfigVar.toString());
|
||||||
}
|
}
|
||||||
else if(!ConfigFile.exists()){
|
else if(!ConfigFile.exists()){
|
||||||
|
|
@ -125,6 +134,9 @@ public class EngineConfig {
|
||||||
EngineConfigVar.setProperty("ShaderRecompiling","true");
|
EngineConfigVar.setProperty("ShaderRecompiling","true");
|
||||||
EngineConfigVar.setProperty("throttle_accuracy","100000");
|
EngineConfigVar.setProperty("throttle_accuracy","100000");
|
||||||
EngineConfigVar.setProperty("throttle_on_unfocus","true");
|
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");
|
EngineConfigVar.store(new FileWriter(path.toAbsolutePath().toString() + "/" + FILENAME), "created new properties file");
|
||||||
Logger.debug("Wrote New Config File [{}]", ConfigFile.getAbsolutePath());
|
Logger.debug("Wrote New Config File [{}]", ConfigFile.getAbsolutePath());
|
||||||
} catch (IOException excp2) {
|
} catch (IOException excp2) {
|
||||||
|
|
@ -158,7 +170,9 @@ public class EngineConfig {
|
||||||
public boolean RecompileShaders(){
|
public boolean RecompileShaders(){
|
||||||
return RecompileShaders;
|
return RecompileShaders;
|
||||||
}
|
}
|
||||||
|
public float GetFOV(){return FOV;}
|
||||||
|
public float GetZFarPlane(){return zFarPlane;}
|
||||||
|
public float GetZNearPlane(){return zNearPlane;}
|
||||||
public boolean VkValidated(){
|
public boolean VkValidated(){
|
||||||
return vkValidated;
|
return vkValidated;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package net.halbear.Terrain4J.EngineCore.Logic;
|
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;
|
import net.halbear.Terrain4J.EngineCore.Display.Window;
|
||||||
|
|
||||||
public record EngineInstance(Window window, Scene scene) {
|
public record EngineInstance(Window window, Scene scene) {
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,13 @@ public class VulkanContext {
|
||||||
VulkanLayersOpen+=5;
|
VulkanLayersOpen+=5;
|
||||||
VkPipelineCache = new PipelineCache(device);
|
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(){
|
public void cleanup(){
|
||||||
swapChain.cleanup(device);
|
swapChain.cleanup(device);
|
||||||
surface.cleanup(Instance);
|
surface.cleanup(Instance);
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package net.halbear.Terrain4J.EngineCore.Main;
|
||||||
|
|
||||||
import net.halbear.Terrain4J.EngineCore.Display.Window;
|
import net.halbear.Terrain4J.EngineCore.Display.Window;
|
||||||
import net.halbear.Terrain4J.EngineCore.Logic.*;
|
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.FastTickThread;
|
||||||
import net.halbear.Terrain4J.EngineCore.Threads.MainThread;
|
import net.halbear.Terrain4J.EngineCore.Threads.MainThread;
|
||||||
import net.halbear.Terrain4J.EngineCore.Threads.RenderThread;
|
import net.halbear.Terrain4J.EngineCore.Threads.RenderThread;
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
package net.halbear.Terrain4J.EngineCore.Main;
|
|
||||||
|
|
||||||
import net.halbear.Terrain4J.EngineCore.Display.Window;
|
|
||||||
|
|
||||||
public class Scene {
|
|
||||||
public Scene(Window window) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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;}
|
||||||
|
}
|
||||||
|
|
@ -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<Actor> 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<Actor> 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()));}
|
||||||
|
}
|
||||||
|
|
@ -1,12 +1,9 @@
|
||||||
package net.halbear.Terrain4J.EngineCore.Threads;
|
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.EngineConfig;
|
||||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
|
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
|
||||||
import net.halbear.Terrain4J.EngineCore.Logic.GameLogic;
|
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.PrimaryRuntime;
|
||||||
import net.halbear.Terrain4J.EngineCore.Main.Scene;
|
|
||||||
import org.tinylog.Logger;
|
import org.tinylog.Logger;
|
||||||
|
|
||||||
public class MainThread extends EngineThread {
|
public class MainThread extends EngineThread {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering;
|
|
||||||
|
|
||||||
public class Image {
|
|
||||||
|
|
||||||
public static class ImageData{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -67,12 +67,42 @@ public class Pipeline {
|
||||||
.pAttachments(BlendAttributeState);
|
.pAttachments(BlendAttributeState);
|
||||||
IntBuffer ColourFormats = MemStack.mallocInt(1);
|
IntBuffer ColourFormats = MemStack.mallocInt(1);
|
||||||
ColourFormats.put(0,BuildInfo.GetColourFormat());
|
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)
|
var RendererCreateInfo = VkPipelineRenderingCreateInfo.calloc(MemStack)
|
||||||
.sType$Default()
|
.sType$Default()
|
||||||
.colorAttachmentCount(1)
|
.colorAttachmentCount(1)
|
||||||
.pColorAttachmentFormats(ColourFormats);
|
.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)
|
var PipelineLayoutCreateInfoPtr = VkPipelineLayoutCreateInfo.calloc(MemStack)
|
||||||
.sType$Default();
|
.sType$Default()
|
||||||
|
.pPushConstantRanges(VkPushConstRangeBuffer);
|
||||||
|
|
||||||
VulkanUtils.vkCheck(vkCreatePipelineLayout(device.FetchVulkanDevice(), PipelineLayoutCreateInfoPtr,null,longPtr)
|
VulkanUtils.vkCheck(vkCreatePipelineLayout(device.FetchVulkanDevice(), PipelineLayoutCreateInfoPtr,null,longPtr)
|
||||||
,"Unable to create new pipeline layout");
|
,"Unable to create new pipeline layout");
|
||||||
VulkanPipelineLayout = longPtr.get(0);
|
VulkanPipelineLayout = longPtr.get(0);
|
||||||
|
|
@ -90,6 +120,9 @@ public class Pipeline {
|
||||||
.pDynamicState(VulkanPipelineDynamicStateCreateInfo)
|
.pDynamicState(VulkanPipelineDynamicStateCreateInfo)
|
||||||
.layout(VulkanPipelineLayout)
|
.layout(VulkanPipelineLayout)
|
||||||
.pNext(RendererCreateInfo);
|
.pNext(RendererCreateInfo);
|
||||||
|
|
||||||
|
if(DepthStencil != null){PipelineCreateInfo.pDepthStencilState(DepthStencil);}
|
||||||
|
|
||||||
VulkanUtils.vkCheck(vkCreateGraphicsPipelines(device.FetchVulkanDevice(),
|
VulkanUtils.vkCheck(vkCreateGraphicsPipelines(device.FetchVulkanDevice(),
|
||||||
VkCtx.GetVkPipelineCache().GetVkPipelineCache(), PipelineCreateInfo,
|
VkCtx.GetVkPipelineCache().GetVkPipelineCache(), PipelineCreateInfo,
|
||||||
null, longPtr),"Could not create new pipeline");
|
null, longPtr),"Could not create new pipeline");
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,35 @@ package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline;
|
||||||
|
|
||||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.ShaderModule;
|
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.ShaderModule;
|
||||||
import org.lwjgl.vulkan.VkPipelineVertexInputStateCreateInfo;
|
import org.lwjgl.vulkan.VkPipelineVertexInputStateCreateInfo;
|
||||||
|
import org.lwjgl.vulkan.VkPushConstantRange;
|
||||||
|
|
||||||
|
import static org.lwjgl.vulkan.VK10.VK_FORMAT_UNDEFINED;
|
||||||
|
|
||||||
public class PipelineBuildInfo {
|
public class PipelineBuildInfo {
|
||||||
private final int ColourFormat;
|
private final int ColourFormat;
|
||||||
private final ShaderModule[] ShaderModules;
|
private final ShaderModule[] ShaderModules;
|
||||||
private final VkPipelineVertexInputStateCreateInfo VertexInput;
|
private final VkPipelineVertexInputStateCreateInfo VertexInput;
|
||||||
|
private int DepthFormat;
|
||||||
|
private PushConstantsRange[] PushConstRanges;
|
||||||
|
|
||||||
public PipelineBuildInfo(ShaderModule[] shaderModules, VkPipelineVertexInputStateCreateInfo VertexInput, int ColourFormat){
|
public PipelineBuildInfo(ShaderModule[] shaderModules, VkPipelineVertexInputStateCreateInfo VertexInput, int ColourFormat){
|
||||||
this.ColourFormat = ColourFormat;
|
this.ColourFormat = ColourFormat;
|
||||||
this.ShaderModules = shaderModules;
|
this.ShaderModules = shaderModules;
|
||||||
this.VertexInput = VertexInput;
|
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 int GetColourFormat(){return ColourFormat;}
|
||||||
public ShaderModule[] GetShaderModules(){return ShaderModules;}
|
public ShaderModule[] GetShaderModules(){return ShaderModules;}
|
||||||
public VkPipelineVertexInputStateCreateInfo GetVertexInputStateCreateInfo(){return VertexInput;}
|
public VkPipelineVertexInputStateCreateInfo GetVertexInputStateCreateInfo(){return VertexInput;}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline;
|
||||||
|
|
||||||
|
public record PushConstantsRange(int Stage, int Offset, int Size) {
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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;
|
import static org.lwjgl.vulkan.VK13.VK_VERTEX_INPUT_RATE_VERTEX;
|
||||||
|
|
||||||
public class VertexBufferStructure {
|
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 int POSITION_COMPONENTS = 3;
|
||||||
|
|
||||||
private final VkPipelineVertexInputStateCreateInfo VertexInput;
|
private final VkPipelineVertexInputStateCreateInfo VertexInput;
|
||||||
|
|
@ -23,14 +24,25 @@ public class VertexBufferStructure {
|
||||||
|
|
||||||
int i =0;
|
int i =0;
|
||||||
int Offset = 0;
|
int Offset = 0;
|
||||||
|
//vertex position
|
||||||
VertexInputAttributes.get(i)
|
VertexInputAttributes.get(i)
|
||||||
.binding(0)
|
.binding(0)
|
||||||
.location(i)
|
.location(i)
|
||||||
.format(VK_FORMAT_R32G32B32_SFLOAT)
|
.format(VK_FORMAT_R32G32B32_SFLOAT)
|
||||||
.offset(Offset);
|
.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)
|
VertexInputBindings.get(0)
|
||||||
.binding(0)
|
.binding(0)
|
||||||
.stride(POSITION_COMPONENTS * VulkanUtils.FLOAT_SIZE)
|
.stride(Stride)
|
||||||
.inputRate(VK_VERTEX_INPUT_RATE_VERTEX);
|
.inputRate(VK_VERTEX_INPUT_RATE_VERTEX);
|
||||||
VertexInput
|
VertexInput
|
||||||
.sType$Default()
|
.sType$Default()
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel;
|
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) {
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,11 @@ public class ModelsCache {
|
||||||
|
|
||||||
private static TransferBuffer CreateVerticesBuffer(VulkanContext VkCtx, MeshData meshData){
|
private static TransferBuffer CreateVerticesBuffer(VulkanContext VkCtx, MeshData meshData){
|
||||||
float[] Positions = meshData.Positions();
|
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;
|
int BufferSize = ElementCount * VulkanUtils.FLOAT_SIZE;
|
||||||
var SrcBuffer = new VulkanBuffer(VkCtx,BufferSize,
|
var SrcBuffer = new VulkanBuffer(VkCtx,BufferSize,
|
||||||
VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
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;
|
int Rows = Positions.length / 3;
|
||||||
for(int Row = 0; Row < Rows; Row++){
|
for(int Row = 0; Row < Rows; Row++){
|
||||||
int StartPos = Row * 3;
|
int StartPos = Row * 3;
|
||||||
|
int StartTexCoordPos = Row * 2;
|
||||||
data.put(Positions[StartPos]);
|
data.put(Positions[StartPos]);
|
||||||
data.put(Positions[StartPos+1]);
|
data.put(Positions[StartPos+1]);
|
||||||
data.put(Positions[StartPos+2]);
|
data.put(Positions[StartPos+2]);
|
||||||
|
data.put(TextureCoords[StartTexCoordPos]);
|
||||||
|
data.put(TextureCoords[StartTexCoordPos + 1]);
|
||||||
}
|
}
|
||||||
SrcBuffer.UnMapMemory(VkCtx);
|
SrcBuffer.UnMapMemory(VkCtx);
|
||||||
return new TransferBuffer(SrcBuffer,DstBuffer);
|
return new TransferBuffer(SrcBuffer,DstBuffer);
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
package net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen;
|
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.EngineConfig;
|
||||||
import net.halbear.Terrain4J.EngineCore.Logic.VulkanContext;
|
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.Pipeline;
|
||||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.PipelineBuildInfo;
|
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.ShaderCompiler;
|
||||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.ShaderModule;
|
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.ShaderModule;
|
||||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VertexBufferStructure;
|
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.Structure.DeviceLayers.CommandBuffer;
|
||||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
|
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
|
||||||
import org.lwjgl.system.MemoryStack;
|
import org.lwjgl.system.MemoryStack;
|
||||||
|
import org.lwjgl.system.MemoryUtil;
|
||||||
import org.lwjgl.util.shaderc.Shaderc;
|
import org.lwjgl.util.shaderc.Shaderc;
|
||||||
import org.lwjgl.vulkan.*;
|
import org.lwjgl.vulkan.*;
|
||||||
import org.tinylog.Logger;
|
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.LongBuffer;
|
import java.nio.LongBuffer;
|
||||||
import java.util.Arrays;
|
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.KHRSynchronization2.VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR;
|
||||||
import static org.lwjgl.vulkan.VK13.*;
|
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 VkClearValue ClearValueColour;
|
||||||
private VkRenderingAttachmentInfo.Buffer[] AttachmentInfoColour;
|
private VkRenderingAttachmentInfo.Buffer[] AttachmentInfoColour;
|
||||||
private VkRenderingInfo[] RenderInfo;
|
private VkRenderingInfo[] RenderInfo;
|
||||||
|
|
@ -44,14 +50,47 @@ public class SceneRender { //dynamic rendering;
|
||||||
private final Pipeline VkPipeline;
|
private final Pipeline VkPipeline;
|
||||||
|
|
||||||
public SceneRender(VulkanContext vulkanContext){
|
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));
|
ClearValueColour = VkClearValue.calloc().color(c->c.float32(0,R).float32(1,G).float32(2,B).float32(3,1.0f));
|
||||||
AttachmentInfoColour = CreateColourAttachmentsInfo(vulkanContext,ClearValueColour);
|
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);
|
ShaderModule[] shaderModules = SceneRender.CreateShaderModules(vulkanContext);
|
||||||
VkPipeline = CreatePipeline(vulkanContext, shaderModules);
|
VkPipeline = CreatePipeline(vulkanContext, shaderModules);
|
||||||
Arrays.asList(shaderModules).forEach(shaderModule -> shaderModule.CleanUp(vulkanContext));
|
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){
|
private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx){
|
||||||
if(EngineConfig.getInstance().RecompileShaders()){
|
if(EngineConfig.getInstance().RecompileShaders()){
|
||||||
ShaderCompiler.CompileGLSLShaderOnChange(VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader);
|
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)
|
new ShaderModule(VkCtx, VK_SHADER_STAGE_FRAGMENT_BIT, FRAGMENT_SHADER_FILE_SPV)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] ShaderModules){
|
private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] ShaderModules){
|
||||||
var vertexBufferStructure = new VertexBufferStructure();
|
var vertexBufferStructure = new VertexBufferStructure();
|
||||||
var BuildInfo = new PipelineBuildInfo(ShaderModules,vertexBufferStructure.getVertexInput(),
|
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);
|
var pipeline = new Pipeline(VkCtx, BuildInfo);
|
||||||
vertexBufferStructure.cleanup();
|
vertexBufferStructure.cleanup();
|
||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateColours(VulkanContext vulkanContext){
|
public void UpdateColours(VulkanContext vulkanContext){
|
||||||
if (Gb){
|
if (Gb){
|
||||||
if (G < 1.0f && Math.random() <0.5) G+=0.0005f;
|
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));
|
ClearValueColour = VkClearValue.calloc().color(c->c.float32(0,R).float32(1,G).float32(2,B).float32(3,1.0f));
|
||||||
AttachmentInfoColour = CreateColourAttachmentsInfo(vulkanContext,ClearValueColour);
|
AttachmentInfoColour = CreateColourAttachmentsInfo(vulkanContext,ClearValueColour);
|
||||||
RenderInfo = CreateRenderInfo(vulkanContext, AttachmentInfoColour);
|
RenderInfo = CreateRenderInfo(vulkanContext, AttachmentInfoColour, AttInfoDepth);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Render(VulkanContext vulkanContext, CommandBuffer commandBuffer,ModelsCache modelsCache, int ImageIndex){
|
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_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_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);
|
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]);
|
vkCmdBeginRendering(CommandHandle, RenderInfo[ImageIndex]);
|
||||||
|
|
||||||
vkCmdBindPipeline(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkPipeline.GetVulkanPipeline());
|
vkCmdBindPipeline(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkPipeline.GetVulkanPipeline());
|
||||||
|
|
||||||
VkExtent2D swapChainExtent = swapChain.GetSwapChainExtent();
|
VkExtent2D swapChainExtent = swapChain.GetSwapChainExtent();
|
||||||
|
|
@ -129,8 +183,11 @@ public class SceneRender { //dynamic rendering;
|
||||||
|
|
||||||
LongBuffer offsets = MemStack.mallocLong(1).put(0,0L);
|
LongBuffer offsets = MemStack.mallocLong(1).put(0,0L);
|
||||||
LongBuffer vertexBuffer = MemStack.mallocLong(1);
|
LongBuffer vertexBuffer = MemStack.mallocLong(1);
|
||||||
|
|
||||||
|
//Fetch Actor Code to be written Later
|
||||||
var VulkanModels = modelsCache.GetModelMap().values();
|
var VulkanModels = modelsCache.GetModelMap().values();
|
||||||
for(VulkanModel VkModel : VulkanModels){
|
for(VulkanModel VkModel : VulkanModels){
|
||||||
|
|
||||||
for(VulkanMesh mesh : VkModel.GetVkMeshList()){
|
for(VulkanMesh mesh : VkModel.GetVkMeshList()){
|
||||||
vertexBuffer.put(0,mesh.VerticesBuffer().GetBuffer());
|
vertexBuffer.put(0,mesh.VerticesBuffer().GetBuffer());
|
||||||
vkCmdBindVertexBuffers(CommandHandle,0,vertexBuffer,offsets);
|
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();
|
SwapChain swapChain = vulkanContext.GetSwapChain();
|
||||||
int ImageCount = swapChain.GetImageCount();
|
int ImageCount = swapChain.GetImageCount();
|
||||||
var Result = new VkRenderingInfo[ImageCount];
|
var Result = new VkRenderingInfo[ImageCount];
|
||||||
|
|
||||||
try(var MemStack = MemoryStack.stackPush()){
|
try(var MemStack = MemoryStack.stackPush()){
|
||||||
VkExtent2D Extent = swapChain.GetSwapChainExtent();
|
VkExtent2D Extent = swapChain.GetSwapChainExtent();
|
||||||
var RenderArea = VkRect2D.calloc(MemStack).extent(Extent);
|
var RenderArea = VkRect2D.calloc(MemStack).extent(Extent);
|
||||||
|
|
||||||
for(int i = 0; i < ImageCount; i++){
|
for(int i = 0; i < ImageCount; i++){
|
||||||
var RenderInfo = VkRenderingInfo.calloc()
|
var RenderInfo = VkRenderingInfo.calloc()
|
||||||
.sType$Default()
|
.sType$Default()
|
||||||
.renderArea(RenderArea)
|
.renderArea(RenderArea)
|
||||||
.layerCount(1)
|
.layerCount(1)
|
||||||
.pColorAttachments(ColourAttachments[i]);
|
.pColorAttachments(ColourAttachments[i])
|
||||||
|
.pDepthAttachment(DepthAttachments[i]);
|
||||||
Result[i] = RenderInfo;
|
Result[i] = RenderInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -185,6 +245,11 @@ public class SceneRender { //dynamic rendering;
|
||||||
VkPipeline.CleanUp(VkCtx);
|
VkPipeline.CleanUp(VkCtx);
|
||||||
Arrays.asList(RenderInfo).forEach(VkRenderingInfo::free);
|
Arrays.asList(RenderInfo).forEach(VkRenderingInfo::free);
|
||||||
Arrays.asList(AttachmentInfoColour).forEach(VkRenderingAttachmentInfo.Buffer::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();
|
ClearValueColour.free();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ public class VulkanUtils {
|
||||||
|
|
||||||
public static final int FLOAT_SIZE = 4;
|
public static final int FLOAT_SIZE = 4;
|
||||||
public static final int INT_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){
|
public static int MemoryTypeFromProperties(VulkanContext vulkanContext, int TypeBits, int ReqMask){
|
||||||
int result = -1;
|
int result = -1;
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ display_height=480
|
||||||
display_width=640
|
display_width=640
|
||||||
|
|
||||||
#Engine Core Settings
|
#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
|
frame_accuracy=0
|
||||||
throttle_on_unfocus=true
|
throttle_on_unfocus=true
|
||||||
throttle_accuracy=500000000
|
throttle_accuracy=500000000
|
||||||
|
|
@ -31,4 +31,9 @@ RequestedImages=3
|
||||||
#This is the name of the GPU you want the engine to use
|
#This is the name of the GPU you want the engine to use
|
||||||
PhysicalDeviceName=
|
PhysicalDeviceName=
|
||||||
|
|
||||||
|
#3D Projection Properties
|
||||||
|
field_of_view=60.0f
|
||||||
|
z_near_plane=1.0f
|
||||||
|
z_far_plane=100.0f
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue