Vertex Rendering!
This commit is contained in:
parent
852336e188
commit
2f626ba00f
20 changed files with 450 additions and 25 deletions
8
resources/shaders/scene_fragment.glsl
Normal file
8
resources/shaders/scene_fragment.glsl
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 outFragColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
outFragColor = vec4(1, 0, 0, 1);
|
||||||
|
}
|
||||||
BIN
resources/shaders/scene_fragment.glsl.spv
Normal file
BIN
resources/shaders/scene_fragment.glsl.spv
Normal file
Binary file not shown.
8
resources/shaders/scene_vertex.glsl
Normal file
8
resources/shaders/scene_vertex.glsl
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
layout(location = 0) in vec3 inPos;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = vec4(inPos,1);
|
||||||
|
}
|
||||||
BIN
resources/shaders/scene_vertex.glsl.spv
Normal file
BIN
resources/shaders/scene_vertex.glsl.spv
Normal file
Binary file not shown.
|
|
@ -2,7 +2,10 @@ package net.halbear.Terrain4J.EngineCore.Display;
|
||||||
|
|
||||||
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.InitData;
|
||||||
import net.halbear.Terrain4J.EngineCore.Logic.VulkanContext;
|
import net.halbear.Terrain4J.EngineCore.Logic.VulkanContext;
|
||||||
|
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.ModelData;
|
||||||
|
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.ModelsCache;
|
||||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.CommandBuffer;
|
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.CommandPool;
|
||||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.GPUSynchronisation.Fence;
|
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.GPUSynchronisation.Fence;
|
||||||
|
|
@ -17,12 +20,15 @@ import org.lwjgl.vulkan.VkSemaphoreSubmitInfo;
|
||||||
import org.tinylog.Logger;
|
import org.tinylog.Logger;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static org.lwjgl.vulkan.VK13.VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT;
|
import static org.lwjgl.vulkan.VK13.VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT;
|
||||||
import static org.lwjgl.vulkan.VK13.VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
|
import static org.lwjgl.vulkan.VK13.VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
|
|
||||||
public class Render {
|
public class Render {
|
||||||
|
|
||||||
|
private final ModelsCache modelsCache;
|
||||||
|
|
||||||
private final CommandBuffer[] CommandBuffers;
|
private final CommandBuffer[] CommandBuffers;
|
||||||
private final CommandPool[] CommandPools;
|
private final CommandPool[] CommandPools;
|
||||||
private final Fence[] Fences;
|
private final Fence[] Fences;
|
||||||
|
|
@ -55,6 +61,14 @@ public class Render {
|
||||||
RenderCompleteSemaphores[i] = new Semaphore(RendererContext);
|
RenderCompleteSemaphores[i] = new Semaphore(RendererContext);
|
||||||
}
|
}
|
||||||
sceneRender = new SceneRender(RendererContext);
|
sceneRender = new SceneRender(RendererContext);
|
||||||
|
modelsCache = new ModelsCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Initialise(InitData initData){
|
||||||
|
List<ModelData> Models = initData.Models();
|
||||||
|
Logger.debug("Loading {} models", Models.size());
|
||||||
|
modelsCache.loadModels(RendererContext, Models, CommandPools[0], GraphicsQueue);
|
||||||
|
Logger.debug("Loaded {} models", Models.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RecordingStart(CommandPool commandPool, CommandBuffer commandBuffer){
|
private void RecordingStart(CommandPool commandPool, CommandBuffer commandBuffer){
|
||||||
|
|
@ -69,7 +83,7 @@ public class Render {
|
||||||
public void cleanup() {
|
public void cleanup() {
|
||||||
RendererContext.GetDevice().waitIdle();
|
RendererContext.GetDevice().waitIdle();
|
||||||
Logger.debug("Waiting Vulkan Context");
|
Logger.debug("Waiting Vulkan Context");
|
||||||
sceneRender.cleanup();
|
sceneRender.cleanup(RendererContext);
|
||||||
Logger.debug("Dynamic Renderer Cleaned up");
|
Logger.debug("Dynamic Renderer Cleaned up");
|
||||||
Arrays.asList(RenderCompleteSemaphores).forEach(i->i.cleanup(RendererContext));
|
Arrays.asList(RenderCompleteSemaphores).forEach(i->i.cleanup(RendererContext));
|
||||||
Logger.debug("Render Semaphores cleaned up");
|
Logger.debug("Render Semaphores cleaned up");
|
||||||
|
|
@ -82,6 +96,7 @@ public class Render {
|
||||||
CommandPools[i].cleanup(RendererContext);
|
CommandPools[i].cleanup(RendererContext);
|
||||||
}
|
}
|
||||||
Logger.debug("Command pools cleaned up");
|
Logger.debug("Command pools cleaned up");
|
||||||
|
modelsCache.CleanUp(RendererContext);
|
||||||
RendererContext.cleanup();
|
RendererContext.cleanup();
|
||||||
}
|
}
|
||||||
public void render(EngineInstance engineInstance){
|
public void render(EngineInstance engineInstance){
|
||||||
|
|
@ -94,7 +109,7 @@ public class Render {
|
||||||
if (ImageIndex < 0){
|
if (ImageIndex < 0){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sceneRender.Render(RendererContext,CommandBuffer,ImageIndex);
|
sceneRender.Render(RendererContext,CommandBuffer, modelsCache,ImageIndex);
|
||||||
RecordingStop(CommandBuffer);
|
RecordingStop(CommandBuffer);
|
||||||
Submit(CommandBuffer, CurrentFrame, ImageIndex);
|
Submit(CommandBuffer, CurrentFrame, ImageIndex);
|
||||||
swapChain.PresentImage(PresentQueue, RenderCompleteSemaphores[ImageIndex],ImageIndex);
|
swapChain.PresentImage(PresentQueue, RenderCompleteSemaphores[ImageIndex],ImageIndex);
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,8 @@ public class EngineConfig {
|
||||||
public static int FrameRate_WINDOW =0;
|
public static int FrameRate_WINDOW =0;
|
||||||
public static int RENDERFRAMES =0;
|
public static int RENDERFRAMES =0;
|
||||||
public static boolean VSYNC = false;
|
public static boolean VSYNC = false;
|
||||||
|
public static boolean ShaderDebug = false;
|
||||||
|
public static boolean RecompileShaders = false;
|
||||||
private boolean vkValidated;
|
private boolean vkValidated;
|
||||||
private String PhysicalDeviceName;
|
private String PhysicalDeviceName;
|
||||||
private int RequestedImages;
|
private int RequestedImages;
|
||||||
|
|
@ -42,7 +44,12 @@ public class EngineConfig {
|
||||||
public boolean GetVSYNC(){
|
public boolean GetVSYNC(){
|
||||||
return VSYNC;
|
return VSYNC;
|
||||||
}
|
}
|
||||||
|
public boolean DebugShaders(){
|
||||||
|
return ShaderDebug;
|
||||||
|
}
|
||||||
|
public boolean RecompileShaders(){
|
||||||
|
return RecompileShaders;
|
||||||
|
}
|
||||||
private EngineConfig() {
|
private EngineConfig() {
|
||||||
var EngineConfigVar = new Properties();
|
var EngineConfigVar = new Properties();
|
||||||
Path path = Paths.get("");
|
Path path = Paths.get("");
|
||||||
|
|
@ -95,6 +102,8 @@ public class EngineConfig {
|
||||||
VSYNC = Boolean.parseBoolean(EngineConfigVar.getOrDefault("vsync", true).toString());
|
VSYNC = Boolean.parseBoolean(EngineConfigVar.getOrDefault("vsync", true).toString());
|
||||||
vkValidated = Boolean.parseBoolean(EngineConfigVar.getOrDefault("vkValidated", false).toString());
|
vkValidated = Boolean.parseBoolean(EngineConfigVar.getOrDefault("vkValidated", false).toString());
|
||||||
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());
|
||||||
|
RecompileShaders =Boolean.parseBoolean(EngineConfigVar.getOrDefault("ShaderRecompiling", true).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()){
|
||||||
|
|
@ -112,6 +121,8 @@ public class EngineConfig {
|
||||||
EngineConfigVar.setProperty("display_height","720");
|
EngineConfigVar.setProperty("display_height","720");
|
||||||
EngineConfigVar.setProperty("vsync","true");
|
EngineConfigVar.setProperty("vsync","true");
|
||||||
EngineConfigVar.setProperty("vkValidated","false");
|
EngineConfigVar.setProperty("vkValidated","false");
|
||||||
|
EngineConfigVar.setProperty("Debug_Shaders","false");
|
||||||
|
EngineConfigVar.setProperty("ShaderRecompiling","true");
|
||||||
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) {
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package net.halbear.Terrain4J.EngineCore.Logic;
|
||||||
|
|
||||||
public interface GameLogic {
|
public interface GameLogic {
|
||||||
void cleanup();
|
void cleanup();
|
||||||
void Initialise(EngineInstance engineInstance);
|
InitData Initialise(EngineInstance engineInstance);
|
||||||
void Input(EngineInstance engineInstance, long FrameDiffNanoSeconds);
|
void Input(EngineInstance engineInstance, long FrameDiffNanoSeconds);
|
||||||
void Update(EngineInstance engineInstance, long FrameDiffNanoSeconds);
|
void Update(EngineInstance engineInstance, long FrameDiffNanoSeconds);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
package net.halbear.Terrain4J.EngineCore.Logic;
|
||||||
|
|
||||||
|
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.ModelData;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public record InitData(List<ModelData> Models) {
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package net.halbear.Terrain4J.EngineCore.Logic;
|
package net.halbear.Terrain4J.EngineCore.Logic;
|
||||||
|
|
||||||
import net.halbear.Terrain4J.EngineCore.Display.Window;
|
import net.halbear.Terrain4J.EngineCore.Display.Window;
|
||||||
|
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.PipelineCache;
|
||||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.Device;
|
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.Device;
|
||||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.PhysicalDevice;
|
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.PhysicalDevice;
|
||||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.Surface;
|
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.Surface;
|
||||||
|
|
@ -15,6 +16,7 @@ public class VulkanContext {
|
||||||
private Surface surface;
|
private Surface surface;
|
||||||
private final PhysicalDevice PhysDevice;
|
private final PhysicalDevice PhysDevice;
|
||||||
private SwapChain swapChain;
|
private SwapChain swapChain;
|
||||||
|
private final PipelineCache VkPipelineCache;
|
||||||
|
|
||||||
public VulkanContext(Window window){
|
public VulkanContext(Window window){
|
||||||
var EngineGlobals = EngineConfig.getInstance();
|
var EngineGlobals = EngineConfig.getInstance();
|
||||||
|
|
@ -24,20 +26,21 @@ public class VulkanContext {
|
||||||
surface = new Surface(Instance, PhysDevice, window);
|
surface = new Surface(Instance, PhysDevice, window);
|
||||||
swapChain = new SwapChain(window, device, surface, EngineGlobals.GetRequestedImages(), EngineGlobals.GetVSYNC());
|
swapChain = new SwapChain(window, device, surface, EngineGlobals.GetRequestedImages(), EngineGlobals.GetVSYNC());
|
||||||
VulkanLayersOpen+=5;
|
VulkanLayersOpen+=5;
|
||||||
|
VkPipelineCache = new PipelineCache(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cleanup(){
|
public void cleanup(){
|
||||||
swapChain.cleanup(device);
|
swapChain.cleanup(device);
|
||||||
surface.cleanup(Instance);
|
surface.cleanup(Instance);
|
||||||
|
VkPipelineCache.CleanUp(device);
|
||||||
device.cleanup();
|
device.cleanup();
|
||||||
PhysDevice.cleanup();
|
PhysDevice.cleanup();
|
||||||
Instance.cleanup();
|
Instance.cleanup();
|
||||||
Logger.debug("Render Thread Finished ending Vulkan Processes\nVulkan Layers Open:[{}]", VulkanContext.VulkanLayersOpen < 0 ? "All processes closed and vulkan instance removed" : VulkanContext.VulkanLayersOpen);
|
Logger.debug("Render Thread Finished ending Vulkan Processes\nVulkan Layers Open:[{}]", VulkanContext.VulkanLayersOpen < 0 ? "All processes closed and vulkan instance removed" : VulkanContext.VulkanLayersOpen);
|
||||||
VulkanLayersOpen--;
|
VulkanLayersOpen--;
|
||||||
}
|
}
|
||||||
public SwapChain GetSwapChain(){
|
public PipelineCache GetVkPipelineCache(){return VkPipelineCache;}
|
||||||
return swapChain;
|
public SwapChain GetSwapChain(){return swapChain;}
|
||||||
}
|
|
||||||
public Device GetDevice(){
|
public Device GetDevice(){
|
||||||
return device;
|
return device;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,12 @@ package net.halbear.Terrain4J.EngineCore.Main;
|
||||||
|
|
||||||
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.Vulkan.Rendering.VkModel.MeshData;
|
||||||
|
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.ModelData;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class GameCore implements GameLogic {
|
public class GameCore implements GameLogic {
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -10,8 +16,19 @@ public class GameCore implements GameLogic {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void Initialise(EngineInstance engineInstance) {
|
public InitData Initialise(EngineInstance engineInstance) {
|
||||||
|
var ModelID = "TriangleModel";
|
||||||
|
MeshData meshData = new MeshData("triangle-mesh", new float[]{
|
||||||
|
-0.5f, -0.5f, 0.0f,
|
||||||
|
0.0f, 0.5f, 0.0f,
|
||||||
|
0.5f, -0.5f, 0.0f},
|
||||||
|
new int[]{0, 1, 2});
|
||||||
|
List<MeshData> MeshDataList = new ArrayList<>();
|
||||||
|
MeshDataList.add(meshData);
|
||||||
|
ModelData modelData = new ModelData(ModelID, MeshDataList);
|
||||||
|
List<ModelData> models = new ArrayList<>();
|
||||||
|
models.add(modelData);
|
||||||
|
return new InitData(models);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,7 @@
|
||||||
package net.halbear.Terrain4J.EngineCore.Main;
|
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.EngineConfig;
|
import net.halbear.Terrain4J.EngineCore.Logic.*;
|
||||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
|
|
||||||
import net.halbear.Terrain4J.EngineCore.Logic.GameLogic;
|
|
||||||
import net.halbear.Terrain4J.EngineCore.Logic.VulkanContext;
|
|
||||||
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;
|
||||||
import org.tinylog.Logger;
|
import org.tinylog.Logger;
|
||||||
|
|
@ -24,9 +21,10 @@ public class PrimaryRuntime {
|
||||||
|
|
||||||
public PrimaryRuntime(String windowTitle, GameLogic appLogic) {
|
public PrimaryRuntime(String windowTitle, GameLogic appLogic) {
|
||||||
window = new Window(windowTitle);
|
window = new Window(windowTitle);
|
||||||
|
InitData initData = appLogic.Initialise(engineInstance);
|
||||||
engineInstance = new EngineInstance(window, new Scene(window));
|
engineInstance = new EngineInstance(window, new Scene(window));
|
||||||
PrimaryThread = new MainThread(engineInstance, appLogic);
|
PrimaryThread = new MainThread(engineInstance, appLogic);
|
||||||
DrawingThread = new RenderThread(window, engineInstance);
|
DrawingThread = new RenderThread(window, engineInstance, initData);
|
||||||
Thread.currentThread().setName("Terrain4J Primary Runtime Thread");
|
Thread.currentThread().setName("Terrain4J Primary Runtime Thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ 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 net.halbear.Terrain4J.EngineCore.Main.Scene;
|
||||||
import org.tinylog.Logger;
|
import org.tinylog.Logger;
|
||||||
|
|
@ -34,7 +35,6 @@ public class MainThread implements Runnable {
|
||||||
}
|
}
|
||||||
public MainThread(EngineInstance engineInstance, GameLogic appLogic){
|
public MainThread(EngineInstance engineInstance, GameLogic appLogic){
|
||||||
this.gameLogic = appLogic;
|
this.gameLogic = appLogic;
|
||||||
gameLogic.Initialise(engineInstance);
|
|
||||||
Logger.debug("Starting Main Thread");
|
Logger.debug("Starting Main Thread");
|
||||||
UpdateTickRateThreshold();
|
UpdateTickRateThreshold();
|
||||||
mainThread = new Thread(this);
|
mainThread = new Thread(this);
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import net.halbear.Terrain4J.EngineCore.Display.Render;
|
||||||
import net.halbear.Terrain4J.EngineCore.Display.Window;
|
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.InitData;
|
||||||
import net.halbear.Terrain4J.EngineCore.Logic.VulkanContext;
|
import net.halbear.Terrain4J.EngineCore.Logic.VulkanContext;
|
||||||
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
|
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
|
||||||
import org.tinylog.Logger;
|
import org.tinylog.Logger;
|
||||||
|
|
@ -15,9 +16,10 @@ public class RenderThread implements Runnable {
|
||||||
private final Render render;
|
private final Render render;
|
||||||
private Window window;
|
private Window window;
|
||||||
|
|
||||||
public RenderThread(Window window,EngineInstance engineInstance) {
|
public RenderThread(Window window, EngineInstance engineInstance, InitData initData) {
|
||||||
//this.window = window;
|
//this.window = window;
|
||||||
render = new Render(engineInstance);
|
render = new Render(engineInstance);
|
||||||
|
render.Initialise(initData);
|
||||||
renderThread = new Thread(this);
|
renderThread = new Thread(this);
|
||||||
renderThread.setName("Terrain4J Vulkan Render Thread");
|
renderThread.setName("Terrain4J Vulkan Render Thread");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline;
|
||||||
|
|
||||||
|
import net.halbear.Terrain4J.EngineCore.Logic.VulkanContext;
|
||||||
|
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.ShaderModule;
|
||||||
|
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.*;
|
||||||
|
import org.tinylog.Logger;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.IntBuffer;
|
||||||
|
import java.nio.LongBuffer;
|
||||||
|
|
||||||
|
import static org.lwjgl.vulkan.VK10.*;
|
||||||
|
import static org.lwjgl.vulkan.VK13.VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||||
|
|
||||||
|
public class Pipeline {
|
||||||
|
private final long VulkanPipeline;
|
||||||
|
private final long VulkanPipelineLayout;
|
||||||
|
|
||||||
|
public Pipeline(VulkanContext VkCtx, PipelineBuildInfo BuildInfo){
|
||||||
|
Logger.debug("Creating Pipeline");
|
||||||
|
Device device = VkCtx.GetDevice();
|
||||||
|
try(var MemStack = MemoryStack.stackPush()){
|
||||||
|
LongBuffer longPtr = MemStack.mallocLong(1);
|
||||||
|
ByteBuffer main = MemStack.UTF8("main");
|
||||||
|
ShaderModule[] ShaderModules = BuildInfo.GetShaderModules();
|
||||||
|
int ModuleCount = ShaderModules.length;
|
||||||
|
var ShaderStages = VkPipelineShaderStageCreateInfo.calloc(ModuleCount, MemStack);
|
||||||
|
for(int i = 0; i < ModuleCount; i++){
|
||||||
|
ShaderModule shaderModule = ShaderModules[i];
|
||||||
|
ShaderStages.get(i)
|
||||||
|
.sType$Default()
|
||||||
|
.stage(shaderModule.GetShaderStage())
|
||||||
|
.module(shaderModule.GetHandle())
|
||||||
|
.pName(main);
|
||||||
|
}
|
||||||
|
|
||||||
|
var AssemblyStateCreateInfo = VkPipelineInputAssemblyStateCreateInfo.calloc(MemStack)
|
||||||
|
.sType$Default()
|
||||||
|
.topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
|
||||||
|
var ViewportCreateStateInfo = VkPipelineViewportStateCreateInfo.calloc(MemStack)
|
||||||
|
.sType$Default()
|
||||||
|
.viewportCount(1)
|
||||||
|
.scissorCount(1);
|
||||||
|
var RasterizationStateCreateInfo = VkPipelineRasterizationStateCreateInfo.calloc(MemStack)
|
||||||
|
.sType$Default()
|
||||||
|
.polygonMode(VK_POLYGON_MODE_FILL)
|
||||||
|
.cullMode(VK_CULL_MODE_NONE)
|
||||||
|
.frontFace(VK_FRONT_FACE_CLOCKWISE)
|
||||||
|
.lineWidth(1.0f);
|
||||||
|
var MultisampleStateCreateInfo = VkPipelineMultisampleStateCreateInfo.calloc(MemStack)
|
||||||
|
.sType$Default()
|
||||||
|
.rasterizationSamples(VK_SAMPLE_COUNT_1_BIT);
|
||||||
|
VkPipelineDynamicStateCreateInfo VulkanPipelineDynamicStateCreateInfo = VkPipelineDynamicStateCreateInfo.calloc(MemStack)
|
||||||
|
.sType(VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO)
|
||||||
|
.pDynamicStates(MemStack.ints(
|
||||||
|
VK_DYNAMIC_STATE_VIEWPORT,
|
||||||
|
VK_DYNAMIC_STATE_SCISSOR
|
||||||
|
));
|
||||||
|
var BlendAttributeState = VkPipelineColorBlendAttachmentState.calloc(1,MemStack)
|
||||||
|
.colorWriteMask(VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT)
|
||||||
|
.blendEnable(false);
|
||||||
|
var ColourBlendState = VkPipelineColorBlendStateCreateInfo.calloc(MemStack)
|
||||||
|
.sType$Default()
|
||||||
|
.pAttachments(BlendAttributeState);
|
||||||
|
IntBuffer ColourFormats = MemStack.mallocInt(1);
|
||||||
|
ColourFormats.put(0,BuildInfo.GetColourFormat());
|
||||||
|
var RendererCreateInfo = VkPipelineRenderingCreateInfo.calloc(MemStack)
|
||||||
|
.sType$Default()
|
||||||
|
.colorAttachmentCount(1)
|
||||||
|
.pColorAttachmentFormats(ColourFormats);
|
||||||
|
var PipelineLayoutCreateInfoPtr = VkPipelineLayoutCreateInfo.calloc(MemStack)
|
||||||
|
.sType$Default();
|
||||||
|
VulkanUtils.vkCheck(vkCreatePipelineLayout(device.FetchVulkanDevice(), PipelineLayoutCreateInfoPtr,null,longPtr)
|
||||||
|
,"Unable to create new pipeline layout");
|
||||||
|
VulkanPipelineLayout = longPtr.get(0);
|
||||||
|
|
||||||
|
var PipelineCreateInfo = VkGraphicsPipelineCreateInfo.calloc(1,MemStack)
|
||||||
|
.sType$Default()
|
||||||
|
.renderPass(VK_NULL_HANDLE)
|
||||||
|
.pStages(ShaderStages)
|
||||||
|
.pVertexInputState(BuildInfo.GetVertexInputStateCreateInfo())
|
||||||
|
.pInputAssemblyState(AssemblyStateCreateInfo)
|
||||||
|
.pViewportState(ViewportCreateStateInfo)
|
||||||
|
.pRasterizationState(RasterizationStateCreateInfo)
|
||||||
|
.pColorBlendState(ColourBlendState)
|
||||||
|
.pMultisampleState(MultisampleStateCreateInfo)
|
||||||
|
.pDynamicState(VulkanPipelineDynamicStateCreateInfo)
|
||||||
|
.layout(VulkanPipelineLayout)
|
||||||
|
.pNext(RendererCreateInfo);
|
||||||
|
VulkanUtils.vkCheck(vkCreateGraphicsPipelines(device.FetchVulkanDevice(),
|
||||||
|
VkCtx.GetVkPipelineCache().GetVkPipelineCache(), PipelineCreateInfo,
|
||||||
|
null, longPtr),"Could not create new pipeline");
|
||||||
|
VulkanPipeline = longPtr.get(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public long GetVulkanPipeline(){return VulkanPipeline;}
|
||||||
|
public long GetVulkanPipelineLayout(){return VulkanPipelineLayout;}
|
||||||
|
public void CleanUp(VulkanContext VkCtx){
|
||||||
|
Logger.debug("destroying Pipeline");
|
||||||
|
VkDevice vkDevice = VkCtx.GetDevice().FetchVulkanDevice();
|
||||||
|
vkDestroyPipelineLayout(vkDevice,VulkanPipelineLayout,null);
|
||||||
|
vkDestroyPipeline(vkDevice,VulkanPipeline,null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline;
|
||||||
|
|
||||||
|
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.ShaderModule;
|
||||||
|
import org.lwjgl.vulkan.VkPipelineVertexInputStateCreateInfo;
|
||||||
|
|
||||||
|
public class PipelineBuildInfo {
|
||||||
|
private final int ColourFormat;
|
||||||
|
private final ShaderModule[] ShaderModules;
|
||||||
|
private final VkPipelineVertexInputStateCreateInfo VertexInput;
|
||||||
|
public PipelineBuildInfo(ShaderModule[] shaderModules, VkPipelineVertexInputStateCreateInfo VertexInput, int ColourFormat){
|
||||||
|
this.ColourFormat = ColourFormat;
|
||||||
|
this.ShaderModules = shaderModules;
|
||||||
|
this.VertexInput = VertexInput;
|
||||||
|
}
|
||||||
|
public int GetColourFormat(){return ColourFormat;}
|
||||||
|
public ShaderModule[] GetShaderModules(){return ShaderModules;}
|
||||||
|
public VkPipelineVertexInputStateCreateInfo GetVertexInputStateCreateInfo(){return VertexInput;}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline;
|
||||||
|
|
||||||
|
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.VkPipelineCacheCreateInfo;
|
||||||
|
import org.tinylog.Logger;
|
||||||
|
|
||||||
|
import java.nio.LongBuffer;
|
||||||
|
|
||||||
|
import static org.lwjgl.vulkan.VK13.vkCreatePipelineCache;
|
||||||
|
import static org.lwjgl.vulkan.VK13.vkDestroyPipelineCache;
|
||||||
|
|
||||||
|
public class PipelineCache {
|
||||||
|
private final long VulkanPipelineCache;
|
||||||
|
public PipelineCache(Device device){
|
||||||
|
Logger.debug("Creating new Vk Pipeline Cache");
|
||||||
|
try(var MemStack = MemoryStack.stackPush()){
|
||||||
|
var PipelineCacheCreateInfo = VkPipelineCacheCreateInfo.calloc(MemStack).sType$Default();
|
||||||
|
LongBuffer longPtr = MemStack.mallocLong(1);
|
||||||
|
VulkanUtils.vkCheck(vkCreatePipelineCache(device.FetchVulkanDevice(), PipelineCacheCreateInfo
|
||||||
|
,null, longPtr),"Error Creating New Pipeline Cache");
|
||||||
|
VulkanPipelineCache = longPtr.get(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void CleanUp(Device device){
|
||||||
|
Logger.debug("Destroying Vulkan Pipeline Cache");
|
||||||
|
vkDestroyPipelineCache(device.FetchVulkanDevice(), VulkanPipelineCache, null);
|
||||||
|
}
|
||||||
|
public long GetVkPipelineCache(){return VulkanPipelineCache;}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader;
|
||||||
|
|
||||||
|
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
|
||||||
|
import org.lwjgl.util.shaderc.Shaderc;
|
||||||
|
import org.tinylog.Logger;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
|
||||||
|
public class ShaderCompiler {
|
||||||
|
private ShaderCompiler(){}
|
||||||
|
|
||||||
|
public static byte[] CompileShader(String ShaderCode, int ShaderType, boolean HLSLshader){
|
||||||
|
long Compiler = 0;
|
||||||
|
long Options = 0;
|
||||||
|
byte[] CompiledShader;
|
||||||
|
try{
|
||||||
|
Compiler = Shaderc.shaderc_compiler_initialize();
|
||||||
|
Options = Shaderc.shaderc_compile_options_initialize();
|
||||||
|
if(EngineConfig.getInstance().DebugShaders()){
|
||||||
|
Shaderc.shaderc_compile_options_set_generate_debug_info(Options);
|
||||||
|
Shaderc.shaderc_compile_options_set_optimization_level(Options,0);
|
||||||
|
}
|
||||||
|
Shaderc.shaderc_compile_options_set_source_language(Options, HLSLshader ? Shaderc.shaderc_source_language_hlsl : Shaderc.shaderc_source_language_glsl);
|
||||||
|
long CompilationResult = Shaderc.shaderc_compile_into_spv(
|
||||||
|
Compiler,
|
||||||
|
ShaderCode,
|
||||||
|
ShaderType,
|
||||||
|
HLSLshader ? "shader.hlsl" : "shader.glsl",
|
||||||
|
"main",
|
||||||
|
Options
|
||||||
|
);
|
||||||
|
if(Shaderc.shaderc_result_get_compilation_status(CompilationResult) !=
|
||||||
|
Shaderc.shaderc_compilation_status_success){
|
||||||
|
throw new RuntimeException("Failed to Compile Shader: " + Shaderc.shaderc_result_get_error_message(CompilationResult));
|
||||||
|
}
|
||||||
|
ByteBuffer buffer = Shaderc.shaderc_result_get_bytes(CompilationResult);
|
||||||
|
assert buffer != null;
|
||||||
|
CompiledShader = new byte[buffer.remaining()];
|
||||||
|
buffer.get(CompiledShader);
|
||||||
|
} finally{
|
||||||
|
Shaderc.shaderc_compile_options_release(Options);
|
||||||
|
Shaderc.shaderc_compiler_release(Compiler);
|
||||||
|
}
|
||||||
|
return CompiledShader;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CompileGLSLShaderOnChange(String ShaderFile, int ShaderType){
|
||||||
|
byte[] CompiledShader;
|
||||||
|
try{
|
||||||
|
var glslFile = new File(ShaderFile);
|
||||||
|
var spvFile = new File(ShaderFile + ".spv");
|
||||||
|
if(!spvFile.exists() || glslFile.lastModified() > spvFile.lastModified()){
|
||||||
|
Logger.debug("Compiling new [{}] shader from [{}] source",spvFile.getPath(),glslFile.getPath());
|
||||||
|
var ShaderCode = new String(Files.readAllBytes(glslFile.toPath()));
|
||||||
|
CompiledShader = CompileShader(ShaderCode, ShaderType, false);
|
||||||
|
Files.write(spvFile.toPath(), CompiledShader);
|
||||||
|
} else{
|
||||||
|
Logger.debug("Loading Compiled Shader [{}]",spvFile.getPath());
|
||||||
|
}
|
||||||
|
} catch(IOException exception){
|
||||||
|
Logger.error(exception);
|
||||||
|
throw new RuntimeException(exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader;
|
||||||
|
|
||||||
|
import net.halbear.Terrain4J.EngineCore.Logic.VulkanContext;
|
||||||
|
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
|
||||||
|
import org.lwjgl.system.MemoryStack;
|
||||||
|
import org.lwjgl.vulkan.VkShaderModuleCreateInfo;
|
||||||
|
import static org.lwjgl.vulkan.VK13.vkCreateShaderModule;
|
||||||
|
import static org.lwjgl.vulkan.VK13.vkDestroyShaderModule;
|
||||||
|
import org.tinylog.Logger;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.LongBuffer;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
|
||||||
|
|
||||||
|
public class ShaderModule {
|
||||||
|
private final long Handle;
|
||||||
|
private final int ShaderStage;
|
||||||
|
|
||||||
|
public ShaderModule(VulkanContext VkCtx, int ShaderStage, String ShaderSPVFile){
|
||||||
|
try{
|
||||||
|
byte[] Contents = Files.readAllBytes(new File(ShaderSPVFile).toPath());
|
||||||
|
Handle = CreateShaderModule(VkCtx, Contents);
|
||||||
|
this.ShaderStage = ShaderStage;
|
||||||
|
} catch(IOException exception){
|
||||||
|
Logger.error("Cannot Read Shader Files",exception);
|
||||||
|
throw new RuntimeException(exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long CreateShaderModule(VulkanContext VkCtx, byte[] Code){
|
||||||
|
try(var MemStack = MemoryStack.stackPush()){
|
||||||
|
ByteBuffer CodePointer = MemStack.malloc(Code.length).put(0,Code);
|
||||||
|
var ShaderModuleCreateInfo = VkShaderModuleCreateInfo.calloc(MemStack)
|
||||||
|
.sType$Default()
|
||||||
|
.pCode(CodePointer);
|
||||||
|
LongBuffer LongPoiner = MemStack.mallocLong(1);
|
||||||
|
VulkanUtils.vkCheck(vkCreateShaderModule(VkCtx.GetDevice().FetchVulkanDevice(), ShaderModuleCreateInfo, null, LongPoiner),"Failed to create a new Shader Module");
|
||||||
|
return LongPoiner.get(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CleanUp(VulkanContext VkCtx){
|
||||||
|
vkDestroyShaderModule(VkCtx.GetDevice().FetchVulkanDevice(), Handle, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long GetHandle(){return Handle;}
|
||||||
|
public int GetShaderStage(){return ShaderStage;}
|
||||||
|
}
|
||||||
|
|
@ -3,12 +3,23 @@ package net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen;
|
||||||
import net.halbear.Terrain4J.EngineCore.Display.Render;
|
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.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.Shader.ShaderCompiler;
|
||||||
|
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.ShaderModule;
|
||||||
|
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VertexBufferStructure;
|
||||||
|
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.ModelsCache;
|
||||||
|
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.VulkanMesh;
|
||||||
|
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.util.shaderc.Shaderc;
|
||||||
import org.lwjgl.vulkan.*;
|
import org.lwjgl.vulkan.*;
|
||||||
import org.tinylog.Logger;
|
import org.tinylog.Logger;
|
||||||
|
|
||||||
|
import java.nio.LongBuffer;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import static org.lwjgl.vulkan.KHRSwapchain.VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
import static org.lwjgl.vulkan.KHRSwapchain.VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||||
|
|
@ -25,12 +36,40 @@ public class SceneRender { //dynamic rendering;
|
||||||
private boolean Rb = false;
|
private boolean Rb = false;
|
||||||
private boolean Gb = true;
|
private boolean Gb = true;
|
||||||
private boolean Bb = false;
|
private boolean Bb = false;
|
||||||
|
|
||||||
|
private static final String FRAGMENT_SHADER_FILE_GLSL = "resources/shaders/scene_fragment.glsl";
|
||||||
|
private static final String FRAGMENT_SHADER_FILE_SPV = FRAGMENT_SHADER_FILE_GLSL + ".spv";
|
||||||
|
private static final String VERTEX_SHADER_FILE_GLSL = "resources/shaders/scene_vertex.glsl";
|
||||||
|
private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv";
|
||||||
|
private final Pipeline VkPipeline;
|
||||||
|
|
||||||
public SceneRender(VulkanContext vulkanContext){
|
public SceneRender(VulkanContext vulkanContext){
|
||||||
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);
|
||||||
}
|
|
||||||
|
|
||||||
|
ShaderModule[] shaderModules = SceneRender.CreateShaderModules(vulkanContext);
|
||||||
|
VkPipeline = CreatePipeline(vulkanContext, shaderModules);
|
||||||
|
Arrays.asList(shaderModules).forEach(shaderModule -> shaderModule.CleanUp(vulkanContext));
|
||||||
|
}
|
||||||
|
private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx){
|
||||||
|
if(EngineConfig.getInstance().RecompileShaders()){
|
||||||
|
ShaderCompiler.CompileGLSLShaderOnChange(VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader);
|
||||||
|
ShaderCompiler.CompileGLSLShaderOnChange(FRAGMENT_SHADER_FILE_GLSL, Shaderc.shaderc_fragment_shader);
|
||||||
|
}
|
||||||
|
return new ShaderModule[]{
|
||||||
|
new ShaderModule(VkCtx, VK_SHADER_STAGE_VERTEX_BIT, VERTEX_SHADER_FILE_SPV),
|
||||||
|
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());
|
||||||
|
var pipeline = new Pipeline(VkCtx, BuildInfo);
|
||||||
|
vertexBufferStructure.cleanup();
|
||||||
|
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;
|
||||||
|
|
@ -58,7 +97,7 @@ public class SceneRender { //dynamic rendering;
|
||||||
RenderInfo = CreateRenderInfo(vulkanContext, AttachmentInfoColour);
|
RenderInfo = CreateRenderInfo(vulkanContext, AttachmentInfoColour);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Render(VulkanContext vulkanContext, CommandBuffer commandBuffer, int ImageIndex){
|
public void Render(VulkanContext vulkanContext, CommandBuffer commandBuffer,ModelsCache modelsCache, int ImageIndex){
|
||||||
UpdateColours(vulkanContext);
|
UpdateColours(vulkanContext);
|
||||||
try(var MemStack = MemoryStack.stackPush()){
|
try(var MemStack = MemoryStack.stackPush()){
|
||||||
SwapChain swapChain = vulkanContext.GetSwapChain();
|
SwapChain swapChain = vulkanContext.GetSwapChain();
|
||||||
|
|
@ -70,6 +109,35 @@ public class SceneRender { //dynamic rendering;
|
||||||
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);
|
||||||
vkCmdBeginRendering(CommandHandle, RenderInfo[ImageIndex]);
|
vkCmdBeginRendering(CommandHandle, RenderInfo[ImageIndex]);
|
||||||
|
vkCmdBindPipeline(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkPipeline.GetVulkanPipeline());
|
||||||
|
|
||||||
|
VkExtent2D swapChainExtent = swapChain.GetSwapChainExtent();
|
||||||
|
int width = swapChainExtent.width();
|
||||||
|
int height = swapChainExtent.height();
|
||||||
|
var Viewport = VkViewport.calloc(1,MemStack)
|
||||||
|
.x(0)
|
||||||
|
.y(height)
|
||||||
|
.height(-height)
|
||||||
|
.width(width)
|
||||||
|
.minDepth(0.0F)
|
||||||
|
.maxDepth(1.0F);
|
||||||
|
vkCmdSetViewport(CommandHandle, 0, Viewport);
|
||||||
|
var Scissor = VkRect2D.calloc(1,MemStack)
|
||||||
|
.extent(it -> it.width(width).height(height))
|
||||||
|
.offset(it->it.x(0).y(0));
|
||||||
|
vkCmdSetScissor(CommandHandle, 0, Scissor);
|
||||||
|
|
||||||
|
LongBuffer offsets = MemStack.mallocLong(1).put(0,0L);
|
||||||
|
LongBuffer vertexBuffer = MemStack.mallocLong(1);
|
||||||
|
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);
|
||||||
|
vkCmdBindIndexBuffer(CommandHandle,mesh.IndicesBuffer().GetBuffer(),0,VK_INDEX_TYPE_UINT32);
|
||||||
|
vkCmdDrawIndexed(CommandHandle,mesh.IndicesCount(),1,0,0,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
vkCmdEndRendering(CommandHandle);
|
vkCmdEndRendering(CommandHandle);
|
||||||
|
|
||||||
VulkanUtils.ImageBarrier(MemStack, CommandHandle, SwapChainImage,
|
VulkanUtils.ImageBarrier(MemStack, CommandHandle, SwapChainImage,
|
||||||
|
|
@ -113,9 +181,11 @@ public class SceneRender { //dynamic rendering;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
public void cleanup(){
|
public void cleanup(VulkanContext 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);
|
||||||
ClearValueColour.free();
|
ClearValueColour.free();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,13 @@
|
||||||
#Default Window dimensions
|
#Application Properties
|
||||||
|
#Title that shows up on app window
|
||||||
|
Software_Title=Terrain4J Game Engine
|
||||||
|
Software_Icon=ProgramIcon.png
|
||||||
|
Software_Icon_Path=/WindowResources/Icon/
|
||||||
|
#Launch Window dimensions
|
||||||
display_height=480
|
display_height=480
|
||||||
display_width=640
|
display_width=640
|
||||||
|
|
||||||
|
#Engine Core Settings
|
||||||
#the precision of frames, set this to 16000 and it will limit the whole engine to 64FPS
|
#the precision of frames, set this to 16000 and it will limit the whole engine to 64FPS
|
||||||
frame_accuracy=0
|
frame_accuracy=0
|
||||||
#event tick rate for game process
|
#event tick rate for game process
|
||||||
|
|
@ -8,15 +15,16 @@ master_tick_rate=120
|
||||||
main_thread_tickrate=120
|
main_thread_tickrate=120
|
||||||
fast_thread_tickrate=240
|
fast_thread_tickrate=240
|
||||||
cap_main_to_tickrate=false
|
cap_main_to_tickrate=false
|
||||||
|
|
||||||
|
#Renderer Properties
|
||||||
|
Debug_Shaders = false
|
||||||
|
ShaderRecompiling = true
|
||||||
#Vulkan Debugging toggle
|
#Vulkan Debugging toggle
|
||||||
vkValidated=true
|
vkValidated=true
|
||||||
|
|
||||||
vsync=false
|
vsync=false
|
||||||
|
#Vsync images
|
||||||
RequestedImages=3
|
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=
|
||||||
#Title that shows up on app window
|
|
||||||
Software_Title=Terrain4J Game Engine
|
|
||||||
Software_Icon=ProgramIcon.png
|
|
||||||
Software_Icon_Path=/WindowResources/Icon/
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue