post processing, FXAA and MSAA 2x-8x
This commit is contained in:
parent
fa266ee48d
commit
8ce30cae83
46 changed files with 1749 additions and 350 deletions
|
|
@ -0,0 +1,55 @@
|
|||
#version 450
|
||||
|
||||
layout(constant_id = 0) const int USE_AA = 0;
|
||||
|
||||
const float GAMMA_CONST = 0.4545;
|
||||
const float SPAN_MAX = 8.0;
|
||||
const float REDUCE_MIN = 1.0/128.0;
|
||||
const float REDUCE_MUL = 1.0/32.0;
|
||||
|
||||
layout(location = 0) in vec2 inTextCoord;
|
||||
layout(location = 0) out vec4 outFragColor;
|
||||
|
||||
layout(set = 0, binding = 0) uniform sampler2DMS inputTexture;
|
||||
|
||||
layout(set = 1, binding = 0) uniform ScreenSize{
|
||||
vec2 size;
|
||||
} screenSize;
|
||||
|
||||
vec4 gamma(vec4 color){
|
||||
return color = vec4(pow(color.rgb,vec3(GAMMA_CONST)),color.a);
|
||||
}
|
||||
|
||||
|
||||
vec4 msaa(int sampleCount, sampler2DMS textureIn,vec2 TextCoord){
|
||||
ivec2 pixelCoords = ivec2(TextCoord * textureSize(textureIn));
|
||||
vec4 colorSum = vec4(0.0);
|
||||
|
||||
for(int i = 0; i < sampleCount; ++i) {
|
||||
vec4 sampleColor = texelFetch(textureIn, pixelCoords, i);
|
||||
sampleColor.rgb = sampleColor.rgb / (sampleColor.rgb + vec3(1.0));
|
||||
colorSum += sampleColor;
|
||||
}
|
||||
return colorSum / float(sampleCount);
|
||||
}
|
||||
|
||||
void main(){
|
||||
ivec2 pixelCoords = ivec2(inTextCoord * textureSize(inputTexture));
|
||||
|
||||
if(USE_AA == 0){
|
||||
outFragColor = texelFetch(inputTexture,pixelCoords,0);
|
||||
}
|
||||
if(USE_AA == 1){
|
||||
outFragColor = texelFetch(inputTexture,pixelCoords,0);
|
||||
}
|
||||
if(USE_AA == 2){
|
||||
outFragColor = msaa(2,inputTexture,inTextCoord);
|
||||
}
|
||||
if(USE_AA == 3){
|
||||
outFragColor = msaa(4,inputTexture,inTextCoord);
|
||||
}
|
||||
if(USE_AA == 4){
|
||||
outFragColor = msaa(8,inputTexture,inTextCoord);
|
||||
}
|
||||
outFragColor = gamma(outFragColor);
|
||||
}
|
||||
91
resources/EngineResources/shaders/post_process_frag.glsl
Normal file
91
resources/EngineResources/shaders/post_process_frag.glsl
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
#version 450
|
||||
|
||||
layout(constant_id = 0) const int USE_AA = 0;
|
||||
|
||||
const float GAMMA_CONST = 0.4545;
|
||||
const float SPAN_MAX = 8.0;
|
||||
const float REDUCE_MIN = 1.0/128.0;
|
||||
const float REDUCE_MUL = 1.0/32.0;
|
||||
|
||||
layout(location = 0) in vec2 inTextCoord;
|
||||
layout(location = 0) out vec4 outFragColor;
|
||||
|
||||
layout(set = 0, binding = 0) uniform sampler2D inputTexture;
|
||||
|
||||
layout(set = 1, binding = 0) uniform ScreenSize{
|
||||
vec2 size;
|
||||
} screenSize;
|
||||
|
||||
vec4 gamma(vec4 color){
|
||||
return color = vec4(pow(color.rgb,vec3(GAMMA_CONST)),color.a);
|
||||
}
|
||||
|
||||
// Sourced from: https://mini.gmshaders.com/p/gm-shaders-mini-fxaa
|
||||
|
||||
vec4 fxaa(sampler2D tex, vec2 uv) {
|
||||
vec2 u_texel = 1.0 / screenSize.size;
|
||||
|
||||
//Sample center and 4 corners
|
||||
vec3 rgbCC = texture(tex, uv).rgb;
|
||||
vec3 rgb00 = texture(tex, uv+vec2(-0.5,-0.5)*u_texel).rgb;
|
||||
vec3 rgb10 = texture(tex, uv+vec2(+0.5,-0.5)*u_texel).rgb;
|
||||
vec3 rgb01 = texture(tex, uv+vec2(-0.5,+0.5)*u_texel).rgb;
|
||||
vec3 rgb11 = texture(tex, uv+vec2(+0.5,+0.5)*u_texel).rgb;
|
||||
|
||||
//Luma coefficients
|
||||
const vec3 luma = vec3(0.299, 0.587, 0.114);
|
||||
//Get luma from the 5 samples
|
||||
float lumaCC = dot(rgbCC, luma);
|
||||
float luma00 = dot(rgb00, luma);
|
||||
float luma10 = dot(rgb10, luma);
|
||||
float luma01 = dot(rgb01, luma);
|
||||
float luma11 = dot(rgb11, luma);
|
||||
|
||||
//Compute gradient from luma values
|
||||
vec2 dir = vec2((luma01 + luma11) - (luma00 + luma10), (luma00 + luma01) - (luma10 + luma11));
|
||||
//Diminish dir length based on total luma
|
||||
float dirReduce = max((luma00 + luma10 + luma01 + luma11) * REDUCE_MUL, REDUCE_MIN);
|
||||
//Divide dir by the distance to nearest edge plus dirReduce
|
||||
float rcpDir = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);
|
||||
//Multiply by reciprocal and limit to pixel span
|
||||
dir = clamp(dir * rcpDir, -SPAN_MAX, SPAN_MAX) * u_texel.xy;
|
||||
|
||||
//Average middle texels along dir line
|
||||
vec4 A = 0.5 * (
|
||||
texture(tex, uv - dir * (1.0/6.0)) +
|
||||
texture(tex, uv + dir * (1.0/6.0)));
|
||||
|
||||
//Average with outer texels along dir line
|
||||
vec4 B = A * 0.5 + 0.25 * (
|
||||
texture(tex, uv - dir * (0.5)) +
|
||||
texture(tex, uv + dir * (0.5)));
|
||||
|
||||
|
||||
//Get lowest and highest luma values
|
||||
float lumaMin = min(lumaCC, min(min(luma00, luma10), min(luma01, luma11)));
|
||||
float lumaMax = max(lumaCC, max(max(luma00, luma10), max(luma01, luma11)));
|
||||
|
||||
//Get average luma
|
||||
float lumaB = dot(B.rgb, luma);
|
||||
//If the average is outside the luma range, using the middle average
|
||||
return ((lumaB < lumaMin) || (lumaB > lumaMax)) ? A : B;
|
||||
}
|
||||
|
||||
void main(){
|
||||
|
||||
if(USE_AA == 1){
|
||||
outFragColor = fxaa(inputTexture, inTextCoord);
|
||||
outFragColor = gamma(outFragColor);
|
||||
return;
|
||||
}
|
||||
if(USE_AA == 2){
|
||||
|
||||
}
|
||||
if(USE_AA == 3){
|
||||
|
||||
}
|
||||
if(USE_AA == 4){
|
||||
|
||||
}
|
||||
outFragColor = gamma(texture(inputTexture,inTextCoord));
|
||||
}
|
||||
9
resources/EngineResources/shaders/post_process_vtx.glsl
Normal file
9
resources/EngineResources/shaders/post_process_vtx.glsl
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#version 450
|
||||
|
||||
layout(location = 0 ) out vec2 outTextCoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
outTextCoord = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
||||
gl_Position = vec4(outTextCoord.x * 2.0f - 1.0f, outTextCoord.y * -2.0f + 1.0f,0.0f,1.0f);
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#version 450
|
||||
|
||||
const int MAX_TEXTURES = 100;
|
||||
const int MAX_TEXTURES = 500;
|
||||
|
||||
layout(location = 0) in vec2 inTextCoords;
|
||||
layout(location = 0) out vec4 outFragColor;
|
||||
|
|
@ -26,7 +26,9 @@ void main()
|
|||
{
|
||||
Material material = matUniform.materials[push_constants.materialIdx];
|
||||
if(material.hasTexture == 1){
|
||||
outFragColor = texture(textSampler[material.textureIdx],inTextCoords);
|
||||
vec4 texColor = texture(textSampler[material.textureIdx],inTextCoords);
|
||||
if(texColor.a < 0.1){discard;}
|
||||
outFragColor = texColor;
|
||||
} else{
|
||||
outFragColor = material.diffuseColor;
|
||||
}
|
||||
10
resources/EngineResources/shaders/swap_frag.glsl
Normal file
10
resources/EngineResources/shaders/swap_frag.glsl
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#version 450
|
||||
layout(location = 0) in vec2 inTextCoord;
|
||||
layout(location = 0) out vec4 outFragColor;
|
||||
|
||||
layout(set = 0, binding = 0) uniform sampler2D albedoSampler;
|
||||
|
||||
void main() {
|
||||
vec3 albedo = texture(albedoSampler, inTextCoord).rgb;
|
||||
outFragColor = vec4(albedo,1.0);
|
||||
}
|
||||
8
resources/EngineResources/shaders/swap_vtx.glsl
Normal file
8
resources/EngineResources/shaders/swap_vtx.glsl
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#version 450
|
||||
|
||||
layout(location = 0) out vec2 outTextCoord;
|
||||
|
||||
void main() {
|
||||
outTextCoord = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
||||
gl_Position = vec4(outTextCoord.x * 2.0f - 1.0f, outTextCoord.y * -2.0f + 1.0f,0.0f,1.0f);
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 64 KiB |
|
|
@ -4,17 +4,17 @@ import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
|
|||
import net.halbear.Terrain4J.EngineCore.Logic.InitData;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.TextureCache;
|
||||
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.Rendering.PostProcessing.PostProcess;
|
||||
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.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.SwapChain;
|
||||
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;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.vulkan.VkCommandBufferSubmitInfo;
|
||||
|
|
@ -22,11 +22,11 @@ import org.lwjgl.vulkan.VkExtent2D;
|
|||
import org.lwjgl.vulkan.VkSemaphoreSubmitInfo;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.lwjgl.vulkan.VK13.VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT;
|
||||
import static org.lwjgl.vulkan.VK13.VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
import static org.lwjgl.vulkan.VK13.*;
|
||||
|
||||
public class Render {
|
||||
|
||||
|
|
@ -39,14 +39,22 @@ public class Render {
|
|||
private final Semaphore[] PresentCompleteSemaphores;
|
||||
private final Queue.PresentQueue PresentQueue;
|
||||
private final Semaphore[] RenderCompleteSemaphores;
|
||||
private final SceneRender sceneRender;
|
||||
private final SceneRenderer sceneRender;
|
||||
private final PostProcess PostProcessor;
|
||||
private final SwapChainRender swapChainRender;
|
||||
private int CurrentFrame;
|
||||
private final VulkanContext RendererContext;
|
||||
private boolean Resize = false;
|
||||
private List<MaterialData> Materials = new ArrayList<>();
|
||||
private List<ModelData> Models = new ArrayList<>();
|
||||
private List<CompatibleVoxelMesh.VoxelModelData> VoxelModels = new ArrayList<>();
|
||||
|
||||
private final MaterialsCache materialsCache;
|
||||
private TextureCache textureCache;
|
||||
|
||||
public TextureCache GetTextureCache(){return textureCache;}
|
||||
public MaterialsCache GetMaterialsCache(){return materialsCache;}
|
||||
|
||||
public Render(EngineInstance engineInstance) {
|
||||
RendererContext = new VulkanContext(engineInstance.window());
|
||||
CurrentFrame = 0;
|
||||
|
|
@ -68,6 +76,8 @@ public class Render {
|
|||
RenderCompleteSemaphores[i] = new Semaphore(RendererContext);
|
||||
}
|
||||
sceneRender = new SceneRender(RendererContext);
|
||||
PostProcessor = new PostProcess(RendererContext,sceneRender.GetAttachmentColour());
|
||||
swapChainRender = new SwapChainRender(RendererContext,PostProcessor.GetAttachment());
|
||||
textureCache = new TextureCache();
|
||||
materialsCache = new MaterialsCache();
|
||||
modelsCache = new ModelsCache();
|
||||
|
|
@ -76,19 +86,27 @@ public class Render {
|
|||
|
||||
public void Initialise(InitData initData){
|
||||
|
||||
List<MaterialData> Materials = initData.Materials();
|
||||
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());
|
||||
|
||||
Logger.debug("Transitioning Textures");
|
||||
//textureCache.CleanUp(RendererContext);
|
||||
textureCache.TransitionTexts(RendererContext, CommandPools[0], GraphicsQueue);
|
||||
Logger.debug("Transitioned Textures");
|
||||
|
||||
List<ModelData> Models = initData.Models();
|
||||
Models.addAll(initData.Models());
|
||||
Logger.debug("Loading {} models", Models.size());
|
||||
//modelsCache.CleanUp(RendererContext);
|
||||
modelsCache.loadModels(RendererContext, Models, CommandPools[0], GraphicsQueue);
|
||||
Logger.debug("Loaded {} models", Models.size());
|
||||
|
||||
VoxelModels.addAll(initData.voxelModels());
|
||||
Logger.debug("Loading {} Voxel models", VoxelModels.size());
|
||||
modelsCache.loadVoxelModels(RendererContext, VoxelModels, CommandPools[0], GraphicsQueue);
|
||||
Logger.debug("Loaded {} Voxel models", VoxelModels.size());
|
||||
sceneRender.LoadMaterials(RendererContext,materialsCache,textureCache);
|
||||
}
|
||||
|
||||
|
|
@ -105,6 +123,8 @@ public class Render {
|
|||
RendererContext.GetDevice().waitIdle();
|
||||
Logger.debug("Waiting Vulkan Context");
|
||||
sceneRender.cleanup(RendererContext);
|
||||
PostProcessor.CleanUp(RendererContext);
|
||||
swapChainRender.CleanUp(RendererContext);
|
||||
Logger.debug("Dynamic Renderer Cleaned up");
|
||||
Arrays.asList(RenderCompleteSemaphores).forEach(i->i.cleanup(RendererContext));
|
||||
Logger.debug("Render Semaphores cleaned up");
|
||||
|
|
@ -128,12 +148,18 @@ public class Render {
|
|||
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());
|
||||
|
||||
int ImageIndex;// = swapChain.FetchNextImage(RendererContext.GetDevice(), PresentCompleteSemaphores[CurrentFrame]);
|
||||
if (Resize || (ImageIndex = swapChain.FetchNextImage(RendererContext.GetDevice(), PresentCompleteSemaphores[CurrentFrame])) < 0){
|
||||
resize(engineInstance);
|
||||
return;
|
||||
}
|
||||
sceneRender.Render(engineInstance,RendererContext,CommandBuffer, modelsCache,materialsCache,ImageIndex,CurrentFrame);
|
||||
|
||||
swapChainRender.Render(RendererContext,CommandBuffer,PostProcessor.GetAttachment(),ImageIndex);
|
||||
|
||||
RecordingStop(CommandBuffer);
|
||||
Submit(CommandBuffer, CurrentFrame, ImageIndex);
|
||||
Resize = swapChain.PresentImage(PresentQueue, RenderCompleteSemaphores[ImageIndex],ImageIndex);
|
||||
|
|
@ -161,6 +187,8 @@ public class Render {
|
|||
VkExtent2D extend = RendererContext.GetSwapChain().GetSwapChainExtent();
|
||||
engineInstance.scene().GetProjection().Resize(extend.width(),extend.height());
|
||||
sceneRender.Resize(engineInstance,RendererContext);
|
||||
PostProcessor.Resize(RendererContext,sceneRender.GetAttachmentColour());
|
||||
swapChainRender.Resize(RendererContext,PostProcessor.GetAttachment());
|
||||
}
|
||||
|
||||
private void ResetFence(int currentFrame){
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ public class MouseListener {
|
|||
middleButtonPressed = button == GLFW_MOUSE_BUTTON_3 && action == GLFW_PRESS;
|
||||
});
|
||||
}
|
||||
public boolean IsWindowFocused(){return FocusWindow;}
|
||||
public Vector2f getCurrentPos() {
|
||||
return currentPos;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ import java.nio.file.Path;
|
|||
import java.nio.file.Paths;
|
||||
import java.util.Properties;
|
||||
|
||||
import static org.lwjgl.vulkan.VK10.*;
|
||||
|
||||
public class EngineConfig {
|
||||
public static final double DegToRad = Math.PI/180.0;
|
||||
public static final double RadToDeg = 180.0/Math.PI;
|
||||
|
|
@ -51,6 +53,8 @@ public class EngineConfig {
|
|||
private float zNearPlane;
|
||||
private boolean GPU_SUPPORTS_LOGGING = true;
|
||||
private int MaxDescriptors = 1000;
|
||||
private int AAValue = 1;
|
||||
private AntiAliasType AAMode = AntiAliasType.FXAA;
|
||||
|
||||
public void GPU_Does_Not_Support_Logging(){
|
||||
GPU_SUPPORTS_LOGGING = false;
|
||||
|
|
@ -58,6 +62,32 @@ public class EngineConfig {
|
|||
public boolean doesGPUSupportLogging(){return GPU_SUPPORTS_LOGGING;}
|
||||
public String GetDefaultTexturePath(){return DefaultTexturePath;}
|
||||
public int GetMaxDescriptors(){return MaxDescriptors;}
|
||||
public int RenderAA(){return AAValue;}
|
||||
|
||||
public enum AntiAliasType{
|
||||
NONE,
|
||||
FXAA,
|
||||
MSAAx2,
|
||||
MSAAx4,
|
||||
MSAAx8
|
||||
}
|
||||
|
||||
public int GetRenderSampleCount(){
|
||||
switch(AAMode){
|
||||
case MSAAx2:
|
||||
return VK_SAMPLE_COUNT_2_BIT;
|
||||
case MSAAx4:
|
||||
return VK_SAMPLE_COUNT_4_BIT;
|
||||
case MSAAx8:
|
||||
return VK_SAMPLE_COUNT_8_BIT;
|
||||
case FXAA:
|
||||
return VK_SAMPLE_COUNT_1_BIT;
|
||||
case NONE:
|
||||
return VK_SAMPLE_COUNT_1_BIT;
|
||||
default:
|
||||
return VK_SAMPLE_COUNT_1_BIT;
|
||||
}
|
||||
}
|
||||
|
||||
private EngineConfig() {
|
||||
var EngineConfigVar = new Properties();
|
||||
|
|
@ -120,6 +150,25 @@ public class EngineConfig {
|
|||
FOV = (float)(DegToRad * Float.parseFloat(EngineConfigVar.getOrDefault("field_of_view", 60.0f).toString()));
|
||||
zNearPlane = (Float.parseFloat(EngineConfigVar.getOrDefault("z_near_plane", 1.0f).toString()));
|
||||
zFarPlane = (Float.parseFloat(EngineConfigVar.getOrDefault("z_far_plane", 100.0f).toString()));
|
||||
AAValue = (Integer.parseInt(EngineConfigVar.getOrDefault("anti_alias_mode", 1).toString()));
|
||||
switch(AAValue){
|
||||
case 0:
|
||||
AAMode = AntiAliasType.NONE;
|
||||
break;
|
||||
case 2:
|
||||
AAMode = AntiAliasType.MSAAx2;
|
||||
break;
|
||||
case 3:
|
||||
AAMode = AntiAliasType.MSAAx4;
|
||||
break;
|
||||
case 4:
|
||||
AAMode = AntiAliasType.MSAAx8;
|
||||
break;
|
||||
case 1:
|
||||
default:
|
||||
AAMode = AntiAliasType.FXAA;
|
||||
break;
|
||||
}
|
||||
DefaultTexturePath = EngineConfigVar.getOrDefault("DefaultTexturePath","/EngineResources/Texture/DefaultTexture.png").toString();
|
||||
Logger.debug("\n\nsuccessfully loaded configuration: \n{}\n\n",EngineConfigVar.toString());
|
||||
}
|
||||
|
|
@ -149,6 +198,7 @@ public class EngineConfig {
|
|||
EngineConfigVar.setProperty("z_far_plane","100");
|
||||
EngineConfigVar.setProperty("DefaultTexturePath",DefaultTexturePath);
|
||||
EngineConfigVar.setProperty("MaxDescriptors","1000");
|
||||
EngineConfigVar.setProperty("anti_alias_mode","1");
|
||||
EngineConfigVar.store(new FileWriter(path.toAbsolutePath().toString() + "/" + FILENAME), "created new properties file");
|
||||
Logger.debug("Wrote New Config File [{}]", ConfigFile.getAbsolutePath());
|
||||
} catch (IOException excp2) {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,14 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Logic;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Display.Render;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
|
||||
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) {
|
||||
public record EngineInstance(Window window, Scene scene, PrimaryRuntime PrimaryThread) {
|
||||
public void cleanup(){
|
||||
window.cleanup();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,9 @@ package net.halbear.Terrain4J.EngineCore.Logic;
|
|||
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.MaterialData;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.ModelData;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.CompatibleVoxelMesh;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record InitData(List<ModelData> Models, List<MaterialData> Materials) {
|
||||
public record InitData(List<ModelData> Models, List<CompatibleVoxelMesh.VoxelModelData> voxelModels, List<MaterialData> Materials) {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Logic;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.MaterialData;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.CompatibleVoxelMesh;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record InitVoxelData(List<CompatibleVoxelMesh.VoxelModelData> Models, List<MaterialData> Materials) {
|
||||
}
|
||||
|
|
@ -208,7 +208,7 @@ public class ModelCompiler {
|
|||
int EmbeddedTextureIndex = matcher.matches() && matcher.groupCount() > 0 ? Integer.parseInt(matcher.group(1)) : -1;
|
||||
if (EmbeddedTextureIndex >= 0 && EmbeddedTextureIndex < EmbeddedTextureCount){
|
||||
var aiTexture = AITexture.create(aiScene.mTextures().get(EmbeddedTextureIndex));
|
||||
String BaseFile = aiTexture.mFilename().dataString() + ".png";
|
||||
String BaseFile = aiTexture.mFilename().dataString() + "ModelTexture" +EmbeddedTextureIndex + ".png";
|
||||
TexturePath = BaseDirectory + File.separator + BaseFile;
|
||||
Logger.info("Dumping Texture File to [{}]",TexturePath);
|
||||
var Channel = FileChannel.open(Path.of(TexturePath), StandardOpenOption.CREATE,StandardOpenOption.WRITE);
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.DescriptorAlloca
|
|||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.Device;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.PhysicalDevice;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.Surface;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.SwapChain;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.SwapChain.SwapChain;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.VulkanInstance;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanMemoryAllocator;
|
||||
import org.tinylog.Logger;
|
||||
|
|
|
|||
|
|
@ -3,16 +3,15 @@ package net.halbear.Terrain4J.EngineCore.Main;
|
|||
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.Logic.GameLogic;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.InitData;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.*;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.ModelLoader;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.Camera;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.Scene;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Util.Maths.T4Math;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.MaterialData;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.ModelData;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.CompatibleVoxelMesh;
|
||||
import org.joml.Vector2f;
|
||||
import org.joml.Vector3f;
|
||||
import org.tinylog.Logger;
|
||||
|
|
@ -33,6 +32,8 @@ public class GameCore implements GameLogic {
|
|||
private List<Vector3f> Velocities = new ArrayList<>();
|
||||
private Actor CubeActor;
|
||||
private List<Actor> CubeActors = new ArrayList<>();
|
||||
private Vector2f LastMousePos = new Vector2f(0,0);
|
||||
private int Ticks = 0;
|
||||
|
||||
@Override
|
||||
public void cleanup() {
|
||||
|
|
@ -41,50 +42,80 @@ public class GameCore implements GameLogic {
|
|||
|
||||
@Override
|
||||
public InitData Initialise(EngineInstance engineInstance) {
|
||||
|
||||
CompatibleVoxelMesh GrassCube = new CompatibleVoxelMesh("GrassBlock")
|
||||
.CreateMeshFace(CompatibleVoxelMesh.FaceDirection.North, "resources/EngineResources/Texture/VoxelTextures/VoxelTexture1.png")
|
||||
.CreateMeshFace(CompatibleVoxelMesh.FaceDirection.East, "resources/EngineResources/Texture/VoxelTextures/VoxelTexture14.png")
|
||||
.CreateMeshFace(CompatibleVoxelMesh.FaceDirection.South, "resources/EngineResources/Texture/VoxelTextures/VoxelTexture13.png")
|
||||
.CreateMeshFace(CompatibleVoxelMesh.FaceDirection.West, "resources/EngineResources/Texture/VoxelTextures/VoxelTexture12.png")
|
||||
.CreateMeshFace(CompatibleVoxelMesh.FaceDirection.Up, "resources/EngineResources/Texture/VoxelTextures/VoxelTexture15.png")
|
||||
.CreateMeshFace(CompatibleVoxelMesh.FaceDirection.Down, "resources/EngineResources/Texture/VoxelTextures/VoxelTexture0.png").CompileMesh();
|
||||
|
||||
InitVoxelData Voxels = CompatibleVoxelMesh.GetVoxelModelsGenerated();
|
||||
List<CompatibleVoxelMesh.VoxelModelData> VoxelModels = Voxels.Models();
|
||||
for(int i = 0; i < VoxelModels.size(); i++){
|
||||
Logger.debug("Voxel -> [{}]",VoxelModels.get(i).ID());
|
||||
}
|
||||
Scene scene = engineInstance.scene();
|
||||
List<ModelData> models = new ArrayList<>();
|
||||
|
||||
//ModelData SponzaData = ModelLoader.LoadModel("resources/models/Unit02/evangelion_unit-02.json");
|
||||
//List<MaterialData> SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Unit02/evangelion_unit-02_mat.json");
|
||||
ModelData SponzaData = ModelLoader.LoadModel("resources/models/Sponza/Sponza.json");
|
||||
List<MaterialData> SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Sponza/Sponza_mat.json");
|
||||
scene.AddActor(new Actor("Sponza", SponzaData.ID(), new Vector3f(0,0,-5f)));
|
||||
|
||||
models.add(ModelLoader.LoadModel("resources/models/Metro/OBJ/MetroLeadCar.json"));
|
||||
models.add(ModelLoader.LoadModel("resources/models/Corvette/CorvetteOBJ.json"));
|
||||
//models.add(ModelLoader.LoadModel("resources/models/Sloop/SloopOBJ.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 < 50000; i++) {
|
||||
CubeActors.add(new Actor("CubeEntity" + i, models.get((int)Math.round(Math.min(Math.max((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))));
|
||||
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)(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);
|
||||
|
||||
List<MaterialData> materials = new ArrayList<>();
|
||||
materials.addAll(ModelLoader.LoadMaterials("resources/models/Metro/OBJ/MetroLeadCar_mat.json"));
|
||||
materials.addAll(ModelLoader.LoadMaterials("resources/models/Corvette/CorvetteOBJ_mat.json"));
|
||||
materials.addAll(ModelLoader.LoadMaterials("resources/models/Sloop/SloopOBJ_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(Voxels.Materials());
|
||||
models.add(SponzaData);
|
||||
Camera camera = scene.GetCamera();
|
||||
camera.SetPosition(0.0f, 0.0f, 0.0f);
|
||||
camera.SetRotation((float) Math.toRadians(0.0f), (float) Math.toRadians(0.0f),0);
|
||||
return new InitData(models,materials);
|
||||
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);
|
||||
return new InitData(models,VoxelModels,materials);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void CameraInput(EngineInstance engineInstance, long FrameDiffNanoSeconds) {
|
||||
float Multiplier = MOUSE_SENSITIVITY;
|
||||
Scene scene = engineInstance.scene();
|
||||
Window window = engineInstance.window();
|
||||
Camera camera = scene.GetCamera();
|
||||
|
||||
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()){
|
||||
Vector2f deltaPos = MouseInput.getDeltaPos();
|
||||
camera.AddRotation((float)Math.toRadians(-deltaPos.y * MOUSE_SENSITIVITY),(float)Math.toRadians(-deltaPos.x * MOUSE_SENSITIVITY),0);
|
||||
|
||||
camera.AddRotation((float)Math.toRadians(-deltaPos.y * Multiplier),(float)Math.toRadians(-deltaPos.x * Multiplier),0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -122,9 +153,13 @@ public class GameCore implements GameLogic {
|
|||
for(int i = 0; i < angles.size()/2; i++) {
|
||||
angles.set(i, (angles.get(i) + 0.1f* 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).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){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -133,7 +168,7 @@ public class GameCore implements GameLogic {
|
|||
for(int i = angles.size()/2; 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).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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,11 @@ import net.halbear.Terrain4J.EngineCore.Threads.MainThread;
|
|||
import net.halbear.Terrain4J.EngineCore.Threads.RenderThread;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
public class PrimaryRuntime {
|
||||
private int Frames = 0;
|
||||
private int TickFrames = 0;
|
||||
|
|
@ -30,9 +35,23 @@ public class PrimaryRuntime {
|
|||
private static GameLogic gameLogic;
|
||||
|
||||
public PrimaryRuntime(String windowTitle, GameLogic appLogic) {
|
||||
String[] knownDLSSfiles = {"nvngx_dlss.dll", "nvngx_dlssg.dll", "_nvngx.dll"};
|
||||
for (String dllName : knownDLSSfiles) {
|
||||
Path dllPath = Paths.get(System.getProperty("user.dir"), dllName);
|
||||
if (Files.exists(dllPath)) {
|
||||
try {
|
||||
Logger.warn("DLSS is not supported, and is not allowed to be used with Terrain4J: [{}]",dllName);
|
||||
Files.delete(dllPath);
|
||||
Logger.info("removed local DLSS hook.");
|
||||
} catch (IOException e) {
|
||||
Logger.error("Could not remove DLSS DLL. Exiting to prevent pipeline corruption.");
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
window = new Window(windowTitle);
|
||||
gameLogic = appLogic;
|
||||
engineInstance = new EngineInstance(window, new Scene(window));
|
||||
engineInstance = new EngineInstance(window, new Scene(window),this);
|
||||
InitData initData = appLogic.Initialise(engineInstance);
|
||||
PrimaryThread = new MainThread(engineInstance, appLogic);
|
||||
FastThread = new FastTickThread(engineInstance, appLogic);
|
||||
|
|
@ -40,6 +59,9 @@ public class PrimaryRuntime {
|
|||
cpuProfiler = new CPUMonitor();
|
||||
Thread.currentThread().setName("Terrain4J Primary Runtime Thread");
|
||||
}
|
||||
public static MainThread GetMainThread(){return PrimaryThread;}
|
||||
public static RenderThread GetRenderThread(){return DrawingThread;}
|
||||
public static FastTickThread GetFastThread(){return FastThread;}
|
||||
public static void UpdateFrameAccuracy(){
|
||||
if(EngineConfig.getInstance().IsEngineThrottled()){
|
||||
Logger.debug("ThrottlingEngine");
|
||||
|
|
@ -101,7 +123,6 @@ public class PrimaryRuntime {
|
|||
EngineConfig.FrameRate_PRIMARYTHREAD = Frames;
|
||||
EngineConfig.TPS = TickFrames;
|
||||
Logger.info("Primary Thread FPS: " + Frames + " TPS: " + TickFrames + " Window Draw FPS: " + EngineConfig.RENDERFRAMES);
|
||||
Logger.info(cpuProfiler.LogCPUUsage() + "\t");
|
||||
Frames = 0;
|
||||
TickFrames = 0;
|
||||
EngineConfig.RENDERFRAMES = 0;
|
||||
|
|
|
|||
|
|
@ -4,4 +4,5 @@ public class T4Math {
|
|||
public static double Log2(int n){
|
||||
return Math.log(n) / Math.log(n);
|
||||
}
|
||||
public static double Square(double n){return n*n;}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ public class FastTickThread extends EngineThread {
|
|||
|
||||
@Override
|
||||
public void TickEvent(long nsTimeDiff){
|
||||
gameLogic.Input(PrimaryRuntime.GetEngineInstance(), (nsTimeDiff));
|
||||
gameLogic.UpdateFastThread(PrimaryRuntime.GetEngineInstance(), nsTimeDiff);
|
||||
}
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ public class MainThread extends EngineThread {
|
|||
|
||||
@Override
|
||||
public void TickEvent(long nsTimeDiff){
|
||||
gameLogic.Update(PrimaryRuntime.GetEngineInstance(), nsTimeDiff);
|
||||
|
||||
}
|
||||
@Override
|
||||
public void FrameEvent(long now, long InitialTime){
|
||||
|
|
|
|||
|
|
@ -18,13 +18,14 @@ public class RenderThread extends EngineThread {
|
|||
render.Initialise(initData);
|
||||
}
|
||||
|
||||
public Render GetRenderer(){return render;}
|
||||
|
||||
@Override
|
||||
public void TickEvent(long nsTimeDiff){
|
||||
|
||||
}
|
||||
@Override
|
||||
public void FrameEvent(long now, long InitialTime){
|
||||
gameLogic.Input(PrimaryRuntime.GetEngineInstance(), (now - InitialTime));
|
||||
gameLogic.Update(PrimaryRuntime.GetEngineInstance(), (now - InitialTime));
|
||||
render.render(PrimaryRuntime.GetEngineInstance());
|
||||
}
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering;
|
||||
|
||||
import org.lwjgl.vulkan.VkPipelineVertexInputStateCreateInfo;
|
||||
|
||||
public class EmptyVertexBufferStruct {
|
||||
|
||||
private final VkPipelineVertexInputStateCreateInfo VertexInput;
|
||||
|
||||
public EmptyVertexBufferStruct(){
|
||||
VertexInput = VkPipelineVertexInputStateCreateInfo.calloc();
|
||||
VertexInput.sType$Default();
|
||||
}
|
||||
|
||||
public void CleanUp(){VertexInput.free();}
|
||||
public VkPipelineVertexInputStateCreateInfo GetVertexInput(){return VertexInput;}
|
||||
}
|
||||
|
|
@ -0,0 +1,193 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.DescriptorSetLayout;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.ShaderModule;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.Device;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.vulkan.*;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.nio.LongBuffer;
|
||||
|
||||
import static org.lwjgl.vulkan.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;
|
||||
private final long VulkanPipelineLayout;
|
||||
|
||||
public DefaultPipeline(VulkanContext VkCtx, PipelineBuildInfo BuildInfo){
|
||||
Logger.debug("Creating Pipeline");
|
||||
Device device = VkCtx.GetDevice();
|
||||
try(var MemStack = MemoryStack.stackPush()){
|
||||
LongBuffer longPtr = MemStack.mallocLong(1);
|
||||
ByteBuffer main = MemStack.UTF8("main");
|
||||
ShaderModule[] ShaderModules = BuildInfo.GetShaderModules();
|
||||
int ModuleCount = ShaderModules.length;
|
||||
var ShaderStages = VkPipelineShaderStageCreateInfo.calloc(ModuleCount, MemStack);
|
||||
for(int i = 0; i < ModuleCount; i++){
|
||||
ShaderModule shaderModule = ShaderModules[i];
|
||||
ShaderStages.get(i)
|
||||
.sType$Default()
|
||||
.stage(shaderModule.GetShaderStage())
|
||||
.module(shaderModule.GetHandle())
|
||||
.pName(main);
|
||||
if(shaderModule.GetSpecializationInfo() != null){
|
||||
ShaderStages.get(i).pSpecializationInfo(shaderModule.GetSpecializationInfo());
|
||||
}
|
||||
}
|
||||
|
||||
var AssemblyStateCreateInfo = VkPipelineInputAssemblyStateCreateInfo.calloc(MemStack)
|
||||
.sType$Default()
|
||||
.topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
|
||||
var ViewportCreateStateInfo = VkPipelineViewportStateCreateInfo.calloc(MemStack)
|
||||
.sType$Default()
|
||||
.viewportCount(1)
|
||||
.scissorCount(1);
|
||||
var RasterizationStateCreateInfo = VkPipelineRasterizationStateCreateInfo.calloc(MemStack)
|
||||
.sType(VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO)
|
||||
.polygonMode(VK_POLYGON_MODE_FILL)
|
||||
.cullMode(VK_CULL_MODE_NONE)
|
||||
.frontFace(VK_FRONT_FACE_CLOCKWISE)
|
||||
.lineWidth(1.0f);
|
||||
int sampleCount = EngineConfig.getInstance().GetRenderSampleCount();
|
||||
var MultisampleStateCreateInfo = VkPipelineMultisampleStateCreateInfo.calloc(MemStack)
|
||||
.sType$Default()
|
||||
.rasterizationSamples(sampleCount)
|
||||
.sampleShadingEnable(false)
|
||||
.minSampleShading(1.0f)
|
||||
.pSampleMask(null)
|
||||
.alphaToCoverageEnable(false)
|
||||
.alphaToOneEnable(false);
|
||||
|
||||
VkPipelineDepthStencilStateCreateInfo DepthStencil = null;
|
||||
if(BuildInfo.GetDepthFormat() != VK_FORMAT_UNDEFINED){
|
||||
DepthStencil = VkPipelineDepthStencilStateCreateInfo.calloc(MemStack)
|
||||
.sType(VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO)
|
||||
.depthTestEnable(true)
|
||||
.depthWriteEnable(true)
|
||||
.depthCompareOp(VK_COMPARE_OP_GREATER_OR_EQUAL)
|
||||
.depthBoundsTestEnable(false)
|
||||
.stencilTestEnable(false);
|
||||
}
|
||||
|
||||
|
||||
VkPipelineDynamicStateCreateInfo VulkanPipelineDynamicStateCreateInfo = VkPipelineDynamicStateCreateInfo.calloc(MemStack)
|
||||
.sType$Default()
|
||||
.pDynamicStates(MemStack.ints(
|
||||
VK_DYNAMIC_STATE_VIEWPORT,
|
||||
VK_DYNAMIC_STATE_SCISSOR
|
||||
));
|
||||
|
||||
|
||||
VkPushConstantRange.Buffer VkPushConstRangeBuffer = null;
|
||||
PushConstantsRange[] PushConstRanges = BuildInfo.GetPushConstantRanges();
|
||||
int PushConstCount = PushConstRanges != null ? PushConstRanges.length != 0 ? PushConstRanges.length : 0 : 0;
|
||||
if(PushConstCount > 0){
|
||||
VkPushConstRangeBuffer = VkPushConstantRange.calloc(PushConstCount,MemStack);
|
||||
for(int i = 0; i < PushConstCount; i++){
|
||||
PushConstantsRange pushConstantsRange = PushConstRanges[i];
|
||||
VkPushConstRangeBuffer.get(i)
|
||||
.stageFlags(pushConstantsRange.Stage())
|
||||
.offset(pushConstantsRange.Offset())
|
||||
.size(pushConstantsRange.Size());
|
||||
}
|
||||
}
|
||||
DescriptorSetLayout[] descriptorSetLayouts = BuildInfo.GetDescriptorSetLayouts();
|
||||
int LayoutCount = descriptorSetLayouts != null ? descriptorSetLayouts.length : 0;
|
||||
LongBuffer ppLayout = MemStack.mallocLong(LayoutCount);
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
.pPushConstantRanges(VkPushConstRangeBuffer);
|
||||
|
||||
VulkanUtils.vkCheck(vkCreatePipelineLayout(device.FetchVulkanDevice(), PipelineLayoutCreateInfoPtr,null,longPtr)
|
||||
,"Unable to create new pipeline layout");
|
||||
VulkanPipelineLayout = longPtr.get(0);
|
||||
|
||||
var PipelineCreateInfo = VkGraphicsPipelineCreateInfo.calloc(1,MemStack)
|
||||
.sType$Default()
|
||||
.renderPass(VK_NULL_HANDLE)
|
||||
.pStages(ShaderStages)
|
||||
.pVertexInputState(BuildInfo.GetVertexInputStateCreateInfo())
|
||||
.pInputAssemblyState(AssemblyStateCreateInfo)
|
||||
.pViewportState(ViewportCreateStateInfo)
|
||||
.pRasterizationState(RasterizationStateCreateInfo)
|
||||
.pColorBlendState(ColourBlendState)
|
||||
.pMultisampleState(MultisampleStateCreateInfo)
|
||||
.pDynamicState(VulkanPipelineDynamicStateCreateInfo)
|
||||
.layout(VulkanPipelineLayout)
|
||||
.pNext(RendererCreateInfo);
|
||||
|
||||
|
||||
if(DepthStencil != null){PipelineCreateInfo.pDepthStencilState(DepthStencil);}
|
||||
|
||||
VulkanUtils.vkCheck(vkCreateGraphicsPipelines(device.FetchVulkanDevice(),
|
||||
VkCtx.GetVkPipelineCache().GetVkPipelineCache(), PipelineCreateInfo,
|
||||
null, longPtr),"Could not create new pipeline");
|
||||
VulkanPipeline = longPtr.get(0);
|
||||
}
|
||||
}
|
||||
public long GetVulkanPipeline(){return VulkanPipeline;}
|
||||
public long GetVulkanPipelineLayout(){return VulkanPipelineLayout;}
|
||||
public void CleanUp(VulkanContext VkCtx){
|
||||
Logger.debug("destroying Pipeline");
|
||||
VkDevice vkDevice = VkCtx.GetDevice().FetchVulkanDevice();
|
||||
vkDestroyPipelineLayout(vkDevice,VulkanPipelineLayout,null);
|
||||
vkDestroyPipeline(vkDevice,VulkanPipeline,null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
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;
|
||||
import org.tinylog.Logger;
|
||||
|
|
@ -29,8 +30,8 @@ public class GraphUtils {
|
|||
IntBuffer height = MemStack.mallocInt(1);
|
||||
image = stbi_load(Filename, width, height, channels, 4);
|
||||
if (image == null) {
|
||||
Logger.error("Could not load or find image inputted.");
|
||||
throw new IOException("Image file [" + Filename + "] not loaded: " + stbi_failure_reason());
|
||||
Logger.error("Could not load or find image inputted. Image file [" + Filename + "] not loaded: " + stbi_failure_reason());
|
||||
image = stbi_load(EngineConfig.getInstance().GetDefaultTexturePath(), width, height, channels, 4);
|
||||
}
|
||||
newImage = new ImageSrc(image, width.get(0), height.get(0), channels.get(0));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
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.DisplayToScreen.ImageView;
|
||||
|
||||
|
|
@ -11,8 +12,8 @@ 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)
|
||||
.Usage(Usage | VK_IMAGE_USAGE_SAMPLED_BIT).MemoryUsage(VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT);
|
||||
var ImageData = new Image.ImageData().Width(Width).Height(Height)
|
||||
.Usage(Usage | VK_IMAGE_USAGE_SAMPLED_BIT).Format(Format).MemoryUsage(VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT).SampleCount(EngineConfig.getInstance().GetRenderSampleCount());
|
||||
VkImage = new Image(VkCtx, ImageData);
|
||||
|
||||
int AspectMask = 0;
|
||||
|
|
@ -25,7 +26,7 @@ public class Attachment {
|
|||
DepthAttachment = true;
|
||||
}
|
||||
var ImageViewData = new ImageView.ImageViewData().Format(VkImage.GetFormat()).AspectMask(AspectMask);
|
||||
VkImageView = new ImageView(VkCtx.GetDevice(), VkImage.getVulkanImage(), ImageViewData,false);
|
||||
VkImageView = new ImageView(VkCtx.GetDevice(), VkImage.getVulkanImage(), ImageViewData,DepthAttachment);
|
||||
}
|
||||
|
||||
public Image GetVkImage(){return VkImage;}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
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;
|
||||
|
|
@ -22,12 +23,19 @@ public class Image {
|
|||
private final int Format;
|
||||
private final int MipLevels;
|
||||
private final long VulkanImage;
|
||||
private final int Width;
|
||||
private final int Height;
|
||||
//private final long VulkanMemory;
|
||||
|
||||
public int GetWidth(){return Width;}
|
||||
public int GetHeight(){return Height;}
|
||||
|
||||
public Image(VulkanContext VkCtx, ImageData imageData){
|
||||
try(var MemStack = MemoryStack.stackPush()){
|
||||
this.Format = imageData.Format;
|
||||
this.MipLevels = imageData.MipMapLevels;
|
||||
this.Width = imageData.Width;
|
||||
this.Height = imageData.Height;
|
||||
|
||||
VkImageCreateInfo vkImageCreateInfo = VkImageCreateInfo.calloc(MemStack)
|
||||
.sType$Default()
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ 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;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ 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;
|
||||
|
|
@ -17,25 +18,16 @@ import java.util.UUID;
|
|||
import static org.lwjgl.vulkan.VK10.VK_FORMAT_R8G8B8A8_SRGB;
|
||||
|
||||
public class TextureCache {
|
||||
public static final int MAX_TEXTURES = 100;
|
||||
public static final int MAX_TEXTURES = 500;
|
||||
private final IndexedLinkedHashMap<String, Texture> TextureMap;
|
||||
private final IndexedLinkedHashMap<String, Texture> UnpaddedTextureMap;
|
||||
|
||||
public TextureCache(){
|
||||
TextureMap = new IndexedLinkedHashMap<>();
|
||||
UnpaddedTextureMap = new IndexedLinkedHashMap<>();
|
||||
}
|
||||
|
||||
public Texture AddTexture(VulkanContext VkCtx, String ID, ImageSrc imageSrc, int Format){
|
||||
if(TextureMap.size() > MAX_TEXTURES){
|
||||
throw new IllegalArgumentException("Texture Cache Is Full");
|
||||
}
|
||||
Texture newTexture = TextureMap.get(ID);
|
||||
if(newTexture == null){
|
||||
newTexture = new Texture(VkCtx, ID, imageSrc, Format);
|
||||
TextureMap.put(ID, newTexture);
|
||||
}
|
||||
return newTexture;
|
||||
}
|
||||
public Texture AddTexture(VulkanContext VkCtx, String ID, String TexturePath, int Format) {
|
||||
public Texture AddToMainMap(VulkanContext VkCtx, String ID, String TexturePath, int Format) {
|
||||
ImageSrc imageSrc = null;
|
||||
Texture result = null;
|
||||
try{
|
||||
|
|
@ -50,15 +42,45 @@ public class TextureCache {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
public Texture AddTexture(VulkanContext VkCtx, String ID, ImageSrc imageSrc, int Format){
|
||||
if(TextureMap.size() > MAX_TEXTURES){
|
||||
throw new IllegalArgumentException("Texture Cache Is Full");
|
||||
}
|
||||
Texture newTexture = UnpaddedTextureMap.get(ID);
|
||||
if(newTexture == null){
|
||||
newTexture = new Texture(VkCtx, ID, imageSrc, Format);
|
||||
UnpaddedTextureMap.put(ID, newTexture);
|
||||
TextureMap.put(ID, newTexture);
|
||||
}
|
||||
return newTexture;
|
||||
}
|
||||
public Texture AddTexture(VulkanContext VkCtx, String ID, String TexturePath, int Format) {
|
||||
ImageSrc imageSrc = null;
|
||||
Texture result = null;
|
||||
try{
|
||||
|
||||
imageSrc = GraphUtils.LoadImage(TexturePath);
|
||||
result = AddTexture(VkCtx, ID, imageSrc, Format);
|
||||
} catch (IOException exception){
|
||||
Logger.error("Could not load texture from patch [{}], exception: {}",TexturePath, exception);
|
||||
} finally{
|
||||
if(imageSrc != null){
|
||||
GraphUtils.CleanImageData(imageSrc);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void TransitionTexts(VulkanContext VkCtx, CommandPool CmdPool, Queue queue){
|
||||
Logger.debug("Recording Texture Transition");
|
||||
TextureMap.clear();
|
||||
TextureMap.putAll(UnpaddedTextureMap);
|
||||
int TextureCount = TextureMap.size();
|
||||
if(TextureCount < MAX_TEXTURES){
|
||||
int PaddingTextCount = MAX_TEXTURES - TextureCount;
|
||||
String DefaultTexturePath = EngineConfig.getInstance().GetDefaultTexturePath();
|
||||
for(int i = 0; i < PaddingTextCount; i++){
|
||||
AddTexture(VkCtx, UUID.randomUUID().toString(), DefaultTexturePath, VK_FORMAT_R8G8B8A8_SRGB);
|
||||
AddToMainMap(VkCtx, UUID.randomUUID().toString(), DefaultTexturePath, VK_FORMAT_R8G8B8A8_SRGB);
|
||||
}
|
||||
}
|
||||
var CommandBuffer = new CommandBuffer(VkCtx, CmdPool, true, true);
|
||||
|
|
@ -71,6 +93,7 @@ public class TextureCache {
|
|||
Logger.debug("Recorded Texture Transition");
|
||||
}
|
||||
|
||||
public IndexedLinkedHashMap<String, Texture> GetTextureCache(){return TextureMap;}
|
||||
public List<Texture> GetTextureList(){return new ArrayList<>(TextureMap.values());}
|
||||
public int GetPosition(String ID){
|
||||
int result = -1;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ 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<>();
|
||||
|
|
@ -20,4 +21,11 @@ public class IndexedLinkedHashMap<K,V> extends LinkedHashMap<K,V> {
|
|||
if(!super.containsKey(key)) IndexList.add(key);
|
||||
return super.put(key,value);
|
||||
}
|
||||
//@Override
|
||||
//public void putAll(Map<? extends K, ? extends V> m) {
|
||||
// m.forEach((k, v)->{
|
||||
// put(k,v);
|
||||
// IndexList.add(k);
|
||||
// });
|
||||
//}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,163 +1,10 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.DescriptorSetLayout;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.ShaderModule;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.Device;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.vulkan.*;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.nio.LongBuffer;
|
||||
|
||||
import static org.lwjgl.vulkan.VK10.*;
|
||||
import static org.lwjgl.vulkan.VK13.VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||
|
||||
public class Pipeline {
|
||||
private final long VulkanPipeline;
|
||||
private final long VulkanPipelineLayout;
|
||||
|
||||
public Pipeline(VulkanContext VkCtx, PipelineBuildInfo BuildInfo){
|
||||
Logger.debug("Creating Pipeline");
|
||||
Device device = VkCtx.GetDevice();
|
||||
try(var MemStack = MemoryStack.stackPush()){
|
||||
LongBuffer longPtr = MemStack.mallocLong(1);
|
||||
ByteBuffer main = MemStack.UTF8("main");
|
||||
ShaderModule[] ShaderModules = BuildInfo.GetShaderModules();
|
||||
int ModuleCount = ShaderModules.length;
|
||||
var ShaderStages = VkPipelineShaderStageCreateInfo.calloc(ModuleCount, MemStack);
|
||||
for(int i = 0; i < ModuleCount; i++){
|
||||
ShaderModule shaderModule = ShaderModules[i];
|
||||
ShaderStages.get(i)
|
||||
.sType$Default()
|
||||
.stage(shaderModule.GetShaderStage())
|
||||
.module(shaderModule.GetHandle())
|
||||
.pName(main);
|
||||
}
|
||||
|
||||
var AssemblyStateCreateInfo = VkPipelineInputAssemblyStateCreateInfo.calloc(MemStack)
|
||||
.sType$Default()
|
||||
.topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
|
||||
var ViewportCreateStateInfo = VkPipelineViewportStateCreateInfo.calloc(MemStack)
|
||||
.sType$Default()
|
||||
.viewportCount(1)
|
||||
.scissorCount(1);
|
||||
var RasterizationStateCreateInfo = VkPipelineRasterizationStateCreateInfo.calloc(MemStack)
|
||||
.sType$Default()
|
||||
.polygonMode(VK_POLYGON_MODE_FILL)
|
||||
.cullMode(VK_CULL_MODE_NONE)
|
||||
.frontFace(VK_FRONT_FACE_CLOCKWISE)
|
||||
.lineWidth(1.0f);
|
||||
var MultisampleStateCreateInfo = VkPipelineMultisampleStateCreateInfo.calloc(MemStack)
|
||||
.sType$Default()
|
||||
.rasterizationSamples(VK_SAMPLE_COUNT_1_BIT);
|
||||
|
||||
VkPipelineDepthStencilStateCreateInfo DepthStencil = null;
|
||||
if(BuildInfo.GetDepthFormat() != VK_FORMAT_UNDEFINED){
|
||||
DepthStencil = VkPipelineDepthStencilStateCreateInfo.calloc(MemStack)
|
||||
.sType$Default()
|
||||
.depthTestEnable(true)
|
||||
.depthWriteEnable(true)
|
||||
.depthCompareOp(VK_COMPARE_OP_LESS_OR_EQUAL)
|
||||
.depthBoundsTestEnable(false)
|
||||
.stencilTestEnable(false);
|
||||
}
|
||||
|
||||
|
||||
VkPipelineDynamicStateCreateInfo VulkanPipelineDynamicStateCreateInfo = VkPipelineDynamicStateCreateInfo.calloc(MemStack)
|
||||
.sType$Default()
|
||||
.pDynamicStates(MemStack.ints(
|
||||
VK_DYNAMIC_STATE_VIEWPORT,
|
||||
VK_DYNAMIC_STATE_SCISSOR
|
||||
));
|
||||
|
||||
|
||||
VkPushConstantRange.Buffer VkPushConstRangeBuffer = null;
|
||||
PushConstantsRange[] PushConstRanges = BuildInfo.GetPushConstantRanges();
|
||||
int PushConstCount = PushConstRanges.length != 0 ? PushConstRanges.length : 0;
|
||||
if(PushConstCount > 0){
|
||||
VkPushConstRangeBuffer = VkPushConstantRange.calloc(PushConstCount,MemStack);
|
||||
for(int i = 0; i < PushConstCount; i++){
|
||||
PushConstantsRange pushConstantsRange = PushConstRanges[i];
|
||||
VkPushConstRangeBuffer.get(i)
|
||||
.stageFlags(pushConstantsRange.Stage())
|
||||
.offset(pushConstantsRange.Offset())
|
||||
.size(pushConstantsRange.Size());
|
||||
}
|
||||
}
|
||||
DescriptorSetLayout[] descriptorSetLayouts = BuildInfo.GetDescriptorSetLayouts();
|
||||
int LayoutCount = descriptorSetLayouts != null ? descriptorSetLayouts.length : 0;
|
||||
LongBuffer ppLayout = MemStack.mallocLong(LayoutCount);
|
||||
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_SRC_ALPHA)
|
||||
.dstAlphaBlendFactor(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)
|
||||
.pPushConstantRanges(VkPushConstRangeBuffer);
|
||||
|
||||
VulkanUtils.vkCheck(vkCreatePipelineLayout(device.FetchVulkanDevice(), PipelineLayoutCreateInfoPtr,null,longPtr)
|
||||
,"Unable to create new pipeline layout");
|
||||
VulkanPipelineLayout = longPtr.get(0);
|
||||
|
||||
var PipelineCreateInfo = VkGraphicsPipelineCreateInfo.calloc(1,MemStack)
|
||||
.sType$Default()
|
||||
.renderPass(VK_NULL_HANDLE)
|
||||
.pStages(ShaderStages)
|
||||
.pVertexInputState(BuildInfo.GetVertexInputStateCreateInfo())
|
||||
.pInputAssemblyState(AssemblyStateCreateInfo)
|
||||
.pViewportState(ViewportCreateStateInfo)
|
||||
.pRasterizationState(RasterizationStateCreateInfo)
|
||||
.pColorBlendState(ColourBlendState)
|
||||
.pMultisampleState(MultisampleStateCreateInfo)
|
||||
.pDynamicState(VulkanPipelineDynamicStateCreateInfo)
|
||||
.layout(VulkanPipelineLayout)
|
||||
.pNext(RendererCreateInfo);
|
||||
|
||||
if(DepthStencil != null){PipelineCreateInfo.pDepthStencilState(DepthStencil);}
|
||||
|
||||
VulkanUtils.vkCheck(vkCreateGraphicsPipelines(device.FetchVulkanDevice(),
|
||||
VkCtx.GetVkPipelineCache().GetVkPipelineCache(), PipelineCreateInfo,
|
||||
null, longPtr),"Could not create new pipeline");
|
||||
VulkanPipeline = longPtr.get(0);
|
||||
}
|
||||
}
|
||||
public long GetVulkanPipeline(){return VulkanPipeline;}
|
||||
public long GetVulkanPipelineLayout(){return VulkanPipelineLayout;}
|
||||
public void CleanUp(VulkanContext VkCtx){
|
||||
Logger.debug("destroying Pipeline");
|
||||
VkDevice vkDevice = VkCtx.GetDevice().FetchVulkanDevice();
|
||||
vkDestroyPipelineLayout(vkDevice,VulkanPipelineLayout,null);
|
||||
vkDestroyPipeline(vkDevice,VulkanPipeline,null);
|
||||
}
|
||||
public interface Pipeline {
|
||||
|
||||
public long GetVulkanPipeline();
|
||||
public long GetVulkanPipelineLayout();
|
||||
public void CleanUp(VulkanContext VkCtx);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,174 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.DescriptorSetLayout;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.Device;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.vulkan.*;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.nio.LongBuffer;
|
||||
|
||||
import static org.lwjgl.vulkan.VK10.*;
|
||||
|
||||
public class VoxelPipeline implements Pipeline{
|
||||
private final long VulkanPipeline;
|
||||
private final long VulkanPipelineLayout;
|
||||
|
||||
public VoxelPipeline(VulkanContext VkCtx, PipelineBuildInfo BuildInfo){
|
||||
Device device = VkCtx.GetDevice();
|
||||
try(var MemStack = MemoryStack.stackPush()) {
|
||||
LongBuffer longPtr = MemStack.mallocLong(1);
|
||||
VkPushConstantRange.Buffer VkPushConstRangeBuffer = null;
|
||||
PushConstantsRange[] PushConstRanges = BuildInfo.GetPushConstantRanges();
|
||||
int PushConstCount = PushConstRanges.length != 0 ? PushConstRanges.length : 0;
|
||||
if (PushConstCount > 0) {
|
||||
VkPushConstRangeBuffer = VkPushConstantRange.calloc(PushConstCount, MemStack);
|
||||
for (int i = 0; i < PushConstCount; i++) {
|
||||
PushConstantsRange pushConstantsRange = PushConstRanges[i];
|
||||
VkPushConstRangeBuffer.get(i)
|
||||
.stageFlags(pushConstantsRange.Stage())
|
||||
.offset(pushConstantsRange.Offset())
|
||||
.size(pushConstantsRange.Size());
|
||||
}
|
||||
}
|
||||
DescriptorSetLayout[] descriptorSetLayouts = BuildInfo.GetDescriptorSetLayouts();
|
||||
int LayoutCount = descriptorSetLayouts != null ? descriptorSetLayouts.length : 0;
|
||||
LongBuffer ppLayout = MemStack.mallocLong(LayoutCount);
|
||||
for (int i = 0; i < LayoutCount; i++) {
|
||||
ppLayout.put(i, descriptorSetLayouts[i].GetVkDescriptorLayout());
|
||||
}
|
||||
|
||||
var PipelineLayoutCreateInfoPtr = VkPipelineLayoutCreateInfo.calloc(MemStack)
|
||||
.sType$Default()
|
||||
.pSetLayouts(ppLayout)
|
||||
.pPushConstantRanges(VkPushConstRangeBuffer);
|
||||
|
||||
VulkanUtils.vkCheck(vkCreatePipelineLayout(device.FetchVulkanDevice(), PipelineLayoutCreateInfoPtr, null, longPtr)
|
||||
, "Unable to create new pipeline layout");
|
||||
VulkanPipelineLayout = longPtr.get(0);
|
||||
VulkanPipeline = CreateVoxelPipeline(VkCtx,device.FetchVulkanDevice(), 0, VulkanPipelineLayout,MemStack);
|
||||
}
|
||||
}
|
||||
|
||||
public static long CreatePipelineLayout(VkDevice device,LongBuffer DescriptorSetLayout, MemoryStack MemStack){
|
||||
VkDescriptorSetLayoutBinding.Buffer BindingBuffer = VkDescriptorSetLayoutBinding.calloc(2,MemStack);
|
||||
BindingBuffer.get(0)
|
||||
.binding(0)
|
||||
.descriptorType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
|
||||
.descriptorCount(1)
|
||||
.stageFlags(VK_SHADER_STAGE_VERTEX_BIT);
|
||||
BindingBuffer.get(1)
|
||||
.binding(1)
|
||||
.descriptorType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
|
||||
.descriptorCount(1)
|
||||
.stageFlags(VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
VkDescriptorSetLayoutCreateInfo LayoutInfo = VkDescriptorSetLayoutCreateInfo.calloc(MemStack)
|
||||
.sType$Default()
|
||||
.pBindings(BindingBuffer);
|
||||
|
||||
LongBuffer LongPtr = MemStack.mallocLong(1);
|
||||
VulkanUtils.vkCheck(vkCreateDescriptorSetLayout(device, LayoutInfo,
|
||||
null, LongPtr),"Could not create new Descriptor Set Layout");
|
||||
Long pDescriptorSetLayout = LongPtr.get(0);
|
||||
DescriptorSetLayout.put(0,pDescriptorSetLayout);
|
||||
LongBuffer LayoutPointer = MemStack.longs(pDescriptorSetLayout);
|
||||
VkPipelineLayoutCreateInfo PipelineLayoutInfo = VkPipelineLayoutCreateInfo.calloc(MemStack)
|
||||
.sType$Default()
|
||||
.pSetLayouts(LayoutPointer);
|
||||
VulkanUtils.vkCheck(vkCreatePipelineLayout(device, PipelineLayoutInfo,
|
||||
null, LongPtr),"Could not create Pipeline Layout");
|
||||
return LongPtr.get(0);
|
||||
}
|
||||
|
||||
public static long CreateVoxelPipeline(VulkanContext VkCtx,VkDevice device, long RenderPass, long PipelineLayout, MemoryStack MemStack) {
|
||||
LongBuffer longPtr = MemStack.mallocLong(1);
|
||||
VkVertexInputBindingDescription.Buffer BindingDescriptionBuffer = VkVertexInputBindingDescription.calloc(1, MemStack)
|
||||
.binding(0)
|
||||
.stride(5)
|
||||
.inputRate(VK_VERTEX_INPUT_RATE_VERTEX);
|
||||
VkVertexInputAttributeDescription.Buffer AttributeDescriptionsBuffer = VkVertexInputAttributeDescription.calloc(2, MemStack);
|
||||
|
||||
AttributeDescriptionsBuffer.get(0)
|
||||
.location(0)
|
||||
.binding(0)
|
||||
.format(VK_FORMAT_R8G8B8_UINT)
|
||||
.offset(0);
|
||||
AttributeDescriptionsBuffer.get(1)
|
||||
.location(1)
|
||||
.binding(0)
|
||||
.format(VK_FORMAT_R8G8_UINT);
|
||||
VkPipelineVertexInputStateCreateInfo VertexInputInfo = VkPipelineVertexInputStateCreateInfo.calloc(MemStack)
|
||||
.sType(VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO)
|
||||
.pVertexBindingDescriptions(BindingDescriptionBuffer)
|
||||
.pVertexAttributeDescriptions(AttributeDescriptionsBuffer);
|
||||
var AssemblyStateCreateInfo = VkPipelineInputAssemblyStateCreateInfo.calloc(MemStack)
|
||||
.sType(VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO)
|
||||
.topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST).primitiveRestartEnable(false);
|
||||
var ViewportCreateStateInfo = VkPipelineViewportStateCreateInfo.calloc(MemStack)
|
||||
.sType$Default()
|
||||
.viewportCount(1)
|
||||
.scissorCount(1);
|
||||
var RasterizationStateCreateInfo = VkPipelineRasterizationStateCreateInfo.calloc(MemStack)
|
||||
.sType(VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO)
|
||||
.depthClampEnable(false)
|
||||
.rasterizerDiscardEnable(false)
|
||||
.polygonMode(VK_POLYGON_MODE_FILL)
|
||||
.cullMode(VK_CULL_MODE_BACK_BIT)
|
||||
.frontFace(VK_FRONT_FACE_CLOCKWISE)
|
||||
.lineWidth(1.0f)
|
||||
.depthBiasEnable(false);
|
||||
var MultisampleStateCreateInfo = VkPipelineMultisampleStateCreateInfo.calloc(MemStack)
|
||||
.sType$Default()
|
||||
.sampleShadingEnable(false)
|
||||
.rasterizationSamples(VK_SAMPLE_COUNT_1_BIT);
|
||||
VkPipelineColorBlendAttachmentState.Buffer ColourBlendAttachment = VkPipelineColorBlendAttachmentState.calloc(1, MemStack)
|
||||
.colorWriteMask(VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT)
|
||||
.blendEnable(false);
|
||||
VkPipelineColorBlendStateCreateInfo ColourBlending = VkPipelineColorBlendStateCreateInfo.calloc(MemStack)
|
||||
.sType(VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO)
|
||||
.logicOpEnable(false)
|
||||
.pAttachments(ColourBlendAttachment);
|
||||
|
||||
VkGraphicsPipelineCreateInfo.Buffer PipelineInfo = VkGraphicsPipelineCreateInfo.calloc(1)
|
||||
.sType(VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO)
|
||||
.pVertexInputState(VertexInputInfo)
|
||||
.pInputAssemblyState(AssemblyStateCreateInfo)
|
||||
.pViewportState(ViewportCreateStateInfo)
|
||||
.pRasterizationState(RasterizationStateCreateInfo)
|
||||
.pMultisampleState(MultisampleStateCreateInfo)
|
||||
.pColorBlendState(ColourBlending)
|
||||
.layout(PipelineLayout)
|
||||
.renderPass(RenderPass)
|
||||
.subpass(0);
|
||||
VulkanUtils.vkCheck(vkCreateGraphicsPipelines(device,
|
||||
VkCtx.GetVkPipelineCache().GetVkPipelineCache(), PipelineInfo,
|
||||
null, longPtr),"Could not create new pipeline");
|
||||
|
||||
// Clean up allocation structs
|
||||
PipelineInfo.free(); ColourBlending.free(); ColourBlendAttachment.free();
|
||||
MultisampleStateCreateInfo.free(); RasterizationStateCreateInfo.free(); ViewportCreateStateInfo.free();
|
||||
AssemblyStateCreateInfo.free(); VertexInputInfo.free(); AssemblyStateCreateInfo.free();
|
||||
BindingDescriptionBuffer.free();
|
||||
|
||||
return longPtr.get(0);
|
||||
}
|
||||
@Override
|
||||
public long GetVulkanPipeline() {
|
||||
return VulkanPipeline;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long GetVulkanPipelineLayout() {
|
||||
return VulkanPipelineLayout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void CleanUp(VulkanContext VkCtx) {
|
||||
Logger.debug("destroying Pipeline");
|
||||
VkDevice vkDevice = VkCtx.GetDevice().FetchVulkanDevice();
|
||||
vkDestroyPipelineLayout(vkDevice,VulkanPipelineLayout,null);
|
||||
vkDestroyPipeline(vkDevice,VulkanPipeline,null);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,219 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.PostProcessing;
|
||||
|
||||
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.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.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 java.nio.FloatBuffer;
|
||||
import java.nio.LongBuffer;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.lwjgl.vulkan.VK10.*;
|
||||
import static org.lwjgl.vulkan.VK13.*;
|
||||
|
||||
public class PostProcess {
|
||||
public static final int COLOUR_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||
private static final String DESCRIPTOR_ID_ATTACHMENT = "POST_DESC_ID_ATT";
|
||||
private static final String DESCRIPTOR_ID_SCREEN_SIZE = "POST_DESC_ID_SCREEN_SIZE";
|
||||
private static final String MULTI_PASS_FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/multi-sampled_post_process_frag.glsl";
|
||||
private static final String MULTI_PASS_FRAGMENT_SHADER_FILE_SPV = MULTI_PASS_FRAGMENT_SHADER_FILE_GLSL + ".spv";
|
||||
private static final String SINGLE_PASS_FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/post_process_frag.glsl";
|
||||
private static final String SINGLE_PASS_FRAGMENT_SHADER_FILE_SPV = SINGLE_PASS_FRAGMENT_SHADER_FILE_GLSL + ".spv";
|
||||
private static final String VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/post_process_vtx.glsl";
|
||||
private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv";
|
||||
|
||||
private final DescriptorSetLayout AttachmentDescriptorSetLayout;
|
||||
private final VkClearValue ClearValueColour;
|
||||
private final DescriptorSetLayout FragmentUniformDescriptorSetLayout;
|
||||
private final Pipeline pipeline;
|
||||
private final VulkanBuffer ScreenSizeBuffer;
|
||||
private final SpecializationConstants specConstants;
|
||||
private final TextureSampler textureSampler;
|
||||
private Attachment ColourAttachment;
|
||||
private VkRenderingAttachmentInfo.Buffer ColourAttachmentInfo;
|
||||
private VkRenderingInfo RenderingInfo;
|
||||
|
||||
public PostProcess(VulkanContext VkCtx, Attachment SrcAttachment){
|
||||
ClearValueColour = VkClearValue.calloc();
|
||||
ClearValueColour.color(c->c.float32(0,0.0f).float32(1,0.0f).float32(2,0.0f).float32(3,0.0f));
|
||||
|
||||
ColourAttachment = CreateColourAttachment(VkCtx);
|
||||
ColourAttachmentInfo = CreateColourAttachmentInfo(ColourAttachment,ClearValueColour);
|
||||
RenderingInfo = CreateRenderInfo(ColourAttachment,ColourAttachmentInfo);
|
||||
|
||||
var TextureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_REPEAT,VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK,1,true);
|
||||
textureSampler = new TextureSampler(VkCtx, TextureSamplerInfo);
|
||||
|
||||
var LayoutInfo = new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,0,1,VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
AttachmentDescriptorSetLayout = new DescriptorSetLayout(VkCtx, LayoutInfo);
|
||||
CreateAttachmentDescriptorSet(VkCtx, AttachmentDescriptorSetLayout, SrcAttachment,textureSampler);
|
||||
|
||||
LayoutInfo = new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0,1,VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
FragmentUniformDescriptorSetLayout = new DescriptorSetLayout(VkCtx, LayoutInfo);
|
||||
ScreenSizeBuffer = VulkanUtils.CreateHostVisibleBuffer(VkCtx, VulkanUtils.VEC2_SIZE, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,DESCRIPTOR_ID_SCREEN_SIZE,FragmentUniformDescriptorSetLayout);
|
||||
SetScreenSizeBuffer(VkCtx);
|
||||
|
||||
specConstants = new SpecializationConstants();
|
||||
ShaderModule[] shaderModules = CreateShaderModules(VkCtx, specConstants);
|
||||
|
||||
pipeline = CreatePipeline(VkCtx, shaderModules, new DescriptorSetLayout[]{AttachmentDescriptorSetLayout, FragmentUniformDescriptorSetLayout});
|
||||
Arrays.asList(shaderModules).forEach(shader->shader.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);
|
||||
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, Attachment attachment, TextureSampler textureSampler){
|
||||
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){
|
||||
String ShaderPath = SINGLE_PASS_FRAGMENT_SHADER_FILE_GLSL;
|
||||
if(EngineConfig.getInstance().RecompileShaders()){
|
||||
ShaderCompiler.CompileGLSLShaderOnChange(VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader);
|
||||
if(EngineConfig.getInstance().RenderAA() > 1) ShaderPath = MULTI_PASS_FRAGMENT_SHADER_FILE_GLSL;
|
||||
ShaderCompiler.CompileGLSLShaderOnChange(ShaderPath, Shaderc.shaderc_glsl_fragment_shader);
|
||||
}
|
||||
ShaderPath = SINGLE_PASS_FRAGMENT_SHADER_FILE_SPV;
|
||||
if(EngineConfig.getInstance().RenderAA() > 1) ShaderPath = MULTI_PASS_FRAGMENT_SHADER_FILE_SPV;
|
||||
return new ShaderModule[]{
|
||||
new ShaderModule(VkCtx,VK_SHADER_STAGE_VERTEX_BIT,VERTEX_SHADER_FILE_SPV,null),
|
||||
new ShaderModule(VkCtx,VK_SHADER_STAGE_FRAGMENT_BIT,ShaderPath,specConstants.GetSpecializationInfo())
|
||||
};
|
||||
}
|
||||
|
||||
public void Render(VulkanContext VkCtx, CommandBuffer commandBuffer, Attachment SrcAttachment){
|
||||
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());
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
public void Resize(VulkanContext VkCtx, Attachment SrcAttachment){
|
||||
RenderingInfo.free();;
|
||||
ColourAttachment.CleanUp(VkCtx);
|
||||
ColourAttachmentInfo.free();
|
||||
ColourAttachment = CreateColourAttachment(VkCtx);
|
||||
ColourAttachmentInfo = CreateColourAttachmentInfo(ColourAttachment,ClearValueColour);
|
||||
RenderingInfo = CreateRenderInfo(ColourAttachment,ColourAttachmentInfo);
|
||||
|
||||
DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator();
|
||||
DescriptorSet descriptorSet = descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_ATTACHMENT);
|
||||
descriptorSet.SetImage(VkCtx.GetDevice(),SrcAttachment.GetVkImageView(),textureSampler,0);
|
||||
|
||||
SetScreenSizeBuffer(VkCtx);
|
||||
}
|
||||
|
||||
private void SetScreenSizeBuffer(VulkanContext VkCtx){
|
||||
long MappedMemory = ScreenSizeBuffer.MapMemory(VkCtx);
|
||||
FloatBuffer dataBuffer = MemoryUtil.memFloatBuffer(MappedMemory,(int)ScreenSizeBuffer.GetRequestedSize());
|
||||
VkExtent2D SwapChainExtent = VkCtx.GetSwapChain().GetSwapChainExtent();
|
||||
dataBuffer.put(0,SwapChainExtent.width());
|
||||
dataBuffer.put(1,SwapChainExtent.height());
|
||||
ScreenSizeBuffer.UnMapMemory(VkCtx);
|
||||
}
|
||||
|
||||
public Attachment GetAttachment(){return ColourAttachment;}
|
||||
|
||||
public void CleanUp(VulkanContext VkCtx){
|
||||
ClearValueColour.free();
|
||||
ColourAttachment.CleanUp(VkCtx);
|
||||
textureSampler.CleanUp(VkCtx);
|
||||
AttachmentDescriptorSetLayout.CleanUp(VkCtx);
|
||||
FragmentUniformDescriptorSetLayout.CleanUp(VkCtx);
|
||||
pipeline.CleanUp(VkCtx);
|
||||
RenderingInfo.free();
|
||||
ColourAttachmentInfo.free();
|
||||
ScreenSizeBuffer.cleanup(VkCtx);
|
||||
specConstants.CleanUp();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.PostProcessing;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.lwjgl.vulkan.VkSpecializationInfo;
|
||||
import org.lwjgl.vulkan.VkSpecializationMapEntry;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class SpecializationConstants {
|
||||
|
||||
private final ByteBuffer data;
|
||||
private final VkSpecializationMapEntry.Buffer SpecializationEntryMap;
|
||||
private final VkSpecializationInfo SpecializationInfo;
|
||||
|
||||
public SpecializationConstants(){
|
||||
var EngineCfg = EngineConfig.getInstance();
|
||||
data = MemoryUtil.memAlloc(VulkanUtils.INT_SIZE);
|
||||
data.putInt(EngineCfg.RenderAA());
|
||||
data.flip();
|
||||
|
||||
SpecializationEntryMap = VkSpecializationMapEntry.calloc(1);
|
||||
SpecializationEntryMap.get(0)
|
||||
.constantID(0)
|
||||
.size(VulkanUtils.INT_SIZE)
|
||||
.offset(0);
|
||||
|
||||
SpecializationInfo = VkSpecializationInfo.calloc();
|
||||
SpecializationInfo.pData(data).pMapEntries(SpecializationEntryMap);
|
||||
}
|
||||
|
||||
public void CleanUp(){
|
||||
MemoryUtil.memFree(SpecializationEntryMap);
|
||||
SpecializationInfo.free();
|
||||
MemoryUtil.memFree(data);
|
||||
}
|
||||
public VkSpecializationInfo GetSpecializationInfo(){return SpecializationInfo;}
|
||||
}
|
||||
|
|
@ -6,6 +6,8 @@ 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;
|
||||
|
||||
import java.io.File;
|
||||
|
|
@ -18,12 +20,14 @@ import java.nio.file.Files;
|
|||
public class ShaderModule {
|
||||
private final long Handle;
|
||||
private final int ShaderStage;
|
||||
private final VkSpecializationInfo SpecializationInfo;
|
||||
|
||||
public ShaderModule(VulkanContext VkCtx, int ShaderStage, String ShaderSPVFile){
|
||||
public ShaderModule(VulkanContext VkCtx, int ShaderStage, String ShaderSPVFile,VkSpecializationInfo SpecializationInfo){
|
||||
try{
|
||||
byte[] Contents = Files.readAllBytes(new File(ShaderSPVFile).toPath());
|
||||
Handle = CreateShaderModule(VkCtx, Contents);
|
||||
this.ShaderStage = ShaderStage;
|
||||
this.SpecializationInfo = SpecializationInfo;
|
||||
} catch(IOException exception){
|
||||
Logger.error("Cannot Read Shader Files",exception);
|
||||
throw new RuntimeException(exception);
|
||||
|
|
@ -42,6 +46,8 @@ public class ShaderModule {
|
|||
}
|
||||
}
|
||||
|
||||
public VkSpecializationInfo GetSpecializationInfo(){return SpecializationInfo;}
|
||||
|
||||
public void CleanUp(VulkanContext VkCtx){
|
||||
vkDestroyShaderModule(VkCtx.GetDevice().FetchVulkanDevice(), Handle, null);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,225 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Display.Render;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.InitVoxelData;
|
||||
|
||||
import org.joml.Vector4f;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
public class CompatibleVoxelMesh {
|
||||
private static final int VERTEX_STRIDE = 6;
|
||||
public static List<VoxelModelInitData> voxelModels = new ArrayList<>();
|
||||
public static List<String> TexturePaths = new ArrayList<>();
|
||||
private Render renderInstance;
|
||||
private float[] VertexArray;
|
||||
private int[] IndicesArray;
|
||||
private final String ID;
|
||||
private boolean[] Faces = new boolean[]{false,false,false,false,false,false};
|
||||
private int[] Textureindex = new int[6];
|
||||
private Vector4f[] DiffuseColours = new Vector4f[]{new Vector4f(0.6f, 0.6f, 0.6f, 1.0f),new Vector4f(0.5f, 0.5f, 0.5f, 1.0f),new Vector4f(0.4f, 0.4f, 0.4f, 1.0f),new Vector4f(0.5f, 0.5f, 0.5f, 1.0f),new Vector4f(0.7f, 0.7f, 0.7f, 1.0f),new Vector4f(0.3f, 0.3f, 0.3f, 1.0f)};
|
||||
|
||||
static{
|
||||
TexturePaths.add("resources/EngineResources/Texture/DefaultTexture.png");
|
||||
}
|
||||
|
||||
public enum FaceDirection{
|
||||
North(0),
|
||||
South(2),
|
||||
East(1),
|
||||
West(3),
|
||||
Up(4),
|
||||
Down(5);
|
||||
|
||||
private final int value;
|
||||
|
||||
FaceDirection(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
// 3. Add a getter method to access the number
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public record VoxelModelInitData(VoxelModelData voxelModel, List<MaterialData> materialData){}
|
||||
public record VoxelModelData(String ID, List<MeshData> meshes, FloatBuffer vertexBuffer, IntBuffer indexBuffer){}
|
||||
public record VoxelMeshData(String ID, FloatBuffer vertexBuffer, IntBuffer indexBuffer, int VertexCount, int IndexCount){}
|
||||
|
||||
public CompatibleVoxelMesh(String VoxelID){
|
||||
VertexArray = new float[6 * 20];
|
||||
IndicesArray = new int[6 * 6];
|
||||
ID = VoxelID;
|
||||
}
|
||||
public CompatibleVoxelMesh(Render rendererInstance, String VoxelID){
|
||||
renderInstance = rendererInstance;
|
||||
VertexArray = new float[6 * 20];
|
||||
IndicesArray = new int[6 * 6];
|
||||
ID = VoxelID;
|
||||
}
|
||||
public CompatibleVoxelMesh SetSideTexture(int SideNumber, String TextureID){
|
||||
int index = TexturePaths.indexOf(TextureID);
|
||||
if(index < 0){
|
||||
TexturePaths.add(TextureID);
|
||||
index = TexturePaths.indexOf(TextureID);
|
||||
}
|
||||
Textureindex[SideNumber] = index;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CompatibleVoxelMesh CreateMeshFace(FaceDirection faceDirection, String TextureID){
|
||||
int side = faceDirection.getValue();
|
||||
Faces[side] = true;
|
||||
|
||||
int index = TexturePaths.indexOf(TextureID);
|
||||
if (index < 0) {
|
||||
TexturePaths.add(TextureID);
|
||||
index = TexturePaths.indexOf(TextureID);
|
||||
}
|
||||
Textureindex[side] = index;
|
||||
|
||||
float[] srcFace = switch (faceDirection) {
|
||||
case North -> FrontFace;
|
||||
case South -> BackFace;
|
||||
case East -> RightFace;
|
||||
case West -> LeftFace;
|
||||
case Up -> TopFace;
|
||||
case Down -> BottomFace;
|
||||
};
|
||||
|
||||
System.arraycopy(srcFace, 0, VertexArray, side * 20, 20);
|
||||
return this;
|
||||
}
|
||||
|
||||
public static InitVoxelData GetVoxelModelsGenerated(){
|
||||
List<VoxelModelData> models = new ArrayList<>();
|
||||
List<MaterialData> materials = new ArrayList<>();
|
||||
for(int i = 0; i < voxelModels.size(); i++){
|
||||
models.add(voxelModels.get(i).voxelModel());
|
||||
materials.addAll(voxelModels.get(i).materialData());
|
||||
}
|
||||
return new InitVoxelData(models,materials);
|
||||
}
|
||||
|
||||
public CompatibleVoxelMesh CompileMesh(){
|
||||
CompileMeshNoReturn();
|
||||
return this;
|
||||
}
|
||||
|
||||
public void CompileMeshNoReturn() {
|
||||
List<MeshData> meshes = new ArrayList<>();
|
||||
List<MaterialData> materials = new ArrayList<>();
|
||||
List<String> AddedMaterials = new ArrayList<>();
|
||||
int faceCount = 0;
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (Faces[i]) {
|
||||
faceCount++;
|
||||
}
|
||||
}
|
||||
VoxelMeshData data = new VoxelMeshData(ID, MemoryUtil.memAllocFloat(20*faceCount), MemoryUtil.memAllocInt(6*faceCount), 4, 6);
|
||||
float[] vertexArray = new float[faceCount * 20];
|
||||
faceCount = 0;
|
||||
for(int i = 0; i < 6; i++){
|
||||
if(Faces[i]){
|
||||
String TextureID = "N/A_NULL";
|
||||
if(Textureindex[i] >= 0 && Textureindex[i] < TexturePaths.size()) TextureID = TexturePaths.get(Textureindex[i]);
|
||||
else TextureID = "resources/EngineResources/Texture/DefaultTexture.png";
|
||||
if(!AddedMaterials.contains(TextureID)) {
|
||||
materials.add(new MaterialData(TextureID, TextureID,DiffuseColours[i]));
|
||||
AddedMaterials.add(TextureID);
|
||||
}
|
||||
for(int j = 0; j < 20; j++){
|
||||
vertexArray[(faceCount * 20) + j] = VertexArray[(i * 20) + j];
|
||||
}
|
||||
if(!Objects.equals(TextureID, "N/A_NULL")){
|
||||
meshes.add(new MeshData(ID + "_" + i, TextureID,faceCount * 20, 20, faceCount * 6, 6));
|
||||
}
|
||||
int offset = faceCount * 4;
|
||||
data.indexBuffer.put(offset);
|
||||
data.indexBuffer.put(offset + 1);
|
||||
data.indexBuffer.put(offset + 2);
|
||||
data.indexBuffer.put(offset + 2);
|
||||
data.indexBuffer.put(offset + 3);
|
||||
data.indexBuffer.put(offset);
|
||||
faceCount++;
|
||||
}
|
||||
}
|
||||
Logger.debug("Voxel with [{}] sides generated",faceCount);
|
||||
data.indexBuffer.flip();
|
||||
data.vertexBuffer.put(vertexArray).flip();
|
||||
VoxelModelData model = new VoxelModelData(ID,meshes, data.vertexBuffer, data.indexBuffer);
|
||||
voxelModels.add(new VoxelModelInitData(model, materials));
|
||||
}
|
||||
|
||||
public float[] FetchFaceWithTexture(float TextureIndex, FaceDirection direction){
|
||||
float[] meshData = new float[20];
|
||||
this.Textureindex[direction.getValue()] = (int) TextureIndex;
|
||||
switch (direction){
|
||||
case North -> {
|
||||
System.arraycopy(FrontFace, 0, meshData, 0, 20);
|
||||
}
|
||||
case South -> {
|
||||
System.arraycopy(BackFace, 0, meshData, 0, 20);
|
||||
}
|
||||
case East -> {
|
||||
System.arraycopy(RightFace, 0, meshData, 0, 20);
|
||||
}
|
||||
case West -> {
|
||||
System.arraycopy(LeftFace, 0, meshData, 0, 20);
|
||||
}
|
||||
case Up -> {
|
||||
System.arraycopy(TopFace, 0, meshData, 0, 20);
|
||||
}
|
||||
case Down -> {
|
||||
System.arraycopy(BottomFace, 0, meshData, 0, 20);
|
||||
}
|
||||
}
|
||||
return meshData;
|
||||
}
|
||||
|
||||
public static final float[] FrontFace = new float[]{
|
||||
-0.5f, -0.5f, 0.5f, 0.0f, 1.0f,
|
||||
0.5f, -0.5f, 0.5f, 1.0f, 1.0f,
|
||||
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
|
||||
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f
|
||||
};
|
||||
public static final float[] BackFace = new float[]{
|
||||
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
|
||||
-0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
|
||||
-0.5f, 0.5f, -0.5f, 1.0f, 0.0f,
|
||||
0.5f, 0.5f, -0.5f, 0.0f, 0.0f
|
||||
};
|
||||
public static final float[] TopFace = new float[]{
|
||||
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
|
||||
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
|
||||
0.5f, 0.5f, -0.5f, 1.0f, 0.0f,
|
||||
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f
|
||||
};
|
||||
public static final float[] BottomFace = new float[]{
|
||||
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
|
||||
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
|
||||
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
|
||||
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f
|
||||
};
|
||||
public static final float[] LeftFace = new float[]{
|
||||
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
|
||||
-0.5f, -0.5f, 0.5f, 1.0f, 1.0f,
|
||||
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
|
||||
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f
|
||||
};
|
||||
public static final float[] RightFace = new float[]{
|
||||
0.5f, -0.5f, 0.5f, 0.0f, 1.0f,
|
||||
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
|
||||
0.5f, 0.5f, -0.5f, 1.0f, 0.0f,
|
||||
0.5f, 0.5f, 0.5f, 0.0f, 0.0f
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -56,15 +56,19 @@ public class MaterialsCache {
|
|||
if(ValidTexture){
|
||||
Logger.debug("Loading Texture [{}]",TexturePath);
|
||||
Texture newTexture = textureCache.AddTexture(VkCtx, TexturePath, TexturePath, VK_FORMAT_R8G8B8A8_SRGB);
|
||||
TransparentTexture = newTexture.HasTransparency();
|
||||
if(newTexture == null) {
|
||||
TransparentTexture = false;
|
||||
TexturePath = "resources/EngineResources/Texture/DefaultTexture.png";
|
||||
}
|
||||
else TransparentTexture = newTexture.HasTransparency();
|
||||
} else{
|
||||
TexturePath = "resources/EngineResources/Texture/DefaultTexture.png";
|
||||
TransparentTexture = Material.DiffuseColour().w < 1.0f;
|
||||
}
|
||||
VulkanMaterial newMaterial = new VulkanMaterial(Material.ID(),TransparentTexture);
|
||||
MaterialsMap.put(newMaterial.ID(), newMaterial);
|
||||
Logger.trace(Material.toString());
|
||||
data.position(Offset);
|
||||
Material.DiffuseColour().get(data);
|
||||
Material.DiffuseColour().get(Offset,data);
|
||||
Logger.debug("Set Diffuse Colour -> [{}]",Material.DiffuseColour());
|
||||
data.putInt(Offset + VulkanUtils.VEC4_SIZE, ValidTexture ? 1 : 0);
|
||||
data.putInt(Offset + VulkanUtils.VEC4_SIZE + VulkanUtils.INT_SIZE, textureCache.GetPosition(TexturePath));
|
||||
|
|
@ -76,6 +80,7 @@ public class MaterialsCache {
|
|||
}
|
||||
data.position(0);
|
||||
|
||||
SrcBuffer.Flush(VkCtx);
|
||||
SrcBuffer.UnMapMemory(VkCtx);
|
||||
transferBuffer.RecordTransferCommand(CmdBuffer);
|
||||
CmdBuffer.EndRecording();
|
||||
|
|
@ -91,6 +96,7 @@ public class MaterialsCache {
|
|||
}
|
||||
}
|
||||
|
||||
public IndexedLinkedHashMap<String, VulkanMaterial> GetMaterialCache(){return MaterialsMap;}
|
||||
public VulkanMaterial GetMaterial(String ID){return MaterialsMap.get(ID);}
|
||||
|
||||
public VulkanBuffer GetMaterialsBuffer(){return MaterialsBuffer;}
|
||||
|
|
|
|||
|
|
@ -10,10 +10,7 @@ import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
|
|||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.*;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -31,6 +28,39 @@ public class ModelsCache {
|
|||
ModelsMap = new HashMap<>();
|
||||
}
|
||||
|
||||
public void loadVoxelModels(VulkanContext VkCtx, List<CompatibleVoxelMesh.VoxelModelData> Models, CommandPool commandPool, Queue queue){
|
||||
try {
|
||||
List<VulkanBuffer> StagingBufferList = new ArrayList<>();
|
||||
var Command = new CommandBuffer(VkCtx, commandPool, true, true);
|
||||
Command.BeginRecording();
|
||||
|
||||
for (CompatibleVoxelMesh.VoxelModelData modelData : Models) {
|
||||
VulkanModel VKModel = new VulkanModel(modelData.ID());
|
||||
ModelsMap.put(VKModel.GetID(), VKModel);
|
||||
|
||||
for (MeshData meshData : modelData.meshes()) {
|
||||
TransferBuffer VerticesBuffers = CreateVoxelVerticesBuffer(VkCtx, meshData,modelData.vertexBuffer());
|
||||
TransferBuffer IndicesBuffers = CreateVoxelIndicesBuffer(VkCtx, meshData,modelData.indexBuffer());
|
||||
StagingBufferList.add(VerticesBuffers.SrcBuffer());
|
||||
StagingBufferList.add(IndicesBuffers.SrcBuffer());
|
||||
VerticesBuffers.RecordTransferCommand(Command);
|
||||
IndicesBuffers.RecordTransferCommand(Command);
|
||||
Logger.debug("Creating new Vulkan Mesh -> ID=[{}] MaterialID=[{}]",meshData.ID(),meshData.MaterialID());
|
||||
VulkanMesh VkMesh = new VulkanMesh(meshData.ID(), VerticesBuffers.DstBuffer(), IndicesBuffers.DstBuffer(),
|
||||
meshData.IndexSize(), meshData.MaterialID());
|
||||
VKModel.GetVkMeshList().add(VkMesh);
|
||||
}
|
||||
}
|
||||
Command.EndRecording();
|
||||
Command.SubmitAndWait(VkCtx,queue);
|
||||
Command.cleanup(VkCtx,commandPool);
|
||||
|
||||
StagingBufferList.forEach(b -> b.cleanup(VkCtx));
|
||||
} catch (Exception exception){
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
}
|
||||
|
||||
public void loadModels(VulkanContext VkCtx, List<ModelData> Models, CommandPool commandPool, Queue queue){
|
||||
try {
|
||||
List<VulkanBuffer> StagingBufferList = new ArrayList<>();
|
||||
|
|
@ -69,6 +99,43 @@ 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();
|
||||
|
|
|
|||
|
|
@ -3,11 +3,12 @@ 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.GameCore;
|
||||
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.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.Images.Texture;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.TextureCache;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Pipeline;
|
||||
|
|
@ -18,6 +19,7 @@ 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;
|
||||
|
|
@ -32,11 +34,10 @@ import java.nio.LongBuffer;
|
|||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.lwjgl.vulkan.KHRSwapchain.VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
import static org.lwjgl.vulkan.KHRSynchronization2.VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR;
|
||||
import static org.lwjgl.vulkan.VK13.*;
|
||||
|
||||
public class SceneRender {//dynamic rendering
|
||||
public class SceneRender 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";
|
||||
|
|
@ -49,26 +50,28 @@ public class SceneRender {//dynamic rendering
|
|||
private final DescriptorSetLayout descriptorLayoutVertexUniform;
|
||||
private final TextureSampler textureSampler;
|
||||
|
||||
private static final int COLOUR_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||
private static final int DEPTH_FORMAT = VK_FORMAT_D16_UNORM;
|
||||
private final VkClearValue ClearValueDepth;
|
||||
private final ByteBuffer PushConstBuffer;
|
||||
private Attachment[] AttDepth;
|
||||
private VkRenderingAttachmentInfo[] AttInfoDepth;
|
||||
private Attachment AttachmentDepth;
|
||||
private Attachment AttachmentColour;
|
||||
private VkRenderingAttachmentInfo AttachmentInfoDepth;
|
||||
private VkClearValue ClearValueColour;
|
||||
private VkRenderingAttachmentInfo.Buffer[] AttachmentInfoColour;
|
||||
private VkRenderingInfo[] RenderInfo;
|
||||
private float R = 0f;
|
||||
private float G = 0.5f;
|
||||
private float B = 0.7f;
|
||||
private VkRenderingAttachmentInfo.Buffer AttachmentInfoColour;
|
||||
private VkRenderingInfo RenderInfo;
|
||||
private float R = 0.5f;
|
||||
private float G = 0.75f;
|
||||
private float B = 1.0f;
|
||||
private boolean Rb = false;
|
||||
private boolean Gb = true;
|
||||
private boolean Bb = false;
|
||||
public int Frames = 0;
|
||||
private static String LastGPULog = "";
|
||||
|
||||
private static final String FRAGMENT_SHADER_FILE_GLSL = "resources/shaders/scene_fragment.glsl";
|
||||
private static final String FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/scene_fragment.glsl";
|
||||
private static final String FRAGMENT_SHADER_FILE_SPV = FRAGMENT_SHADER_FILE_GLSL + ".spv";
|
||||
private static final String VERTEX_SHADER_FILE_GLSL = "resources/shaders/scene_vertex.glsl";
|
||||
private static final String VERTEX_SHADER_FILE_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 final Pipeline VkPipeline;
|
||||
|
|
@ -76,14 +79,14 @@ public class SceneRender {//dynamic rendering
|
|||
|
||||
public SceneRender(VulkanContext vulkanContext){
|
||||
ClearValueColour = VkClearValue.calloc().color(
|
||||
c -> c.float32(0, 0.0f).float32(1, 0.0f).float32(2, 0.0f).float32(3, 0.0f));
|
||||
//ClearValueDepth = VkClearValue.calloc().color(c -> c.float32(0, 1.0f));
|
||||
ClearValueDepth = VkClearValue.calloc().depthStencil(c -> c.depth(1.0f).stencil());
|
||||
AttDepth = createDepthAttachments(vulkanContext);
|
||||
AttInfoDepth = createDepthAttachmentsInfo(vulkanContext, AttDepth, ClearValueDepth);
|
||||
ClearValueColour = VkClearValue.calloc().color(c->c.float32(0,R).float32(1,G).float32(2,B).float32(3,1.0f));
|
||||
AttachmentInfoColour = CreateColourAttachmentsInfo(vulkanContext,ClearValueColour);
|
||||
RenderInfo = CreateRenderInfo(vulkanContext, AttachmentInfoColour, AttInfoDepth);
|
||||
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));
|
||||
AttachmentColour = CreateColourAttachment(vulkanContext);
|
||||
AttachmentDepth = CreateDepthAttachment(vulkanContext);
|
||||
AttachmentInfoDepth = CreateDepthAttachmentInfo(AttachmentDepth, ClearValueDepth);
|
||||
AttachmentInfoColour = CreateColourAttachmentInfo(AttachmentColour,ClearValueColour);
|
||||
RenderInfo = CreateRenderInfo(AttachmentColour, AttachmentInfoColour, AttachmentInfoDepth);
|
||||
|
||||
ShaderModule[] shaderModules = SceneRender.CreateShaderModules(vulkanContext);
|
||||
PushConstBuffer = (MemoryUtil.memAlloc(PUSH_CONSTANTS_SIZE));
|
||||
|
||||
|
|
@ -114,6 +117,40 @@ public class SceneRender {//dynamic rendering
|
|||
Arrays.asList(shaderModules).forEach(shaderModule -> shaderModule.CleanUp(vulkanContext));
|
||||
}
|
||||
|
||||
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 Attachment CreateDepthAttachment(VulkanContext VkCtx){
|
||||
SwapChain swapChain = VkCtx.GetSwapChain();
|
||||
VkExtent2D swapChainExtent = swapChain.GetSwapChainExtent();
|
||||
return new Attachment(VkCtx, swapChainExtent.width(), swapChainExtent.height(),
|
||||
DEPTH_FORMAT,VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
||||
}
|
||||
|
||||
|
||||
private static VkRenderingAttachmentInfo CreateDepthAttachmentInfo(Attachment DepthAttachment, VkClearValue clearValue){
|
||||
return VkRenderingAttachmentInfo.calloc()
|
||||
.sType$Default()
|
||||
.imageView(DepthAttachment.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 Attachment[] createDepthAttachments(VulkanContext VkCtx){
|
||||
SwapChain swapChain = VkCtx.GetSwapChain();
|
||||
int ImageCount = swapChain.GetImageCount();
|
||||
|
|
@ -149,15 +186,14 @@ public class SceneRender {//dynamic rendering
|
|||
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),
|
||||
new ShaderModule(VkCtx, VK_SHADER_STAGE_FRAGMENT_BIT, FRAGMENT_SHADER_FILE_SPV)
|
||||
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)
|
||||
};
|
||||
}
|
||||
|
||||
private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] ShaderModules, DescriptorSetLayout[] DescriptorSetLayouts){
|
||||
var vertexBufferStructure = new VertexBufferStructure();
|
||||
var BuildInfo = new PipelineBuildInfo(ShaderModules,vertexBufferStructure.getVertexInput(),
|
||||
VkCtx.GetSurface().GetSurfaceFormat().ImageFormat())
|
||||
var BuildInfo = new PipelineBuildInfo(ShaderModules,vertexBufferStructure.getVertexInput(),COLOUR_FORMAT)
|
||||
.SetDepthFormat(DEPTH_FORMAT)
|
||||
.SetPushConstantRanges(
|
||||
new PushConstantsRange[]{
|
||||
|
|
@ -166,62 +202,33 @@ public class SceneRender {//dynamic rendering
|
|||
})
|
||||
.SetDescriptorSetLayouts(DescriptorSetLayouts)
|
||||
.BlendingIsUsed(true);
|
||||
var pipeline = new Pipeline(VkCtx, BuildInfo);
|
||||
var pipeline = new DefaultPipeline(VkCtx, BuildInfo);
|
||||
vertexBufferStructure.cleanup();
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
public void UpdateColours(VulkanContext vulkanContext){
|
||||
if (Gb){
|
||||
if (G < 1.0f && Math.random() <0.5) G+=0.0005f;
|
||||
else if (G >= 1.0f) Gb = false;
|
||||
} else{
|
||||
if (G >0.0f&& Math.random() <0.5) G-=0.0005f;
|
||||
else if (G <= 0.0f) Gb = true;
|
||||
}
|
||||
if (Rb){
|
||||
if (R < 1.0f&& Math.random() <0.3) R+=0.0005f;
|
||||
else if (R >= 1.0f) Rb = false;
|
||||
} else{
|
||||
if (R >0.0f&& Math.random() <0.3) R-=0.0005f;
|
||||
else if (R <= 0.0f) Rb = true;
|
||||
}
|
||||
if (Bb){
|
||||
if (B < 1.0f&& Math.random() <0.7) B+=0.0005f;
|
||||
else if (B >= 1.0f) Bb = false;
|
||||
} else{
|
||||
if (B >0.0f&& Math.random() <0.7) B-=0.0005f;
|
||||
else if (B <= 0.0f) Bb = true;
|
||||
}
|
||||
//ClearValueColour = VkClearValue.calloc().color(c->c.float32(0,R).float32(1,G).float32(2,B).float32(3,1.0f));
|
||||
//AttachmentInfoColour = CreateColourAttachmentsInfo(vulkanContext,ClearValueColour);
|
||||
//RenderInfo = CreateRenderInfo(vulkanContext, AttachmentInfoColour, AttInfoDepth);
|
||||
}
|
||||
|
||||
public void Render(EngineInstance engineInstance,VulkanContext vulkanContext, CommandBuffer commandBuffer, ModelsCache modelsCache,MaterialsCache materialsCache, int ImageIndex, int CurrentFrame){
|
||||
UpdateColours(vulkanContext);
|
||||
public void Render(EngineInstance engineInstance,VulkanContext vulkanContext, CommandBuffer commandBuffer, ModelsCache modelsCache,MaterialsCache materialsCache, int CurrentFrame){
|
||||
try(var MemStack = MemoryStack.stackPush()){
|
||||
SwapChain swapChain = vulkanContext.GetSwapChain();
|
||||
long SwapChainImage = swapChain.GetVulkanImageView(ImageIndex).GetVulkanImage();
|
||||
VkCommandBuffer CommandHandle = commandBuffer.GetVulkanCommandBuffer();
|
||||
VulkanUtils.ImageBarrier(MemStack, CommandHandle, SwapChainImage,
|
||||
VulkanUtils.ImageBarrier(MemStack, CommandHandle, AttachmentColour.GetVkImage().getVulkanImage(),
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
VK_ACCESS_2_NONE, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
VulkanUtils.ImageBarrier(MemStack, CommandHandle, AttDepth[ImageIndex].GetVkImage().getVulkanImage(),
|
||||
VulkanUtils.ImageBarrier(MemStack, CommandHandle, AttachmentDepth.GetVkImage().getVulkanImage(),
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT,
|
||||
VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT,
|
||||
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
VK_IMAGE_ASPECT_DEPTH_BIT);
|
||||
|
||||
vkCmdBeginRendering(CommandHandle, RenderInfo[ImageIndex]);
|
||||
vkCmdBeginRendering(CommandHandle, RenderInfo);
|
||||
|
||||
vkCmdBindPipeline(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkPipeline.GetVulkanPipeline());
|
||||
|
||||
VkExtent2D swapChainExtent = swapChain.GetSwapChainExtent();
|
||||
int width = swapChainExtent.width();
|
||||
int height = swapChainExtent.height();
|
||||
Image ColourImage = AttachmentColour.GetVkImage();
|
||||
int width = ColourImage.GetWidth();
|
||||
int height = ColourImage.GetHeight();
|
||||
var Viewport = VkViewport.calloc(1,MemStack)
|
||||
.x(0)
|
||||
.y(height)
|
||||
|
|
@ -239,7 +246,7 @@ public class SceneRender {//dynamic rendering
|
|||
DescriptorAllocator descriptorAllocator = vulkanContext.GetDescriptorAllocator();
|
||||
LongBuffer DescriptorSets = MemStack.mallocLong(4)
|
||||
.put(0,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_PRJ).GetVkDescriptorSet())
|
||||
.put(1,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_VIEW).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, VkPipeline.GetVulkanPipelineLayout(),0,DescriptorSets,null);
|
||||
|
|
@ -248,12 +255,6 @@ public class SceneRender {//dynamic rendering
|
|||
RenderActors(engineInstance, CommandHandle, modelsCache, materialsCache, true);
|
||||
|
||||
vkCmdEndRendering(CommandHandle);
|
||||
|
||||
VulkanUtils.ImageBarrier(MemStack, CommandHandle, SwapChainImage,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
||||
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT,
|
||||
VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_2_NONE,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -294,19 +295,23 @@ public class SceneRender {//dynamic rendering
|
|||
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));
|
||||
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){
|
||||
Arrays.asList(RenderInfo).forEach(VkRenderingInfo::free);
|
||||
Arrays.asList(AttInfoDepth).forEach(VkRenderingAttachmentInfo::free);
|
||||
Arrays.asList(AttachmentInfoColour).forEach(VkRenderingAttachmentInfo.Buffer::free);
|
||||
Arrays.asList(AttDepth).forEach(Attachment->Attachment.CleanUp(VkCtx));
|
||||
AttDepth = createDepthAttachments(VkCtx);
|
||||
AttachmentInfoColour = CreateColourAttachmentsInfo(VkCtx, ClearValueColour);
|
||||
AttInfoDepth = createDepthAttachmentsInfo(VkCtx, AttDepth, ClearValueDepth);
|
||||
RenderInfo = CreateRenderInfo(VkCtx, AttachmentInfoColour, AttInfoDepth);
|
||||
RenderInfo.free();
|
||||
AttachmentInfoColour.free();
|
||||
AttachmentColour.CleanUp(VkCtx);
|
||||
AttachmentDepth.CleanUp(VkCtx);
|
||||
AttachmentInfoDepth.free();
|
||||
AttachmentColour = CreateColourAttachment(VkCtx);
|
||||
AttachmentDepth = CreateDepthAttachment(VkCtx);
|
||||
AttachmentInfoColour = CreateColourAttachmentInfo(AttachmentColour, ClearValueColour);
|
||||
AttachmentInfoDepth = CreateDepthAttachmentInfo(AttachmentDepth, ClearValueDepth);
|
||||
RenderInfo = CreateRenderInfo(AttachmentColour, AttachmentInfoColour, AttachmentInfoDepth);
|
||||
VulkanUtils.CopyMatrixToBuffer(VkCtx, BufferProjectionMatrix, instance.scene().GetProjection().GetProjectionMatrix(),0);
|
||||
}
|
||||
|
||||
|
|
@ -322,24 +327,19 @@ public class SceneRender {//dynamic rendering
|
|||
descriptorSet.SetImageArray(device,imageViews,textureSampler,0);
|
||||
}
|
||||
|
||||
private static VkRenderingInfo[] CreateRenderInfo(VulkanContext vulkanContext, VkRenderingAttachmentInfo.Buffer[] ColourAttachments, VkRenderingAttachmentInfo[] DepthAttachments){
|
||||
SwapChain swapChain = vulkanContext.GetSwapChain();
|
||||
int ImageCount = swapChain.GetImageCount();
|
||||
var Result = new VkRenderingInfo[ImageCount];
|
||||
|
||||
private static VkRenderingInfo CreateRenderInfo(Attachment ColourAttachment, VkRenderingAttachmentInfo.Buffer ColourAttachmentInfo, VkRenderingAttachmentInfo DepthAttachmentInfo){
|
||||
VkRenderingInfo Result;
|
||||
try(var MemStack = MemoryStack.stackPush()){
|
||||
VkExtent2D Extent = swapChain.GetSwapChainExtent();
|
||||
VkExtent2D Extent = VkExtent2D.calloc(MemStack);
|
||||
Extent.width(ColourAttachment.GetVkImage().GetWidth());
|
||||
Extent.height(ColourAttachment.GetVkImage().GetHeight());
|
||||
var RenderArea = VkRect2D.calloc(MemStack).extent(Extent);
|
||||
|
||||
for(int i = 0; i < ImageCount; i++){
|
||||
var RenderInfo = VkRenderingInfo.calloc()
|
||||
Result = VkRenderingInfo.calloc()
|
||||
.sType$Default()
|
||||
.renderArea(RenderArea)
|
||||
.layerCount(1)
|
||||
.pColorAttachments(ColourAttachments[i])
|
||||
.pDepthAttachment(DepthAttachments[i]);
|
||||
Result[i] = RenderInfo;
|
||||
}
|
||||
.pColorAttachments(ColourAttachmentInfo)
|
||||
.pDepthAttachment(DepthAttachmentInfo);
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
|
@ -361,12 +361,12 @@ public class SceneRender {//dynamic rendering
|
|||
}
|
||||
public void cleanup(VulkanContext VkCtx){
|
||||
VkPipeline.CleanUp(VkCtx);
|
||||
Arrays.asList(RenderInfo).forEach(VkRenderingInfo::free);
|
||||
Arrays.asList(BufferViewMatrices).forEach(buffer -> buffer.cleanup(VkCtx));
|
||||
Arrays.asList(AttachmentInfoColour).forEach(VkRenderingAttachmentInfo.Buffer::free);
|
||||
Arrays.asList(AttInfoDepth).forEach(VkRenderingAttachmentInfo::free);
|
||||
Arrays.asList(AttachmentInfoColour).forEach(VkRenderingAttachmentInfo.Buffer::free);
|
||||
Arrays.asList(AttDepth).forEach(Attachment->Attachment.CleanUp(VkCtx));
|
||||
RenderInfo.free();
|
||||
AttachmentInfoColour.free();
|
||||
AttachmentColour.CleanUp(VkCtx);
|
||||
AttachmentDepth.CleanUp(VkCtx);
|
||||
AttachmentInfoDepth.free();
|
||||
MemoryUtil.memFree(PushConstBuffer);
|
||||
ClearValueDepth.free();
|
||||
ClearValueColour.free();
|
||||
|
|
@ -376,4 +376,9 @@ public class SceneRender {//dynamic rendering
|
|||
descriptorLayoutVertexUniform.CleanUp(VkCtx);
|
||||
textureSampler.CleanUp(VkCtx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Attachment GetAttachmentColour() {
|
||||
return AttachmentColour;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
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.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 {
|
||||
|
||||
public void Render(EngineInstance engineInstance, VulkanContext vulkanContext, CommandBuffer commandBuffer, ModelsCache modelsCache, MaterialsCache materialsCache, int CurrentFrame);
|
||||
public void Resize(EngineInstance instance, VulkanContext VkCtx);
|
||||
public void LoadMaterials(VulkanContext VkCtx, MaterialsCache materialsCache, TextureCache textureCache);
|
||||
public void cleanup(VulkanContext VkCtx);
|
||||
public Attachment GetAttachmentColour();
|
||||
}
|
||||
|
|
@ -15,6 +15,7 @@ import java.nio.IntBuffer;
|
|||
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 {
|
||||
|
|
@ -52,11 +53,11 @@ public class Surface {
|
|||
var SurfaceFormats = VkSurfaceFormatKHR.calloc(SurfaceFormatCount, MemStack);
|
||||
vkCheck(KHRSurface.vkGetPhysicalDeviceSurfaceFormatsKHR(PhysDevice.GetPhysicalDevice(),VulkanSurface, IntPointer, SurfaceFormats), "Failed to get surface formats");
|
||||
|
||||
ImageFormat = VK_FORMAT_B8G8R8A8_SRGB;
|
||||
ImageFormat = VK_FORMAT_B8G8R8A8_UNORM;
|
||||
ColourSpace = SurfaceFormats.get(0).colorSpace();
|
||||
for(int i = 0; i < SurfaceFormatCount; i++){
|
||||
VkSurfaceFormatKHR SurfaceFormatKHR = SurfaceFormats.get(i);
|
||||
if (SurfaceFormatKHR.format() == VK_FORMAT_B8G8R8A8_SRGB && SurfaceFormatKHR.colorSpace() == KHRSurface.VK_COLOR_SPACE_SRGB_NONLINEAR_KHR){
|
||||
if (SurfaceFormatKHR.format() == VK_FORMAT_B8G8R8A8_UNORM && SurfaceFormatKHR.colorSpace() == KHRSurface.VK_COLOR_SPACE_SRGB_NONLINEAR_KHR){
|
||||
ImageFormat = SurfaceFormatKHR.format();
|
||||
ColourSpace = SurfaceFormatKHR.colorSpace();
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen;
|
||||
package net.halbear.Terrain4J.EngineCore.Vulkan.Structure.SwapChain;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Display.Window;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.Device;
|
||||
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.ImageView;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.Surface;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.lwjgl.vulkan.*;
|
||||
|
|
@ -0,0 +1,192 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Vulkan.Structure.SwapChain;
|
||||
|
||||
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.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.Util.VulkanUtils;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.util.shaderc.Shaderc;
|
||||
import org.lwjgl.vulkan.*;
|
||||
|
||||
import java.nio.LongBuffer;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.lwjgl.vulkan.KHRSwapchain.VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
import static org.lwjgl.vulkan.KHRSynchronization2.VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR;
|
||||
import static org.lwjgl.vulkan.VK10.*;
|
||||
import static org.lwjgl.vulkan.VK13.*;
|
||||
|
||||
public class SwapChainRender {
|
||||
|
||||
private static final String DESCRIPTOR_ID_ATTACHMENT = "FWD_DESC_ID_ATT";
|
||||
private static final String FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/swap_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/swap_vtx.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 VkRenderingAttachmentInfo.Buffer[] ColourAttachmentsInfo;
|
||||
private VkRenderingInfo[] RenderInfo;
|
||||
|
||||
public SwapChainRender(VulkanContext VkCtx, Attachment SrcAttachment){
|
||||
ClearValueColour = VkClearValue.calloc();
|
||||
ClearValueColour.color(c->c.float32(0,0.0f).float32(1,0.0f).float32(2,0.0f).float32(3,0.0f));
|
||||
|
||||
ColourAttachmentsInfo = CreateColourAttachmentsInfo(VkCtx,ClearValueColour);
|
||||
RenderInfo = CreateRenderInfo(VkCtx,ColourAttachmentsInfo);
|
||||
|
||||
var TextureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_REPEAT,VK_BORDER_COLOR_INT_OPAQUE_BLACK,1,true);
|
||||
textureSampler = new TextureSampler(VkCtx,TextureSamplerInfo);
|
||||
|
||||
var LayoutInfo = new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,0,1,VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
AttachmentDescriptorSetLayout = new DescriptorSetLayout(VkCtx,LayoutInfo);
|
||||
CreateAttachmentDescriptorSet(VkCtx,AttachmentDescriptorSetLayout,SrcAttachment,textureSampler);
|
||||
|
||||
ShaderModule[] shaderModules = CreateShaderModules(VkCtx);
|
||||
|
||||
pipeline = CreatePipeline(VkCtx,shaderModules,new DescriptorSetLayout[]{AttachmentDescriptorSetLayout});
|
||||
Arrays.asList(shaderModules).forEach(s->s.CleanUp(VkCtx));
|
||||
}
|
||||
|
||||
private static void CreateAttachmentDescriptorSet(VulkanContext VkCtx, DescriptorSetLayout descriptorSetLayout, Attachment attachment, TextureSampler sampler){
|
||||
DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator();
|
||||
Device device = VkCtx.GetDevice();
|
||||
DescriptorSet descriptorSet = descriptorAllocator.AddDescriptorSets(device,DESCRIPTOR_ID_ATTACHMENT,1,descriptorSetLayout)[0];
|
||||
descriptorSet.SetImage(device,attachment.GetVkImageView(),sampler,0);
|
||||
}
|
||||
|
||||
private static VkRenderingAttachmentInfo.Buffer[] CreateColourAttachmentsInfo(VulkanContext VkCtx, VkClearValue ClearView){
|
||||
SwapChain swapChain = VkCtx.GetSwapChain();
|
||||
int ImageCount = swapChain.GetImageCount();
|
||||
var Result = new VkRenderingAttachmentInfo.Buffer[ImageCount];
|
||||
|
||||
for(int i = 0; i < ImageCount; i++){
|
||||
var Attachments = VkRenderingAttachmentInfo.calloc(1);
|
||||
Attachments.get(0)
|
||||
.sType$Default()
|
||||
.imageView(swapChain.GetVulkanImageView(i).GetVulkanImageView())
|
||||
.imageLayout(VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR)
|
||||
.loadOp(VK_ATTACHMENT_LOAD_OP_CLEAR)
|
||||
.storeOp(VK_ATTACHMENT_STORE_OP_STORE)
|
||||
.clearValue(ClearView);
|
||||
Result[i] = Attachments;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
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 pipeline = new DefaultPipeline(VkCtx,BuildInfo);
|
||||
VertexBufferStruct.CleanUp();
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
private static VkRenderingInfo[] CreateRenderInfo(VulkanContext VkCtx, VkRenderingAttachmentInfo.Buffer[] ColourAttachments){
|
||||
SwapChain swapChain = VkCtx.GetSwapChain();
|
||||
int ImageCount = swapChain.GetImageCount();
|
||||
var Result = new VkRenderingInfo[ImageCount];
|
||||
|
||||
try(var MemStack = MemoryStack.stackPush()){
|
||||
VkExtent2D extent2D = swapChain.GetSwapChainExtent();
|
||||
var RenderArea = VkRect2D.calloc(MemStack).extent(extent2D);
|
||||
|
||||
for(int i = 0; i < ImageCount; i++){
|
||||
var renderingInfo = VkRenderingInfo.calloc()
|
||||
.sType$Default()
|
||||
.renderArea(RenderArea)
|
||||
.layerCount(1)
|
||||
.pColorAttachments(ColourAttachments[i]);
|
||||
Result[i] = renderingInfo;
|
||||
}
|
||||
}
|
||||
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(VulkanContext VkCtx, CommandBuffer commandBuffer, Attachment SrcAttachment, int ImageIndex){
|
||||
try(var MemStack = MemoryStack.stackPush()){
|
||||
SwapChain swapChain = VkCtx.GetSwapChain();
|
||||
|
||||
long SwapChainImage = swapChain.GetVulkanImageView(ImageIndex).GetVulkanImage();
|
||||
VkCommandBuffer CommandHandle = commandBuffer.GetVulkanCommandBuffer();
|
||||
|
||||
VulkanUtils.ImageBarrier(MemStack,CommandHandle,SwapChainImage,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_2_NONE,VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
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);
|
||||
|
||||
vkCmdBeginRendering(CommandHandle, RenderInfo[ImageIndex]);
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
VulkanUtils.ImageBarrier(MemStack,CommandHandle,SwapChainImage,VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
||||
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT, VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
VK_PIPELINE_STAGE_2_NONE, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
public void Resize(VulkanContext VkCtx, Attachment SrcAttachment){
|
||||
Arrays.asList(RenderInfo).forEach(VkRenderingInfo::free);
|
||||
Arrays.asList(ColourAttachmentsInfo).forEach(VkRenderingAttachmentInfo.Buffer::free);
|
||||
ColourAttachmentsInfo = CreateColourAttachmentsInfo(VkCtx,ClearValueColour);
|
||||
RenderInfo = CreateRenderInfo(VkCtx,ColourAttachmentsInfo);
|
||||
|
||||
DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator();
|
||||
DescriptorSet descriptorSet = descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_ATTACHMENT);
|
||||
descriptorSet.SetImage(VkCtx.GetDevice(),SrcAttachment.GetVkImageView(),textureSampler,0);
|
||||
}
|
||||
|
||||
public void CleanUp(VulkanContext VkCtx){
|
||||
textureSampler.CleanUp(VkCtx);
|
||||
AttachmentDescriptorSetLayout.CleanUp(VkCtx);
|
||||
pipeline.CleanUp(VkCtx);
|
||||
Arrays.asList(RenderInfo).forEach(VkRenderingInfo::free);
|
||||
Arrays.asList(ColourAttachmentsInfo).forEach(VkRenderingAttachmentInfo.Buffer::free);
|
||||
ClearValueColour.free();
|
||||
}
|
||||
}
|
||||
|
|
@ -56,27 +56,6 @@ public class VulkanBuffer {
|
|||
Buffer = LongPointer.get(0);
|
||||
Allocation = AllocationPointer.get(0);
|
||||
pointerBuffer = MemoryUtil.memAllocPointer(1);
|
||||
/* var MemoryRequirements = VkMemoryRequirements.calloc(MemStack);
|
||||
vkGetBufferMemoryRequirements(device.FetchVulkanDevice(), Buffer, MemoryRequirements);
|
||||
|
||||
var MemoryAllocation = VkMemoryAllocateInfo.calloc(MemStack)
|
||||
.sType$Default()
|
||||
.allocationSize(MemoryRequirements.size())
|
||||
.memoryTypeIndex(VulkanUtils.MemoryTypeFromProperties(vulkanContext, MemoryRequirements.memoryTypeBits(), RequestMask));
|
||||
|
||||
vkCheck(vkAllocateMemory(device.FetchVulkanDevice(),MemoryAllocation,null,LongPointer),"Failed to allocate memory for Vulkan");
|
||||
AllocationSize = MemoryAllocation.allocationSize();
|
||||
Memory = LongPointer.get(0);
|
||||
pointerBuffer = MemoryUtil.memAllocPointer(1);
|
||||
if (Buffer == 0) {
|
||||
Logger.error("Vulkan crash blocked: Native bufferHandle cannot be 0!");
|
||||
throw new IllegalArgumentException("Vulkan crash blocked: Native bufferHandle cannot be 0!");
|
||||
}
|
||||
if (Memory == 0) {
|
||||
Logger.error("Vulkan crash blocked: Native memoryHandle cannot be 0! Device out of memory or allocation failed.");
|
||||
throw new IllegalArgumentException("Vulkan crash blocked: Native memoryHandle cannot be 0! Device out of memory or allocation failed.");
|
||||
}
|
||||
vkCheck(vkBindBufferMemory(device.FetchVulkanDevice(),Buffer,Memory,0),"Failed to Bind Vulkan Memory Buffer");*/
|
||||
}
|
||||
}
|
||||
public void cleanup(VulkanContext vulkanContext){
|
||||
|
|
|
|||
|
|
@ -10,7 +10,13 @@ import org.lwjgl.system.MemoryStack;
|
|||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.lwjgl.vulkan.*;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.Locale;
|
||||
|
||||
import static org.lwjgl.util.vma.Vma.VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
|
||||
|
|
@ -25,6 +31,7 @@ public class VulkanUtils {
|
|||
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;
|
||||
public static final int VEC2_SIZE = 2 * FLOAT_SIZE;
|
||||
|
||||
public static void CopyMatrixToBuffer(VulkanContext VkCtx, VulkanBuffer VkBuffer, Matrix4f matrix, int Offset){
|
||||
long MappedMemory = VkBuffer.MapMemory(VkCtx);
|
||||
|
|
@ -136,4 +143,24 @@ public class VulkanUtils {
|
|||
throw new RuntimeException(ErrorMessage + ": " + ErrorCode + " [" + Error + "]");
|
||||
}
|
||||
}
|
||||
|
||||
public static InputStream convertFloatBufferToInputStream(FloatBuffer floatBuffer) {
|
||||
floatBuffer.rewind();
|
||||
byte[] byteArray = new byte[floatBuffer.remaining() * 4];
|
||||
ByteBuffer byteBuffer = ByteBuffer.wrap(byteArray);
|
||||
byteBuffer.order(ByteOrder.nativeOrder());
|
||||
byteBuffer.asFloatBuffer().put(floatBuffer);
|
||||
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArray);
|
||||
return new BufferedInputStream(byteArrayInputStream);
|
||||
}
|
||||
|
||||
public static InputStream convertIntBufferToInputStream(IntBuffer intBuffer) {
|
||||
intBuffer.rewind();
|
||||
byte[] byteArray = new byte[intBuffer.remaining() * 4];
|
||||
ByteBuffer byteBuffer = ByteBuffer.wrap(byteArray);
|
||||
byteBuffer.order(ByteOrder.nativeOrder());
|
||||
byteBuffer.asIntBuffer().put(intBuffer);
|
||||
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArray);
|
||||
return new BufferedInputStream(byteArrayInputStream);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,14 +13,21 @@ frame_accuracy=0
|
|||
throttle_on_unfocus=true
|
||||
throttle_accuracy=500000000
|
||||
#event tick rate for game process
|
||||
master_tick_rate=120
|
||||
master_tick_rate=240
|
||||
main_thread_tickrate=120
|
||||
fast_thread_tickrate=240
|
||||
cap_master_to_tickrate=false
|
||||
cap_master_to_tickrate=true
|
||||
cap_main_to_tickrate=true
|
||||
cap_fast_to_tickrate=true
|
||||
|
||||
#Renderer Properties
|
||||
#AA settings
|
||||
#0=No AA
|
||||
#1=FXAA
|
||||
#2=MSAAx2
|
||||
#3=MSAAx4
|
||||
#4=MSAAx8
|
||||
anti_alias_mode=0
|
||||
Debug_Shaders = false
|
||||
ShaderRecompiling = true
|
||||
#Vulkan Debugging toggle
|
||||
|
|
@ -34,7 +41,7 @@ PhysicalDeviceName=
|
|||
|
||||
#3D Projection Properties
|
||||
field_of_view=60.0f
|
||||
z_near_plane=0.10f
|
||||
z_far_plane=1000.0f
|
||||
z_far_plane=1f
|
||||
z_near_plane=10000.0f
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue