Updated to deferred renderer
This commit is contained in:
parent
2d37c574d6
commit
4a7c820cec
316 changed files with 1192631 additions and 158432 deletions
|
|
@ -6,6 +6,7 @@ import static org.lwjgl.openal.AL10.*;
|
|||
|
||||
public class AudioSource {
|
||||
private final int SourceID;
|
||||
private float Gain = 1.0f;
|
||||
public AudioSource(boolean loop, boolean relative){
|
||||
this.SourceID = alGenSources();
|
||||
alSourcei(SourceID, AL_LOOPING, loop ? AL_TRUE: AL_FALSE);
|
||||
|
|
@ -20,10 +21,16 @@ public class AudioSource {
|
|||
Stop();
|
||||
alSourcei(SourceID, AL_BUFFER, Buffer);
|
||||
}
|
||||
public float GetGain(){
|
||||
return Gain;
|
||||
}
|
||||
public boolean isPlaying(){return alGetSourcei(SourceID, AL_SOURCE_STATE) == AL_PLAYING;}
|
||||
public void Pause(){alSourcePause(SourceID);}
|
||||
public void Play(){alSourcePlay(SourceID);}
|
||||
public void SetGain(float gain){alSourcef(SourceID, AL_GAIN, gain);}
|
||||
public void SetGain(float gain){
|
||||
alSourcef(SourceID, AL_GAIN, gain);
|
||||
Gain = gain;
|
||||
}
|
||||
public void SetPosition(Vector3f position){alSource3f(SourceID, AL_POSITION, position.x,position.y,position.z);}
|
||||
public void Stop(){alSourceStop(SourceID);}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,16 +6,20 @@ import net.halbear.Terrain4J.EngineCore.Logic.InitData;
|
|||
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.GUI.GuiRenderer;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.GUI.GuiTexture;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Deferred.LightRenderer;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.DeferredRendering.LightRenderer;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.TextureCache;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.PostProcessing.PostProcess;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.*;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.MaterialData;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.MaterialsCache;
|
||||
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.CommandPool;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.GPUSynchronisation.Fence;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.GPUSynchronisation.Semaphore;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.Queues.Queue;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.SceneRender;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.DeferredSceneRender;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.ForwardSceneRender;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.SceneRenderer;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.SwapChain.SwapChain;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.SwapChain.SwapChainRender;
|
||||
|
|
@ -56,15 +60,19 @@ public class Render {
|
|||
private final MaterialsCache materialsCache;
|
||||
private TextureCache textureCache;
|
||||
private EngineConfig.AntiAliasType CurrentAAMode;
|
||||
private final boolean Deferred;
|
||||
|
||||
public TextureCache GetTextureCache(){return textureCache;}
|
||||
public MaterialsCache GetMaterialsCache(){return materialsCache;}
|
||||
public VulkanContext GetVulkanContext(){return RendererContext;}
|
||||
|
||||
public EngineConfig.AntiAliasType GetCurrentAAMode(){return CurrentAAMode;}
|
||||
public SceneRender GetSceneRender(){return (SceneRender) sceneRender;}
|
||||
public SceneRenderer GetSceneRender(){return sceneRender;}
|
||||
|
||||
public boolean GetDeferred(){return Deferred;}
|
||||
|
||||
public Render(EngineInstance engineInstance) {
|
||||
Deferred = EngineConfig.getInstance().DeferredRendering();
|
||||
RendererContext = new VulkanContext(engineInstance.window());
|
||||
CurrentFrame = 0;
|
||||
GraphicsQueue = new Queue.GraphicsQueue(RendererContext, 0);
|
||||
|
|
@ -78,15 +86,21 @@ public class Render {
|
|||
for(int i = 0; i < VulkanUtils.MAX_IN_FLIGHT; i++){
|
||||
CommandPools[i] = new CommandPool(RendererContext, GraphicsQueue.GetQueueFamilyIndex(), false);
|
||||
CommandBuffers[i] = new CommandBuffer(RendererContext, CommandPools[i],true, true);
|
||||
PresentCompleteSemaphores[i] = new Semaphore(RendererContext);
|
||||
Fences[i] = new Fence(RendererContext, true);
|
||||
PresentCompleteSemaphores[i] = new Semaphore(RendererContext);
|
||||
}
|
||||
for(int i = 0; i < SwapChainImageCount; i++){
|
||||
RenderCompleteSemaphores[i] = new Semaphore(RendererContext);
|
||||
}
|
||||
sceneRender = new SceneRender(RendererContext);
|
||||
lightRenderer = new LightRenderer(RendererContext, sceneRender.GetMRTAttachments().GetAllAttachments());
|
||||
PostProcessor = new PostProcess(RendererContext,sceneRender.GetCurrentDeferred() ? lightRenderer.GetColourAttachment() : sceneRender.GetAttachmentColour());
|
||||
if(Deferred) {
|
||||
sceneRender = new DeferredSceneRender(RendererContext, engineInstance);
|
||||
lightRenderer = new LightRenderer(RendererContext, sceneRender.GetMRTAttachments().GetAllAttachments());
|
||||
PostProcessor = new PostProcess(RendererContext, lightRenderer.getAttachment());
|
||||
} else{
|
||||
sceneRender = new ForwardSceneRender(RendererContext);
|
||||
PostProcessor = new PostProcess(RendererContext, sceneRender.GetAttachmentColour());
|
||||
lightRenderer = null;
|
||||
}
|
||||
GuiRender = new GuiRenderer(engineInstance, RendererContext, GraphicsQueue, PostProcessor.GetAttachment());
|
||||
swapChainRender = new SwapChainRender(RendererContext,PostProcessor.GetAttachment());
|
||||
textureCache = new TextureCache();
|
||||
|
|
@ -100,10 +114,14 @@ public class Render {
|
|||
|
||||
Materials.addAll(initData.Materials());
|
||||
Logger.debug("Loading {} Materials", Materials.size());
|
||||
//materialsCache.CleanUp(RendererContext);
|
||||
materialsCache.LoadMaterials(RendererContext, Materials,textureCache, CommandPools[0], GraphicsQueue);
|
||||
Logger.debug("Loaded {} Materials", Materials.size());
|
||||
|
||||
List<GuiTexture> guiTextures = initData.GuiTextures();
|
||||
if(guiTextures != null){
|
||||
initData.GuiTextures().forEach(texture -> textureCache.AddTexture(RendererContext, texture.TexturePath(), texture.TexturePath(), VK_FORMAT_R8G8B8A8_SRGB));
|
||||
}
|
||||
|
||||
Logger.debug("Transitioning Textures");
|
||||
//textureCache.CleanUp(RendererContext);
|
||||
textureCache.TransitionTexts(RendererContext, CommandPools[0], GraphicsQueue);
|
||||
|
|
@ -115,11 +133,6 @@ public class Render {
|
|||
modelsCache.loadModels(RendererContext, Models, CommandPools[0], GraphicsQueue);
|
||||
Logger.debug("Loaded {} models", Models.size());
|
||||
|
||||
List<GuiTexture> guiTextures = initData.GuiTextures();
|
||||
if(guiTextures != null){
|
||||
initData.GuiTextures().forEach(texture -> textureCache.AddTexture(RendererContext, texture.TexturePath(), texture.TexturePath(), VK_FORMAT_R8G8B8A8_SRGB));
|
||||
}
|
||||
|
||||
sceneRender.LoadMaterials(RendererContext,materialsCache,textureCache);
|
||||
GuiRender.LoadTextures(RendererContext,initData.GuiTextures(),textureCache);
|
||||
}
|
||||
|
|
@ -140,10 +153,13 @@ public class Render {
|
|||
RendererContext.GetDevice().waitIdle();
|
||||
Logger.debug("Waiting Vulkan Context");
|
||||
sceneRender.cleanup(RendererContext);
|
||||
if(lightRenderer != null)lightRenderer.cleanup(RendererContext);
|
||||
PostProcessor.CleanUp(RendererContext);
|
||||
swapChainRender.CleanUp(RendererContext);
|
||||
lightRenderer.CleanUp(RendererContext);
|
||||
GuiRender.CleanUp(RendererContext);
|
||||
modelsCache.CleanUp(RendererContext);
|
||||
materialsCache.CleanUp(RendererContext);
|
||||
textureCache.CleanUp(RendererContext);
|
||||
Logger.debug("Dynamic Renderer Cleaned up");
|
||||
Arrays.asList(RenderCompleteSemaphores).forEach(i->i.cleanup(RendererContext));
|
||||
Logger.debug("Render Semaphores cleaned up");
|
||||
|
|
@ -156,31 +172,28 @@ public class Render {
|
|||
CommandPools[i].cleanup(RendererContext);
|
||||
}
|
||||
Logger.debug("Command pools cleaned up");
|
||||
modelsCache.CleanUp(RendererContext);
|
||||
materialsCache.CleanUp(RendererContext);
|
||||
textureCache.CleanUp(RendererContext);
|
||||
RendererContext.cleanup();
|
||||
}
|
||||
public void render(EngineInstance engineInstance){
|
||||
public void DeferredRender(EngineInstance engineInstance){
|
||||
SwapChain swapChain = RendererContext.GetSwapChain();
|
||||
WaitForFence(CurrentFrame);
|
||||
|
||||
int ImageIndex;
|
||||
if (Resize || (ImageIndex = swapChain.FetchNextImage(RendererContext.GetDevice(), PresentCompleteSemaphores[CurrentFrame])) < 0){
|
||||
resize(engineInstance);
|
||||
return;
|
||||
}
|
||||
int imageAcquisitionIndex = CurrentFrame;
|
||||
|
||||
var CommandPool = CommandPools[CurrentFrame];
|
||||
var CommandBuffer = CommandBuffers[CurrentFrame];
|
||||
RecordingStart(CommandPool, CommandBuffer);
|
||||
|
||||
sceneRender.Render(engineInstance,RendererContext,CommandBuffer, modelsCache,materialsCache,CurrentFrame);
|
||||
lightRenderer.Render(RendererContext,CommandBuffer,sceneRender.GetMRTAttachments());
|
||||
PostProcessor.Render(RendererContext,CommandBuffer,sceneRender.GetCurrentDeferred() ? lightRenderer.GetColourAttachment() : sceneRender.GetAttachmentColour());
|
||||
|
||||
lightRenderer.render(engineInstance, RendererContext, CommandBuffer, sceneRender.GetMRTAttachments(), CurrentFrame);
|
||||
PostProcessor.Render(RendererContext,CommandBuffer,lightRenderer.getAttachment());
|
||||
GuiRender.Render(RendererContext,CommandBuffer,CurrentFrame,PostProcessor.GetAttachment());
|
||||
|
||||
int ImageIndex;
|
||||
if (Resize || (ImageIndex = swapChain.FetchNextImage(RendererContext.GetDevice(), PresentCompleteSemaphores[imageAcquisitionIndex])) < 0){
|
||||
resize(engineInstance);
|
||||
return;
|
||||
}
|
||||
|
||||
swapChainRender.Render(RendererContext,CommandBuffer,PostProcessor.GetAttachment(),ImageIndex);
|
||||
|
||||
RecordingStop(CommandBuffer);
|
||||
|
|
@ -189,6 +202,36 @@ public class Render {
|
|||
CurrentFrame = (CurrentFrame + 1) % VulkanUtils.MAX_IN_FLIGHT;
|
||||
}
|
||||
|
||||
public void ForwardRender(EngineInstance engineInstance){
|
||||
SwapChain swapChain = RendererContext.GetSwapChain();
|
||||
WaitForFence(CurrentFrame); //problem child found
|
||||
var CommandPool = CommandPools[CurrentFrame];
|
||||
var CommandBuffer = CommandBuffers[CurrentFrame];
|
||||
RecordingStart(CommandPool, CommandBuffer);
|
||||
|
||||
sceneRender.Render(engineInstance,RendererContext,CommandBuffer, modelsCache,materialsCache,CurrentFrame);
|
||||
PostProcessor.Render(RendererContext,CommandBuffer,sceneRender.GetAttachmentColour());
|
||||
GuiRender.Render(RendererContext,CommandBuffer,CurrentFrame,PostProcessor.GetAttachment());
|
||||
|
||||
int ImageIndex;
|
||||
if (Resize || (ImageIndex = swapChain.FetchNextImage(RendererContext.GetDevice(), PresentCompleteSemaphores[CurrentFrame])) < 0){
|
||||
resize(engineInstance);
|
||||
return;
|
||||
}
|
||||
|
||||
swapChainRender.Render(RendererContext,CommandBuffer,PostProcessor.GetAttachment(),ImageIndex);
|
||||
|
||||
RecordingStop(CommandBuffer);
|
||||
Submit(CommandBuffer, CurrentFrame, ImageIndex);
|
||||
Resize = swapChain.PresentImage(PresentQueue, RenderCompleteSemaphores[ImageIndex],ImageIndex);
|
||||
CurrentFrame = (CurrentFrame + 1) % VulkanUtils.MAX_IN_FLIGHT;
|
||||
}
|
||||
|
||||
public void render(EngineInstance engineInstance){
|
||||
if(Deferred) DeferredRender(engineInstance);
|
||||
else ForwardRender(engineInstance);
|
||||
}
|
||||
|
||||
private void resize(EngineInstance engineInstance){
|
||||
Window window = engineInstance.window();
|
||||
if(window.getWidth() == 0 && window.getHeight() == 0){
|
||||
|
|
@ -210,8 +253,12 @@ public class Render {
|
|||
VkExtent2D extend = RendererContext.GetSwapChain().GetSwapChainExtent();
|
||||
engineInstance.scene().GetProjection().Resize(extend.width(),extend.height());
|
||||
sceneRender.Resize(engineInstance,RendererContext);
|
||||
lightRenderer.Resize(RendererContext,sceneRender.GetMRTAttachments().GetAllAttachments());
|
||||
PostProcessor.Resize(RendererContext,sceneRender.GetCurrentDeferred() ? lightRenderer.GetColourAttachment() : sceneRender.GetAttachmentColour());
|
||||
if(Deferred) {
|
||||
lightRenderer.resize(RendererContext, sceneRender.GetMRTAttachments().GetAllAttachments());
|
||||
PostProcessor.Resize(RendererContext, lightRenderer.getAttachment());
|
||||
} else{
|
||||
PostProcessor.Resize(RendererContext, sceneRender.GetAttachmentColour());
|
||||
}
|
||||
GuiRender.Resize(RendererContext,PostProcessor.GetAttachment());
|
||||
swapChainRender.Resize(RendererContext,PostProcessor.GetAttachment());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Logic;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.SceneRender;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.DeferredSceneRender;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.ForwardSceneRender;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.io.*;
|
||||
|
|
@ -218,7 +218,8 @@ public class EngineConfig {
|
|||
renderer = Integer.parseInt(EngineConfigVar.getOrDefault("Renderer", 1).toString()) == 0 ? Renderer.Forward: Renderer.Deferred;
|
||||
CompatibilityMode = Boolean.parseBoolean(EngineConfigVar.getOrDefault("compatibility_mode", false).toString());
|
||||
AlphaToCoverage = Boolean.parseBoolean(EngineConfigVar.getOrDefault("AlphaToCoverage", false).toString());
|
||||
SceneRender.SetDualPassRendering(Boolean.parseBoolean(EngineConfigVar.getOrDefault("DualPassRendering", true).toString()));
|
||||
ForwardSceneRender.SetDualPassRendering(Boolean.parseBoolean(EngineConfigVar.getOrDefault("DualPassRendering", true).toString()));
|
||||
DeferredSceneRender.SetDualPassRendering(Boolean.parseBoolean(EngineConfigVar.getOrDefault("DualPassRendering", true).toString()));
|
||||
switch(AAValue){
|
||||
case 0:
|
||||
AAMode = AntiAliasType.NONE;
|
||||
|
|
|
|||
|
|
@ -3,13 +3,14 @@ package net.halbear.Terrain4J.EngineCore.Logic;
|
|||
import net.halbear.Terrain4J.EngineCore.Audio.AudioManager;
|
||||
import net.halbear.Terrain4J.EngineCore.Display.Render;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.IScene;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.Scene;
|
||||
import net.halbear.Terrain4J.EngineCore.Display.Window;
|
||||
import net.halbear.Terrain4J.EngineCore.Threads.FastTickThread;
|
||||
import net.halbear.Terrain4J.EngineCore.Threads.MainThread;
|
||||
import net.halbear.Terrain4J.EngineCore.Threads.RenderThread;
|
||||
|
||||
public record EngineInstance(Window window, Scene scene, PrimaryRuntime PrimaryThread, AudioManager audioManager) {
|
||||
public record EngineInstance(Window window, IScene scene, PrimaryRuntime PrimaryThread, AudioManager audioManager) {
|
||||
public void cleanup(){
|
||||
window.cleanup();
|
||||
audioManager.CleanUp();
|
||||
|
|
|
|||
|
|
@ -113,27 +113,56 @@ public class ModelCompiler {
|
|||
if(Result == aiReturn_SUCCESS){
|
||||
diffuse.set(colour.r(), colour.g(), colour.b(), colour.a());
|
||||
}
|
||||
String DiffuseTexture = ProcessTexture(aiScene, aiMaterial, BaseDirectory, aiTextureType_DIFFUSE);
|
||||
return new MaterialData(ModelName + "-mat-" + Position,DiffuseTexture,diffuse);
|
||||
String DiffuseTexture = ProcessTexture(aiScene,aiMaterial,BaseDirectory,aiTextureType_DIFFUSE);
|
||||
String NormalTexture = ProcessTexture(aiScene,aiMaterial,BaseDirectory,aiTextureType_NORMALS);
|
||||
String MetallicRoughTexture = ProcessTexture(aiScene, aiMaterial, BaseDirectory, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE);
|
||||
|
||||
float[] MetallicArray = new float[]{0.0f};
|
||||
int[] MaxPointer = new int[]{1};
|
||||
Result = aiGetMaterialFloatArray(aiMaterial,AI_MATKEY_METALLIC_FACTOR,aiTextureType_NONE,0,MetallicArray,MaxPointer);
|
||||
if(Result != aiReturn_SUCCESS){
|
||||
MetallicArray = new float[]{0.0f};
|
||||
}
|
||||
|
||||
float[] RoughnessArray = new float[]{0.0f};
|
||||
Result = aiGetMaterialFloatArray(aiMaterial,AI_MATKEY_ROUGHNESS_FACTOR,aiTextureType_NONE,0,RoughnessArray,MaxPointer);
|
||||
if(Result != aiReturn_SUCCESS){
|
||||
RoughnessArray = new float[]{0.0f};
|
||||
}
|
||||
|
||||
|
||||
return new MaterialData(ModelName + "-mat-" + Position,DiffuseTexture,NormalTexture, MetallicRoughTexture,diffuse,RoughnessArray[0],MetallicArray[0]);
|
||||
}
|
||||
|
||||
public static MeshData ProcessMesh(AIMesh aiMesh, List<MaterialData> MaterialList, int MeshPosition, ModelBinaryData BinaryData) throws IOException {
|
||||
List<Float> vertices = ProcessVertices(aiMesh);
|
||||
List<Float> Vertices = ProcessVertices(aiMesh);
|
||||
List<Float> Normals = ProcessNormals(aiMesh);
|
||||
List<Float> Tangents = ProcessTangents(aiMesh,Normals);
|
||||
List<Float> BiTangents = ProcessBiTangents(aiMesh,Normals);
|
||||
List<Float> textureCoordinates = ProcessTextureCoords(aiMesh);
|
||||
List<Integer> indices = ProcessIndices(aiMesh);
|
||||
|
||||
int VerticesSize = vertices.size();
|
||||
int VerticesSize = Vertices.size();
|
||||
if(textureCoordinates.isEmpty()){textureCoordinates = Collections.nCopies((VerticesSize/3)*2,0.0f);}
|
||||
|
||||
DataOutputStream VerticesOutput = BinaryData.GetVertexOutput();
|
||||
int Rows = VerticesSize/3;
|
||||
int VertexIncrement = (VerticesSize + textureCoordinates.size()) * VulkanUtils.FLOAT_SIZE;
|
||||
int VertexIncrement = (VerticesSize + textureCoordinates.size() + Normals.size() + Tangents.size() + BiTangents.size()) * VulkanUtils.FLOAT_SIZE;
|
||||
for(int row = 0; row < Rows; row++){
|
||||
int StartPos = row * 3;
|
||||
int StartTextureCoord = row * 2;
|
||||
VerticesOutput.writeFloat(vertices.get(StartPos));
|
||||
VerticesOutput.writeFloat(vertices.get(StartPos + 1));
|
||||
VerticesOutput.writeFloat(vertices.get(StartPos + 2));
|
||||
VerticesOutput.writeFloat(Vertices.get(StartPos));
|
||||
VerticesOutput.writeFloat(Vertices.get(StartPos + 1));
|
||||
VerticesOutput.writeFloat(Vertices.get(StartPos + 2));
|
||||
VerticesOutput.writeFloat(Normals.get(StartPos));
|
||||
VerticesOutput.writeFloat(Normals.get(StartPos + 1));
|
||||
VerticesOutput.writeFloat(Normals.get(StartPos + 2));
|
||||
VerticesOutput.writeFloat(Tangents.get(StartPos));
|
||||
VerticesOutput.writeFloat(Tangents.get(StartPos + 1));
|
||||
VerticesOutput.writeFloat(Tangents.get(StartPos + 2));
|
||||
VerticesOutput.writeFloat(BiTangents.get(StartPos));
|
||||
VerticesOutput.writeFloat(BiTangents.get(StartPos + 1));
|
||||
VerticesOutput.writeFloat(BiTangents.get(StartPos + 2));
|
||||
VerticesOutput.writeFloat(textureCoordinates.get(StartTextureCoord));
|
||||
VerticesOutput.writeFloat(textureCoordinates.get(StartTextureCoord + 1));
|
||||
}
|
||||
|
|
@ -158,6 +187,48 @@ public class ModelCompiler {
|
|||
return meshData;
|
||||
}
|
||||
|
||||
public static List<Float> ProcessBiTangents(AIMesh aiMesh, List<Float> Normals){
|
||||
List<Float> BiTangents = new ArrayList<>();
|
||||
AIVector3D.Buffer aiBiTangents = aiMesh.mBitangents();
|
||||
while(aiBiTangents != null && aiBiTangents.remaining() > 0){
|
||||
AIVector3D aiBiTangent = aiBiTangents.get();
|
||||
BiTangents.add(aiBiTangent.x());
|
||||
BiTangents.add(aiBiTangent.y());
|
||||
BiTangents.add(aiBiTangent.z());
|
||||
}
|
||||
if (BiTangents.isEmpty()) { // create empty BiTangents if assimp can't generate them
|
||||
BiTangents = new ArrayList<>(Collections.nCopies(Normals.size(), 0.0f));
|
||||
}
|
||||
return BiTangents;
|
||||
}
|
||||
|
||||
private static List<Float> ProcessNormals(AIMesh aiMesh){
|
||||
List<Float> Normals = new ArrayList<>();
|
||||
AIVector3D.Buffer aiNormals = aiMesh.mNormals();
|
||||
while(aiNormals != null && aiNormals.remaining() > 0){
|
||||
AIVector3D normal = aiNormals.get();
|
||||
Normals.add(normal.x());
|
||||
Normals.add(normal.y());
|
||||
Normals.add(normal.z());
|
||||
}
|
||||
return Normals;
|
||||
}
|
||||
|
||||
private static List<Float> ProcessTangents(AIMesh aiMesh, List<Float> Normals){
|
||||
List<Float> Tangents = new ArrayList<>();
|
||||
AIVector3D.Buffer aiTangents = aiMesh.mTangents();
|
||||
while(aiTangents != null && aiTangents.remaining() > 0){
|
||||
AIVector3D Tangent = aiTangents.get();
|
||||
Tangents.add(Tangent.x());
|
||||
Tangents.add(Tangent.y());
|
||||
Tangents.add(Tangent.z());
|
||||
}
|
||||
if (Tangents.isEmpty()) { // create empty BiTangents if assimp can't generate them
|
||||
Tangents = new ArrayList<>(Collections.nCopies(Normals.size(), 0.0f));
|
||||
}
|
||||
return Tangents;
|
||||
}
|
||||
|
||||
public static List<Float> ProcessTextureCoords(AIMesh aiMesh){
|
||||
List<Float> TextureCoords = new ArrayList<>();
|
||||
AIVector3D.Buffer aiTextureCoords = aiMesh.mTextureCoords(0);
|
||||
|
|
@ -185,15 +256,15 @@ public class ModelCompiler {
|
|||
}
|
||||
|
||||
public static List<Float> ProcessVertices(AIMesh aiMesh){
|
||||
List<Float> vertices = new ArrayList<>();
|
||||
List<Float> Vertices = new ArrayList<>();
|
||||
AIVector3D.Buffer aiVertices = aiMesh.mVertices();
|
||||
while(aiVertices.remaining() > 0){
|
||||
AIVector3D aiVertex = aiVertices.get();
|
||||
vertices.add(aiVertex.x());
|
||||
vertices.add(aiVertex.y());
|
||||
vertices.add(aiVertex.z());
|
||||
Vertices.add(aiVertex.x());
|
||||
Vertices.add(aiVertex.y());
|
||||
Vertices.add(aiVertex.z());
|
||||
}
|
||||
return vertices;
|
||||
return Vertices;
|
||||
}
|
||||
|
||||
public static String ProcessTexture(AIScene aiScene, AIMaterial aiMaterial, String BaseDirectory,int TextType ) throws IOException{
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import net.halbear.Terrain4J.EngineCore.Profiling.GPUProfiler;
|
|||
import net.halbear.Terrain4J.EngineCore.Vulkan.GUI.GuiTexture;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.MaterialData;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.ModelData;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.SceneRender;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.ForwardSceneRender;
|
||||
import org.joml.Vector2f;
|
||||
import org.joml.Vector3f;
|
||||
import org.lwjgl.openal.AL11;
|
||||
|
|
@ -43,18 +43,7 @@ public class GameCore implements GameLogic {
|
|||
private static final String SOUND_SOURCE_MUSIC = "music-sound-source";
|
||||
private static final String SOUND_SOURCE_PLAYER = "player-sound-source";
|
||||
|
||||
private final Vector3f rotatingAngle = new Vector3f(0, 1, 0);
|
||||
private float angle = 180;
|
||||
private List<Float> angles = new ArrayList<>();
|
||||
private List<Vector3f> rotatingAngles = new ArrayList<>();
|
||||
private List<Vector3f> Velocities = new ArrayList<>();
|
||||
private Actor CubeActor;
|
||||
public List<Actor> CubeActors = new ArrayList<>();
|
||||
public List<JackOfAllTradesActor> entities = new ArrayList<>();
|
||||
public List<ParticleActor> particleActors = new ArrayList<>();
|
||||
private Vector2f LastMousePos = new Vector2f(0,0);
|
||||
private int Ticks = 0;
|
||||
private int GUI_MODE = 0;
|
||||
private GuiTexture guiTexture;
|
||||
public List<String[]> PerformanceMetrics = new ArrayList<>();
|
||||
public List<String[]> SettingPerformanceMetrics = new ArrayList<>();
|
||||
|
|
@ -65,6 +54,10 @@ public class GameCore implements GameLogic {
|
|||
public long CoolDown = 1000;
|
||||
public ModelData MusicParticle;
|
||||
public ModelData radio;
|
||||
public ModelData Train;
|
||||
public ModelData RoundHouse;
|
||||
public ModelData Class08_9;
|
||||
public ILight SkyLight;
|
||||
|
||||
@Override
|
||||
public void cleanup() {
|
||||
|
|
@ -73,65 +66,69 @@ public class GameCore implements GameLogic {
|
|||
|
||||
@Override
|
||||
public InitData Initialise(EngineInstance engineInstance) {
|
||||
Scene scene = engineInstance.scene();
|
||||
IScene scene = engineInstance.scene();
|
||||
List<ModelData> models = new ArrayList<>();
|
||||
MusicParticle = ModelLoader.LoadModel("resources/models/MusicParticle/MusicParticle.json");
|
||||
List<MaterialData> MusicParticleMat = ModelLoader.LoadMaterials("resources/models/MusicParticle/MusicParticle_mat.json");
|
||||
ModelData SponzaData = ModelLoader.LoadModel("resources/models/Forest/forest.json");
|
||||
List<MaterialData> SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Forest/forest_mat.json");
|
||||
radio = ModelLoader.LoadModel("resources/models/radio/radio.json");
|
||||
List<MaterialData> SponzaMaterial1 = ModelLoader.LoadMaterials("resources/models/radio/radio_mat.json");
|
||||
//ModelData SponzaData = ModelLoader.LoadModel("resources/models/Cafe/exterior.json");
|
||||
//List<MaterialData> SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Cafe/exterior_mat.json");
|
||||
//ModelData SponzaData1 = ModelLoader.LoadModel("resources/models/Cafe/interior.json");
|
||||
//List<MaterialData> SponzaMaterial1= ModelLoader.LoadMaterials("resources/models/Cafe/interior_mat.json");
|
||||
scene.AddActor(new Actor("Sponza1", SponzaData.ID(), new Vector3f(0,0f,-5f)));
|
||||
//JackOfAllTradesActor newJackentity = new JackOfAllTradesActor("Sponza2", radio.ID(), new Vector3f(40.0f, 155.0f, -42.0f),MusicParticle).SetAudio(engineInstance, "resources/EngineResources/audio/sounds/youusedtocallmeonyourcellphone.ogg").SetScale(0.01f);
|
||||
//entities.add(newJackentity);
|
||||
//scene.AddActor(newJackentity);
|
||||
|
||||
models.add(ModelLoader.LoadModel("resources/models/Metro/OBJ/MetroLeadCar.json"));
|
||||
models.add(ModelLoader.LoadModel("resources/models/melona/melona.json"));
|
||||
models.add(ModelLoader.LoadModel("resources/models/Alice/Welsh040Alice.json"));
|
||||
models.add(ModelLoader.LoadModel("resources/models/Sloop/SloopOBJ.json"));
|
||||
models.add(ModelLoader.LoadModel("resources/models/Corvette/corvetteclass.json"));
|
||||
for(int i = 0; i < 0; i++) {
|
||||
CubeActors.add(new Actor("AdvancedModel" + i, models.get((int)Math.round(Math.min(Math.max(Math.random() *(Math.random() * models.size() - 1),0),models.size() - 1))).ID(), new Vector3f((float)(-200 + Math.random() * 400), (float)(-50 + Math.random() * 100), (float)(250 + Math.random() * -500))));
|
||||
angles.add((float)(Math.random() * 360));
|
||||
rotatingAngles.add(new Vector3f((float)(Math.random()*2), (float)(Math.random()*2), (float)(Math.random()*2)));
|
||||
Velocities.add(new Vector3f((float)(-2 + Math.random()*4), -2 + (float)(Math.random()*4), -2 + (float)(Math.random()*4)));
|
||||
}
|
||||
CubeActors.forEach(scene::AddActor);
|
||||
Train = ModelLoader.LoadModel("resources/models/train/trainModel.json");
|
||||
List<MaterialData> TrainMat = ModelLoader.LoadMaterials("resources/models/train/trainModel_mat.json");
|
||||
RoundHouse = ModelLoader.LoadModel("resources/models/roundHouse/RoundHouse.json");
|
||||
List<MaterialData> RoundHouseMat = ModelLoader.LoadMaterials("resources/models/roundHouse/RoundHouse_mat.json");
|
||||
Class08_9 = ModelLoader.LoadModel("resources/models/MainMenu/MainMenu.json");
|
||||
List<MaterialData> Class08_9mat = ModelLoader.LoadMaterials("resources/models/MainMenu/MainMenu_mat.json");
|
||||
|
||||
List<MaterialData> materials = new ArrayList<>();
|
||||
materials.addAll(ModelLoader.LoadMaterials("resources/models/Metro/OBJ/MetroLeadCar_mat.json"));
|
||||
materials.addAll(ModelLoader.LoadMaterials("resources/models/Corvette/corvetteclass_mat.json"));
|
||||
materials.addAll(ModelLoader.LoadMaterials("resources/models/melona/melona_mat.json"));
|
||||
materials.addAll(ModelLoader.LoadMaterials("resources/models/Alice/Welsh040Alice_mat.json"));
|
||||
materials.addAll(ModelLoader.LoadMaterials("resources/models/Sloop/SloopOBJ_mat.json"));
|
||||
materials.addAll(SponzaMaterial);
|
||||
materials.addAll(MusicParticleMat);
|
||||
materials.addAll(SponzaMaterial1);
|
||||
models.add(SponzaData);
|
||||
materials.addAll(TrainMat);
|
||||
materials.addAll(RoundHouseMat);
|
||||
materials.addAll(Class08_9mat);
|
||||
models.add(MusicParticle);
|
||||
models.add(radio);
|
||||
models.add(Train);
|
||||
models.add(RoundHouse);
|
||||
models.add(Class08_9);
|
||||
Camera camera = scene.GetCamera();
|
||||
scene.AddCameraFrame("Default", new CameraFrame(new Vector3f(-120.10f,136.83f,-62.63f),new Vector3f(-1.90f,78.09f,0),scene.GetCamera().GetFOV(),"Second"));
|
||||
scene.AddCameraFrame("Second", new CameraFrame(new Vector3f(-40.26f,141.08f,-72.12f),new Vector3f(-2.40f,143,0.0f),scene.GetCamera().GetFOV(),"Third"));
|
||||
scene.AddCameraFrame("Third", new CameraFrame(new Vector3f(10.85f,149.56f,-14.10f),new Vector3f(2.5f,36.37f,0.00f),scene.GetCamera().GetFOV(),"Fourth"));
|
||||
scene.AddCameraFrame("Fourth", new CameraFrame(new Vector3f(40.0f, 155.0f, -42.0f),new Vector3f(10,90,0),scene.GetCamera().GetFOV(),"Fifth"));
|
||||
scene.AddCameraFrame("Fifth", new CameraFrame(new Vector3f(64.92f,158.06f,-35.25f),new Vector3f(-11.20f,156.5f,0.0f),scene.GetCamera().GetFOV(),"Sixth"));
|
||||
scene.AddCameraFrame("Sixth", new CameraFrame(new Vector3f(94.52f,172.54f,47.57f),new Vector3f(4.3f,329.27f,0.0f),scene.GetCamera().GetFOV(),"NO_FRAME"));
|
||||
camera.SetPosition(40.0f, 155.0f, -42.0f);
|
||||
//camera.SetPosition(0,0,0);
|
||||
camera.SetRotation((float) Math.toRadians(10.0f), (float) Math.toRadians(-90.0f),0);
|
||||
//camera.SetRotation(0,0,0);
|
||||
Actor TrainActor = new Actor("Train",Train.ID(),new Vector3f(0,0,-10f)).SetScale(1.0f);
|
||||
scene.AddActor(TrainActor);
|
||||
scene.AddActor(new Actor("RoundHouse",RoundHouse.ID(),new Vector3f(0,-0.2f,-10f)));
|
||||
Actor TrainActor2 = new Actor("Class08_9",Class08_9.ID(),new Vector3f(-50,-0.5f,-71f)).SetScale(1.0f);
|
||||
TrainActor2.SetRotationDegrees(0,90,0);
|
||||
scene.AddActor(TrainActor2);
|
||||
|
||||
//camera.SetPosition(-5.82f,1.59f,-14.37f);
|
||||
//camera.SetRotation((float) (2*EngineConfig.DegToRad),(float) (125.20*EngineConfig.DegToRad),0);
|
||||
camera.SetPosition(-88.81f,3.15f,-41.28f);
|
||||
camera.SetRotation((float) (-5.63f*EngineConfig.DegToRad),(float) (291.05f*EngineConfig.DegToRad),0);
|
||||
|
||||
guiTexture = new GuiTexture("resources/EngineResources/Texture/DefaultTexture.png");
|
||||
Logger.debug("GUI TEXTURE CREATED, ID->[{}], PATH->[{}]",guiTexture.ID(),guiTexture.TexturePath());
|
||||
List<GuiTexture> guiTextures = new ArrayList<>();
|
||||
guiTextures.add(guiTexture);
|
||||
|
||||
|
||||
scene.GetLightingManager().GetAmbientLightColour().set(0.5f, 0.5f, 0.5f);
|
||||
scene.GetLightingManager().SetAmbientLightIntensity(0.2f);
|
||||
|
||||
SkyLight = new Light(new Vector3f(0.25f, 1.0f, 1.5f),new Vector3f(0.0f, -1.0f, 0.0f), true, 2.00f);
|
||||
|
||||
|
||||
List<ILight> lights = new ArrayList<>();
|
||||
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-108.21f,11.5f,-76f),false,1000f));
|
||||
lights.add(new Light(new Vector3f(2,0,0),new Vector3f(-94.86f,6.27f,-85.72f),false,500f));
|
||||
lights.add(new Light(new Vector3f(1,0.65f,0.2f),new Vector3f(-107.01f,6.21f,-57.04f),false,3f));
|
||||
lights.add(new Light(new Vector3f(1,0.65f,0.2f),new Vector3f(-105.17f,6.19f,-57.39f),false,3f));
|
||||
lights.add(new Light(new Vector3f(1,0.65f,0.2f),new Vector3f(-109.03f,6.23f,-56.9f),false,3f));
|
||||
|
||||
scene.SetSkyLight(SkyLight);
|
||||
lights.add(scene.GetSkyLight());
|
||||
ILight[] lightArr = new ILight[lights.size()];
|
||||
lightArr = lights.toArray(lightArr);
|
||||
scene.GetLightingManager().AddLights(lightArr);
|
||||
|
||||
|
||||
InitiateAudio(engineInstance);
|
||||
|
||||
return new InitData(models,materials,guiTextures);
|
||||
|
|
@ -143,49 +140,23 @@ public class GameCore implements GameLogic {
|
|||
audioManager.SetAttenuationModel(AL11.AL_EXPONENT_DISTANCE);
|
||||
audioManager.SetListener(new SoundListener(camera.GetPosition()));
|
||||
|
||||
SoundBuffer buffer = new SoundBuffer("resources/EngineResources/audio/sounds/youusedtocallmeonyourcellphone.ogg");
|
||||
SoundBuffer buffer = new SoundBuffer("resources/EngineResources/audio/music/MainThemeCEZ4434_12.ogg");
|
||||
audioManager.AddSoundBuffer(SOUND_BUFFER_PLAYER, buffer);
|
||||
AudioSource playerAudioSource = new AudioSource(true,false);
|
||||
playerAudioSource.SetPosition(new Vector3f(40.0f, 155.0f, -42.0f));
|
||||
playerAudioSource.SetBuffer(buffer.GetBufferID());
|
||||
audioManager.AddSoundSource(SOUND_SOURCE_PLAYER,playerAudioSource);
|
||||
|
||||
engineInstance.scene().SetUpAudio(engineInstance);
|
||||
//playerAudioSource.Play();
|
||||
buffer = new SoundBuffer("resources/EngineResources/audio/music/chimken_wing.ogg");
|
||||
audioManager.AddSoundBuffer(SOUND_BUFFER_MUSIC,buffer);
|
||||
AudioSource source = new AudioSource(true, true);
|
||||
source.SetBuffer(buffer.GetBufferID());
|
||||
audioManager.AddSoundSource(SOUND_SOURCE_MUSIC,source);
|
||||
//source.Play();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void CameraInput(EngineInstance engineInstance, long FrameDiffNanoSeconds) {
|
||||
float Multiplier = MOUSE_SENSITIVITY;
|
||||
Scene scene = engineInstance.scene();
|
||||
Camera camera = scene.GetCamera();
|
||||
Window window = engineInstance.window();
|
||||
|
||||
MouseListener MouseInput = window.getMouseInput();
|
||||
Vector2f CurrentMousePos = window.getMouseInput().getCurrentPos();
|
||||
Vector2f deltaPos = new Vector2f(0,0);
|
||||
deltaPos.x = 0;
|
||||
deltaPos.y = 0;
|
||||
if (LastMousePos.x >= 0 && LastMousePos.y >= 0 && window.getMouseInput().IsWindowFocused()) {
|
||||
deltaPos.x = CurrentMousePos.x - LastMousePos.x;
|
||||
deltaPos.y = CurrentMousePos.y - LastMousePos.y;
|
||||
}
|
||||
LastMousePos.x = CurrentMousePos.x;
|
||||
LastMousePos.y = CurrentMousePos.y;
|
||||
if(MouseInput.isRightButtonPressed()){
|
||||
|
||||
camera.AddRotation((float)Math.toRadians(-deltaPos.y * Multiplier),(float)Math.toRadians(-deltaPos.x * Multiplier),0);
|
||||
}
|
||||
engineInstance.audioManager().UpdateListenerPosition(camera);
|
||||
engineInstance.scene().CameraInput(engineInstance,FrameDiffNanoSeconds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void RenderThreadInput(EngineInstance engineInstance, long FrameDiffNanoSeconds) {
|
||||
engineInstance.scene().CameraTick(FrameDiffNanoSeconds);
|
||||
public void CheckRenderSettings(){
|
||||
if(ChangeGraphicsSettings){
|
||||
if(NextAAMode != -1){
|
||||
EngineConfig.getInstance().SetRenderAAType(NextAAMode);
|
||||
|
|
@ -198,47 +169,17 @@ public class GameCore implements GameLogic {
|
|||
} else{
|
||||
LastFrameTime = System.nanoTime();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void RenderThreadInput(EngineInstance engineInstance, long FrameDiffNanoSeconds) {
|
||||
engineInstance.scene().RenderThreadInput(engineInstance,FrameDiffNanoSeconds);
|
||||
CheckRenderSettings();
|
||||
HandleGui(engineInstance, FrameDiffNanoSeconds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Input(EngineInstance engineInstance, long FrameDiffNanoSeconds) {
|
||||
Scene scene = engineInstance.scene();
|
||||
Window window = engineInstance.window();
|
||||
|
||||
KeyboardInput input = window.getKeyboardInput();
|
||||
float MovementDist = (float)(FrameDiffNanoSeconds / 1000000L) * MOVEMENT_SPEED;
|
||||
Camera camera = scene.GetCamera();
|
||||
if(input.keyPressed(GLFW_KEY_1)){
|
||||
GUI_MODE = 0;
|
||||
}
|
||||
if(input.keyPressed(GLFW_KEY_2)){
|
||||
GUI_MODE = 1;
|
||||
}
|
||||
if(input.keyPressed(GLFW_KEY_3)){
|
||||
GUI_MODE = 2;
|
||||
}
|
||||
if(input.keyPressed(GLFW_KEY_W)){
|
||||
camera.MoveForward(MovementDist);
|
||||
}
|
||||
if(input.keyPressed(GLFW_KEY_S)){
|
||||
camera.MoveBackward(MovementDist);
|
||||
}
|
||||
if(input.keyPressed(GLFW_KEY_A)){
|
||||
camera.MoveLeft(MovementDist);
|
||||
}
|
||||
if(input.keyPressed(GLFW_KEY_D)){
|
||||
camera.MoveRight(MovementDist);
|
||||
}
|
||||
if(input.keyPressed(GLFW_KEY_SPACE)){
|
||||
camera.MoveUp(MovementDist);
|
||||
}
|
||||
if(input.keyPressed(GLFW_KEY_LEFT_SHIFT)){
|
||||
camera.MoveDown(MovementDist);
|
||||
}
|
||||
if(input.keyPressed(GLFW_KEY_LEFT_CONTROL)){
|
||||
camera.Sprint(true);
|
||||
} else camera.Sprint(false);
|
||||
engineInstance.scene().Input(engineInstance,FrameDiffNanoSeconds);
|
||||
}
|
||||
|
||||
private boolean HandleGui(EngineInstance engineInstance, long frameTimeNS){
|
||||
|
|
@ -256,19 +197,7 @@ public class GameCore implements GameLogic {
|
|||
| ImGuiWindowFlags.NoNav
|
||||
| ImGuiWindowFlags.NoMove;
|
||||
ImGui.newFrame();
|
||||
if(GUI_MODE == 0){
|
||||
PerformanceOverlay overlay = new PerformanceOverlay();
|
||||
overlay.RenderGUI(engineInstance,frameTimeNS,this);
|
||||
} else if (GUI_MODE == 1){
|
||||
|
||||
ImGui.setNextWindowPos(0,0, ImGuiCond.Always);
|
||||
ImGui.setNextWindowSize(500,500);
|
||||
ImGui.begin("Test Window");
|
||||
ImGui.image(PrimaryRuntime.GetRenderThread().GetRenderer().GetGuiTexture(guiTexture.ID()),300,300);
|
||||
Logger.debug(PrimaryRuntime.GetRenderThread().GetRenderer().GetGuiTexture(guiTexture.ID()));
|
||||
ImGui.end();
|
||||
} else if (GUI_MODE == 2){
|
||||
}
|
||||
engineInstance.scene().RenderGUIs(engineInstance,frameTimeNS,this);
|
||||
if (ChangeGraphicsSettings){
|
||||
ImGuiViewport viewport = ImGui.getMainViewport();
|
||||
float CenterX = viewport.getWorkPosX() + viewport.getWorkSizeX() / 2.0f;
|
||||
|
|
@ -287,22 +216,14 @@ public class GameCore implements GameLogic {
|
|||
|
||||
@Override
|
||||
public void Update(EngineInstance engineInstance, long FrameDiffNanoSeconds) {
|
||||
engineInstance.scene().Update(engineInstance,FrameDiffNanoSeconds);
|
||||
float DeltaTime = (float)(FrameDiffNanoSeconds/16000000.0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void UpdateFastThread(EngineInstance engineInstance, long FrameDiffNanoSeconds) {
|
||||
engineInstance.scene().UpdateFastThread(engineInstance,FrameDiffNanoSeconds);
|
||||
float DeltaTime = (float)(FrameDiffNanoSeconds/16000000.0);
|
||||
for(int i = 0; i < angles.size(); i++) {
|
||||
angles.set(i, (angles.get(i) + 1.0f* DeltaTime) % 360);
|
||||
CubeActors.get(i).GetRotation().identity().rotateAxis((float) EngineConfig.DegToRad * angles.get(i), rotatingAngles.get(i));
|
||||
CubeActors.get(i).GetPosition().add((Velocities.get(i).x/100.0f) * DeltaTime,(Velocities.get(i).y/100.0f) * DeltaTime,(Velocities.get(i).z/100.0f) * DeltaTime);
|
||||
CubeActors.get(i).UpdateModelMatrix();
|
||||
}
|
||||
Ticks++;
|
||||
if(Ticks == 1000){
|
||||
engineInstance.scene().StartCameraTrack("Default","Second",24000);
|
||||
}
|
||||
for(int i = 0; i < entities.size(); i++){
|
||||
JackOfAllTradesActor entity = entities.get(i);
|
||||
entity.tick(engineInstance.scene());
|
||||
|
|
@ -311,6 +232,7 @@ public class GameCore implements GameLogic {
|
|||
|
||||
@Override
|
||||
public void SecondUpdate(EngineInstance engineInstance) {
|
||||
engineInstance.scene().SecondUpdate(engineInstance);
|
||||
SettingPerformanceMetrics.clear();
|
||||
List<String[]> Metrics = new ArrayList<>();
|
||||
String[] SceneDetails = new String[7];
|
||||
|
|
@ -320,7 +242,7 @@ public class GameCore implements GameLogic {
|
|||
SceneDetails[1] = String.format(" Camera Position: X: %.2f Y: %.2f Z: %.2f",Position.x ,Position.y ,Position.z);
|
||||
SceneDetails[2] = String.format(" Camera Rotation: X: %.2f° Y: %.2f° Z: %.2f°",Rotation.x *EngineConfig.RadToDeg,Rotation.y *EngineConfig.RadToDeg ,Rotation.z *EngineConfig.RadToDeg);
|
||||
SceneDetails[3] = String.format(" Anti Aliasing: " + EngineConfig.getInstance().RenderAAType().name());
|
||||
SceneDetails[4] = String.format(" Pipeline: " + (SceneRender.DualPassRendering() ? " Dual Pass" : "Single Pass"));
|
||||
SceneDetails[4] = String.format(" Pipeline: " + (ForwardSceneRender.DualPassRendering() ? " Dual Pass" : "Single Pass"));
|
||||
SceneDetails[5] = String.format(" AlphaToCoverage: " + EngineConfig.getInstance().AlphaToCoverage());
|
||||
SceneDetails[6] = String.format(" FOV: %.2f°",(EngineConfig.getInstance().GetFOV()*EngineConfig.RadToDeg));
|
||||
String[] DeviceInfo = new String[5];
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import net.halbear.Terrain4J.EngineCore.Audio.AudioManager;
|
|||
import net.halbear.Terrain4J.EngineCore.Display.Window;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.*;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.MainMenuScene;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.Scene;
|
||||
import net.halbear.Terrain4J.EngineCore.Profiling.CPUMonitor;
|
||||
import net.halbear.Terrain4J.EngineCore.Threads.FastTickThread;
|
||||
|
|
@ -54,7 +55,7 @@ public class PrimaryRuntime {
|
|||
}
|
||||
window = new Window(windowTitle);
|
||||
gameLogic = appLogic;
|
||||
engineInstance = new EngineInstance(window, new Scene(window),this, new AudioManager());
|
||||
engineInstance = new EngineInstance(window, new MainMenuScene(window),this, new AudioManager());
|
||||
InitData initData = appLogic.Initialise(engineInstance);
|
||||
PrimaryThread = new MainThread(engineInstance, appLogic);
|
||||
FastThread = new FastTickThread(engineInstance, appLogic);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Main.Scene;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
|
|
@ -36,6 +37,13 @@ public class Actor{
|
|||
UpdateModelMatrix();
|
||||
}
|
||||
|
||||
public final void SetRotationDegrees(float x, float y, float z){
|
||||
Rotation.rotateX((float)Math.toRadians(x));
|
||||
Rotation.rotateY((float)Math.toRadians(y));
|
||||
Rotation.rotateZ((float)Math.toRadians(z));
|
||||
UpdateModelMatrix();
|
||||
}
|
||||
|
||||
public Actor SetScale(float Scale){
|
||||
this.Scale = Scale;
|
||||
UpdateModelMatrix();
|
||||
|
|
|
|||
|
|
@ -9,12 +9,14 @@ import net.halbear.Terrain4J.EngineCore.Main.GameCore;
|
|||
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIOverlay;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.JackOfAllTradesActor;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.SceneRender;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.GUI.GuiRenderer;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.ForwardSceneRender;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
public class PerformanceOverlay implements GUIOverlay {
|
||||
@Override
|
||||
public void RenderGUI(EngineInstance engineInstance, long frameTimeNS, GameCore parent) {
|
||||
ImGui.pushFont(GuiRenderer.fontMap.get("Title"),20.0f);
|
||||
int windowFlags = ImGuiWindowFlags.NoDecoration
|
||||
| ImGuiWindowFlags.AlwaysAutoResize
|
||||
| ImGuiWindowFlags.NoSavedSettings
|
||||
|
|
@ -40,7 +42,7 @@ public class PerformanceOverlay implements GUIOverlay {
|
|||
parent.ChangeGraphicsSettings = true;
|
||||
parent.CoolDown = 2000;
|
||||
parent.NextAAMode = (0);
|
||||
SceneRender.SetDualPassRendering(false);
|
||||
ForwardSceneRender.SetDualPassRendering(false);
|
||||
EngineConfig.getInstance().SetAlphaToCoverage(false);
|
||||
PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
|
||||
}
|
||||
|
|
@ -49,7 +51,7 @@ public class PerformanceOverlay implements GUIOverlay {
|
|||
parent.ChangeGraphicsSettings = true;
|
||||
parent.CoolDown = 2000;
|
||||
parent.NextAAMode = (1);
|
||||
SceneRender.SetDualPassRendering(true);
|
||||
ForwardSceneRender.SetDualPassRendering(true);
|
||||
EngineConfig.getInstance().SetAlphaToCoverage(true);
|
||||
PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
|
||||
}
|
||||
|
|
@ -58,7 +60,7 @@ public class PerformanceOverlay implements GUIOverlay {
|
|||
parent.ChangeGraphicsSettings = true;
|
||||
parent.CoolDown = 2000;
|
||||
parent.NextAAMode = (4);
|
||||
SceneRender.SetDualPassRendering(true);
|
||||
ForwardSceneRender.SetDualPassRendering(true);
|
||||
EngineConfig.getInstance().SetAlphaToCoverage(false);
|
||||
PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
|
||||
}
|
||||
|
|
@ -97,13 +99,13 @@ public class PerformanceOverlay implements GUIOverlay {
|
|||
if(ImGui.button("Single Pass")){
|
||||
parent.ChangeGraphicsSettings = true;
|
||||
parent.CoolDown = 500;
|
||||
SceneRender.SetDualPassRendering(false);
|
||||
ForwardSceneRender.SetDualPassRendering(false);
|
||||
}
|
||||
ImGui.sameLine();
|
||||
if(ImGui.button("dual Pass")){
|
||||
parent.ChangeGraphicsSettings = true;
|
||||
parent.CoolDown = 500;
|
||||
SceneRender.SetDualPassRendering(true);
|
||||
ForwardSceneRender.SetDualPassRendering(true);
|
||||
}
|
||||
if(ImGui.button("Forward Rendering")){
|
||||
parent.ChangeGraphicsSettings = true;
|
||||
|
|
@ -132,7 +134,7 @@ public class PerformanceOverlay implements GUIOverlay {
|
|||
ImGui.separator();
|
||||
ImGui.text("Level Tools:");
|
||||
if(ImGui.button("Spawn Radio")){
|
||||
JackOfAllTradesActor newJackentity = new JackOfAllTradesActor("Radio" + parent.entities.size(), parent.radio.ID(), new Vector3f(engineInstance.scene().GetCamera().GetPosition()),parent.MusicParticle).SetAudio(engineInstance, "resources/EngineResources/audio/sounds/youusedtocallmeonyourcellphone.ogg").SetScale(0.01f);
|
||||
JackOfAllTradesActor newJackentity = new JackOfAllTradesActor("Radio" + parent.entities.size(), parent.radio.ID(), new Vector3f(engineInstance.scene().GetCamera().GetPosition()),parent.MusicParticle).SetAudio(engineInstance, "resources/EngineResources/audio/sounds/IntroMusicMono.ogg").SetScale(0.01f);
|
||||
parent.entities.add(newJackentity);
|
||||
engineInstance.scene().AddActor(newJackentity);
|
||||
}
|
||||
|
|
@ -149,6 +151,7 @@ public class PerformanceOverlay implements GUIOverlay {
|
|||
ImGui.text(" ");
|
||||
}
|
||||
}
|
||||
ImGui.popFont();
|
||||
ImGui.end();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,78 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs;
|
||||
|
||||
import imgui.ImDrawList;
|
||||
import imgui.ImGui;
|
||||
import imgui.ImGuiIO;
|
||||
import imgui.flag.ImGuiCond;
|
||||
import imgui.flag.ImGuiWindowFlags;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.GameCore;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIOverlay;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.JackOfAllTradesActor;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.GUI.GuiRenderer;
|
||||
import org.joml.Vector3f;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.Objects;
|
||||
|
||||
public class WarHorseMainMenu implements GUIOverlay {
|
||||
@Override
|
||||
public void RenderGUI(EngineInstance engineInstance, long frameTimeNS, GameCore parent) {
|
||||
int textColor = ImGui.getColorU32(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
int shadowColor = ImGui.getColorU32(0.0f, 0.0f, 0.0f, 0.5f);
|
||||
int windowFlags = ImGuiWindowFlags.NoDecoration
|
||||
| ImGuiWindowFlags.AlwaysAutoResize
|
||||
| ImGuiWindowFlags.NoSavedSettings
|
||||
| ImGuiWindowFlags.NoFocusOnAppearing
|
||||
| ImGuiWindowFlags.NoNav
|
||||
| ImGuiWindowFlags.NoMove
|
||||
| ImGuiWindowFlags.NoBackground;
|
||||
double FrameTimeMS = (frameTimeNS/1000000.0);
|
||||
double AverageGPUTimeMS = EngineConfig.LAST_AVERAGE_GPU_TIME/1000000.0;
|
||||
try(var MemStack = MemoryStack.stackPush()) {
|
||||
IntBuffer pWidth = MemStack.mallocInt(1);
|
||||
IntBuffer pHeight = MemStack.mallocInt(1);
|
||||
|
||||
// Get the actual pixel dimensions of the Vulkan surface
|
||||
GLFW.glfwGetFramebufferSize(engineInstance.window().getHandle(), pWidth, pHeight);
|
||||
|
||||
int displayWidth = pWidth.get(0);
|
||||
int displayHeight = pHeight.get(0);
|
||||
ImGuiIO io = ImGui.getIO();
|
||||
ImGui.setNextWindowPos(30, 10, ImGuiCond.Always);
|
||||
//ImGui.setNextWindowSize(300,100);
|
||||
ImDrawList drawList = ImGui.getForegroundDrawList();
|
||||
|
||||
ImGui.pushFont(GuiRenderer.fontMap.get("Title"), displayHeight/3.75f);
|
||||
ImGui.begin("WarHorseMenu", windowFlags);
|
||||
drawList.addText(40, 20, shadowColor, "War Horse");
|
||||
drawList.addText(30, 10, textColor, "War Horse");
|
||||
ImGui.text(" ");
|
||||
ImGui.popFont();
|
||||
ImGui.pushFont(GuiRenderer.fontMap.get("Title"), displayHeight/11.25f);
|
||||
if (ImGui.button("Campaign")) {
|
||||
|
||||
}
|
||||
if (ImGui.button("Free Roam")) {
|
||||
|
||||
}
|
||||
if (ImGui.button(!Objects.equals(engineInstance.scene().GetActiveCameraFrame(), "RoundHouseAngle") ? "Roundhouse" : "Back")) {
|
||||
if (!Objects.equals(engineInstance.scene().GetActiveCameraFrame(), "RoundHouseAngle"))
|
||||
engineInstance.scene().StartCameraTrack(Objects.equals(engineInstance.scene().GetActiveCameraFrame(), "NO_FRAME") ? "MainAngle" : engineInstance.scene().GetActiveCameraFrame(), "RoundHouseAngle", 5600);
|
||||
else engineInstance.scene().StartCameraTrack("RoundHouseAngle", "MainAngle", 5600);
|
||||
}
|
||||
if (ImGui.button("Settings")) {
|
||||
|
||||
}
|
||||
if (ImGui.button("Quit")) {
|
||||
System.exit(1);
|
||||
}
|
||||
ImGui.popFont();
|
||||
ImGui.end();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Main.Scene;
|
||||
|
||||
import org.joml.Vector3f;
|
||||
|
||||
public interface ILight {
|
||||
|
||||
public Vector3f GetColour();
|
||||
public float GetIntensity();
|
||||
public Vector3f GetPosition();
|
||||
public boolean IsDirectional();
|
||||
public void SetIntensity(float intensity);
|
||||
public void SetColour(Vector3f Colour);
|
||||
public void SetPositon(Vector3f Position);
|
||||
public void SetDirectional(boolean Directional);
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Main.Scene;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.GameCore;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Projection.Project3D;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface IScene {
|
||||
|
||||
public void CameraTick(long FrameDiffNanoSeconds);
|
||||
public Map<String, CameraFrame> GetCameraFrameReg();
|
||||
public CameraFrame GetCameraFrame(String Name);
|
||||
public Scene AddCameraFrame(String Name, CameraFrame frame);
|
||||
public void StartCameraTrack(String StartFrame, String EndFrame, int TickAmount);
|
||||
public void SetActiveCameraFrame(String frameName);
|
||||
public Camera GetCamera();
|
||||
public void AddActor(Actor NewActor);
|
||||
public List<Actor> GetActors();
|
||||
public Project3D GetProjection();
|
||||
public void RemoveAllActors();
|
||||
public void RemoveActor(Actor actor);
|
||||
public void Input(EngineInstance engineInstance, long FrameDiffNanoSeconds);
|
||||
public void Update(EngineInstance engineInstance, long FrameDiffNanoSeconds);
|
||||
public void UpdateFastThread(EngineInstance engineInstance, long FrameDiffNanoSeconds);
|
||||
public void SecondUpdate(EngineInstance engineInstance);
|
||||
public void RenderThreadInput(EngineInstance engineInstance, long FrameDiffNanoSeconds);
|
||||
public void RenderGUIs(EngineInstance engineInstance, long frameTimeNS, GameCore parent);
|
||||
public void CameraInput(EngineInstance engineInstance, long FrameDiffNanoSeconds);
|
||||
public String GetActiveCameraFrame();
|
||||
public void SetUpAudio(EngineInstance engineInstance);
|
||||
public ISceneLightingManager GetLightingManager();
|
||||
public void SetSkyLight(ILight light);
|
||||
public ILight GetSkyLight();
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Main.Scene;
|
||||
|
||||
import org.joml.Vector3f;
|
||||
|
||||
public interface ISceneLightingManager {
|
||||
public Vector3f GetAmbientLightColour();
|
||||
public float GetAmbientLightIntensity();
|
||||
public ILight[] GetLights();
|
||||
public void SetAmbientLightIntensity(float Intensity);
|
||||
public void SetAmbientLightColour(Vector3f Colour);
|
||||
public void SetLights(ILight[] lights);
|
||||
public void AddLight(ILight light);
|
||||
public void AddLights(ILight[] lights);
|
||||
public void SetSkyColour(Vector3f SkyColourIn);
|
||||
public Vector3f GetSkyColour();
|
||||
}
|
||||
|
|
@ -46,7 +46,7 @@ public class JackOfAllTradesActor extends Actor {
|
|||
return this;
|
||||
}
|
||||
|
||||
public void tick(Scene scene){
|
||||
public void tick(IScene scene){
|
||||
List<Integer> ParticlesToDelete = new ArrayList<>();
|
||||
if((int)(Math.random() * 20) == 0){
|
||||
ParticleActor particle = new ParticleActor("particle" + particleActors.size(), Particle.ID(), new Vector3f(GetPosition()),new Vector3f(1,1,1),0,new Vector3f(-1f + (float)Math.random() * 2,-1f + (float)Math.random() * 2,-1f + (float)Math.random() * 2),0.0005f,5000);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Main.Scene;
|
||||
|
||||
import org.joml.Vector3f;
|
||||
|
||||
public class Light implements ILight{
|
||||
|
||||
private final Vector3f Colour;
|
||||
private final Vector3f Position;
|
||||
private boolean Directional;
|
||||
private float Intensity;
|
||||
|
||||
public Light(Vector3f Colour, Vector3f Position, boolean Directional, float Intensity){
|
||||
this.Colour = Colour;
|
||||
this.Position = Position;
|
||||
this.Directional = Directional;
|
||||
this.Intensity = Intensity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3f GetColour() {
|
||||
return Colour;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float GetIntensity() {
|
||||
return Intensity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3f GetPosition() {
|
||||
return Position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean IsDirectional() {
|
||||
return Directional;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void SetIntensity(float intensity) {
|
||||
this.Intensity = intensity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void SetColour(Vector3f Colour) {
|
||||
this.Colour.set(new Vector3f(Colour));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void SetPositon(Vector3f Position) {
|
||||
this.Position.set(new Vector3f(Position));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void SetDirectional(boolean Directional) {
|
||||
this.Directional = Directional;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Main.Scene;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Audio.AudioManager;
|
||||
import net.halbear.Terrain4J.EngineCore.Audio.AudioSource;
|
||||
import net.halbear.Terrain4J.EngineCore.Audio.SoundBuffer;
|
||||
import net.halbear.Terrain4J.EngineCore.Display.Window;
|
||||
import net.halbear.Terrain4J.EngineCore.Input.KeyboardInput;
|
||||
import net.halbear.Terrain4J.EngineCore.Input.MouseListener;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.GameCore;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.PerformanceOverlay;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.WarHorseMainMenu;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Projection.Project3D;
|
||||
import org.joml.Vector2f;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.lwjgl.glfw.GLFW.*;
|
||||
|
||||
public class MainMenuScene extends Scene{
|
||||
|
||||
private static String ROUNDHOUSE_PLAYER = "round_house_player";
|
||||
private static String ROUNDHOUSE_BUFFER = "round_house_buffer";
|
||||
private static String MAINTHEME_PLAYER = "main_theme_player";
|
||||
private static String MAINTHEME_BUFFER = "main_theme_buffer";
|
||||
|
||||
private final Map<String,AudioSource> soundMap;
|
||||
private final Map<String, LightingPreset> lightingPresetMap;
|
||||
|
||||
public record LightingPreset(Vector3f AmbientColour, float AmbientStrength, Vector3f SkyLightColour, Vector3f SkyLightPosition, float SkyLightStrength, Vector3f SkyColour){
|
||||
public LightingPreset Lerp(LightingPreset presetIn, int CurrentTick, int TotalTickTime){
|
||||
double t = (double)CurrentTick/(double)TotalTickTime;
|
||||
Vector3f newAmbientColour = new Vector3f(0,0,0);
|
||||
Vector3f NewSkyLightColour = new Vector3f(0,0,0);
|
||||
Vector3f NewSkyLightPosition = new Vector3f(0,0,0);
|
||||
Vector3f NewSkyColour = new Vector3f(0,0,0);
|
||||
float NewAmbientStrength = (float) org.joml.Math.lerp(this.AmbientStrength, presetIn.AmbientStrength(), t);
|
||||
float NewSkyLightStrength = (float) org.joml.Math.lerp(this.SkyLightStrength, presetIn.SkyLightStrength(), t);
|
||||
newAmbientColour.x = (float) org.joml.Math.lerp(AmbientColour.x, presetIn.AmbientColour().x, t);
|
||||
newAmbientColour.y = (float) org.joml.Math.lerp(AmbientColour.y, presetIn.AmbientColour().y, t);
|
||||
newAmbientColour.z = (float) org.joml.Math.lerp(AmbientColour.z, presetIn.AmbientColour().z, t);
|
||||
NewSkyLightColour.x = (float) org.joml.Math.lerp(SkyLightColour.x, presetIn.SkyLightColour().x, t);
|
||||
NewSkyLightColour.y = (float) org.joml.Math.lerp(SkyLightColour.y, presetIn.SkyLightColour().y, t);
|
||||
NewSkyLightColour.z = (float) org.joml.Math.lerp(SkyLightColour.z, presetIn.SkyLightColour().z, t);
|
||||
NewSkyLightPosition.x = (float) org.joml.Math.lerp(SkyLightPosition.x, presetIn.SkyLightPosition().x, t);
|
||||
NewSkyLightPosition.y = (float) org.joml.Math.lerp(SkyLightPosition.y, presetIn.SkyLightPosition().y, t);
|
||||
NewSkyLightPosition.z = (float) org.joml.Math.lerp(SkyLightPosition.z, presetIn.SkyLightPosition().z, t);
|
||||
NewSkyColour.x = (float) org.joml.Math.lerp(SkyColour.x, presetIn.SkyColour().x, t);
|
||||
NewSkyColour.y = (float) org.joml.Math.lerp(SkyColour.y, presetIn.SkyColour().y, t);
|
||||
NewSkyColour.z = (float) org.joml.Math.lerp(SkyColour.z, presetIn.SkyColour().z, t);
|
||||
return new LightingPreset(newAmbientColour, NewAmbientStrength, NewSkyLightColour, NewSkyLightPosition,NewSkyLightStrength,NewSkyColour);
|
||||
}
|
||||
}
|
||||
|
||||
public MainMenuScene(Window window) {
|
||||
super(window);
|
||||
soundMap = new HashMap<>();
|
||||
lightingPresetMap = new HashMap<>();
|
||||
GUIReg.put("MainMenu",new WarHorseMainMenu());
|
||||
AddCameraFrame("MainAngle",new CameraFrame(new Vector3f(-88.81f,3.15f,-41.28f),new Vector3f(-5.63f,291.05f,0),(float)Math.toRadians(60),"NO_FRAME"));
|
||||
AddCameraFrame("RoundHouseAngle",new CameraFrame(new Vector3f(-5.82f,1.59f,-14.37f),new Vector3f(2,125.20f,0),(float)Math.toRadians(60),"NO_FRAME"));
|
||||
lightingPresetMap.put("MainAngle",new LightingPreset(new Vector3f(0.5f, 0.5f, 0.5f),0.2f,new Vector3f(0.25f, 1.0f, 1.5f),new Vector3f(0.0f, -1.0f, 0.0f), 2.00f, new Vector3f(0.01f,0.02f,0.03f)));
|
||||
lightingPresetMap.put("RoundHouseAngle",new LightingPreset(new Vector3f(1.5f, 1.0f, 0.5f),0.5f,new Vector3f(1.5f, 1.0f, 0.75f),new Vector3f(0.0f, -0.7f, 0.0f), 2.00f, new Vector3f(0.5f,1.0f,1.5f)));
|
||||
SetActiveCameraFrame("MainAngle");
|
||||
ActiveGUIs.remove("PerformanceOverlay");
|
||||
ActiveGUIs.add("MainMenu");
|
||||
}
|
||||
|
||||
public void AddNewAudio(String Path, String Player, String Buffer, String Name, AudioManager audioManager){
|
||||
SoundBuffer buffer = new SoundBuffer(Path);
|
||||
audioManager.AddSoundBuffer(Buffer,buffer);
|
||||
AudioSource source = new AudioSource(true, true);
|
||||
source.SetBuffer(buffer.GetBufferID());
|
||||
source.SetGain(0.0f);
|
||||
soundMap.put(Name, source);
|
||||
audioManager.AddSoundSource(Player,source);
|
||||
source.Play();
|
||||
}
|
||||
@Override
|
||||
public void Input(EngineInstance engineInstance, long FrameDiffNanoSeconds) {
|
||||
|
||||
}
|
||||
@Override
|
||||
public void SetUpAudio(EngineInstance engineInstance){
|
||||
AudioManager audioManager = engineInstance.audioManager();
|
||||
AddNewAudio("resources/EngineResources/audio/music/RoundHouseThemeCEZ4434_03.ogg",ROUNDHOUSE_PLAYER,ROUNDHOUSE_BUFFER,"RoundHouseAngle",audioManager);
|
||||
AddNewAudio("resources/EngineResources/audio/music/MainThemeCEZ4434_12.ogg",MAINTHEME_PLAYER,MAINTHEME_BUFFER,"MainAngle",audioManager);
|
||||
}
|
||||
@Override
|
||||
public void CameraInput(EngineInstance engineInstance, long FrameDiffNanoSeconds) {
|
||||
// super.CameraInput(engineInstance,FrameDiffNanoSeconds);
|
||||
if(TransitionCameraFrame){
|
||||
float Lerp = (CurrentTransitionTick/TotalTransitionTicks)/2f;
|
||||
if(ActiveCameraFrame != "NO_FRAME"){
|
||||
soundMap.get(ActiveCameraFrame).SetGain(0.5f - Lerp);
|
||||
}
|
||||
if(SetCameraFrame != "NO_FRAME"){
|
||||
soundMap.get(SetCameraFrame).SetGain(Lerp);
|
||||
}
|
||||
if(ActiveCameraFrame != "NO_FRAME" && SetCameraFrame != "NO_FRAME") {
|
||||
LightingPreset Lerped = lightingPresetMap.get(ActiveCameraFrame).Lerp(lightingPresetMap.get(SetCameraFrame),(int)CurrentTransitionTick,TotalTransitionTicks);
|
||||
skyLight.SetColour(Lerped.SkyLightColour);
|
||||
skyLight.SetIntensity(Lerped.SkyLightStrength);
|
||||
skyLight.SetPositon(Lerped.SkyLightPosition);
|
||||
GetLightingManager().SetAmbientLightColour(Lerped.AmbientColour());
|
||||
GetLightingManager().SetAmbientLightIntensity(Lerped.AmbientStrength());
|
||||
GetLightingManager().SetSkyColour(Lerped.SkyColour);
|
||||
}
|
||||
} else if(ActiveCameraFrame != "NO_FRAME" && soundMap.get(ActiveCameraFrame).GetGain() != 0.5f){
|
||||
soundMap.get(ActiveCameraFrame).SetGain(0.5f);
|
||||
LightingPreset Lerped = lightingPresetMap.get(ActiveCameraFrame);
|
||||
skyLight.SetColour(Lerped.SkyLightColour);
|
||||
skyLight.SetIntensity(Lerped.SkyLightStrength);
|
||||
skyLight.SetPositon(Lerped.SkyLightPosition);
|
||||
GetLightingManager().SetAmbientLightColour(Lerped.AmbientColour());
|
||||
GetLightingManager().SetAmbientLightIntensity(Lerped.AmbientStrength());
|
||||
GetLightingManager().SetSkyColour(Lerped.SkyColour);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +1,43 @@
|
|||
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.Input.KeyboardInput;
|
||||
import net.halbear.Terrain4J.EngineCore.Input.MouseListener;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.GameCore;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.PerformanceOverlay;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Projection.Project3D;
|
||||
import org.joml.Vector2f;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class Scene {
|
||||
import static org.lwjgl.glfw.GLFW.*;
|
||||
|
||||
public class Scene implements IScene {
|
||||
|
||||
private static final float MOUSE_SENSITIVITY = 0.1f;
|
||||
private static final float MOVEMENT_SPEED = 0.025f;
|
||||
private final List<Actor> Actors;
|
||||
private final Map<String, CameraFrame> CameraFrames;
|
||||
private final Project3D Projection;
|
||||
private final Camera camera;
|
||||
private String ActiveCameraFrame = "NO_FRAME";
|
||||
private String SetCameraFrame = "NO_FRAME";
|
||||
private boolean TransitionCameraFrame = false;
|
||||
public String ActiveCameraFrame = "NO_FRAME";
|
||||
public String SetCameraFrame = "NO_FRAME";
|
||||
public boolean TransitionCameraFrame = false;
|
||||
private CameraFrame LastCameraFrame;
|
||||
private int TotalTransitionTicks = 1000;
|
||||
private float CurrentTransitionTick = 0;
|
||||
public int TotalTransitionTicks = 1000;
|
||||
public float CurrentTransitionTick = 0;
|
||||
private Vector2f LastMousePos = new Vector2f(0,0);
|
||||
private final ISceneLightingManager lightingManager;
|
||||
public ILight skyLight;
|
||||
|
||||
public List<String> ActiveGUIs = new ArrayList<>();
|
||||
public Map<String, GUIOverlay> GUIReg = new HashMap<>();
|
||||
|
||||
public Scene(Window window) {
|
||||
lightingManager = new SceneLightingManager(1000,new Vector3f(1f,1f,1f), 0.5f);
|
||||
Actors = new ArrayList<>();
|
||||
CameraFrames = new HashMap<>();
|
||||
var EngConfig = EngineConfig.getInstance();
|
||||
|
|
@ -28,6 +45,20 @@ public class Scene {
|
|||
LastCameraFrame = new CameraFrame(camera.GetPosition(),camera.GetRotation(),camera.GetFOV(), "NO_FRAME");
|
||||
Projection = new Project3D(camera.GetFOV(),EngConfig.GetZNearPlane(), EngConfig.GetZFarPlane(),
|
||||
window.getWidth(), window.getHeight());
|
||||
GUIReg.put("PerformanceOverlay",new PerformanceOverlay());
|
||||
ActiveGUIs.add("PerformanceOverlay");
|
||||
}
|
||||
|
||||
public ISceneLightingManager GetLightingManager(){return lightingManager;}
|
||||
|
||||
@Override
|
||||
public void SetSkyLight(ILight light) {
|
||||
skyLight = light;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ILight GetSkyLight() {
|
||||
return skyLight;
|
||||
}
|
||||
|
||||
public void CameraTick(long FrameDiffNanoSeconds){
|
||||
|
|
@ -39,7 +70,7 @@ public class Scene {
|
|||
Vector3f StartRot = LastCameraFrame.Rotation();
|
||||
CameraFrame StartFrame;
|
||||
if(CameraFrames.containsKey(ActiveCameraFrame)){
|
||||
StartFrame = CameraFrames.get(ActiveCameraFrame);
|
||||
StartFrame = CameraFrames.get(ActiveCameraFrame);
|
||||
} else StartFrame = new CameraFrame(StartPos,StartRot,StartFOV, "NO_FRAME");
|
||||
float EndFOV = camera.GetFOV();
|
||||
Vector3f EndPos = camera.GetPosition();
|
||||
|
|
@ -50,9 +81,9 @@ public class Scene {
|
|||
} else EndFrame = new CameraFrame(EndPos,EndRot,EndFOV, "NO_FRAME");
|
||||
CameraFrame LerpedFrame = StartFrame.Lerp(EndFrame, (int)CurrentTransitionTick, TotalTransitionTicks);
|
||||
camera.SetCameraFrame(LerpedFrame);
|
||||
if(LastCameraFrame.FOV() != LerpedFrame.FOV()){
|
||||
// if(LastCameraFrame.FOV() != LerpedFrame.FOV()){
|
||||
Projection.ChangeFOV(LerpedFrame.FOV());
|
||||
}
|
||||
// }
|
||||
CurrentTransitionTick+= DeltaTime;
|
||||
} else if (TransitionCameraFrame){
|
||||
CurrentTransitionTick = 0;
|
||||
|
|
@ -85,10 +116,110 @@ public class Scene {
|
|||
SetCameraFrame = EndFrame;
|
||||
}
|
||||
public void SetActiveCameraFrame(String frameName){SetCameraFrame = frameName;}
|
||||
public String GetActiveCameraFrame(){return ActiveCameraFrame;}
|
||||
public Camera GetCamera(){return camera;}
|
||||
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()));}
|
||||
|
||||
public void SetUpAudio(EngineInstance engineInstance){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Input(EngineInstance engineInstance, long FrameDiffNanoSeconds) {
|
||||
IScene scene = engineInstance.scene();
|
||||
Window window = engineInstance.window();
|
||||
|
||||
KeyboardInput input = window.getKeyboardInput();
|
||||
float MovementDist = (float)(FrameDiffNanoSeconds / 1000000L) * MOVEMENT_SPEED;
|
||||
Camera camera = scene.GetCamera();
|
||||
if(input.keyPressed(GLFW_KEY_1)){
|
||||
|
||||
}
|
||||
if(input.keyPressed(GLFW_KEY_2)){
|
||||
|
||||
}
|
||||
if(input.keyPressed(GLFW_KEY_3)){
|
||||
|
||||
}
|
||||
if(input.keyPressed(GLFW_KEY_W)){
|
||||
camera.MoveForward(MovementDist);
|
||||
}
|
||||
if(input.keyPressed(GLFW_KEY_S)){
|
||||
camera.MoveBackward(MovementDist);
|
||||
}
|
||||
if(input.keyPressed(GLFW_KEY_A)){
|
||||
camera.MoveLeft(MovementDist);
|
||||
}
|
||||
if(input.keyPressed(GLFW_KEY_D)){
|
||||
camera.MoveRight(MovementDist);
|
||||
}
|
||||
if(input.keyPressed(GLFW_KEY_SPACE)){
|
||||
camera.MoveUp(MovementDist);
|
||||
}
|
||||
if(input.keyPressed(GLFW_KEY_LEFT_SHIFT)){
|
||||
camera.MoveDown(MovementDist);
|
||||
}
|
||||
if(input.keyPressed(GLFW_KEY_LEFT_CONTROL)){
|
||||
camera.Sprint(true);
|
||||
} else camera.Sprint(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Update(EngineInstance engineInstance, long FrameDiffNanoSeconds) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void UpdateFastThread(EngineInstance engineInstance, long FrameDiffNanoSeconds) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void SecondUpdate(EngineInstance engineInstance) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void RenderThreadInput(EngineInstance engineInstance, long FrameDiffNanoSeconds) {
|
||||
CameraTick(FrameDiffNanoSeconds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void RenderGUIs(EngineInstance engineInstance, long frameTimeNS, GameCore parent) {
|
||||
List<String> ActiveGuis = new ArrayList<>(ActiveGUIs);
|
||||
ActiveGuis.forEach(gui->{
|
||||
if(GUIReg.containsKey(gui)){
|
||||
GUIReg.get(gui).RenderGUI(engineInstance,frameTimeNS,parent);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void CameraInput(EngineInstance engineInstance, long FrameDiffNanoSeconds) {
|
||||
float Multiplier = MOUSE_SENSITIVITY;
|
||||
IScene scene = engineInstance.scene();
|
||||
Camera camera = scene.GetCamera();
|
||||
Window window = engineInstance.window();
|
||||
|
||||
MouseListener MouseInput = window.getMouseInput();
|
||||
Vector2f CurrentMousePos = window.getMouseInput().getCurrentPos();
|
||||
Vector2f deltaPos = new Vector2f(0,0);
|
||||
deltaPos.x = 0;
|
||||
deltaPos.y = 0;
|
||||
if (LastMousePos.x >= 0 && LastMousePos.y >= 0 && window.getMouseInput().IsWindowFocused()) {
|
||||
deltaPos.x = CurrentMousePos.x - LastMousePos.x;
|
||||
deltaPos.y = CurrentMousePos.y - LastMousePos.y;
|
||||
}
|
||||
LastMousePos.x = CurrentMousePos.x;
|
||||
LastMousePos.y = CurrentMousePos.y;
|
||||
if(MouseInput.isRightButtonPressed()){
|
||||
|
||||
camera.AddRotation((float)Math.toRadians(-deltaPos.y * Multiplier),(float)Math.toRadians(-deltaPos.x * Multiplier),0);
|
||||
}
|
||||
engineInstance.audioManager().UpdateListenerPosition(camera);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,93 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Main.Scene;
|
||||
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class SceneLightingManager implements ISceneLightingManager {
|
||||
public static int MaxLights;
|
||||
private Vector3f AmbientLightingColour;
|
||||
private float AmbientLightIntensity;
|
||||
private List<ILight> LightingList;
|
||||
private final Vector3f SkyColour = new Vector3f(0,0,0);
|
||||
|
||||
public SceneLightingManager(int MaxLights,Vector3f AmbientLightingColour, float AmbientLightIntensity){
|
||||
this.MaxLights = MaxLights;
|
||||
this.AmbientLightingColour = new Vector3f(AmbientLightingColour);
|
||||
this.AmbientLightIntensity = AmbientLightIntensity;
|
||||
LightingList = new ArrayList<>();
|
||||
}
|
||||
|
||||
public static int GetMaxLights() {
|
||||
return MaxLights;
|
||||
}
|
||||
|
||||
public static void SetMaxLights(int MaxLights) {
|
||||
MaxLights = MaxLights;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void SetSkyColour(Vector3f SkyColourIn) {
|
||||
SkyColour.set(SkyColourIn);
|
||||
}
|
||||
@Override
|
||||
public Vector3f GetSkyColour() {
|
||||
return SkyColour;
|
||||
}
|
||||
@Override
|
||||
public Vector3f GetAmbientLightColour() {
|
||||
return AmbientLightingColour;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float GetAmbientLightIntensity() {
|
||||
return AmbientLightIntensity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ILight[] GetLights() {
|
||||
return LightingList.toArray(new ILight[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void SetAmbientLightIntensity(float Intensity) {
|
||||
this.AmbientLightIntensity = Intensity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void SetAmbientLightColour(Vector3f Colour) {
|
||||
this.AmbientLightingColour = new Vector3f(Colour);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void SetLights(ILight[] lights) {
|
||||
if(LightingList == null){
|
||||
LightingList = new ArrayList<>();
|
||||
}
|
||||
LightingList.clear();
|
||||
AddLights(lights);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void AddLights(ILight[] lights) {
|
||||
if(LightingList == null){
|
||||
LightingList = new ArrayList<>();
|
||||
}
|
||||
LightingList.addAll(Arrays.asList(lights));
|
||||
if(LightingList.size() > MaxLights){
|
||||
List<ILight> cutDown = new ArrayList<>();
|
||||
cutDown.addAll(LightingList.subList(0,MaxLights));
|
||||
LightingList = new ArrayList<>(cutDown);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void AddLight(ILight light) {
|
||||
if(LightingList == null){
|
||||
LightingList = new ArrayList<>();
|
||||
}
|
||||
if(LightingList.size() < MaxLights)LightingList.add(light);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,16 +2,16 @@ package net.halbear.Terrain4J.EngineCore.Threads;
|
|||
|
||||
import net.halbear.Terrain4J.EngineCore.Display.Render;
|
||||
import net.halbear.Terrain4J.EngineCore.Display.Window;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.*;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.GameLogic;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.InitData;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
|
||||
import net.halbear.Terrain4J.EngineCore.Profiling.CPUMonitor;
|
||||
import net.halbear.Terrain4J.EngineCore.Profiling.GPUProfiler;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.SceneRender;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.DeferredSceneRender;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class RenderThread extends EngineThread {
|
||||
|
|
@ -42,18 +42,21 @@ public class RenderThread extends EngineThread {
|
|||
|
||||
}
|
||||
|
||||
public void RefreshRenderer(){
|
||||
render.cleanup();
|
||||
render = new Render(PrimaryRuntime.GetEngineInstance());
|
||||
render.Initialise(initData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void SecondEvent(){
|
||||
EngineConfig.LAST_AVERAGE_GPU_TIME = SceneRender.GetGPUTimeNS();
|
||||
EngineConfig.LAST_AVERAGE_GPU_TIME = DeferredSceneRender.GetGPUTimeNS();
|
||||
List<String[]> Profiling =GPUProfiler.GetVramUsage(render.GetVulkanContext().GetPhysicalDevice().GetPhysicalDevice());
|
||||
EngineConfig.getInstance().SetMemoryProfiling(Profiling);
|
||||
EngineConfig.FrameRate_RENDERTHREAD = Frames;
|
||||
EngineConfig.TPS_RENDERTHREAD = TickFrames;
|
||||
if(render.GetCurrentAAMode() != EngineConfig.getInstance().RenderAAType() || render.GetSceneRender().GetCurrentDeferred() != EngineConfig.getInstance().DeferredRendering()){
|
||||
render.cleanup();
|
||||
render = new Render(PrimaryRuntime.GetEngineInstance());
|
||||
render.Initialise(initData);
|
||||
if(render.GetCurrentAAMode() != EngineConfig.getInstance().RenderAAType() || render.GetDeferred() != EngineConfig.getInstance().DeferredRendering()){
|
||||
RefreshRenderer();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Vulkan.GUI;
|
||||
|
||||
import imgui.ImDrawData;
|
||||
import imgui.ImGui;
|
||||
import imgui.ImGuiIO;
|
||||
import imgui.ImVec4;
|
||||
import imgui.*;
|
||||
import imgui.glfw.ImGuiImplGlfw;
|
||||
import imgui.type.ImInt;
|
||||
import net.halbear.Terrain4J.EngineCore.Input.KeyboardInput;
|
||||
|
|
@ -45,6 +42,8 @@ public class GuiRenderer {
|
|||
private static final String GUI_VERTEX_SHADER_GLSL = "resources/EngineResources/GuiShaders/gui_vertex.glsl";
|
||||
private static final String GUI_VERTEX_SHADER_SPV = GUI_VERTEX_SHADER_GLSL + ".spv";
|
||||
|
||||
public static final Map<String, ImFont> fontMap = new HashMap<>();
|
||||
|
||||
private final VulkanBuffer[] IndexBuffers;
|
||||
private final VulkanBuffer[] VertexBuffers;
|
||||
private final Texture FontsTexture;
|
||||
|
|
@ -98,7 +97,7 @@ public class GuiRenderer {
|
|||
private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] shaderModules, DescriptorSetLayout[] descriptorSetLayouts){
|
||||
var VertexBufferStructure = new GuiVertexBufferStruct();
|
||||
var BuildInfo = new PipelineBuildInfo(shaderModules, VertexBufferStructure.GetVertexInput(),
|
||||
PostProcess.COLOUR_FORMAT)
|
||||
new int[]{PostProcess.COLOUR_FORMAT})
|
||||
.SetPushConstantRanges(
|
||||
new PushConstantsRange[]{
|
||||
new PushConstantsRange(VK_SHADER_STAGE_VERTEX_BIT,0,VulkanUtils.VEC2_SIZE)
|
||||
|
|
@ -156,6 +155,9 @@ public class GuiRenderer {
|
|||
private static Texture InitGUI(VulkanContext VkCtx, Queue queue){
|
||||
ImGui.createContext();
|
||||
ImGuiIO imGuiIO = ImGui.getIO();
|
||||
ImFont newFont = imGuiIO.getFonts().addFontFromFileTTF("resources/EngineResources/Fonts/Oswald-VariableFont_wght.ttf",512);
|
||||
fontMap.put("Title",newFont);
|
||||
imGuiIO.getFonts().build();
|
||||
imGuiIO.setIniFilename(null);
|
||||
VkExtent2D SwapChainExtent = VkCtx.GetSwapChain().GetSwapChainExtent();
|
||||
imGuiIO.setDisplaySize(SwapChainExtent.width(), SwapChainExtent.height());
|
||||
|
|
|
|||
|
|
@ -1,213 +0,0 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Deferred;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.EmptyVertexBufferStruct;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.DefaultPipeline;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.Attachment;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.Image;
|
||||
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.PostProcessing.SpecializationConstants;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.*;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.CommandBuffer;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.Device;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.ImageView;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.SwapChain.SwapChain;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.util.shaderc.Shaderc;
|
||||
import org.lwjgl.vulkan.*;
|
||||
|
||||
import java.nio.LongBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.lwjgl.vulkan.VK13.*;
|
||||
|
||||
public class LightRenderer {
|
||||
private static final int COLOUR_FORMAT = VK_FORMAT_R32G32B32A32_SFLOAT;
|
||||
private static final String DESCRIPTOR_ID_ATTACHMENT = "LIGHT_DESC_ID_ATT";
|
||||
private static final String FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/lighting_frag.glsl";
|
||||
private static final String FRAGMENT_SHADER_FILE_SPV = FRAGMENT_SHADER_FILE_GLSL + ".spv";
|
||||
private static final String VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/lighting_vertex.glsl";
|
||||
private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv";
|
||||
|
||||
private final DescriptorSetLayout AttachmentDescriptorSetLayout;
|
||||
private final VkClearValue ClearValueColour;
|
||||
private final Pipeline pipeline;
|
||||
private final TextureSampler textureSampler;
|
||||
private Attachment AttachmentColour;
|
||||
private VkRenderingAttachmentInfo.Buffer AttachmentInfoColour;
|
||||
private VkRenderingInfo RenderingInfo;
|
||||
|
||||
public LightRenderer(VulkanContext VkCtx, List<Attachment> attachmentList){
|
||||
ClearValueColour=VkClearValue.calloc().color(
|
||||
c->c.float32(0,0.0f).float32(1,0.0f).float32(2,0.0f).float32(3,0.0f));
|
||||
AttachmentColour = CreateColourAttachment(VkCtx);
|
||||
AttachmentInfoColour = CreateColourAttachmentInfo(AttachmentColour,ClearValueColour);
|
||||
RenderingInfo = CreateRenderInfo(AttachmentColour,AttachmentInfoColour);
|
||||
|
||||
ShaderModule[] shaderModules = CreateShaderModules(VkCtx);
|
||||
|
||||
var textureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_REPEAT,VK_BORDER_COLOR_INT_OPAQUE_BLACK,1,true);
|
||||
textureSampler = new TextureSampler(VkCtx, textureSamplerInfo);
|
||||
int AttachmentCount = attachmentList.size();
|
||||
DescriptorSetLayout.LayoutInformation[] descriptorSetLayouts = new DescriptorSetLayout.LayoutInformation[AttachmentCount];
|
||||
for(int i = 0; i < AttachmentCount; i++){
|
||||
descriptorSetLayouts[i] = new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, i,1,VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
}
|
||||
AttachmentDescriptorSetLayout = new DescriptorSetLayout(VkCtx, descriptorSetLayouts);
|
||||
CreateAttachmentDescriptorSet(VkCtx, AttachmentDescriptorSetLayout, attachmentList, textureSampler);
|
||||
|
||||
pipeline = CreatePipeline(VkCtx,shaderModules,new DescriptorSetLayout[]{AttachmentDescriptorSetLayout});
|
||||
Arrays.asList(shaderModules).forEach(s->{s.CleanUp(VkCtx);});
|
||||
}
|
||||
|
||||
private static Attachment CreateColourAttachment(VulkanContext VkCtx){
|
||||
SwapChain swapChain = VkCtx.GetSwapChain();
|
||||
VkExtent2D SwapChainExtent = swapChain.GetSwapChainExtent();
|
||||
return new Attachment(VkCtx,SwapChainExtent.width(),SwapChainExtent.height(),
|
||||
COLOUR_FORMAT,VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
|
||||
}
|
||||
|
||||
private static VkRenderingAttachmentInfo.Buffer CreateColourAttachmentInfo(Attachment SrcAttachment, VkClearValue ClearValue){
|
||||
return VkRenderingAttachmentInfo.calloc(1)
|
||||
.sType$Default()
|
||||
.imageView(SrcAttachment.GetVkImageView().GetVulkanImageView())
|
||||
.imageLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
|
||||
.loadOp(VK_ATTACHMENT_LOAD_OP_CLEAR)
|
||||
.storeOp(VK_ATTACHMENT_STORE_OP_STORE)
|
||||
.clearValue(ClearValue);
|
||||
}
|
||||
|
||||
private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] shaderModules, DescriptorSetLayout[] descriptorSetLayouts){
|
||||
var VertexBufferStruct = new EmptyVertexBufferStruct();
|
||||
var BuildInfo = new PipelineBuildInfo(shaderModules,VertexBufferStruct.GetVertexInput(),COLOUR_FORMAT)
|
||||
.SetDescriptorSetLayouts(descriptorSetLayouts)
|
||||
.BlendingIsUsed(true)
|
||||
.SetDepthWrite(false)
|
||||
.SetDepthTest(false);
|
||||
var PipeLine = new DefaultPipeline(VkCtx,BuildInfo);
|
||||
VertexBufferStruct.CleanUp();
|
||||
return PipeLine;
|
||||
}
|
||||
|
||||
private static VkRenderingInfo CreateRenderInfo(Attachment ColourAttachment, VkRenderingAttachmentInfo.Buffer ColourAttachmentInfo){
|
||||
VkRenderingInfo renderingInfo;
|
||||
try(var MemStack = MemoryStack.stackPush()){
|
||||
Image image = ColourAttachment.GetVkImage();
|
||||
VkExtent2D extent2D = VkExtent2D.calloc(MemStack).width(image.GetWidth()).height(image.GetHeight());
|
||||
var RenderArea = VkRect2D.calloc(MemStack).extent(extent2D);
|
||||
|
||||
renderingInfo = VkRenderingInfo.calloc()
|
||||
.sType$Default()
|
||||
.renderArea(RenderArea)
|
||||
.layerCount(1)
|
||||
.pColorAttachments(ColourAttachmentInfo);
|
||||
}
|
||||
return renderingInfo;
|
||||
}
|
||||
|
||||
private static void CreateAttachmentDescriptorSet(VulkanContext VkCtx, DescriptorSetLayout descriptorSetLayout, List<Attachment> attachments, TextureSampler textureSampler){
|
||||
DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator();
|
||||
Device device = VkCtx.GetDevice();
|
||||
DescriptorSet descriptorSet = descriptorAllocator.AddDescriptorSet(device, DESCRIPTOR_ID_ATTACHMENT, descriptorSetLayout);
|
||||
List<ImageView> imageViews = new ArrayList<>();
|
||||
attachments.forEach(a->imageViews.add(a.GetVkImageView()));
|
||||
descriptorSet.SetImages(device, imageViews, textureSampler, 0);
|
||||
}
|
||||
|
||||
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_glsl_fragment_shader);
|
||||
}
|
||||
return new ShaderModule[]{
|
||||
new ShaderModule(VkCtx,VK_SHADER_STAGE_VERTEX_BIT,VERTEX_SHADER_FILE_SPV,null),
|
||||
new ShaderModule(VkCtx,VK_SHADER_STAGE_FRAGMENT_BIT,FRAGMENT_SHADER_FILE_SPV,null)
|
||||
};
|
||||
}
|
||||
|
||||
public Attachment GetColourAttachment(){
|
||||
return AttachmentColour;
|
||||
}
|
||||
|
||||
public void Render(VulkanContext VkCtx, CommandBuffer commandBuffer, MultiRenderTargetAttachments MRTAttachments){
|
||||
try(var MemStack = MemoryStack.stackPush()){
|
||||
VkCommandBuffer CommandHandle = commandBuffer.GetVulkanCommandBuffer();
|
||||
|
||||
VulkanUtils.ImageBarrier(MemStack, CommandHandle, AttachmentColour.GetVkImage().getVulkanImage(),
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_2_TOP_OF_PIPE_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);
|
||||
|
||||
List<Attachment> ColourAttachments = MRTAttachments.GetColourAttachments();
|
||||
int AttachmentCount = ColourAttachments.size();
|
||||
for(int i = 0; i < AttachmentCount; i++) {
|
||||
Attachment colourAttachment = ColourAttachments.get(i);
|
||||
VulkanUtils.ImageBarrier(MemStack, CommandHandle, colourAttachment.GetVkImage().getVulkanImage(),
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
|
||||
VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_2_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
}
|
||||
VulkanUtils.ImageBarrier(MemStack, CommandHandle, MRTAttachments.GetDepthAttachment().GetVkImage().getVulkanImage(),
|
||||
VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
|
||||
VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,VK_ACCESS_2_SHADER_READ_BIT,
|
||||
VK_IMAGE_ASPECT_DEPTH_BIT);
|
||||
|
||||
vkCmdBeginRendering(CommandHandle, RenderingInfo);
|
||||
|
||||
vkCmdBindPipeline(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.GetVulkanPipeline());
|
||||
|
||||
Image colourImage = AttachmentColour.GetVkImage();
|
||||
int width = colourImage.GetWidth();
|
||||
int height = colourImage.GetHeight();
|
||||
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);
|
||||
|
||||
DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator();
|
||||
LongBuffer DescriptorSets = MemStack.mallocLong(1)
|
||||
.put(0,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_ATTACHMENT).GetVkDescriptorSet());
|
||||
vkCmdBindDescriptorSets(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.GetVulkanPipelineLayout(),0,DescriptorSets,null);
|
||||
vkCmdDraw(CommandHandle,3,1,0,0);
|
||||
vkCmdEndRendering(CommandHandle);
|
||||
}
|
||||
}
|
||||
|
||||
public void Resize(VulkanContext VkCtx, List<Attachment> attachments){
|
||||
RenderingInfo.free();
|
||||
AttachmentInfoColour.free();
|
||||
AttachmentColour.CleanUp(VkCtx);
|
||||
|
||||
AttachmentColour = CreateColourAttachment(VkCtx);
|
||||
AttachmentInfoColour = CreateColourAttachmentInfo(AttachmentColour, ClearValueColour);
|
||||
RenderingInfo = CreateRenderInfo(AttachmentColour, AttachmentInfoColour);
|
||||
DescriptorSet descriptorSet = VkCtx.GetDescriptorAllocator().GetDescriptorSet(DESCRIPTOR_ID_ATTACHMENT);
|
||||
var ImageViews = new ArrayList<ImageView>();
|
||||
attachments.forEach(a->ImageViews.add(a.GetVkImageView()));
|
||||
descriptorSet.SetImages(VkCtx.GetDevice(),ImageViews,textureSampler,0);
|
||||
}
|
||||
|
||||
public void CleanUp(VulkanContext VkCtx){
|
||||
pipeline.CleanUp(VkCtx);
|
||||
AttachmentDescriptorSetLayout.CleanUp(VkCtx);
|
||||
textureSampler.CleanUp(VkCtx);
|
||||
RenderingInfo.free();
|
||||
AttachmentColour.CleanUp(VkCtx);
|
||||
AttachmentInfoColour.free();
|
||||
ClearValueColour.free();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,308 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.DeferredRendering;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.ILight;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.IScene;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.SceneLightingManager;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.EmptyVertexBufferStruct;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.DefaultPipeline;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.Attachment;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.Image;
|
||||
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.Shader.*;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.CommandBuffer;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.Device;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.ImageView;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.SwapChain.SwapChain;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanBuffer;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.lwjgl.util.shaderc.Shaderc;
|
||||
import org.lwjgl.vulkan.*;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.LongBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.lwjgl.vulkan.VK10.*;
|
||||
import static org.lwjgl.vulkan.VK13.*;
|
||||
|
||||
public class LightRenderer {
|
||||
private static final int COLOUR_FORMAT = VK_FORMAT_R32G32B32A32_SFLOAT;
|
||||
private static final String DESC_ID_ATT = "LIGHT_DESC_ID_ATT";
|
||||
private static final String DESC_ID_LIGHTS = "LIGHT_DESC_ID_LIGHTS";
|
||||
private static final String DESC_ID_SCENE = "LIGHT_DESC_ID_SCENE ";
|
||||
private static final String FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/lighting_frag.glsl";
|
||||
private static final String FRAGMENT_SHADER_FILE_SPV = FRAGMENT_SHADER_FILE_GLSL + ".spv";
|
||||
private static final String VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/lighting_vertex.glsl";
|
||||
private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv";
|
||||
|
||||
private final DescriptorSetLayout AttachmentDescriptorSetLayout;
|
||||
private final VkClearValue ClearValueColour;
|
||||
private final Pipeline pipeline;
|
||||
private final TextureSampler textureSampler;
|
||||
private Attachment AttachmentColour;
|
||||
private VkRenderingAttachmentInfo.Buffer AttachmentInfoColour;
|
||||
private VkRenderingInfo RenderInfo;
|
||||
private final VulkanBuffer[] LightBuffer;
|
||||
private final VulkanBuffer[] SceneBuffer;
|
||||
private final DescriptorSetLayout SceneDescriptorSetLayout;
|
||||
private final DescriptorSetLayout StorageDescriptorSetLayout;
|
||||
|
||||
public LightRenderer(VulkanContext VkCtx, List<Attachment> attachments){
|
||||
ClearValueColour = VkClearValue.calloc().color(
|
||||
c -> c.float32(0, 0.0f).float32(1, 0.0f).float32(2, 0.0f).float32(3, 0.0f));
|
||||
|
||||
AttachmentColour = CreateColourAttachment(VkCtx);
|
||||
AttachmentInfoColour = CreateColourAttachmentInfo(AttachmentColour, ClearValueColour);
|
||||
RenderInfo = CreateRenderInfo(AttachmentColour, AttachmentInfoColour);
|
||||
|
||||
ShaderModule[] shaderModules = CreateShaderModules(VkCtx);
|
||||
|
||||
var textureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
||||
VK_BORDER_COLOR_INT_OPAQUE_BLACK, 1, true);
|
||||
textureSampler = new TextureSampler(VkCtx, textureSamplerInfo);
|
||||
int numAttachments = attachments.size();
|
||||
DescriptorSetLayout.LayoutInformation[] descSetLayouts = new DescriptorSetLayout.LayoutInformation[numAttachments];
|
||||
for (int i = 0; i < numAttachments; i++) {
|
||||
descSetLayouts[i] = new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, i, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
}
|
||||
AttachmentDescriptorSetLayout = new DescriptorSetLayout(VkCtx, descSetLayouts);
|
||||
|
||||
CreateAttachmentDescriptorSet(VkCtx, AttachmentDescriptorSetLayout, attachments, textureSampler);
|
||||
|
||||
StorageDescriptorSetLayout = new DescriptorSetLayout(VkCtx, new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0, 1,
|
||||
VK_SHADER_STAGE_FRAGMENT_BIT));
|
||||
long buffSize = (long) (VulkanUtils.VEC3_SIZE * 2 + VulkanUtils.INT_SIZE + VulkanUtils.FLOAT_SIZE) * SceneLightingManager.MaxLights;
|
||||
LightBuffer = VulkanUtils.CreateHostVisibleBuffers(VkCtx, buffSize, VulkanUtils.MAX_IN_FLIGHT,
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, DESC_ID_LIGHTS, StorageDescriptorSetLayout);
|
||||
|
||||
SceneDescriptorSetLayout = new DescriptorSetLayout(VkCtx, new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, 1,
|
||||
VK_SHADER_STAGE_FRAGMENT_BIT));
|
||||
buffSize = VulkanUtils.VEC3_SIZE * 2 + VulkanUtils.FLOAT_SIZE + VulkanUtils.INT_SIZE;
|
||||
SceneBuffer = VulkanUtils.CreateHostVisibleBuffers(VkCtx, buffSize, VulkanUtils.MAX_IN_FLIGHT,
|
||||
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, DESC_ID_SCENE, SceneDescriptorSetLayout);
|
||||
|
||||
pipeline = createPipeline(VkCtx, shaderModules, new DescriptorSetLayout[]{AttachmentDescriptorSetLayout, StorageDescriptorSetLayout,
|
||||
SceneDescriptorSetLayout});
|
||||
Logger.debug("Light Renderer Pipeline -> [{}]",pipeline.GetVulkanPipeline());
|
||||
Arrays.asList(shaderModules).forEach(s -> s.CleanUp(VkCtx));
|
||||
}
|
||||
|
||||
private static void CreateAttachmentDescriptorSet(VulkanContext VkCtx, DescriptorSetLayout descSetLayout, List<Attachment> attachments,
|
||||
TextureSampler sampler) {
|
||||
DescriptorAllocator descAllocator = VkCtx.GetDescriptorAllocator();
|
||||
Device device = VkCtx.GetDevice();
|
||||
DescriptorSet descSet = descAllocator.AddDescriptorSet(device, DESC_ID_ATT, descSetLayout);
|
||||
List<ImageView> imageViews = new ArrayList<>();
|
||||
attachments.forEach(a -> imageViews.add(a.GetVkImageView()));
|
||||
descSet.SetImages(device, imageViews, sampler, 0);
|
||||
}
|
||||
|
||||
private static Attachment CreateColourAttachment(VulkanContext VkCtx) {
|
||||
SwapChain swapChain = VkCtx.GetSwapChain();
|
||||
VkExtent2D swapChainExtent = swapChain.GetSwapChainExtent();
|
||||
return new Attachment(VkCtx, swapChainExtent.width(), swapChainExtent.height(),
|
||||
COLOUR_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
|
||||
}
|
||||
|
||||
private static VkRenderingAttachmentInfo.Buffer CreateColourAttachmentInfo(Attachment attachment, VkClearValue clearValue) {
|
||||
return VkRenderingAttachmentInfo.calloc(1)
|
||||
.sType$Default()
|
||||
.imageView(attachment.GetVkImageView().GetVulkanImageView())
|
||||
.imageLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
|
||||
.loadOp(VK_ATTACHMENT_LOAD_OP_CLEAR)
|
||||
.storeOp(VK_ATTACHMENT_STORE_OP_STORE)
|
||||
.clearValue(clearValue);
|
||||
}
|
||||
|
||||
private static Pipeline createPipeline(VulkanContext VkCtx, ShaderModule[] shaderModules, DescriptorSetLayout[] descSetLayouts) {
|
||||
var vtxBuffStruct = new EmptyVertexBufferStruct();
|
||||
var buildInfo = new PipelineBuildInfo(shaderModules, vtxBuffStruct.GetVertexInput(),new int[]{COLOUR_FORMAT})
|
||||
.SetDescriptorSetLayouts(descSetLayouts)
|
||||
.BlendingIsUsed(true)
|
||||
.SetBlendingMethod(1)
|
||||
.SetDepthWrite(false)
|
||||
.SetDepthTest(false);
|
||||
var pipeline = new DefaultPipeline(VkCtx, buildInfo);
|
||||
vtxBuffStruct.CleanUp();
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
private static VkRenderingInfo CreateRenderInfo(Attachment ColourAttachment, VkRenderingAttachmentInfo.Buffer ColourAttachmentInfo) {
|
||||
VkRenderingInfo result;
|
||||
try (var stack = MemoryStack.stackPush()) {
|
||||
VkExtent2D extent = VkExtent2D.calloc(stack);
|
||||
extent.width(ColourAttachment.GetVkImage().GetWidth());
|
||||
extent.height(ColourAttachment.GetVkImage().GetHeight());
|
||||
var renderArea = VkRect2D.calloc(stack).extent(extent);
|
||||
|
||||
result = VkRenderingInfo.calloc()
|
||||
.sType$Default()
|
||||
.renderArea(renderArea)
|
||||
.layerCount(1)
|
||||
.pColorAttachments(ColourAttachmentInfo);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
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_glsl_fragment_shader);
|
||||
}
|
||||
return new ShaderModule[]{
|
||||
new ShaderModule(VkCtx, VK_SHADER_STAGE_VERTEX_BIT, VERTEX_SHADER_FILE_SPV, null),
|
||||
new ShaderModule(VkCtx, VK_SHADER_STAGE_FRAGMENT_BIT, FRAGMENT_SHADER_FILE_SPV, null),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public void render(EngineInstance engineInstance, VulkanContext VkCtx, CommandBuffer cmdBuffer, MultiRenderTargetAttachments mrtAttachments,int CurrentFrame) {
|
||||
try (var stack = MemoryStack.stackPush()) {
|
||||
VkCommandBuffer cmdHandle = cmdBuffer.GetVulkanCommandBuffer();
|
||||
|
||||
VulkanUtils.ImageBarrier(stack, cmdHandle, AttachmentColour.GetVkImage().getVulkanImage(),
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_2_TOP_OF_PIPE_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);
|
||||
|
||||
List<Attachment> attachments = mrtAttachments.GetColourAttachments();
|
||||
// Logger.debug("Colour Attachments -> \n1: [{}]\n 2:[{}] \n3:[{}]\n 4:[{}]",attachments.get(0),attachments.get(1),attachments.get(2),attachments.get(3));
|
||||
int numAttachments = attachments.size();
|
||||
for (int i = 0; i < numAttachments; i++) {
|
||||
Attachment attachment = attachments.get(i);
|
||||
VulkanUtils.ImageBarrier(stack, cmdHandle, attachment.GetVkImage().getVulkanImage(),
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
|
||||
VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_2_SHADER_READ_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
}
|
||||
VulkanUtils.ImageBarrier(stack, cmdHandle, mrtAttachments.GetDepthAttachment().GetVkImage().getVulkanImage(),
|
||||
VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
|
||||
VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_2_SHADER_READ_BIT,
|
||||
VK_IMAGE_ASPECT_DEPTH_BIT);
|
||||
|
||||
vkCmdBeginRendering(cmdHandle, RenderInfo);
|
||||
|
||||
vkCmdBindPipeline(cmdHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.GetVulkanPipeline());
|
||||
|
||||
|
||||
Image ColourImage = AttachmentColour.GetVkImage();
|
||||
int width = ColourImage.GetWidth();
|
||||
int height = ColourImage.GetHeight();
|
||||
var viewport = VkViewport.calloc(1, stack)
|
||||
.x(0)
|
||||
.y(height)
|
||||
.height(-height)
|
||||
.width(width)
|
||||
.minDepth(0.0f)
|
||||
.maxDepth(1.0f);
|
||||
vkCmdSetViewport(cmdHandle, 0, viewport);
|
||||
|
||||
var scissor = VkRect2D.calloc(1, stack)
|
||||
.extent(it -> it.width(width).height(height))
|
||||
.offset(it -> it.x(0).y(0));
|
||||
vkCmdSetScissor(cmdHandle, 0, scissor);
|
||||
|
||||
DescriptorAllocator descAllocator = VkCtx.GetDescriptorAllocator();
|
||||
LongBuffer descriptorSets = stack.mallocLong(3)
|
||||
.put(0, descAllocator.GetDescriptorSet(DESC_ID_ATT).GetVkDescriptorSet())
|
||||
.put(1, descAllocator.GetDescriptorSet(DESC_ID_LIGHTS, CurrentFrame).GetVkDescriptorSet())
|
||||
.put(2, descAllocator.GetDescriptorSet(DESC_ID_SCENE, CurrentFrame).GetVkDescriptorSet());
|
||||
IScene scene = engineInstance.scene();
|
||||
UpdateSceneInfo(VkCtx, scene, CurrentFrame);
|
||||
UpdateLights(VkCtx, scene, CurrentFrame);
|
||||
vkCmdBindDescriptorSets(cmdHandle, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
pipeline.GetVulkanPipelineLayout(), 0, descriptorSets, null);
|
||||
|
||||
vkCmdDraw(cmdHandle, 3, 1, 0, 0);
|
||||
|
||||
vkCmdEndRendering(cmdHandle);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateSceneInfo(VulkanContext VkCtx, IScene scene, int CurrentFrame){
|
||||
VulkanBuffer buffer = SceneBuffer[CurrentFrame];
|
||||
long MappedMemory = buffer.MapMemory(VkCtx);
|
||||
ByteBuffer dataBuffer = MemoryUtil.memByteBuffer(MappedMemory, (int)buffer.GetRequestedSize());
|
||||
|
||||
int Offset = 0;
|
||||
scene.GetCamera().GetPosition().get(Offset,dataBuffer);
|
||||
Offset += VulkanUtils.VEC3_SIZE;
|
||||
|
||||
dataBuffer.putFloat(Offset, scene.GetLightingManager().GetAmbientLightIntensity());
|
||||
Offset += VulkanUtils.FLOAT_SIZE;
|
||||
|
||||
scene.GetLightingManager().GetAmbientLightColour().get(Offset, dataBuffer);
|
||||
Offset += VulkanUtils.VEC3_SIZE;
|
||||
|
||||
ILight[] lights = scene.GetLightingManager().GetLights();
|
||||
int LightCount = lights != null ? lights.length : 0;
|
||||
dataBuffer.putInt(Offset, LightCount);
|
||||
buffer.UnMapMemory(VkCtx);
|
||||
}
|
||||
public void UpdateLights(VulkanContext VkCtx, IScene scene, int CurrentFrame){
|
||||
ILight[] lights = scene.GetLightingManager().GetLights();
|
||||
VulkanBuffer buffer = LightBuffer[CurrentFrame];
|
||||
long MappedMemory = buffer.MapMemory(VkCtx);
|
||||
ByteBuffer dataBuffer = MemoryUtil.memByteBuffer(MappedMemory, (int)buffer.GetRequestedSize());
|
||||
|
||||
int Offset = 0;
|
||||
int lightCount = lights != null ? lights.length : 0;
|
||||
for(int i = 0; i < lightCount; i++){
|
||||
ILight light = lights[i];
|
||||
light.GetPosition().get(Offset, dataBuffer);
|
||||
Offset += VulkanUtils.VEC3_SIZE;
|
||||
dataBuffer.putInt(Offset, light.IsDirectional() ? 1 : 0);
|
||||
Offset += VulkanUtils.INT_SIZE;
|
||||
dataBuffer.putFloat(Offset, light.GetIntensity());
|
||||
Offset += VulkanUtils.FLOAT_SIZE;
|
||||
light.GetColour().get(Offset, dataBuffer);
|
||||
Offset += VulkanUtils.VEC3_SIZE;
|
||||
}
|
||||
buffer.UnMapMemory(VkCtx);
|
||||
}
|
||||
|
||||
public void resize(VulkanContext VkCtx, List<Attachment> attachments) {
|
||||
RenderInfo.free();
|
||||
AttachmentInfoColour.free();
|
||||
AttachmentColour.CleanUp(VkCtx);
|
||||
|
||||
AttachmentColour = CreateColourAttachment(VkCtx);
|
||||
AttachmentInfoColour = CreateColourAttachmentInfo(AttachmentColour, ClearValueColour);
|
||||
RenderInfo = CreateRenderInfo(AttachmentColour, AttachmentInfoColour);
|
||||
|
||||
DescriptorSet descSet = VkCtx.GetDescriptorAllocator().GetDescriptorSet(DESC_ID_ATT);
|
||||
var imageViews = new ArrayList<ImageView>();
|
||||
attachments.forEach(a -> imageViews.add(a.GetVkImageView()));
|
||||
descSet.SetImages(VkCtx.GetDevice(), imageViews, textureSampler, 0);
|
||||
}
|
||||
|
||||
public void cleanup(VulkanContext VkCtx) {
|
||||
StorageDescriptorSetLayout.CleanUp(VkCtx);
|
||||
Arrays.asList(LightBuffer).forEach(b -> b.cleanup(VkCtx));
|
||||
SceneDescriptorSetLayout.CleanUp(VkCtx);
|
||||
Arrays.asList(SceneBuffer).forEach(b -> b.cleanup(VkCtx));
|
||||
pipeline.CleanUp(VkCtx);
|
||||
AttachmentDescriptorSetLayout.CleanUp(VkCtx);
|
||||
textureSampler.CleanUp(VkCtx);
|
||||
RenderInfo.free();
|
||||
AttachmentColour.CleanUp(VkCtx);
|
||||
AttachmentInfoColour.free();
|
||||
ClearValueColour.free();
|
||||
}
|
||||
|
||||
public Attachment getAttachment() {
|
||||
return AttachmentColour;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Deferred;
|
||||
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.DeferredRendering;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.Attachment;
|
||||
|
|
@ -7,12 +7,14 @@ import org.lwjgl.vulkan.VkExtent2D;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.lwjgl.vulkan.VK13.*;
|
||||
import static org.lwjgl.vulkan.VK10.*;
|
||||
|
||||
//multiple render target attachments
|
||||
public class MultiRenderTargetAttachments {
|
||||
public static final int ALBEDO_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||
public static final int DEPTH_FORMAT = VK_FORMAT_D32_SFLOAT_S8_UINT;
|
||||
public static final int NORMAL_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||
public static final int PBR_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||
public static final int POSITION_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||
private final List<Attachment> ColourAttachments;
|
||||
private final Attachment DepthAttachment;
|
||||
private final int Height;
|
||||
|
|
@ -24,9 +26,18 @@ public class MultiRenderTargetAttachments {
|
|||
Height = extent2D.height();
|
||||
ColourAttachments = new ArrayList<>();
|
||||
|
||||
var AlbedoAttachment = new Attachment(VkCtx, Width, Height, ALBEDO_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
|
||||
ColourAttachments.add(AlbedoAttachment);
|
||||
|
||||
//Position
|
||||
var Attachment = new Attachment(VkCtx, Width, Height, POSITION_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
|
||||
ColourAttachments.add(Attachment);
|
||||
//albedo
|
||||
Attachment = new Attachment(VkCtx, Width, Height, ALBEDO_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
|
||||
ColourAttachments.add(Attachment);
|
||||
//Normals
|
||||
Attachment = new Attachment(VkCtx, Width, Height, NORMAL_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
|
||||
ColourAttachments.add(Attachment);
|
||||
//PBR
|
||||
Attachment = new Attachment(VkCtx, Width, Height, PBR_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
|
||||
ColourAttachments.add(Attachment);
|
||||
DepthAttachment = new Attachment(VkCtx, Width, Height, DEPTH_FORMAT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
||||
}
|
||||
|
||||
|
|
@ -9,6 +9,8 @@ public class EmptyVertexBufferStruct {
|
|||
public EmptyVertexBufferStruct(){
|
||||
VertexInput = VkPipelineVertexInputStateCreateInfo.calloc();
|
||||
VertexInput.sType$Default();
|
||||
VertexInput .pVertexBindingDescriptions(null)
|
||||
.pVertexAttributeDescriptions(null);
|
||||
}
|
||||
|
||||
public void CleanUp(){VertexInput.free();}
|
||||
|
|
|
|||
|
|
@ -15,26 +15,6 @@ import java.nio.IntBuffer;
|
|||
import java.nio.LongBuffer;
|
||||
|
||||
import static org.lwjgl.vulkan.VK13.*;
|
||||
import static org.lwjgl.vulkan.VK13.VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
import static org.lwjgl.vulkan.VK13.VK_BLEND_FACTOR_SRC_ALPHA;
|
||||
import static org.lwjgl.vulkan.VK13.VK_BLEND_FACTOR_ZERO;
|
||||
import static org.lwjgl.vulkan.VK13.VK_BLEND_OP_ADD;
|
||||
import static org.lwjgl.vulkan.VK13.VK_COLOR_COMPONENT_A_BIT;
|
||||
import static org.lwjgl.vulkan.VK13.VK_COLOR_COMPONENT_B_BIT;
|
||||
import static org.lwjgl.vulkan.VK13.VK_COLOR_COMPONENT_G_BIT;
|
||||
import static org.lwjgl.vulkan.VK13.VK_COLOR_COMPONENT_R_BIT;
|
||||
import static org.lwjgl.vulkan.VK13.VK_CULL_MODE_NONE;
|
||||
import static org.lwjgl.vulkan.VK13.VK_DYNAMIC_STATE_SCISSOR;
|
||||
import static org.lwjgl.vulkan.VK13.VK_DYNAMIC_STATE_VIEWPORT;
|
||||
import static org.lwjgl.vulkan.VK13.VK_FORMAT_UNDEFINED;
|
||||
import static org.lwjgl.vulkan.VK13.VK_FRONT_FACE_CLOCKWISE;
|
||||
import static org.lwjgl.vulkan.VK13.VK_NULL_HANDLE;
|
||||
import static org.lwjgl.vulkan.VK13.VK_SAMPLE_COUNT_1_BIT;
|
||||
import static org.lwjgl.vulkan.VK13.VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
|
||||
import static org.lwjgl.vulkan.VK13.vkCreateGraphicsPipelines;
|
||||
import static org.lwjgl.vulkan.VK13.vkCreatePipelineLayout;
|
||||
import static org.lwjgl.vulkan.VK13.vkDestroyPipeline;
|
||||
import static org.lwjgl.vulkan.VK13.vkDestroyPipelineLayout;
|
||||
|
||||
public class DefaultPipeline implements Pipeline {
|
||||
private final long VulkanPipeline;
|
||||
|
|
@ -88,7 +68,7 @@ public class DefaultPipeline implements Pipeline {
|
|||
if(BuildInfo.GetDepthFormat() != VK_FORMAT_UNDEFINED){
|
||||
DepthStencil = VkPipelineDepthStencilStateCreateInfo.calloc(MemStack)
|
||||
.sType(VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO)
|
||||
.depthTestEnable(BuildInfo.performDepthTest())
|
||||
.depthTestEnable(BuildInfo.GetDepthTest())
|
||||
.depthWriteEnable(BuildInfo.performDepthWrite())
|
||||
.depthCompareOp(VK_COMPARE_OP_GREATER_OR_EQUAL)
|
||||
.depthBoundsTestEnable(false)
|
||||
|
|
@ -123,32 +103,38 @@ public class DefaultPipeline implements Pipeline {
|
|||
for(int i = 0; i < LayoutCount; i++){
|
||||
ppLayout.put(i, descriptorSetLayouts[i].GetVkDescriptorLayout());
|
||||
}
|
||||
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(BuildInfo.BlendingUsed());
|
||||
if(BuildInfo.BlendingUsed()){
|
||||
BlendAttributeState.get(0).colorBlendOp(VK_BLEND_OP_ADD)
|
||||
.alphaBlendOp(VK_BLEND_OP_ADD)
|
||||
.srcColorBlendFactor(VK_BLEND_FACTOR_SRC_ALPHA)
|
||||
.dstColorBlendFactor(VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA)
|
||||
.srcAlphaBlendFactor(VK_BLEND_FACTOR_ONE)
|
||||
.dstAlphaBlendFactor(VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
|
||||
int[] ColourFormats = BuildInfo.GetColourFormat();
|
||||
int ColourFormatCount = ColourFormats.length;
|
||||
IntBuffer ColourFormatsBuffer = MemStack.mallocInt(ColourFormatCount);
|
||||
ColourFormatsBuffer.put(0,ColourFormats);
|
||||
|
||||
var RendererCreateInfo = VkPipelineRenderingCreateInfo.calloc(MemStack)
|
||||
.sType$Default()
|
||||
.colorAttachmentCount(ColourFormatCount)
|
||||
.pColorAttachmentFormats(ColourFormatsBuffer);
|
||||
|
||||
if(DepthStencil != null){RendererCreateInfo.depthAttachmentFormat(BuildInfo.GetDepthFormat());}
|
||||
|
||||
VkPipelineColorBlendAttachmentState.Buffer BlendAttributeState = VkPipelineColorBlendAttachmentState.calloc(ColourFormatCount,MemStack);
|
||||
for(int i = 0; i < ColourFormatCount; i++){
|
||||
BlendAttributeState.get(i).colorWriteMask(VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT)
|
||||
.blendEnable(BuildInfo.BlendingUsed());
|
||||
if(BuildInfo.BlendingUsed()) {
|
||||
BlendAttributeState.get(i).colorBlendOp(VK_BLEND_OP_ADD)
|
||||
.alphaBlendOp(VK_BLEND_OP_ADD)
|
||||
.srcColorBlendFactor(VK_BLEND_FACTOR_SRC_ALPHA)
|
||||
.dstColorBlendFactor(VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA)
|
||||
.srcAlphaBlendFactor(BuildInfo.GetBlendingMethod() == 0 ? VK_BLEND_FACTOR_ONE : VK_BLEND_FACTOR_SRC_ALPHA)
|
||||
.dstAlphaBlendFactor(BuildInfo.GetBlendingMethod() == 0 ? VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA : VK_BLEND_FACTOR_ZERO);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if(DepthStencil != null){RendererCreateInfo.depthAttachmentFormat(BuildInfo.GetDepthFormat());}
|
||||
|
||||
var PipelineLayoutCreateInfoPtr = VkPipelineLayoutCreateInfo.calloc(MemStack)
|
||||
.sType$Default()
|
||||
.pSetLayouts(ppLayout)
|
||||
|
|
@ -160,7 +146,6 @@ public class DefaultPipeline implements Pipeline {
|
|||
|
||||
var PipelineCreateInfo = VkGraphicsPipelineCreateInfo.calloc(1,MemStack)
|
||||
.sType$Default()
|
||||
.renderPass(VK_NULL_HANDLE)
|
||||
.pStages(ShaderStages)
|
||||
.pVertexInputState(BuildInfo.GetVertexInputStateCreateInfo())
|
||||
.pInputAssemblyState(AssemblyStateCreateInfo)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Display.GLFWImageParser;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.ImageSrc;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
|
|||
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.ImageView;
|
||||
|
||||
import static org.lwjgl.util.vma.Vma.VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;
|
||||
import static org.lwjgl.vulkan.VK13.*;
|
||||
public class Attachment {
|
||||
private final Image VkImage;
|
||||
|
|
@ -12,7 +11,7 @@ public class Attachment {
|
|||
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).MemoryUsage(VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT).SampleCount(EngineConfig.getInstance().GetRenderSampleCount());
|
||||
var ImageData = new Image.ImageData().Width(Width).Height(Height).Format(Format).SampleCount(EngineConfig.getInstance().GetRenderSampleCount());
|
||||
|
||||
int AspectMask = 0;
|
||||
if((Usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) > 0){
|
||||
|
|
@ -22,7 +21,7 @@ public class Attachment {
|
|||
}
|
||||
if((Usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) > 0){
|
||||
ImageData.Usage(Usage | VK_IMAGE_USAGE_SAMPLED_BIT);
|
||||
AspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
AspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
DepthAttachment = true;
|
||||
}
|
||||
VkImage = new Image(VkCtx, ImageData);
|
||||
|
|
|
|||
|
|
@ -1,15 +1,11 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.Device;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.util.vma.VmaAllocationCreateInfo;
|
||||
import org.lwjgl.vulkan.VkImageCreateInfo;
|
||||
import org.lwjgl.vulkan.VkMemoryAllocateInfo;
|
||||
import org.lwjgl.vulkan.VkMemoryRequirements;
|
||||
|
||||
import java.nio.LongBuffer;
|
||||
|
||||
|
|
@ -89,7 +85,7 @@ public class Image {
|
|||
MipMapLevels = 1;
|
||||
SampleCount = 1;
|
||||
ArrayLayers = 1;
|
||||
MemoryUsage = 0;
|
||||
MemoryUsage = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;
|
||||
}
|
||||
public ImageData MemoryUsage(int memoryUsage){
|
||||
this.MemoryUsage = memoryUsage;
|
||||
|
|
|
|||
|
|
@ -5,18 +5,15 @@ import net.halbear.Terrain4J.EngineCore.Main.Util.Maths.T4Math;
|
|||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.CommandBuffer;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.ImageView;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanBuffer;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.lwjgl.vulkan.*;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import static org.lwjgl.util.vma.Vma.VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
|
||||
import static org.lwjgl.util.vma.Vma.VMA_MEMORY_USAGE_AUTO;
|
||||
import static org.lwjgl.vulkan.VK10.*;
|
||||
import static org.lwjgl.vulkan.VK13.VK_ACCESS_2_NONE;
|
||||
import static org.lwjgl.vulkan.VK13.vkCmdPipelineBarrier2;
|
||||
|
||||
public class Texture {
|
||||
|
|
@ -61,7 +58,8 @@ public class Texture {
|
|||
}
|
||||
public void CreateStgBuffer(VulkanContext VkCtx, ByteBuffer data){
|
||||
int Size = data.remaining();
|
||||
stgBuffer = new VulkanBuffer(VkCtx, Size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,VMA_MEMORY_USAGE_AUTO,VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
|
||||
stgBuffer = new VulkanBuffer(VkCtx, Size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_AUTO,
|
||||
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
|
||||
long MappedMemory = stgBuffer.MapMemory(VkCtx);
|
||||
ByteBuffer buffer = MemoryUtil.memByteBuffer(MappedMemory, (int) stgBuffer.GetRequestedSize());
|
||||
buffer.put(data);
|
||||
|
|
@ -69,13 +67,35 @@ public class Texture {
|
|||
stgBuffer.UnMapMemory(VkCtx);
|
||||
}
|
||||
|
||||
private void RecordImageTransition(MemoryStack stack, CommandBuffer cmd) {
|
||||
var imageBarrier = VkImageMemoryBarrier2.calloc(1, stack)
|
||||
.sType$Default()
|
||||
.oldLayout(VK_IMAGE_LAYOUT_UNDEFINED)
|
||||
.newLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
|
||||
.srcStageMask(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT)
|
||||
.dstStageMask(VK_PIPELINE_STAGE_TRANSFER_BIT)
|
||||
.srcAccessMask(0)
|
||||
.dstAccessMask(VK_ACCESS_TRANSFER_WRITE_BIT)
|
||||
.subresourceRange(it -> it
|
||||
.aspectMask(VK_IMAGE_ASPECT_COLOR_BIT)
|
||||
.baseMipLevel(0)
|
||||
.levelCount(image.GetMipLevels())
|
||||
.baseArrayLayer(0)
|
||||
.layerCount(1))
|
||||
.image(image.getVulkanImage());
|
||||
|
||||
VkDependencyInfo depInfo = VkDependencyInfo.calloc(stack)
|
||||
.sType$Default()
|
||||
.pImageMemoryBarriers(imageBarrier);
|
||||
|
||||
vkCmdPipelineBarrier2(cmd.GetVulkanCommandBuffer(), depInfo);
|
||||
}
|
||||
|
||||
public void RecordTextureTransition(CommandBuffer commandBuffer){
|
||||
if(stgBuffer != null && !RecordedTransition){
|
||||
RecordedTransition = true;
|
||||
try(var MemStack = MemoryStack.stackPush()){
|
||||
VulkanUtils.ImageBarrier(MemStack, commandBuffer.GetVulkanCommandBuffer(), image.getVulkanImage(),
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_2_NONE, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
RecordImageTransition(MemStack, commandBuffer);
|
||||
RecordCopyBuffer(MemStack, commandBuffer, stgBuffer);
|
||||
RecordGenerateMipMaps(MemStack, commandBuffer);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
|
|||
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.GraphUtils;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.IndexedLinkedHashMap;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.VulkanMaterial;
|
||||
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.Queues.Queue;
|
||||
|
|
@ -18,7 +17,7 @@ import java.util.UUID;
|
|||
import static org.lwjgl.vulkan.VK10.VK_FORMAT_R8G8B8A8_SRGB;
|
||||
|
||||
public class TextureCache {
|
||||
public static final int MAX_TEXTURES = 500;
|
||||
public static final int MAX_TEXTURES = 512;
|
||||
private final IndexedLinkedHashMap<String, Texture> TextureMap;
|
||||
private final List<String> ActualTextures;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline;
|
|||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class IndexedLinkedHashMap<K,V> extends LinkedHashMap<K,V> {
|
||||
private final List<K> IndexList = new ArrayList<>();
|
||||
|
|
|
|||
|
|
@ -1,15 +1,12 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.DescriptorSet;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.DescriptorSetLayout;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.ShaderModule;
|
||||
import org.lwjgl.vulkan.VkPipelineVertexInputStateCreateInfo;
|
||||
import org.lwjgl.vulkan.VkPushConstantRange;
|
||||
|
||||
import static org.lwjgl.vulkan.VK10.VK_FORMAT_UNDEFINED;
|
||||
|
||||
public class PipelineBuildInfo {
|
||||
private final int ColourFormat;
|
||||
private final ShaderModule[] ShaderModules;
|
||||
private final VkPipelineVertexInputStateCreateInfo VertexInput;
|
||||
private int DepthFormat;
|
||||
|
|
@ -20,15 +17,23 @@ public class PipelineBuildInfo {
|
|||
private boolean DepthTest = true;
|
||||
private boolean DualPass = false;
|
||||
private boolean alphaToCoverage = false;
|
||||
private final int[] ColourFormats;
|
||||
private int BlendingMethod = 0;
|
||||
|
||||
public PipelineBuildInfo(ShaderModule[] shaderModules, VkPipelineVertexInputStateCreateInfo VertexInput, int ColourFormat){
|
||||
this.ColourFormat = ColourFormat;
|
||||
public PipelineBuildInfo(ShaderModule[] shaderModules, VkPipelineVertexInputStateCreateInfo VertexInput, int[] ColourFormat){
|
||||
this.ColourFormats = ColourFormat;
|
||||
this.ShaderModules = shaderModules;
|
||||
this.VertexInput = VertexInput;
|
||||
DepthFormat = VK_FORMAT_UNDEFINED;
|
||||
useBlend = true;
|
||||
}
|
||||
|
||||
public PipelineBuildInfo SetBlendingMethod(int in){
|
||||
BlendingMethod = in;
|
||||
return this;
|
||||
}
|
||||
public int GetBlendingMethod(){return BlendingMethod;}
|
||||
|
||||
public PipelineBuildInfo SetAlphaToCoverage(boolean alphaToCoverage){
|
||||
this.alphaToCoverage = alphaToCoverage;
|
||||
return this;
|
||||
|
|
@ -37,18 +42,15 @@ public class PipelineBuildInfo {
|
|||
this.DualPass = DualPass;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PipelineBuildInfo SetDepthTest(boolean DepthTest){
|
||||
this.DepthTest = DepthTest;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean performDepthTest(){return DepthTest;}
|
||||
|
||||
public PipelineBuildInfo SetDepthWrite(boolean DepthWrite){
|
||||
this.DepthWrite = DepthWrite;
|
||||
return this;
|
||||
}
|
||||
public PipelineBuildInfo SetDepthTest(boolean DepthTest){
|
||||
this.DepthTest = DepthTest;
|
||||
return this;
|
||||
}
|
||||
public boolean GetDepthTest(){return DepthTest;}
|
||||
|
||||
public boolean performDepthWrite(){return DepthWrite;}
|
||||
public boolean PassTwice(){return DualPass;}
|
||||
|
|
@ -80,7 +82,7 @@ public class PipelineBuildInfo {
|
|||
|
||||
public PushConstantsRange[] GetPushConstantRanges(){return PushConstRanges;}
|
||||
public int GetDepthFormat(){return DepthFormat;}
|
||||
public int GetColourFormat(){return ColourFormat;}
|
||||
public int[] GetColourFormat(){return ColourFormats;}
|
||||
public ShaderModule[] GetShaderModules(){return ShaderModules;}
|
||||
public VkPipelineVertexInputStateCreateInfo GetVertexInputStateCreateInfo(){return VertexInput;}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import org.lwjgl.system.MemoryStack;
|
|||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.lwjgl.util.shaderc.Shaderc;
|
||||
import org.lwjgl.vulkan.*;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.LongBuffer;
|
||||
|
|
@ -73,6 +74,7 @@ public class PostProcess {
|
|||
|
||||
pipeline = CreatePipeline(VkCtx, shaderModules, new DescriptorSetLayout[]{AttachmentDescriptorSetLayout, FragmentUniformDescriptorSetLayout});
|
||||
Arrays.asList(shaderModules).forEach(shader->shader.CleanUp(VkCtx));
|
||||
Logger.debug("Post Process Renderer Pipeline -> [{}]",pipeline.GetVulkanPipeline());
|
||||
}
|
||||
|
||||
private static Attachment CreateColourAttachment(VulkanContext VkCtx){
|
||||
|
|
@ -93,7 +95,7 @@ public class PostProcess {
|
|||
|
||||
private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] shaderModules, DescriptorSetLayout[] descriptorSetLayouts){
|
||||
var VertexBufferStruct = new EmptyVertexBufferStruct();
|
||||
var BuildInfo = new PipelineBuildInfo(shaderModules,VertexBufferStruct.GetVertexInput(),COLOUR_FORMAT).SetDescriptorSetLayouts(descriptorSetLayouts).BlendingIsUsed(true);
|
||||
var BuildInfo = new PipelineBuildInfo(shaderModules,VertexBufferStruct.GetVertexInput(),new int[]{COLOUR_FORMAT}).SetDescriptorSetLayouts(descriptorSetLayouts).BlendingIsUsed(true);
|
||||
var PipeLine = new DefaultPipeline(VkCtx,BuildInfo);
|
||||
VertexBufferStruct.CleanUp();
|
||||
return PipeLine;
|
||||
|
|
@ -116,12 +118,10 @@ public class PostProcess {
|
|||
}
|
||||
|
||||
private static void CreateAttachmentDescriptorSet(VulkanContext VkCtx, DescriptorSetLayout descriptorSetLayout, Attachment attachment, TextureSampler textureSampler){
|
||||
if(!EngineConfig.getInstance().DeferredRendering() && attachment != null) {
|
||||
DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator();
|
||||
Device device = VkCtx.GetDevice();
|
||||
DescriptorSet descriptorSet = descriptorAllocator.AddDescriptorSets(device, DESCRIPTOR_ID_ATTACHMENT, 1, descriptorSetLayout)[0];
|
||||
descriptorSet.SetImage(device, attachment.GetVkImageView(), textureSampler, 0);
|
||||
}
|
||||
DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator();
|
||||
Device device = VkCtx.GetDevice();
|
||||
DescriptorSet descriptorSet = descriptorAllocator.AddDescriptorSets(device,DESCRIPTOR_ID_ATTACHMENT,1 , descriptorSetLayout)[0];
|
||||
descriptorSet.SetImage(device,attachment.GetVkImageView(),textureSampler,0);
|
||||
}
|
||||
|
||||
private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx, SpecializationConstants specConstants){
|
||||
|
|
@ -140,47 +140,43 @@ public class PostProcess {
|
|||
}
|
||||
|
||||
public void Render(VulkanContext VkCtx, CommandBuffer commandBuffer, Attachment SrcAttachment){
|
||||
if(SrcAttachment != null) {
|
||||
try (var MemStack = MemoryStack.stackPush()) {
|
||||
SwapChain swapChain = VkCtx.GetSwapChain();
|
||||
VkCommandBuffer CommandHandle = commandBuffer.GetVulkanCommandBuffer();
|
||||
try(var MemStack = MemoryStack.stackPush()){
|
||||
SwapChain swapChain = VkCtx.GetSwapChain();
|
||||
VkCommandBuffer CommandHandle = commandBuffer.GetVulkanCommandBuffer();
|
||||
|
||||
VulkanUtils.ImageBarrier(MemStack, CommandHandle, SrcAttachment.GetVkImage().getVulkanImage(),
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_2_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
VulkanUtils.ImageBarrier(MemStack, CommandHandle, ColourAttachment.GetVkImage().getVulkanImage(),
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_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);
|
||||
vkCmdBeginRendering(CommandHandle, RenderingInfo);
|
||||
vkCmdBindPipeline(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.GetVulkanPipeline());
|
||||
VulkanUtils.ImageBarrier(MemStack, CommandHandle, SrcAttachment.GetVkImage().getVulkanImage(),
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,VK_ACCESS_2_SHADER_READ_BIT,VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
VulkanUtils.ImageBarrier(MemStack,CommandHandle,ColourAttachment.GetVkImage().getVulkanImage(),
|
||||
VK_IMAGE_LAYOUT_UNDEFINED,VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,VK_PIPELINE_STAGE_2_TOP_OF_PIPE_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);
|
||||
vkCmdBeginRendering(CommandHandle,RenderingInfo);
|
||||
vkCmdBindPipeline(CommandHandle,VK_PIPELINE_BIND_POINT_GRAPHICS,pipeline.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);
|
||||
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);
|
||||
var Scissor = VkRect2D.calloc(1,MemStack)
|
||||
.extent(it->it.width(Width).height(Height))
|
||||
.offset(it->it.x(0).y(0));
|
||||
vkCmdSetScissor(CommandHandle,0,Scissor);
|
||||
|
||||
DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator();
|
||||
if(descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_ATTACHMENT) != null && descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_SCREEN_SIZE) != null) {
|
||||
LongBuffer DescriptorSets = MemStack.mallocLong(2)
|
||||
.put(0, descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_ATTACHMENT).GetVkDescriptorSet())
|
||||
.put(1, descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_SCREEN_SIZE).GetVkDescriptorSet());
|
||||
vkCmdBindDescriptorSets(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.GetVulkanPipelineLayout(), 0, DescriptorSets, null);
|
||||
vkCmdDraw(CommandHandle, 3, 1, 0, 0);
|
||||
}
|
||||
vkCmdEndRendering(CommandHandle);
|
||||
}
|
||||
DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator();
|
||||
LongBuffer DescriptorSets = MemStack.mallocLong(2)
|
||||
.put(0,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_ATTACHMENT).GetVkDescriptorSet())
|
||||
.put(1,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_SCREEN_SIZE).GetVkDescriptorSet());
|
||||
vkCmdBindDescriptorSets(CommandHandle,VK_PIPELINE_BIND_POINT_GRAPHICS,pipeline.GetVulkanPipelineLayout(),0,DescriptorSets,null);
|
||||
vkCmdDraw(CommandHandle,3,1,0,0);
|
||||
vkCmdEndRendering(CommandHandle);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader;
|
|||
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.Device;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.PhysicalDevice;
|
||||
import org.lwjgl.vulkan.VkPhysicalDeviceFeatures2;
|
||||
import org.lwjgl.vulkan.VkPhysicalDeviceLimits;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ public class DescriptorSetLayout {
|
|||
private final LayoutInformation[] LayoutInfos;
|
||||
protected long VkDescriptorLayout;
|
||||
public DescriptorSetLayout(VulkanContext VkCtx, LayoutInformation LayoutInfo){
|
||||
this(VkCtx, new DescriptorSetLayout.LayoutInformation[]{LayoutInfo});
|
||||
this(VkCtx, new LayoutInformation[]{LayoutInfo});
|
||||
}
|
||||
public DescriptorSetLayout(VulkanContext VkCtx, LayoutInformation[] LayoutInfos){
|
||||
this.LayoutInfos = LayoutInfos;
|
||||
|
|
|
|||
|
|
@ -4,9 +4,6 @@ import net.halbear.Terrain4J.EngineCore.Logic.Rendering.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.lwjgl.vulkan.VkSpecializationInfo;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
|
|
@ -16,6 +13,9 @@ import java.nio.ByteBuffer;
|
|||
import java.nio.LongBuffer;
|
||||
import java.nio.file.Files;
|
||||
|
||||
import static org.lwjgl.vulkan.VK13.vkCreateShaderModule;
|
||||
import static org.lwjgl.vulkan.VK13.vkDestroyShaderModule;
|
||||
|
||||
|
||||
public class ShaderModule {
|
||||
private final long Handle;
|
||||
|
|
|
|||
|
|
@ -5,12 +5,14 @@ import org.lwjgl.vulkan.VkPipelineVertexInputStateCreateInfo;
|
|||
import org.lwjgl.vulkan.VkVertexInputAttributeDescription;
|
||||
import org.lwjgl.vulkan.VkVertexInputBindingDescription;
|
||||
|
||||
import static org.lwjgl.vulkan.VK10.VK_FORMAT_R32G32_SFLOAT;
|
||||
import static org.lwjgl.vulkan.VK13.VK_FORMAT_R32G32B32_SFLOAT;
|
||||
import static org.lwjgl.vulkan.VK13.VK_VERTEX_INPUT_RATE_VERTEX;
|
||||
|
||||
public class VertexBufferStructure {
|
||||
public static final int TEXT_COORD_COMPONENTS = 2;
|
||||
private static final int NUMBER_OF_ATTRIBUTES = 2;
|
||||
public static final int NORMAL_COMPONENTS = 3;
|
||||
private static final int NUMBER_OF_ATTRIBUTES = 5;
|
||||
private final int POSITION_COMPONENTS = 3;
|
||||
|
||||
private final VkPipelineVertexInputStateCreateInfo VertexInput;
|
||||
|
|
@ -32,12 +34,36 @@ public class VertexBufferStructure {
|
|||
.offset(Offset);
|
||||
i++;
|
||||
Offset += POSITION_COMPONENTS * VulkanUtils.FLOAT_SIZE;
|
||||
//texture coordinates
|
||||
//Normals
|
||||
VertexInputAttributes.get(i)
|
||||
.binding(0)
|
||||
.location(i)
|
||||
.format(VK_FORMAT_R32G32B32_SFLOAT)
|
||||
.offset(Offset);
|
||||
i++;
|
||||
Offset += NORMAL_COMPONENTS * VulkanUtils.FLOAT_SIZE;
|
||||
//Tangents
|
||||
VertexInputAttributes.get(i)
|
||||
.binding(0)
|
||||
.location(i)
|
||||
.format(VK_FORMAT_R32G32B32_SFLOAT)
|
||||
.offset(Offset);
|
||||
i++;
|
||||
Offset += NORMAL_COMPONENTS * VulkanUtils.FLOAT_SIZE;
|
||||
//BiTangents
|
||||
VertexInputAttributes.get(i)
|
||||
.binding(0)
|
||||
.location(i)
|
||||
.format(VK_FORMAT_R32G32B32_SFLOAT)
|
||||
.offset(Offset);
|
||||
i++;
|
||||
Offset += NORMAL_COMPONENTS * VulkanUtils.FLOAT_SIZE;
|
||||
//texture coordinates
|
||||
VertexInputAttributes.get(i)
|
||||
.binding(0)
|
||||
.location(i)
|
||||
.format(VK_FORMAT_R32G32_SFLOAT)
|
||||
.offset(Offset);
|
||||
|
||||
int Stride = Offset + TEXT_COORD_COMPONENTS * VulkanUtils.FLOAT_SIZE;
|
||||
VertexInputBindings.get(0)
|
||||
|
|
|
|||
|
|
@ -2,5 +2,5 @@ package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel;
|
|||
|
||||
import org.joml.Vector4f;
|
||||
|
||||
public record MaterialData(String ID, String TexturePath, Vector4f DiffuseColour) {
|
||||
public record MaterialData(String ID, String TexturePath,String NormalTexturePath,String MetalRoughnessMap, Vector4f DiffuseColour,float Roughness, float Metallic) {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,10 +12,8 @@ import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanBuffer;
|
|||
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.tinylog.Logger;
|
||||
import org.w3c.dom.Text;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.lwjgl.util.vma.Vma.VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
|
||||
|
|
@ -23,7 +21,7 @@ import static org.lwjgl.util.vma.Vma.VMA_MEMORY_USAGE_AUTO;
|
|||
import static org.lwjgl.vulkan.VK10.*;
|
||||
|
||||
public class MaterialsCache {
|
||||
private static final int MATERIAL_SIZE = VulkanUtils.VEC4_SIZE + VulkanUtils.INT_SIZE * 4;
|
||||
private static final int MATERIAL_SIZE = VulkanUtils.VEC4_SIZE * 3;
|
||||
private final IndexedLinkedHashMap<String, VulkanMaterial> MaterialsMap;
|
||||
private VulkanBuffer MaterialsBuffer;
|
||||
|
||||
|
|
@ -36,7 +34,8 @@ public class MaterialsCache {
|
|||
int MaterialCount = Materials.size();
|
||||
int BufferSize = MATERIAL_SIZE * MaterialCount;
|
||||
var SrcBuffer = new VulkanBuffer(VkCtx, BufferSize,
|
||||
VK_BUFFER_USAGE_TRANSFER_SRC_BIT,VMA_MEMORY_USAGE_AUTO,VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
|
||||
VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
|
||||
MaterialsBuffer = new VulkanBuffer(VkCtx, BufferSize,
|
||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VMA_MEMORY_USAGE_AUTO,0,0);
|
||||
|
||||
|
|
@ -53,6 +52,7 @@ public class MaterialsCache {
|
|||
String TexturePath = Material.TexturePath();
|
||||
boolean ValidTexture = TexturePath != null && !TexturePath.isEmpty();
|
||||
boolean TransparentTexture;
|
||||
Logger.debug("Material Texture Path -> [{}]",Material.TexturePath());
|
||||
if(ValidTexture){
|
||||
Texture newTexture = textureCache.AddTexture(VkCtx, TexturePath, TexturePath, VK_FORMAT_R8G8B8A8_SRGB);
|
||||
if(newTexture == null) {
|
||||
|
|
@ -67,18 +67,42 @@ public class MaterialsCache {
|
|||
VulkanMaterial newMaterial = new VulkanMaterial(Material.ID(),TransparentTexture);
|
||||
MaterialsMap.put(newMaterial.ID(), newMaterial);
|
||||
Logger.trace(Material.toString());
|
||||
Material.DiffuseColour().get(Offset,data);
|
||||
data.putInt(Offset + VulkanUtils.VEC4_SIZE, ValidTexture ? 1 : 0);
|
||||
data.putInt(Offset + VulkanUtils.VEC4_SIZE + VulkanUtils.INT_SIZE, textureCache.GetPosition(TexturePath));
|
||||
//pad data because the minimum size of data in the shader layout is a multiple of Vec4,
|
||||
// compensate with 2 more as we only need 6 currently
|
||||
data.putInt(Offset + VulkanUtils.VEC4_SIZE + VulkanUtils.INT_SIZE * 2,0);
|
||||
data.putInt(Offset + VulkanUtils.VEC4_SIZE + VulkanUtils.INT_SIZE * 3,0);
|
||||
Offset += MATERIAL_SIZE;
|
||||
}
|
||||
data.position(0);
|
||||
|
||||
SrcBuffer.Flush(VkCtx);
|
||||
Material.DiffuseColour().get(Offset,data);
|
||||
Offset += VulkanUtils.VEC4_SIZE;
|
||||
data.putInt(Offset, ValidTexture ? 1 : 0);
|
||||
Offset += VulkanUtils.INT_SIZE;
|
||||
data.putInt(Offset, textureCache.GetPosition(TexturePath));
|
||||
Offset += VulkanUtils.INT_SIZE;
|
||||
|
||||
String NormalMap = Material.NormalTexturePath();
|
||||
boolean hasNormalMap = NormalMap != null && !NormalMap.isEmpty();
|
||||
if(hasNormalMap){
|
||||
textureCache.AddTexture(VkCtx,NormalMap,NormalMap,VK_FORMAT_R8G8B8A8_UNORM);
|
||||
}
|
||||
data.putInt(Offset, hasNormalMap ? 1 : 0);
|
||||
Offset += VulkanUtils.INT_SIZE;
|
||||
data.putInt(Offset, textureCache.GetPosition(NormalMap));
|
||||
Offset += VulkanUtils.INT_SIZE;
|
||||
|
||||
String RoughnessMap = Material.MetalRoughnessMap();
|
||||
boolean hasRoughness = RoughnessMap != null && !RoughnessMap.isEmpty();
|
||||
if(hasRoughness){
|
||||
textureCache.AddTexture(VkCtx,RoughnessMap,RoughnessMap,VK_FORMAT_R8G8B8A8_UNORM);
|
||||
}
|
||||
data.putInt(Offset, hasRoughness ? 1 : 0);
|
||||
Offset += VulkanUtils.INT_SIZE;
|
||||
data.putInt(Offset, textureCache.GetPosition(RoughnessMap));
|
||||
Offset += VulkanUtils.INT_SIZE;
|
||||
|
||||
data.putFloat(Offset, Material.Roughness());
|
||||
Offset += VulkanUtils.FLOAT_SIZE;
|
||||
data.putFloat(Offset, Material.Metallic());
|
||||
Offset += VulkanUtils.FLOAT_SIZE;
|
||||
}
|
||||
// data.position(0);
|
||||
|
||||
// SrcBuffer.Flush(VkCtx);
|
||||
SrcBuffer.UnMapMemory(VkCtx);
|
||||
transferBuffer.RecordTransferCommand(CmdBuffer);
|
||||
CmdBuffer.EndRecording();
|
||||
|
|
|
|||
|
|
@ -10,7 +10,10 @@ import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
|
|||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -50,6 +53,7 @@ public class ModelsCache {
|
|||
StagingBufferList.add(IndicesBuffers.SrcBuffer());
|
||||
VerticesBuffers.RecordTransferCommand(Command);
|
||||
IndicesBuffers.RecordTransferCommand(Command);
|
||||
|
||||
VulkanMesh VkMesh = new VulkanMesh(meshData.ID(), VerticesBuffers.DstBuffer(), IndicesBuffers.DstBuffer(),
|
||||
meshData.IndexSize() / VulkanUtils.INT_SIZE, meshData.MaterialID());
|
||||
VKModel.GetVkMeshList().add(VkMesh);
|
||||
|
|
@ -65,43 +69,6 @@ public class ModelsCache {
|
|||
}
|
||||
}
|
||||
|
||||
private static TransferBuffer CreateVoxelIndicesBuffer(VulkanContext VkCtx, MeshData meshData, IntBuffer IndexBuffer) throws IOException{
|
||||
int BufferSize = meshData.IndexSize();
|
||||
var SrcBuffer = new VulkanBuffer(VkCtx,BufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_AUTO,VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
|
||||
var DstBuffer = new VulkanBuffer(VkCtx, BufferSize,
|
||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VMA_MEMORY_USAGE_AUTO,0,0);
|
||||
long MappedMemory = SrcBuffer.MapMemory(VkCtx);
|
||||
IntBuffer data = MemoryUtil.memIntBuffer(MappedMemory,(int) SrcBuffer.GetRequestedSize());
|
||||
IndexBuffer.rewind();
|
||||
for(int i = 0; i < meshData.IndexSize(); i++){
|
||||
data.put(IndexBuffer.get(meshData.OffsetIndex() + i));
|
||||
}
|
||||
SrcBuffer.UnMapMemory(VkCtx);
|
||||
return new TransferBuffer(SrcBuffer,DstBuffer);
|
||||
}
|
||||
private static TransferBuffer CreateVoxelVerticesBuffer(VulkanContext VkCtx, MeshData meshData, FloatBuffer VertexBuffer) throws IOException {
|
||||
Logger.debug("Creating Vertices Transfer Buffer, Mesh Data -> ID=[{}] VertexSize=[{}]",meshData.ID(),meshData.VertexSize());
|
||||
int BufferSize = meshData.VertexSize();
|
||||
var SrcBuffer = new VulkanBuffer(VkCtx,BufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_AUTO,VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
|
||||
var DstBuffer = new VulkanBuffer(VkCtx, BufferSize,
|
||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VMA_MEMORY_USAGE_AUTO,0,0);
|
||||
if (BufferSize <= 0) {
|
||||
Logger.error("Computed buffer allocation size cannot be 0. SrcBuffer -> [{}] DstBuffer -> [{}]",SrcBuffer,DstBuffer);
|
||||
throw new RuntimeException("Computed buffer allocation size cannot be 0. SrcBuffer -> ["+SrcBuffer+"] DstBuffer -> ["+DstBuffer+"]");
|
||||
}
|
||||
Logger.debug("Starting to create vertex Transfer Buffer");
|
||||
long MappedMemory = SrcBuffer.MapMemory(VkCtx);
|
||||
FloatBuffer data = MemoryUtil.memFloatBuffer(MappedMemory, (int) SrcBuffer.GetRequestedSize());
|
||||
VertexBuffer.rewind();
|
||||
for(int i = 0; i < meshData.VertexSize(); i++){
|
||||
data.put(VertexBuffer.get(meshData.OffsetVertex() + i));
|
||||
}
|
||||
SrcBuffer.UnMapMemory(VkCtx);
|
||||
return new TransferBuffer(SrcBuffer,DstBuffer);
|
||||
}
|
||||
|
||||
private static TransferBuffer CreateVerticesBuffer(VulkanContext VkCtx, MeshData meshData, DataInputStream VertexStream) throws IOException {
|
||||
Logger.debug("Creating Vertices Transfer Buffer, Mesh Data -> ID=[{}] VertexSize=[{}]",meshData.ID(),meshData.VertexSize());
|
||||
int BufferSize = meshData.VertexSize();
|
||||
|
|
@ -109,18 +76,10 @@ public class ModelsCache {
|
|||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
|
||||
var DstBuffer = new VulkanBuffer(VkCtx, BufferSize,
|
||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VMA_MEMORY_USAGE_AUTO,0,0);
|
||||
if (BufferSize <= 0) {
|
||||
Logger.error("Computed buffer allocation size cannot be 0. SrcBuffer -> [{}] DstBuffer -> [{}]",SrcBuffer,DstBuffer);
|
||||
throw new RuntimeException("Computed buffer allocation size cannot be 0. SrcBuffer -> ["+SrcBuffer+"] DstBuffer -> ["+DstBuffer+"]");
|
||||
}
|
||||
long MappedMemory = SrcBuffer.MapMemory(VkCtx);
|
||||
FloatBuffer data = MemoryUtil.memFloatBuffer(MappedMemory, (int) SrcBuffer.GetRequestedSize());
|
||||
|
||||
int ValuesToRead = meshData.VertexSize()/VulkanUtils.FLOAT_SIZE;
|
||||
if (ValuesToRead <= 0) {
|
||||
Logger.error("Cannot allocate vertex buffer: Model mesh has 0 or negative vertices! Vertex Stream -> [{}]",VertexStream);
|
||||
throw new RuntimeException("Cannot allocate vertex buffer: Model mesh has 0 or negative vertices! Vertex Stream -> [{"+VertexStream+"]");
|
||||
}
|
||||
while(ValuesToRead > 0){
|
||||
data.put(VertexStream.readFloat());
|
||||
ValuesToRead--;
|
||||
|
|
|
|||
|
|
@ -41,6 +41,9 @@ public class Device {
|
|||
.sType$Default()
|
||||
.dynamicRendering(true)
|
||||
.synchronization2(true);
|
||||
var features12 = VkPhysicalDeviceVulkan12Features.calloc(MemStack)
|
||||
.sType$Default()
|
||||
.scalarBlockLayout(true);
|
||||
var features2 = VkPhysicalDeviceFeatures2.calloc(MemStack).sType$Default();
|
||||
var features = features2.features();
|
||||
|
||||
|
|
@ -50,6 +53,7 @@ public class Device {
|
|||
features.samplerAnisotropy(true);
|
||||
}
|
||||
features2.pNext(features13.address());
|
||||
features13.pNext(features12.address());
|
||||
|
||||
var DeviceCreateInfo = VkDeviceCreateInfo.calloc(MemStack)
|
||||
.sType$Default()
|
||||
|
|
|
|||
|
|
@ -7,11 +7,7 @@ import org.lwjgl.vulkan.VkFenceCreateInfo;
|
|||
import java.nio.LongBuffer;
|
||||
|
||||
import static net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils.vkCheck;
|
||||
import static org.lwjgl.vulkan.VK13.vkResetFences;
|
||||
import static org.lwjgl.vulkan.VK13.vkWaitForFences;
|
||||
import static org.lwjgl.vulkan.VK13.vkDestroyFence;
|
||||
import static org.lwjgl.vulkan.VK13.VK_FENCE_CREATE_SIGNALED_BIT;
|
||||
import static org.lwjgl.vulkan.VK13.vkCreateFence;
|
||||
import static org.lwjgl.vulkan.VK13.*;
|
||||
|
||||
public class Fence {
|
||||
private final long VulkanFence;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,410 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.IScene;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.DeferredRendering.MultiRenderTargetAttachments;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.DefaultPipeline;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.Attachment;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.Texture;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.TextureCache;
|
||||
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.PushConstantsRange;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.*;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VertexBufferStructure;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.*;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.CommandBuffer;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.Device;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.SwapChain.SwapChain;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanBuffer;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector3f;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.lwjgl.util.shaderc.Shaderc;
|
||||
import org.lwjgl.vulkan.*;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.LongBuffer;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.lwjgl.vulkan.VK13.*;
|
||||
|
||||
public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
|
||||
|
||||
private static final String DESCRIPTOR_ID_MAT = "SCN_DESC_ID_MAT";
|
||||
private static final String DESCRIPTOR_ID_PRJ = "SCN_DESC_ID_PRJ";
|
||||
private static final String DESCRIPTOR_ID_TEXT = "SCN_DESC_ID_TEXT";
|
||||
private static final String DESCRIPTOR_ID_VIEW = "SCN_DESC_ID_VIEW";
|
||||
private static final int PUSH_CONSTANTS_SIZE = VulkanUtils.MATRIX4X4_SIZE + VulkanUtils.INT_SIZE;
|
||||
private final VulkanBuffer BufferProjectionMatrix;
|
||||
private final DescriptorSetLayout descriptorLayoutFragStorage;
|
||||
private final DescriptorSetLayout descriptorLayoutTexture;
|
||||
private final DescriptorSetLayout descriptorLayoutVertexUniform;
|
||||
private final TextureSampler textureSampler;
|
||||
|
||||
public static final int COLOUR_FORMAT = VK_FORMAT_R32G32B32A32_SFLOAT;
|
||||
public static final int DEPTH_FORMAT = VK_FORMAT_D32_SFLOAT;
|
||||
private final VkClearValue ClearValueDepth;
|
||||
private final ByteBuffer PushConstBuffer;
|
||||
private VkRenderingAttachmentInfo AttachmentInfoDepth;
|
||||
private VkClearValue ClearValueColour;
|
||||
private VkRenderingAttachmentInfo.Buffer AttachmentInfoColour;
|
||||
private VkRenderingInfo RenderInfo;
|
||||
public int Frames = 0;
|
||||
private static String LastGPULog = "";
|
||||
public static long GPUTIME = 0;
|
||||
public static long CYCLES = 0;
|
||||
private static boolean DualPassRendering = false;
|
||||
|
||||
private static final String FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/scene_fragment_deferred.glsl";
|
||||
private static final String FRAGMENT_TRANSLUCENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/scene_translucent_fragment_deferred.glsl";
|
||||
private static final String FRAGMENT_OPAQUE_SHADER_FILE_GLSL = "resources/EngineResources/shaders/scene_opaque_fragment_deferred.glsl";
|
||||
private static final String FRAGMENT_SHADER_FILE_SPV = FRAGMENT_SHADER_FILE_GLSL + ".spv";
|
||||
private static final String FRAGMENT_TRANSLUCENT_SHADER_FILE_SPV = FRAGMENT_TRANSLUCENT_SHADER_FILE_GLSL + ".spv";
|
||||
private static final String FRAGMENT_OPAQUE_SHADER_FILE_SPV = FRAGMENT_OPAQUE_SHADER_FILE_GLSL + ".spv";
|
||||
private static final String VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/scene_vertex.glsl";
|
||||
private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv";
|
||||
private final VulkanBuffer[] BufferViewMatrices;
|
||||
private Pipeline VkPipeline;
|
||||
private Pipeline VkPipelineOpaque;
|
||||
private Pipeline VkPipelineTranslucent;
|
||||
private Vector3f SkyColour = new Vector3f(0,0,0);
|
||||
private Matrix4f ProjectionMatrix;
|
||||
private MultiRenderTargetAttachments MRTAttachments;
|
||||
|
||||
public static long GetGPUTimeNS(){
|
||||
long time = 0;
|
||||
if(CYCLES > 0){
|
||||
time = GPUTIME/CYCLES;
|
||||
}
|
||||
GPUTIME = 0;
|
||||
CYCLES = 0;
|
||||
return time;
|
||||
}
|
||||
|
||||
public DeferredSceneRender(VulkanContext vulkanContext, EngineInstance engineInstance){
|
||||
SkyColour = new Vector3f(engineInstance.scene().GetLightingManager().GetSkyColour());
|
||||
ClearValueColour = VkClearValue.calloc().color(
|
||||
c -> c.float32(0, SkyColour.x).float32(1, SkyColour.y).float32(2, SkyColour.z).float32(3, 1.0f));
|
||||
ClearValueDepth = VkClearValue.calloc().color(c -> c.float32(0, 0.0f));
|
||||
MRTAttachments = new MultiRenderTargetAttachments(vulkanContext);
|
||||
AttachmentInfoColour = CreateColourAttachmentInfo(MRTAttachments, ClearValueColour);
|
||||
AttachmentInfoDepth = CreateDepthAttachmentInfo(MRTAttachments, ClearValueDepth);
|
||||
RenderInfo = CreateRenderInfo(vulkanContext, AttachmentInfoColour, AttachmentInfoDepth);
|
||||
|
||||
PushConstBuffer = MemoryUtil.memAlloc(PUSH_CONSTANTS_SIZE);
|
||||
|
||||
descriptorLayoutVertexUniform = new DescriptorSetLayout(vulkanContext, new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
0, 1, VK_SHADER_STAGE_VERTEX_BIT));
|
||||
BufferProjectionMatrix = VulkanUtils.CreateHostVisibleBuffer(vulkanContext, VulkanUtils.MATRIX4X4_SIZE, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
||||
DESCRIPTOR_ID_PRJ, descriptorLayoutVertexUniform);
|
||||
VulkanUtils.CopyMatrixToBuffer(vulkanContext, BufferProjectionMatrix, engineInstance.scene().GetProjection().GetProjectionMatrix(), 0);
|
||||
|
||||
BufferViewMatrices = VulkanUtils.CreateHostVisibleBuffers(vulkanContext, VulkanUtils.MATRIX4X4_SIZE, VulkanUtils.MAX_IN_FLIGHT,
|
||||
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, DESCRIPTOR_ID_VIEW, descriptorLayoutVertexUniform);
|
||||
|
||||
descriptorLayoutFragStorage = new DescriptorSetLayout(vulkanContext, new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
0, 1, VK_SHADER_STAGE_FRAGMENT_BIT));
|
||||
|
||||
var textureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
||||
VK_BORDER_COLOR_INT_OPAQUE_BLACK, 1, true);
|
||||
textureSampler = new TextureSampler(vulkanContext, textureSamplerInfo);
|
||||
descriptorLayoutTexture = new DescriptorSetLayout(vulkanContext, new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
0, TextureCache.MAX_TEXTURES, VK_SHADER_STAGE_FRAGMENT_BIT));
|
||||
|
||||
CreatePipelines(vulkanContext);
|
||||
Logger.debug("Deferred Renderer Pipeline -> [{}]",VkPipeline.GetVulkanPipeline());
|
||||
|
||||
}
|
||||
|
||||
public void CreatePipelines(VulkanContext vulkanContext){
|
||||
DescriptorSetLayout[] layouts = new DescriptorSetLayout[]{
|
||||
descriptorLayoutVertexUniform,
|
||||
descriptorLayoutVertexUniform,
|
||||
descriptorLayoutFragStorage,
|
||||
descriptorLayoutTexture
|
||||
};
|
||||
|
||||
ShaderModule[] shaderModules = DeferredSceneRender.CreateShaderModules(vulkanContext,0);
|
||||
VkPipeline = CreatePipeline(vulkanContext, shaderModules, layouts, true, false,EngineConfig.getInstance().AlphaToCoverage());
|
||||
Arrays.asList(shaderModules).forEach(shaderModule -> shaderModule.CleanUp(vulkanContext));
|
||||
shaderModules = DeferredSceneRender.CreateShaderModules(vulkanContext,1);
|
||||
VkPipelineOpaque = CreatePipeline(vulkanContext, shaderModules, layouts, true, true,EngineConfig.getInstance().AlphaToCoverage());
|
||||
Arrays.asList(shaderModules).forEach(shaderModule -> shaderModule.CleanUp(vulkanContext));
|
||||
shaderModules = DeferredSceneRender.CreateShaderModules(vulkanContext,2);
|
||||
VkPipelineTranslucent = CreatePipeline(vulkanContext, shaderModules, layouts, false, true,EngineConfig.getInstance().AlphaToCoverage());
|
||||
Arrays.asList(shaderModules).forEach(shaderModule -> shaderModule.CleanUp(vulkanContext));
|
||||
}
|
||||
|
||||
public void RebuildPipelines(VulkanContext vulkanContext){
|
||||
CreatePipelines(vulkanContext);
|
||||
}
|
||||
|
||||
public static void SetDualPassRendering(boolean dualPass){
|
||||
DualPassRendering = dualPass;
|
||||
}
|
||||
|
||||
public static boolean DualPassRendering(){return DualPassRendering;}
|
||||
|
||||
private static VkRenderingAttachmentInfo.Buffer CreateColourAttachmentInfo(MultiRenderTargetAttachments attachment, VkClearValue ClearValue){
|
||||
List<Attachment> attachments = attachment.GetColourAttachments();
|
||||
int numAttachments = attachments.size();
|
||||
VkRenderingAttachmentInfo.Buffer result = VkRenderingAttachmentInfo.calloc(numAttachments);
|
||||
for (int i = 0; i < numAttachments; ++i) {
|
||||
result.get(i)
|
||||
.sType$Default()
|
||||
.imageView(attachments.get(i).GetVkImageView().GetVulkanImageView())
|
||||
.imageLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
|
||||
.loadOp(VK_ATTACHMENT_LOAD_OP_CLEAR)
|
||||
.storeOp(VK_ATTACHMENT_STORE_OP_STORE)
|
||||
.clearValue(ClearValue);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private static VkRenderingAttachmentInfo CreateDepthAttachmentInfo(MultiRenderTargetAttachments DepthAttachment, VkClearValue clearValue){
|
||||
return VkRenderingAttachmentInfo.calloc()
|
||||
.sType$Default()
|
||||
.imageView(DepthAttachment.GetDepthAttachment().GetVkImageView().GetVulkanImageView())
|
||||
.imageLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)
|
||||
.loadOp(VK_ATTACHMENT_LOAD_OP_CLEAR)
|
||||
.storeOp(VK_ATTACHMENT_STORE_OP_DONT_CARE)
|
||||
.clearValue(clearValue);
|
||||
}
|
||||
|
||||
private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx, int Translucent){
|
||||
if(EngineConfig.getInstance().RecompileShaders()){
|
||||
ShaderCompiler.CompileGLSLShaderOnChange(VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader);
|
||||
ShaderCompiler.CompileGLSLShaderOnChange( Translucent == 2 ? FRAGMENT_TRANSLUCENT_SHADER_FILE_GLSL : Translucent == 1 ? FRAGMENT_OPAQUE_SHADER_FILE_GLSL : FRAGMENT_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_fragment_shader);
|
||||
}
|
||||
return new ShaderModule[]{
|
||||
new ShaderModule(VkCtx, VK_SHADER_STAGE_VERTEX_BIT, VERTEX_SHADER_FILE_SPV,null),
|
||||
new ShaderModule(VkCtx, VK_SHADER_STAGE_FRAGMENT_BIT, Translucent == 2 ? FRAGMENT_TRANSLUCENT_SHADER_FILE_SPV : Translucent == 1 ? FRAGMENT_OPAQUE_SHADER_FILE_SPV : FRAGMENT_SHADER_FILE_SPV,null)
|
||||
};
|
||||
}
|
||||
|
||||
private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] ShaderModules, DescriptorSetLayout[] DescriptorSetLayouts, boolean DepthWrite, boolean DualRender, boolean AlphaToCoverage){
|
||||
var vertexBufferStructure = new VertexBufferStructure();
|
||||
var BuildInfo = new PipelineBuildInfo(ShaderModules,vertexBufferStructure.getVertexInput(),new int[]{
|
||||
MultiRenderTargetAttachments.POSITION_FORMAT, MultiRenderTargetAttachments.ALBEDO_FORMAT, MultiRenderTargetAttachments.NORMAL_FORMAT, MultiRenderTargetAttachments.PBR_FORMAT})
|
||||
.SetDepthFormat(MultiRenderTargetAttachments.DEPTH_FORMAT)
|
||||
.SetDepthWrite(DepthWrite)
|
||||
.SetPushConstantRanges(
|
||||
new PushConstantsRange[]{
|
||||
new PushConstantsRange(VK_SHADER_STAGE_VERTEX_BIT,0,VulkanUtils.MATRIX4X4_SIZE),
|
||||
new PushConstantsRange(VK_SHADER_STAGE_FRAGMENT_BIT,VulkanUtils.MATRIX4X4_SIZE,VulkanUtils.INT_SIZE)
|
||||
})
|
||||
.SetDescriptorSetLayouts(DescriptorSetLayouts)
|
||||
.BlendingIsUsed(DualRender ? !DepthWrite : true)
|
||||
.SetDualPass(DualRender)
|
||||
.SetAlphaToCoverage(AlphaToCoverage);
|
||||
var pipeline = new DefaultPipeline(VkCtx, BuildInfo);
|
||||
vertexBufferStructure.cleanup();
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
|
||||
public void Render(EngineInstance engineInstance,VulkanContext vulkanContext, CommandBuffer commandBuffer, ModelsCache modelsCache,MaterialsCache materialsCache, int CurrentFrame){
|
||||
SkyColour = new Vector3f(engineInstance.scene().GetLightingManager().GetSkyColour());
|
||||
ClearValueColour = VkClearValue.calloc().color(
|
||||
c -> c.float32(0, SkyColour.x).float32(1, SkyColour.y).float32(2, SkyColour.z).float32(3, 1.0f));
|
||||
var mattachments = MRTAttachments.GetColourAttachments();
|
||||
int numAttachments = mattachments.size();
|
||||
for (int i = 0; i < numAttachments; ++i) {
|
||||
AttachmentInfoColour.get(i)
|
||||
.sType$Default()
|
||||
.imageView(mattachments.get(i).GetVkImageView().GetVulkanImageView())
|
||||
.imageLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
|
||||
.loadOp(VK_ATTACHMENT_LOAD_OP_CLEAR)
|
||||
.storeOp(VK_ATTACHMENT_STORE_OP_STORE)
|
||||
.clearValue(ClearValueColour);
|
||||
}
|
||||
try(var MemStack = MemoryStack.stackPush()){
|
||||
VkCommandBuffer CommandHandle = commandBuffer.GetVulkanCommandBuffer();
|
||||
|
||||
List<Attachment> attachments = MRTAttachments.GetColourAttachments();
|
||||
int AttachmentCount = attachments.size();
|
||||
for (int i = 0; i < AttachmentCount; i++) {
|
||||
Attachment attachment = attachments.get(i);
|
||||
VulkanUtils.ImageBarrier(MemStack, CommandHandle, attachment.GetVkImage().getVulkanImage(),
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
VK_ACCESS_NONE, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
}
|
||||
VulkanUtils.ImageBarrier(MemStack, CommandHandle, MRTAttachments.GetDepthAttachment().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);
|
||||
|
||||
long InitialTime = System.nanoTime();
|
||||
vkCmdBeginRendering(CommandHandle, RenderInfo);
|
||||
|
||||
vkCmdBindPipeline(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, DualPassRendering ? VkPipelineOpaque.GetVulkanPipeline() : VkPipeline.GetVulkanPipeline());
|
||||
|
||||
int width = MRTAttachments.GetWidth();
|
||||
int height = MRTAttachments.GetHeight();
|
||||
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);
|
||||
|
||||
VulkanUtils.CopyMatrixToBuffer(vulkanContext, BufferViewMatrices[CurrentFrame],engineInstance.scene().GetCamera().GetViewMatrix(), 0); // here
|
||||
DescriptorAllocator descriptorAllocator = vulkanContext.GetDescriptorAllocator();
|
||||
LongBuffer DescriptorSets = MemStack.mallocLong(4)
|
||||
.put(0,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_PRJ).GetVkDescriptorSet())
|
||||
.put(1,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_VIEW, CurrentFrame).GetVkDescriptorSet())
|
||||
.put(2,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_MAT).GetVkDescriptorSet())
|
||||
.put(3,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_TEXT).GetVkDescriptorSet());
|
||||
vkCmdBindDescriptorSets(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, DualPassRendering ? VkPipelineOpaque.GetVulkanPipelineLayout() : VkPipeline.GetVulkanPipelineLayout(),0,DescriptorSets,null);
|
||||
|
||||
RenderActors(engineInstance, CommandHandle, modelsCache, materialsCache, false);
|
||||
if(DualPassRendering) {
|
||||
vkCmdBindPipeline(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkPipelineTranslucent.GetVulkanPipeline());
|
||||
vkCmdSetViewport(CommandHandle, 0, Viewport);
|
||||
vkCmdSetScissor(CommandHandle, 0, Scissor);
|
||||
vkCmdBindDescriptorSets(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkPipelineTranslucent.GetVulkanPipelineLayout(), 0, DescriptorSets, null);
|
||||
}
|
||||
RenderActors(engineInstance, CommandHandle, modelsCache, materialsCache, true);
|
||||
|
||||
vkCmdEndRendering(CommandHandle);
|
||||
|
||||
GPUTIME += System.nanoTime() - InitialTime;
|
||||
CYCLES++;
|
||||
}
|
||||
}
|
||||
|
||||
private void RenderActors(EngineInstance instance, VkCommandBuffer CommandHandle, ModelsCache modelsCache, MaterialsCache materialsCache, boolean Transparent){
|
||||
try(var MemStack = MemoryStack.stackPush()){
|
||||
LongBuffer offsets = MemStack.mallocLong(1).put(0,0L);
|
||||
LongBuffer vertexBuffer = MemStack.mallocLong(1);
|
||||
IScene scene = instance.scene();
|
||||
List<Actor> Actors = scene.GetActors();
|
||||
int ActorCount = Actors.size();
|
||||
for(int i = 0; i < ActorCount; i++){
|
||||
if(i < Actors.size()) {
|
||||
var Actor = Actors.get(i);
|
||||
if(Actor != null) {
|
||||
VulkanModel model = modelsCache.GetModel(Actor.GetModelID());
|
||||
List<VulkanMesh> VkMeshList = model.GetVkMeshList();
|
||||
int MeshCount = VkMeshList.size();
|
||||
for (int j = 0; j < MeshCount; j++) {
|
||||
var VkMesh = VkMeshList.get(j);
|
||||
String MaterialID = VkMesh.MaterialID();
|
||||
int MaterialIndex = materialsCache.GetPosition(MaterialID);
|
||||
VulkanMaterial vulkanMaterial = materialsCache.GetMaterial(MaterialID);
|
||||
if (vulkanMaterial == null) {
|
||||
Logger.warn("Mesh [{}] in model [{}] does not have material", j, model.GetID());
|
||||
continue;
|
||||
}
|
||||
if (DualPassRendering || vulkanMaterial.HasTransparency() == Transparent) {
|
||||
SetPushConstants(CommandHandle, Actor.GetModelMatrix(), MaterialIndex);
|
||||
vertexBuffer.put(0, VkMesh.VerticesBuffer().GetBuffer());
|
||||
vkCmdBindVertexBuffers(CommandHandle, 0, vertexBuffer, offsets);
|
||||
vkCmdBindIndexBuffer(CommandHandle, VkMesh.IndicesBuffer().GetBuffer(), 0, VK_INDEX_TYPE_UINT32);
|
||||
vkCmdDrawIndexed(CommandHandle, VkMesh.IndicesCount(), 1, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SetPushConstants(VkCommandBuffer CmdHandle, Matrix4f ModelMatrix, int MaterialIndex){
|
||||
ModelMatrix.get(0,PushConstBuffer);
|
||||
PushConstBuffer.putInt(VulkanUtils.MATRIX4X4_SIZE, MaterialIndex);
|
||||
vkCmdPushConstants(CmdHandle, VkPipeline.GetVulkanPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0,
|
||||
PushConstBuffer.slice(0,VulkanUtils.MATRIX4X4_SIZE));
|
||||
vkCmdPushConstants(CmdHandle, VkPipeline.GetVulkanPipelineLayout(), VK_SHADER_STAGE_FRAGMENT_BIT, VulkanUtils.MATRIX4X4_SIZE,
|
||||
PushConstBuffer.slice(VulkanUtils.MATRIX4X4_SIZE, VulkanUtils.INT_SIZE));
|
||||
}
|
||||
|
||||
public void Resize(EngineInstance instance, VulkanContext VkCtx){
|
||||
RenderInfo.free();
|
||||
AttachmentInfoDepth.free();
|
||||
MRTAttachments.CleanUp(VkCtx);
|
||||
Arrays.asList(AttachmentInfoColour).forEach(VkRenderingAttachmentInfo.Buffer::free);
|
||||
|
||||
MRTAttachments = new MultiRenderTargetAttachments(VkCtx);
|
||||
AttachmentInfoColour = CreateColourAttachmentInfo(MRTAttachments, ClearValueColour);
|
||||
AttachmentInfoDepth = CreateDepthAttachmentInfo(MRTAttachments, ClearValueDepth);
|
||||
RenderInfo = CreateRenderInfo(VkCtx, AttachmentInfoColour, AttachmentInfoDepth);
|
||||
|
||||
VulkanUtils.CopyMatrixToBuffer(VkCtx, BufferProjectionMatrix, instance.scene().GetProjection().GetProjectionMatrix(), 0);}
|
||||
|
||||
public void LoadMaterials(VulkanContext VkCtx, MaterialsCache materialsCache, TextureCache textureCache){
|
||||
DescriptorAllocator descAllocator = VkCtx.GetDescriptorAllocator();
|
||||
Device device = VkCtx.GetDevice();
|
||||
DescriptorSet descSet = descAllocator.AddDescriptorSet(device, DESCRIPTOR_ID_MAT, descriptorLayoutFragStorage);
|
||||
DescriptorSetLayout.LayoutInformation layoutInfo = descriptorLayoutFragStorage.GetLayoutInfo();
|
||||
var buffer = materialsCache.GetMaterialsBuffer();
|
||||
descSet.SetBuffer(device, buffer, buffer.GetRequestedSize(), layoutInfo.Binding(), layoutInfo.DescriptorType());
|
||||
|
||||
List<ImageView> imageViews = textureCache.GetTextureList().stream().map(Texture::GetImageView).toList();
|
||||
descSet = VkCtx.GetDescriptorAllocator().AddDescriptorSet(device, DESCRIPTOR_ID_TEXT, descriptorLayoutTexture);
|
||||
descSet.SetImageArray(device, imageViews, textureSampler, 0);
|
||||
}
|
||||
|
||||
private static VkRenderingInfo CreateRenderInfo(VulkanContext VkCtx, VkRenderingAttachmentInfo.Buffer ColourAttachmentInfo, VkRenderingAttachmentInfo DepthAttachmentInfo){
|
||||
SwapChain swapChain = VkCtx.GetSwapChain();
|
||||
VkExtent2D Extent = swapChain.GetSwapChainExtent();
|
||||
VkRenderingInfo Result = VkRenderingInfo.calloc();
|
||||
try(var MemStack = MemoryStack.stackPush()){
|
||||
var RenderArea = VkRect2D.calloc(MemStack).extent(Extent);
|
||||
Result.sType$Default()
|
||||
.renderArea(RenderArea)
|
||||
.layerCount(1)
|
||||
.pColorAttachments(ColourAttachmentInfo)
|
||||
.pDepthAttachment(DepthAttachmentInfo);
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
public void cleanup(VulkanContext VkCtx){
|
||||
VkPipeline.CleanUp(VkCtx);
|
||||
VkPipelineOpaque.CleanUp(VkCtx);
|
||||
VkPipelineTranslucent.CleanUp(VkCtx);
|
||||
Arrays.asList(BufferViewMatrices).forEach(b -> b.cleanup(VkCtx));
|
||||
descriptorLayoutTexture.CleanUp(VkCtx);
|
||||
textureSampler.CleanUp(VkCtx);
|
||||
descriptorLayoutFragStorage.CleanUp(VkCtx);
|
||||
BufferProjectionMatrix.cleanup(VkCtx);
|
||||
descriptorLayoutVertexUniform.CleanUp(VkCtx);
|
||||
RenderInfo.free();
|
||||
AttachmentInfoDepth.free();
|
||||
MRTAttachments.CleanUp(VkCtx);
|
||||
AttachmentInfoColour.free();
|
||||
MemoryUtil.memFree(PushConstBuffer);
|
||||
ClearValueDepth.free();
|
||||
ClearValueColour.free();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiRenderTargetAttachments GetMRTAttachments() {
|
||||
return MRTAttachments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Attachment GetAttachmentColour() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -5,8 +5,8 @@ import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
|
|||
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.Scene;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Deferred.MultiRenderTargetAttachments;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.IScene;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.DeferredRendering.MultiRenderTargetAttachments;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.DefaultPipeline;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.Attachment;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.Image;
|
||||
|
|
@ -32,12 +32,12 @@ import org.tinylog.Logger;
|
|||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.LongBuffer;
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.lwjgl.vulkan.KHRSynchronization2.VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR;
|
||||
import static org.lwjgl.vulkan.VK13.*;
|
||||
|
||||
public class SceneRender implements SceneRenderer {//dynamic rendering
|
||||
public class ForwardSceneRender implements SceneRenderer {//dynamic rendering
|
||||
|
||||
private static final String FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/scene_fragment.glsl";
|
||||
private static final String FRAGMENT_TRANSLUCENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/scene_translucent_fragment.glsl";
|
||||
|
|
@ -67,9 +67,9 @@ public class SceneRender implements SceneRenderer {//dynamic rendering
|
|||
private VkClearValue ClearValueColour;
|
||||
private VkRenderingAttachmentInfo.Buffer AttachmentInfoColour;
|
||||
private VkRenderingInfo RenderInfo;
|
||||
private float R = 0.5f;
|
||||
private float G = 0.75f;
|
||||
private float B = 1.0f;
|
||||
private float R = 0.005f;
|
||||
private float G = 0.0075f;
|
||||
private float B = 0.0175f;
|
||||
private boolean Rb = false;
|
||||
private boolean Gb = true;
|
||||
private boolean Bb = false;
|
||||
|
|
@ -83,7 +83,6 @@ public class SceneRender implements SceneRenderer {//dynamic rendering
|
|||
private Pipeline VkPipelineOpaque;
|
||||
private Pipeline VkPipelineTranslucent;
|
||||
private Matrix4f ProjectionMatrix;
|
||||
private MultiRenderTargetAttachments MRTAttachments;
|
||||
private boolean Deferred = false;
|
||||
|
||||
public static long GetGPUTimeNS(){
|
||||
|
|
@ -96,25 +95,15 @@ public class SceneRender implements SceneRenderer {//dynamic rendering
|
|||
return time;
|
||||
}
|
||||
|
||||
public boolean GetCurrentDeferred(){return Deferred;}
|
||||
|
||||
public void UpdateDeferred(VulkanContext vulkanContext){
|
||||
Deferred = EngineConfig.getInstance().DeferredRendering();
|
||||
CreateRenderAttachments(vulkanContext);
|
||||
CreatePipelines(vulkanContext);
|
||||
}
|
||||
|
||||
public void CreateRenderAttachments(VulkanContext vulkanContext){
|
||||
MRTAttachments = new MultiRenderTargetAttachments(vulkanContext);
|
||||
AttachmentColour = CreateColourAttachment(vulkanContext);
|
||||
AttachmentDepth = CreateDepthAttachment(vulkanContext);
|
||||
AttachmentInfoDepth = Deferred ? CreateDeferredDepthAttachmentInfo(MRTAttachments, ClearValueDepth) : CreateDepthAttachmentInfo(AttachmentDepth, ClearValueDepth);
|
||||
AttachmentInfoColour = Deferred ? CreateDeferredColourAttachmentInfo(MRTAttachments, ClearValueDepth) : CreateColourAttachmentInfo(AttachmentColour,ClearValueColour);
|
||||
RenderInfo = Deferred ? CreateDeferredRenderInfo(vulkanContext, AttachmentInfoColour, AttachmentInfoDepth) : CreateRenderInfo(AttachmentColour, AttachmentInfoColour, AttachmentInfoDepth);
|
||||
AttachmentInfoDepth = CreateDepthAttachmentInfo(AttachmentDepth, ClearValueDepth);
|
||||
AttachmentInfoColour =CreateColourAttachmentInfo(AttachmentColour,ClearValueColour);
|
||||
RenderInfo = CreateRenderInfo(AttachmentColour, AttachmentInfoColour, AttachmentInfoDepth);
|
||||
}
|
||||
|
||||
public SceneRender(VulkanContext vulkanContext){
|
||||
Deferred = EngineConfig.getInstance().DeferredRendering();
|
||||
public ForwardSceneRender(VulkanContext vulkanContext){
|
||||
ClearValueColour = VkClearValue.calloc().color(
|
||||
c -> c.float32(0, R).float32(1, G).float32(2, B).float32(3, 1.0f));
|
||||
ClearValueDepth = VkClearValue.calloc().color(c -> c.float32(0, 0.0f));
|
||||
|
|
@ -138,10 +127,11 @@ public class SceneRender implements SceneRenderer {//dynamic rendering
|
|||
));
|
||||
BufferViewMatrices = VulkanUtils.CreateHostVisibleBuffers(vulkanContext, VulkanUtils.MATRIX4X4_SIZE, VulkanUtils.MAX_IN_FLIGHT, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, DESCRIPTOR_ID_VIEW, descriptorLayoutVertexUniform);
|
||||
CreatePipelines(vulkanContext);
|
||||
Logger.debug("Forward Renderer Pipelines:\nSingle Pass -> [{}]\nOpaque Dual Pass -> [{}]\nTranslucent Dual Pass -> [{}]",VkPipeline.GetVulkanPipeline(),VkPipelineOpaque.GetVulkanPipeline(), VkPipelineTranslucent.GetVulkanPipeline());
|
||||
}
|
||||
|
||||
public void CreatePipelines(VulkanContext vulkanContext){
|
||||
|
||||
|
||||
DescriptorSetLayout[] layouts = new DescriptorSetLayout[]{
|
||||
descriptorLayoutVertexUniform,
|
||||
descriptorLayoutVertexUniform,
|
||||
|
|
@ -149,12 +139,12 @@ public class SceneRender implements SceneRenderer {//dynamic rendering
|
|||
descriptorLayoutTexture
|
||||
};
|
||||
|
||||
ShaderModule[] shaderModules = SceneRender.CreateShaderModules(vulkanContext,0);
|
||||
VkPipeline = Deferred ? CreateDeferredPipeline(vulkanContext, shaderModules, layouts, true, false,EngineConfig.getInstance().AlphaToCoverage()) : CreatePipeline(vulkanContext, shaderModules, layouts, true, false,EngineConfig.getInstance().AlphaToCoverage());
|
||||
shaderModules = SceneRender.CreateShaderModules(vulkanContext,1);
|
||||
VkPipelineOpaque = Deferred ? CreateDeferredPipeline(vulkanContext, shaderModules, layouts, true, true,EngineConfig.getInstance().AlphaToCoverage()) : CreatePipeline(vulkanContext, shaderModules, layouts, true, true,EngineConfig.getInstance().AlphaToCoverage());
|
||||
shaderModules = SceneRender.CreateShaderModules(vulkanContext,2);
|
||||
VkPipelineTranslucent = Deferred ? CreateDeferredPipeline(vulkanContext, shaderModules, layouts, false, true,EngineConfig.getInstance().AlphaToCoverage()) : CreatePipeline(vulkanContext, shaderModules, layouts, false, true,EngineConfig.getInstance().AlphaToCoverage());
|
||||
ShaderModule[] shaderModules = CreateShaderModules(vulkanContext,0);
|
||||
VkPipeline = CreatePipeline(vulkanContext, shaderModules, layouts, true, false,EngineConfig.getInstance().AlphaToCoverage());
|
||||
shaderModules = CreateShaderModules(vulkanContext,1);
|
||||
VkPipelineOpaque = CreatePipeline(vulkanContext, shaderModules, layouts, true, true,EngineConfig.getInstance().AlphaToCoverage());
|
||||
shaderModules = CreateShaderModules(vulkanContext,2);
|
||||
VkPipelineTranslucent = CreatePipeline(vulkanContext, shaderModules, layouts, false, true,EngineConfig.getInstance().AlphaToCoverage());
|
||||
Arrays.asList(shaderModules).forEach(shaderModule -> shaderModule.CleanUp(vulkanContext));
|
||||
}
|
||||
|
||||
|
|
@ -174,21 +164,6 @@ public class SceneRender implements SceneRenderer {//dynamic rendering
|
|||
return new Attachment(VkCtx, SwapChainExtent.width(), SwapChainExtent.height(), COLOUR_FORMAT,VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
|
||||
}
|
||||
|
||||
private static VkRenderingAttachmentInfo.Buffer CreateDeferredColourAttachmentInfo(MultiRenderTargetAttachments attachment, VkClearValue ClearValue){
|
||||
List<Attachment> colourAttachments = attachment.GetColourAttachments();
|
||||
int AttachmentCount = colourAttachments.size();
|
||||
VkRenderingAttachmentInfo.Buffer result = VkRenderingAttachmentInfo.calloc(AttachmentCount);
|
||||
for(int i = 0; i < AttachmentCount; i++) {
|
||||
result.get(i).sType$Default()
|
||||
.imageView(attachment.GetColourAttachments().get(i).GetVkImageView().GetVulkanImageView())
|
||||
.imageLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
|
||||
.loadOp(VK_ATTACHMENT_LOAD_OP_CLEAR)
|
||||
.storeOp(VK_ATTACHMENT_STORE_OP_STORE)
|
||||
.clearValue(ClearValue);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private static VkRenderingAttachmentInfo.Buffer CreateColourAttachmentInfo(Attachment attachment, VkClearValue ClearValue){
|
||||
return VkRenderingAttachmentInfo.calloc(1)
|
||||
|
|
@ -208,16 +183,6 @@ public class SceneRender implements SceneRenderer {//dynamic rendering
|
|||
}
|
||||
|
||||
|
||||
private static VkRenderingAttachmentInfo CreateDeferredDepthAttachmentInfo(MultiRenderTargetAttachments DepthAttachment, VkClearValue clearValue){
|
||||
return VkRenderingAttachmentInfo.calloc()
|
||||
.sType$Default()
|
||||
.imageView(DepthAttachment.GetDepthAttachment().GetVkImageView().GetVulkanImageView())
|
||||
.imageLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)
|
||||
.loadOp(VK_ATTACHMENT_LOAD_OP_CLEAR)
|
||||
.storeOp(VK_ATTACHMENT_STORE_OP_DONT_CARE)
|
||||
.clearValue(clearValue);
|
||||
}
|
||||
|
||||
private static VkRenderingAttachmentInfo CreateDepthAttachmentInfo(Attachment DepthAttachment, VkClearValue clearValue){
|
||||
return VkRenderingAttachmentInfo.calloc()
|
||||
.sType$Default()
|
||||
|
|
@ -240,28 +205,11 @@ public class SceneRender implements SceneRenderer {//dynamic rendering
|
|||
};
|
||||
}
|
||||
|
||||
private static Pipeline CreateDeferredPipeline(VulkanContext VkCtx, ShaderModule[] ShaderModules, DescriptorSetLayout[] DescriptorSetLayouts, boolean DepthWrite, boolean DualRender, boolean AlphaToCoverage){
|
||||
var vertexBufferStructure = new VertexBufferStructure();
|
||||
var BuildInfo = new PipelineBuildInfo(ShaderModules,vertexBufferStructure.getVertexInput(),MultiRenderTargetAttachments.ALBEDO_FORMAT)
|
||||
.SetDepthFormat(MultiRenderTargetAttachments.DEPTH_FORMAT)
|
||||
.SetDepthWrite(DepthWrite)
|
||||
.SetPushConstantRanges(
|
||||
new PushConstantsRange[]{
|
||||
new PushConstantsRange(VK_SHADER_STAGE_VERTEX_BIT,0,VulkanUtils.MATRIX4X4_SIZE),
|
||||
new PushConstantsRange(VK_SHADER_STAGE_FRAGMENT_BIT,VulkanUtils.MATRIX4X4_SIZE,VulkanUtils.INT_SIZE)
|
||||
})
|
||||
.SetDescriptorSetLayouts(DescriptorSetLayouts)
|
||||
.BlendingIsUsed(DualRender ? !DepthWrite : true)
|
||||
.SetDualPass(DualRender)
|
||||
.SetAlphaToCoverage(AlphaToCoverage);
|
||||
var pipeline = new DefaultPipeline(VkCtx, BuildInfo);
|
||||
vertexBufferStructure.cleanup();
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] ShaderModules, DescriptorSetLayout[] DescriptorSetLayouts, boolean DepthWrite, boolean DualRender, boolean AlphaToCoverage){
|
||||
var vertexBufferStructure = new VertexBufferStructure();
|
||||
var BuildInfo = new PipelineBuildInfo(ShaderModules,vertexBufferStructure.getVertexInput(),COLOUR_FORMAT)
|
||||
var BuildInfo = new PipelineBuildInfo(ShaderModules,vertexBufferStructure.getVertexInput(),new int[]{
|
||||
MultiRenderTargetAttachments.POSITION_FORMAT, MultiRenderTargetAttachments.ALBEDO_FORMAT, MultiRenderTargetAttachments.NORMAL_FORMAT, MultiRenderTargetAttachments.PBR_FORMAT})
|
||||
.SetDepthFormat(DEPTH_FORMAT)
|
||||
.SetDepthWrite(DepthWrite)
|
||||
.SetPushConstantRanges(
|
||||
|
|
@ -322,7 +270,6 @@ public class SceneRender implements SceneRenderer {//dynamic rendering
|
|||
.put(2,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_MAT).GetVkDescriptorSet())
|
||||
.put(3,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_TEXT).GetVkDescriptorSet());
|
||||
vkCmdBindDescriptorSets(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, DualPassRendering ? VkPipelineOpaque.GetVulkanPipelineLayout() : VkPipeline.GetVulkanPipelineLayout(),0,DescriptorSets,null);
|
||||
|
||||
RenderActors(engineInstance, CommandHandle, modelsCache, materialsCache, false);
|
||||
if(DualPassRendering) {
|
||||
vkCmdBindPipeline(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkPipelineTranslucent.GetVulkanPipeline());
|
||||
|
|
@ -337,86 +284,17 @@ public class SceneRender implements SceneRenderer {//dynamic rendering
|
|||
CYCLES++;
|
||||
}
|
||||
}
|
||||
public void DeferredRender(EngineInstance engineInstance,VulkanContext vulkanContext, CommandBuffer commandBuffer, ModelsCache modelsCache,MaterialsCache materialsCache, int CurrentFrame){
|
||||
try(var MemStack = MemoryStack.stackPush()){
|
||||
VkCommandBuffer CommandHandle = commandBuffer.GetVulkanCommandBuffer();
|
||||
|
||||
List<Attachment> ColourAttachments = MRTAttachments.GetColourAttachments();
|
||||
int AttachmentCount = ColourAttachments.size();
|
||||
for(int i = 0; i < AttachmentCount; i++) {
|
||||
Attachment colourAttachment = ColourAttachments.get(i);
|
||||
VulkanUtils.ImageBarrier(MemStack, CommandHandle, colourAttachment.GetVkImage().getVulkanImage(),
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
VK_ACCESS_NONE, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
}
|
||||
VulkanUtils.ImageBarrier(MemStack, CommandHandle, MRTAttachments.GetDepthAttachment().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);
|
||||
|
||||
long InitialTime = System.nanoTime();
|
||||
vkCmdBeginRendering(CommandHandle, RenderInfo);
|
||||
|
||||
vkCmdBindPipeline(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, DualPassRendering ? VkPipelineOpaque.GetVulkanPipeline() : VkPipeline.GetVulkanPipeline());
|
||||
|
||||
int width = MRTAttachments.GetWidth();
|
||||
int height = MRTAttachments.GetHeight();
|
||||
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);
|
||||
|
||||
VulkanUtils.CopyMatrixToBuffer(vulkanContext, BufferViewMatrices[CurrentFrame],engineInstance.scene().GetCamera().GetViewMatrix(), 0); // here
|
||||
DescriptorAllocator descriptorAllocator = vulkanContext.GetDescriptorAllocator();
|
||||
LongBuffer DescriptorSets = MemStack.mallocLong(4)
|
||||
.put(0,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_PRJ).GetVkDescriptorSet())
|
||||
.put(1,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_VIEW, CurrentFrame).GetVkDescriptorSet())
|
||||
.put(2,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_MAT).GetVkDescriptorSet())
|
||||
.put(3,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_TEXT).GetVkDescriptorSet());
|
||||
vkCmdBindDescriptorSets(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, DualPassRendering ? VkPipelineOpaque.GetVulkanPipelineLayout() : VkPipeline.GetVulkanPipelineLayout(),0,DescriptorSets,null);
|
||||
|
||||
RenderActors(engineInstance, CommandHandle, modelsCache, materialsCache, false);
|
||||
if(DualPassRendering) {
|
||||
vkCmdBindPipeline(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkPipelineTranslucent.GetVulkanPipeline());
|
||||
vkCmdSetViewport(CommandHandle, 0, Viewport);
|
||||
vkCmdSetScissor(CommandHandle, 0, Scissor);
|
||||
vkCmdBindDescriptorSets(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkPipelineTranslucent.GetVulkanPipelineLayout(), 0, DescriptorSets, null);
|
||||
}
|
||||
RenderActors(engineInstance, CommandHandle, modelsCache, materialsCache, true);
|
||||
|
||||
vkCmdEndRendering(CommandHandle);
|
||||
GPUTIME += System.nanoTime() - InitialTime;
|
||||
CYCLES++;
|
||||
}
|
||||
}
|
||||
|
||||
public MultiRenderTargetAttachments GetMRTAttachments(){
|
||||
return MRTAttachments;
|
||||
}
|
||||
|
||||
public void Render(EngineInstance engineInstance,VulkanContext vulkanContext, CommandBuffer commandBuffer, ModelsCache modelsCache,MaterialsCache materialsCache, int CurrentFrame){
|
||||
|
||||
if(Deferred) DeferredRender(engineInstance,vulkanContext,commandBuffer,modelsCache,materialsCache,CurrentFrame);
|
||||
else ForwardRender(engineInstance,vulkanContext,commandBuffer,modelsCache,materialsCache,CurrentFrame);
|
||||
|
||||
ForwardRender(engineInstance,vulkanContext,commandBuffer,modelsCache,materialsCache,CurrentFrame);
|
||||
}
|
||||
|
||||
private void RenderActors(EngineInstance instance, VkCommandBuffer CommandHandle, ModelsCache modelsCache, MaterialsCache materialsCache, boolean Transparent){
|
||||
try(var MemStack = MemoryStack.stackPush()){
|
||||
LongBuffer offsets = MemStack.mallocLong(1).put(0,0L);
|
||||
LongBuffer vertexBuffer = MemStack.mallocLong(1);
|
||||
Scene scene = instance.scene();
|
||||
IScene scene = instance.scene();
|
||||
List<Actor> Actors = scene.GetActors();
|
||||
int ActorCount = Actors.size();
|
||||
for(int i = 0; i < ActorCount; i++){
|
||||
|
|
@ -462,9 +340,7 @@ public class SceneRender implements SceneRenderer {//dynamic rendering
|
|||
public void Resize(EngineInstance instance, VulkanContext VkCtx){
|
||||
RenderInfo.free();
|
||||
AttachmentInfoDepth.free();
|
||||
MRTAttachments.CleanUp(VkCtx);
|
||||
if(Deferred)Arrays.asList(AttachmentInfoColour).forEach(VkRenderingAttachmentInfo.Buffer::free);
|
||||
else AttachmentInfoColour.free();
|
||||
AttachmentInfoColour.free();
|
||||
AttachmentColour.CleanUp(VkCtx);
|
||||
AttachmentDepth.CleanUp(VkCtx);
|
||||
CreateRenderAttachments(VkCtx);
|
||||
|
|
@ -515,15 +391,16 @@ public class SceneRender implements SceneRenderer {//dynamic rendering
|
|||
return Result;
|
||||
}
|
||||
public void cleanup(VulkanContext VkCtx){
|
||||
|
||||
|
||||
VkPipeline.CleanUp(VkCtx);
|
||||
VkPipelineTranslucent.CleanUp(VkCtx);
|
||||
VkPipelineOpaque.CleanUp(VkCtx);
|
||||
Arrays.asList(BufferViewMatrices).forEach(buffer -> buffer.cleanup(VkCtx));
|
||||
RenderInfo.free();
|
||||
AttachmentInfoColour.free();
|
||||
AttachmentColour.CleanUp(VkCtx);
|
||||
AttachmentDepth.CleanUp(VkCtx);
|
||||
AttachmentInfoDepth.free();
|
||||
MRTAttachments.CleanUp(VkCtx);
|
||||
MemoryUtil.memFree(PushConstBuffer);
|
||||
ClearValueDepth.free();
|
||||
ClearValueColour.free();
|
||||
|
|
@ -534,6 +411,11 @@ public class SceneRender implements SceneRenderer {//dynamic rendering
|
|||
textureSampler.CleanUp(VkCtx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiRenderTargetAttachments GetMRTAttachments() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Attachment GetAttachmentColour() {
|
||||
return AttachmentColour;
|
||||
|
|
@ -72,27 +72,27 @@ public class ImageView {
|
|||
this.MipLevels = 1;
|
||||
this.ViewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
}
|
||||
public ImageView.ImageViewData AspectMask(int aspectMask){
|
||||
public ImageViewData AspectMask(int aspectMask){
|
||||
this.AspectMask = aspectMask;
|
||||
return this;
|
||||
}
|
||||
public ImageView.ImageViewData BaseArrayLayer(int baseArrayLayer){
|
||||
public ImageViewData BaseArrayLayer(int baseArrayLayer){
|
||||
this.BaseArrayLayer = baseArrayLayer;
|
||||
return this;
|
||||
}
|
||||
public ImageView.ImageViewData Format(int format){
|
||||
public ImageViewData Format(int format){
|
||||
this.Format = format;
|
||||
return this;
|
||||
}
|
||||
public ImageView.ImageViewData LayerCount(int layerCount){
|
||||
public ImageViewData LayerCount(int layerCount){
|
||||
this.LayerCount = layerCount;
|
||||
return this;
|
||||
}
|
||||
public ImageView.ImageViewData MipLevels(int mipLevels){
|
||||
public ImageViewData MipLevels(int mipLevels){
|
||||
this.MipLevels = mipLevels;
|
||||
return this;
|
||||
}
|
||||
public ImageView.ImageViewData ViewType(int viewType){
|
||||
public ImageViewData ViewType(int viewType){
|
||||
this.ViewType = viewType;
|
||||
return this;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,18 +2,12 @@ package net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen;
|
|||
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Deferred.MultiRenderTargetAttachments;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.DeferredRendering.MultiRenderTargetAttachments;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.Attachment;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.TextureCache;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Pipeline;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.DescriptorSetLayout;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.ShaderModule;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.MaterialsCache;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.ModelsCache;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.CommandBuffer;
|
||||
import org.lwjgl.vulkan.VkClearValue;
|
||||
import org.lwjgl.vulkan.VkCommandBuffer;
|
||||
import org.lwjgl.vulkan.VkRenderingAttachmentInfo;
|
||||
|
||||
public interface SceneRenderer {
|
||||
|
||||
|
|
@ -21,7 +15,7 @@ public interface SceneRenderer {
|
|||
public void Resize(EngineInstance instance, VulkanContext VkCtx);
|
||||
public void LoadMaterials(VulkanContext VkCtx, MaterialsCache materialsCache, TextureCache textureCache);
|
||||
public void cleanup(VulkanContext VkCtx);
|
||||
public Attachment GetAttachmentColour();
|
||||
public MultiRenderTargetAttachments GetMRTAttachments();
|
||||
public boolean GetCurrentDeferred();
|
||||
public Attachment GetAttachmentColour();
|
||||
public void RebuildPipelines(VulkanContext VkCtx);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ import java.nio.LongBuffer;
|
|||
|
||||
import static net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils.vkCheck;
|
||||
import static org.lwjgl.vulkan.VK10.VK_FORMAT_B8G8R8A8_UNORM;
|
||||
import static org.lwjgl.vulkan.VK13.VK_FORMAT_B8G8R8A8_SRGB;
|
||||
|
||||
public class Surface {
|
||||
private final VkSurfaceCapabilitiesKHR SurfaceCapabilities;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
|
|||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.util.shaderc.Shaderc;
|
||||
import org.lwjgl.vulkan.*;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.nio.LongBuffer;
|
||||
import java.util.Arrays;
|
||||
|
|
@ -55,6 +56,8 @@ public class SwapChainRender {
|
|||
|
||||
pipeline = CreatePipeline(VkCtx,shaderModules,new DescriptorSetLayout[]{AttachmentDescriptorSetLayout});
|
||||
Arrays.asList(shaderModules).forEach(s->s.CleanUp(VkCtx));
|
||||
Logger.debug("Swap Chain Renderer Pipeline -> [{}]",pipeline.GetVulkanPipeline());
|
||||
|
||||
}
|
||||
|
||||
private static void CreateAttachmentDescriptorSet(VulkanContext VkCtx, DescriptorSetLayout descriptorSetLayout, Attachment attachment, TextureSampler sampler){
|
||||
|
|
@ -84,7 +87,7 @@ public class SwapChainRender {
|
|||
}
|
||||
private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] shaderModules, DescriptorSetLayout[] descriptorSetLayouts){
|
||||
var VertexBufferStruct = new EmptyVertexBufferStruct();
|
||||
var BuildInfo = new PipelineBuildInfo(shaderModules, VertexBufferStruct.GetVertexInput(),VkCtx.GetSurface().GetSurfaceFormat().ImageFormat()).SetDescriptorSetLayouts(descriptorSetLayouts).BlendingIsUsed(true);
|
||||
var BuildInfo = new PipelineBuildInfo(shaderModules, VertexBufferStruct.GetVertexInput(),new int[]{VkCtx.GetSurface().GetSurfaceFormat().ImageFormat()}).SetDescriptorSetLayouts(descriptorSetLayouts).BlendingIsUsed(true);
|
||||
var pipeline = new DefaultPipeline(VkCtx,BuildInfo);
|
||||
VertexBufferStruct.CleanUp();
|
||||
return pipeline;
|
||||
|
|
|
|||
|
|
@ -39,7 +39,13 @@ public class VulkanInstance {
|
|||
Logger.debug("Initialising Vulkan Instance");
|
||||
try (MemoryStack MemStack = MemoryStack.stackPush()) {
|
||||
ByteBuffer appShortName = MemStack.UTF8("Terrain4J");
|
||||
var appInfo = VkApplicationInfo.calloc(MemStack).sType$Default().pApplicationName(appShortName).applicationVersion(1).pEngineName(appShortName).engineVersion(3).apiVersion(VK_API_VERSION_1_3);
|
||||
var appInfo = VkApplicationInfo.calloc(MemStack)
|
||||
.sType$Default()
|
||||
.pApplicationName(appShortName)
|
||||
.applicationVersion(1)
|
||||
.pEngineName(appShortName)
|
||||
.engineVersion(0)
|
||||
.apiVersion(VK_API_VERSION_1_3);
|
||||
|
||||
//Vulkan operates in "Layers" and does minimal validation as it expects the developer to be competent, so we add these ourseves for better debugging
|
||||
//refer to https://vulkan-tutorial.com/Drawing_a_triangle/Setup/Validation_layers for an explanation
|
||||
|
|
|
|||
|
|
@ -1,24 +1,19 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Vulkan.Util;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.Device;
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.lwjgl.util.vma.VmaAllocationCreateInfo;
|
||||
import org.lwjgl.util.vma.VmaAllocatorCreateInfo;
|
||||
import org.lwjgl.vulkan.VkBufferCreateInfo;
|
||||
import org.lwjgl.vulkan.VkDevice;
|
||||
import org.lwjgl.vulkan.VkMemoryAllocateInfo;
|
||||
import org.lwjgl.vulkan.VkMemoryRequirements;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.nio.LongBuffer;
|
||||
|
||||
import static net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils.vkCheck;
|
||||
import static org.lwjgl.system.MemoryUtil.NULL;
|
||||
import static org.lwjgl.util.vma.Vma.*;
|
||||
import static org.lwjgl.vulkan.VK13.*;
|
||||
import static org.lwjgl.vulkan.VK13.VK_SHARING_MODE_EXCLUSIVE;
|
||||
import static org.lwjgl.vulkan.VK13.VK_WHOLE_SIZE;
|
||||
|
||||
public class VulkanBuffer {
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,10 @@ import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.Device;
|
|||
import org.joml.Matrix4f;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.lwjgl.vulkan.*;
|
||||
import org.lwjgl.vulkan.VkCommandBuffer;
|
||||
import org.lwjgl.vulkan.VkDependencyInfo;
|
||||
import org.lwjgl.vulkan.VkImageMemoryBarrier2;
|
||||
import org.lwjgl.vulkan.VkMemoryType;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
|
@ -28,6 +31,7 @@ public class VulkanUtils {
|
|||
public enum OSType {WINDOWS, MACOS, LINUX, UNSUPPORTED}
|
||||
|
||||
public static final int FLOAT_SIZE = 4;
|
||||
public static final int VEC3_SIZE = 3 * FLOAT_SIZE;
|
||||
public static final int INT_SIZE = 4;
|
||||
public static final int MATRIX4X4_SIZE = 16 * FLOAT_SIZE;
|
||||
public static final int VEC4_SIZE = 4 * FLOAT_SIZE;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue