Instantly share code, notes, and snippets.
Created
October 31, 2018 17:20
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
-
Save BeRo1985/ab4c97b5e17b84b46b9cecc19db450a9 to your computer and use it in GitHub Desktop.
PasVulkan Frame graph API code example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| unit UnitScreenMainMenu; | |
| {$ifdef fpc} | |
| {$mode delphi} | |
| {$ifdef cpu386} | |
| {$asmmode intel} | |
| {$endif} | |
| {$ifdef cpuamd64} | |
| {$asmmode intel} | |
| {$endif} | |
| {$else} | |
| {$ifdef conditionalexpressions} | |
| {$if CompilerVersion>=24.0} | |
| {$legacyifend on} | |
| {$ifend} | |
| {$endif} | |
| {$endif} | |
| {$if defined(Win32) or defined(Win64)} | |
| {$define Windows} | |
| {$ifend} | |
| interface | |
| uses SysUtils, | |
| Classes, | |
| Math, | |
| PasMP, | |
| Vulkan, | |
| PasVulkan.Types, | |
| PasVulkan.Math, | |
| PasVulkan.Framework, | |
| PasVulkan.FrameGraph, | |
| PasVulkan.Application, | |
| PasVulkan.Audio; | |
| type PScreenMainMenuBackgroundUniformBuffer=^TScreenMainMenuBackgroundUniformBuffer; | |
| TScreenMainMenuBackgroundUniformBuffer=packed record | |
| InverseViewProjectionMatrix:TpvMatrix4x4; | |
| Resolution:TpvVector2; | |
| MusicTick:TpvFloat; | |
| PressStartOffset:TpvFloat; | |
| end; | |
| PScreenMainMenuTerrainUniformBuffer=^TScreenMainMenuTerrainUniformBuffer; | |
| TScreenMainMenuTerrainUniformBuffer=packed record | |
| ModelViewMatrix:TpvMatrix4x4; | |
| ModelViewProjectionMatrix:TpvMatrix4x4; | |
| Offset:TpvFloat; | |
| end; | |
| PScreenMainMenuForegroundUniformBuffer=^TScreenMainMenuForegroundUniformBuffer; | |
| TScreenMainMenuForegroundUniformBuffer=packed record | |
| ViewProjectionMatrix:TpvMatrix4x4; | |
| InverseViewProjectionMatrix:TpvMatrix4x4; | |
| Resolution:TpvVector2; | |
| MusicTick:TpvFloat; | |
| PressStartOffset:TpvFloat; | |
| end; | |
| TScreenMainMenu=class; | |
| TScreenMainMenuSceneContentRenderPass=class(TpvFrameGraph.TRenderPass) | |
| public | |
| const TerrainTextureSize=32; | |
| TerrainTextureBorderSize=2; | |
| TerrainParts=4; | |
| HeightMapWidth=64; | |
| HeightMapHeight=128; | |
| GridSize=4; | |
| type TTerrainTexturePixel=packed record | |
| r,g,b,a:TpvUInt8; | |
| end; | |
| PTerrainTexturePixel=^TTerrainTexturePixel; | |
| TTerrainTexture=array[0..TerrainTextureSize-1,0..TerrainTextureSize-1] of TTerrainTexturePixel; | |
| PTerrainTexture=^TTerrainTexture; | |
| TTerrainVertex=packed record // 16 bytes per vertex | |
| Position:TpvVector3; | |
| TexCoord:TpvHalfFloatVector2; | |
| end; | |
| PTerrainVertex=^TTerrainVertex; | |
| TTerrainHeightMap=array[0..(HeightMapWidth*HeightMapHeight)-1] of TpvFloat; | |
| PTerrainHeightMap=^TTerrainHeightMap; | |
| TTerrainVertices=array[0..((HeightMapWidth*HeightMapHeight)*TerrainParts)-1] of TTerrainVertex; | |
| PTerrainVertices=^TTerrainVertices; | |
| TTerrainIndices=array[0..(((HeightMapWidth-1)*(HeightMapHeight-1))*6*TerrainParts)-1] of TVkUInt32; | |
| PTerrainIndices=^TTerrainIndices; | |
| private | |
| fVulkanRenderPass:TpvVulkanRenderPass; | |
| fParent:TScreenMainMenu; | |
| fResourceColor:TpvFrameGraph.TPass.TUsedImageResource; | |
| fResourceDepth:TpvFrameGraph.TPass.TUsedImageResource; | |
| fVulkanGraphicsCommandBuffer:TpvVulkanCommandBuffer; | |
| fVulkanGraphicsCommandBufferFence:TpvVulkanFence; | |
| fVulkanTransferCommandBuffer:TpvVulkanCommandBuffer; | |
| fVulkanTransferCommandBufferFence:TpvVulkanFence; | |
| fBackgroundVertexShaderModule:TpvVulkanShaderModule; | |
| fBackgroundFragmentShaderModule:TpvVulkanShaderModule; | |
| fBackgroundVulkanPipelineShaderStageVertex:TpvVulkanPipelineShaderStage; | |
| fBackgroundVulkanPipelineShaderStageFragment:TpvVulkanPipelineShaderStage; | |
| fBackgroundVulkanGraphicsPipeline:TpvVulkanGraphicsPipeline; | |
| fBackgroundVulkanUniformBuffers:array[0..MaxSwapChainImages-1] of TpvVulkanBuffer; | |
| fBackgroundVulkanDescriptorPool:TpvVulkanDescriptorPool; | |
| fBackgroundVulkanDescriptorSetLayout:TpvVulkanDescriptorSetLayout; | |
| fBackgroundVulkanDescriptorSets:array[0..MaxSwapChainImages-1] of TpvVulkanDescriptorSet; | |
| fBackgroundVulkanPipelineLayout:TpvVulkanPipelineLayout; | |
| fBackgroundUniformBuffers:array[0..MaxSwapChainImages-1] of TScreenMainMenuBackgroundUniformBuffer; | |
| fTerrainTextureData:TTerrainTexture; | |
| fTerrainTexture:TpvVulkanTexture; | |
| fTerrainHeightMap:TTerrainHeightMap; | |
| fTerrainVertices:TTerrainVertices; | |
| fTerrainIndices:TTerrainIndices; | |
| fTerrainVertexShaderModule:TpvVulkanShaderModule; | |
| fTerrainFragmentShaderModule:TpvVulkanShaderModule; | |
| fTerrainVulkanPipelineShaderStageVertex:TpvVulkanPipelineShaderStage; | |
| fTerrainVulkanPipelineShaderStageFragment:TpvVulkanPipelineShaderStage; | |
| fTerrainVulkanGraphicsPipeline:TpvVulkanGraphicsPipeline; | |
| fTerrainVulkanVertexBuffer:TpvVulkanBuffer; | |
| fTerrainVulkanIndexBuffer:TpvVulkanBuffer; | |
| fTerrainVulkanUniformBuffers:array[0..MaxSwapChainImages-1] of TpvVulkanBuffer; | |
| fTerrainVulkanDescriptorPool:TpvVulkanDescriptorPool; | |
| fTerrainVulkanDescriptorSetLayout:TpvVulkanDescriptorSetLayout; | |
| fTerrainVulkanDescriptorSets:array[0..MaxSwapChainImages-1] of TpvVulkanDescriptorSet; | |
| fTerrainVulkanPipelineLayout:TpvVulkanPipelineLayout; | |
| fTerrainUniformBuffers:array[0..MaxSwapChainImages-1] of TScreenMainMenuTerrainUniformBuffer; | |
| fForegroundVertexShaderModule:TpvVulkanShaderModule; | |
| fForegroundFragmentShaderModule:TpvVulkanShaderModule; | |
| fForegroundVulkanPipelineShaderStageVertex:TpvVulkanPipelineShaderStage; | |
| fForegroundVulkanPipelineShaderStageFragment:TpvVulkanPipelineShaderStage; | |
| fForegroundVulkanGraphicsPipeline:TpvVulkanGraphicsPipeline; | |
| fForegroundVulkanUniformBuffers:array[0..MaxSwapChainImages-1] of TpvVulkanBuffer; | |
| fForegroundVulkanDescriptorPool:TpvVulkanDescriptorPool; | |
| fForegroundVulkanDescriptorSetLayout:TpvVulkanDescriptorSetLayout; | |
| fForegroundVulkanDescriptorSets:array[0..MaxSwapChainImages-1] of TpvVulkanDescriptorSet; | |
| fForegroundVulkanPipelineLayout:TpvVulkanPipelineLayout; | |
| fForegroundUniformBuffers:array[0..MaxSwapChainImages-1] of TScreenMainMenuForegroundUniformBuffer; | |
| procedure TerrainHeightMapGenerationParallelForJobMethod(const aJob:PPasMPJob;const aThreadIndex:TPasMPInt32;const aData:pointer;const aFromIndex,aToIndex:TPasMPNativeInt); | |
| procedure TerrainVerticesGenerationParallelForJobMethod(const aJob:PPasMPJob;const aThreadIndex:TPasMPInt32;const aData:pointer;const aFromIndex,aToIndex:TPasMPNativeInt); | |
| procedure TerrainIndicesGenerationParallelForJobMethod(const aJob:PPasMPJob;const aThreadIndex:TPasMPInt32;const aData:pointer;const aFromIndex,aToIndex:TPasMPNativeInt); | |
| public | |
| constructor Create(const aFrameGraph:TpvFrameGraph;const aParent:TScreenMainMenu); reintroduce; | |
| destructor Destroy; override; | |
| procedure Show; override; | |
| procedure Hide; override; | |
| procedure AfterCreateSwapChain; override; | |
| procedure BeforeDestroySwapChain; override; | |
| procedure Update(const aUpdateSwapChainImageIndex,aUpdateFrameIndex:TpvSizeInt); override; | |
| procedure Execute(const aCommandBuffer:TpvVulkanCommandBuffer;const aSwapChainImageIndex,aFrameIndex:TpvSizeInt); override; | |
| end; | |
| TScreenMainMenuTonemappingRenderPass=class(TpvFrameGraph.TRenderPass) | |
| private | |
| fVulkanRenderPass:TpvVulkanRenderPass; | |
| fResourceColor:TpvFrameGraph.TPass.TUsedImageResource; | |
| fResourceSurface:TpvFrameGraph.TPass.TUsedImageResource; | |
| fVulkanTransferCommandBuffer:TpvVulkanCommandBuffer; | |
| fVulkanTransferCommandBufferFence:TpvVulkanFence; | |
| fVulkanVertexShaderModule:TpvVulkanShaderModule; | |
| fVulkanFragmentShaderModule:TpvVulkanShaderModule; | |
| fVulkanPipelineShaderStageVertex:TpvVulkanPipelineShaderStage; | |
| fVulkanPipelineShaderStageFragment:TpvVulkanPipelineShaderStage; | |
| fVulkanGraphicsPipeline:TpvVulkanGraphicsPipeline; | |
| fVulkanUniformBuffers:array[0..MaxSwapChainImages-1] of TpvVulkanBuffer; | |
| fVulkanDescriptorPool:TpvVulkanDescriptorPool; | |
| fVulkanDescriptorSetLayout:TpvVulkanDescriptorSetLayout; | |
| fVulkanDescriptorSets:array[0..MaxSwapChainImages-1] of TpvVulkanDescriptorSet; | |
| fVulkanPipelineLayout:TpvVulkanPipelineLayout; | |
| fBackgroundUniformBuffers:array[0..MaxSwapChainImages-1] of TScreenMainMenuBackgroundUniformBuffer; | |
| public | |
| constructor Create(const aFrameGraph:TpvFrameGraph); override; | |
| destructor Destroy; override; | |
| procedure Show; override; | |
| procedure Hide; override; | |
| procedure AfterCreateSwapChain; override; | |
| procedure BeforeDestroySwapChain; override; | |
| procedure Update(const aUpdateSwapChainImageIndex,aUpdateFrameIndex:TpvSizeInt); override; | |
| procedure Execute(const aCommandBuffer:TpvVulkanCommandBuffer;const aSwapChainImageIndex,aFrameIndex:TpvSizeInt); override; | |
| end; | |
| TScreenMainMenuAntialiasingRenderPass=class(TpvFrameGraph.TRenderPass) | |
| private | |
| fVulkanRenderPass:TpvVulkanRenderPass; | |
| fResourceColor:TpvFrameGraph.TPass.TUsedImageResource; | |
| fResourceSurface:TpvFrameGraph.TPass.TUsedImageResource; | |
| fVulkanTransferCommandBuffer:TpvVulkanCommandBuffer; | |
| fVulkanTransferCommandBufferFence:TpvVulkanFence; | |
| fVulkanVertexShaderModule:TpvVulkanShaderModule; | |
| fVulkanFragmentShaderModule:TpvVulkanShaderModule; | |
| fVulkanPipelineShaderStageVertex:TpvVulkanPipelineShaderStage; | |
| fVulkanPipelineShaderStageFragment:TpvVulkanPipelineShaderStage; | |
| fVulkanGraphicsPipeline:TpvVulkanGraphicsPipeline; | |
| fVulkanSampler:TpvVulkanSampler; | |
| fVulkanUniformBuffers:array[0..MaxSwapChainImages-1] of TpvVulkanBuffer; | |
| fVulkanDescriptorPool:TpvVulkanDescriptorPool; | |
| fVulkanDescriptorSetLayout:TpvVulkanDescriptorSetLayout; | |
| fVulkanDescriptorSets:array[0..MaxSwapChainImages-1] of TpvVulkanDescriptorSet; | |
| fVulkanPipelineLayout:TpvVulkanPipelineLayout; | |
| fBackgroundUniformBuffers:array[0..MaxSwapChainImages-1] of TScreenMainMenuBackgroundUniformBuffer; | |
| public | |
| constructor Create(const aFrameGraph:TpvFrameGraph); override; | |
| destructor Destroy; override; | |
| procedure Show; override; | |
| procedure Hide; override; | |
| procedure AfterCreateSwapChain; override; | |
| procedure BeforeDestroySwapChain; override; | |
| procedure Update(const aUpdateSwapChainImageIndex,aUpdateFrameIndex:TpvSizeInt); override; | |
| procedure Execute(const aCommandBuffer:TpvVulkanCommandBuffer;const aSwapChainImageIndex,aFrameIndex:TpvSizeInt); override; | |
| end; | |
| TScreenMainMenu=class(TpvApplicationScreen) | |
| private | |
| fFrameGraph:TpvFrameGraph; | |
| fSceneContentRenderPass:TScreenMainMenuSceneContentRenderPass; | |
| fTonemappingRenderPass:TScreenMainMenuTonemappingRenderPass; | |
| fAntialiasingRenderPass:TScreenMainMenuAntialiasingRenderPass; | |
| fVulkanSampleCountFlagBits:TVkSampleCountFlagBits; | |
| fVulkanRenderSemaphores:array[0..MaxSwapChainImages-1] of TpvVulkanSemaphore; | |
| fReady:boolean; | |
| fSelectedIndex:TpvInt32; | |
| fStartY:TpvFloat; | |
| fTime:TpvDouble; | |
| fTimeToMusicTickFactor:TpvDouble; | |
| fAudioSoundOGGSoundTrack1:TpvAudioSoundOGG; | |
| public | |
| constructor Create; override; | |
| destructor Destroy; override; | |
| procedure Show; override; | |
| procedure Hide; override; | |
| procedure Resume; override; | |
| procedure Pause; override; | |
| procedure Resize(const aWidth,aHeight:TpvInt32); override; | |
| procedure AfterCreateSwapChain; override; | |
| procedure BeforeDestroySwapChain; override; | |
| function KeyEvent(const aKeyEvent:TpvApplicationInputKeyEvent):boolean; override; | |
| function PointerEvent(const aPointerEvent:TpvApplicationInputPointerEvent):boolean; override; | |
| function Scrolled(const aRelativeAmount:TpvVector2):boolean; override; | |
| function CanBeParallelProcessed:boolean; override; | |
| procedure Update(const aDeltaTime:TpvDouble); override; | |
| procedure Draw(const aSwapChainImageIndex:TpvInt32;var aWaitSemaphore:TpvVulkanSemaphore;const aWaitFence:TpvVulkanFence=nil); override; | |
| end; | |
| implementation | |
| uses UnitApplication; | |
| const MainMenuFullscreenTriangleVertices:array[0..2,0..1,0..1] of TpvFloat= | |
| (((-1.0,-1.0),(0.0,0.0)), | |
| ((-1.0,3.0),(0.0,2.0)), | |
| ((3.0,-1.0),(2.0,0.0))); | |
| FullscreenTriangleIndices:array[0..2] of TpvInt32=(0,1,2); | |
| Offsets:array[0..0] of TVkDeviceSize=(0); | |
| FontSize=3.0; | |
| { TScreenMainMenuSceneContentRenderPass } | |
| constructor TScreenMainMenuSceneContentRenderPass.Create(const aFrameGraph:TpvFrameGraph;const aParent:TScreenMainMenu); | |
| begin | |
| inherited Create(aFrameGraph); | |
| fParent:=aParent; | |
| Name:='SceneContent'; | |
| Queue:=aFrameGraph.UniversalQueue; | |
| pvApplication.PasMPInstance.Invoke(pvApplication.PasMPInstance.ParallelFor(nil, | |
| 0, | |
| (HeightMapWidth*HeightMapHeight)-1, | |
| TerrainHeightMapGenerationParallelForJobMethod, | |
| HeightMapWidth, | |
| 16, | |
| nil)); | |
| pvApplication.PasMPInstance.Invoke(pvApplication.PasMPInstance.ParallelFor(nil, | |
| 0, | |
| (HeightMapWidth*HeightMapHeight)-1, | |
| TerrainVerticesGenerationParallelForJobMethod, | |
| HeightMapWidth, | |
| 16, | |
| nil)); | |
| pvApplication.PasMPInstance.Invoke(pvApplication.PasMPInstance.ParallelFor(nil, | |
| 0, | |
| ((HeightMapWidth-1)*(HeightMapHeight-1))-1, | |
| TerrainIndicesGenerationParallelForJobMethod, | |
| HeightMapWidth-1, | |
| 16, | |
| nil)); | |
| Size:=TpvFrameGraph.TImageSize.Create(TpvFrameGraph.TImageSize.TKind.SurfaceDependent, | |
| 1.0, | |
| 1.0); | |
| if fParent.fVulkanSampleCountFlagBits=TVkSampleCountFlagBits(VK_SAMPLE_COUNT_1_BIT) then begin | |
| fResourceColor:=AddImageOutput('resourcetype_color', | |
| 'scene_color', | |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, | |
| TpvFrameGraph.TLoadOp.Create(TpvFrameGraph.TLoadOp.TKind.Clear, | |
| TpvVector4.InlineableCreate(0.0,0.0,0.0,1.0)), | |
| [TpvFrameGraph.TResourceTransition.TFlag.Attachment] | |
| ); | |
| fResourceDepth:=AddImageDepthOutput('resourcetype_depth', | |
| 'scene_depth', | |
| VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, | |
| TpvFrameGraph.TLoadOp.Create(TpvFrameGraph.TLoadOp.TKind.Clear, | |
| TpvVector4.InlineableCreate(1.0,1.0,1.0,1.0)), | |
| [TpvFrameGraph.TResourceTransition.TFlag.Attachment] | |
| ); | |
| end else begin | |
| fResourceColor:=AddImageOutput('resourcetype_msaa_color', | |
| 'scene_msaa_color', | |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, | |
| TpvFrameGraph.TLoadOp.Create(TpvFrameGraph.TLoadOp.TKind.Clear, | |
| TpvVector4.InlineableCreate(0.0,0.0,0.0,1.0)), | |
| [TpvFrameGraph.TResourceTransition.TFlag.Attachment] | |
| ); | |
| fResourceColor:=AddImageResolveOutput('resourcetype_color', | |
| 'scene_color', | |
| 'scene_msaa_color', | |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, | |
| TpvFrameGraph.TLoadOp.Create(TpvFrameGraph.TLoadOp.TKind.DontCare, | |
| TpvVector4.InlineableCreate(0.0,0.0,0.0,1.0)), | |
| [TpvFrameGraph.TResourceTransition.TFlag.Attachment] | |
| ); | |
| fResourceDepth:=AddImageDepthOutput('resourcetype_msaa_depth', | |
| 'scene_msaa_depth', | |
| VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, | |
| TpvFrameGraph.TLoadOp.Create(TpvFrameGraph.TLoadOp.TKind.Clear, | |
| TpvVector4.InlineableCreate(1.0,1.0,1.0,1.0)), | |
| [TpvFrameGraph.TResourceTransition.TFlag.Attachment] | |
| ); | |
| end; | |
| end; | |
| destructor TScreenMainMenuSceneContentRenderPass.Destroy; | |
| begin | |
| inherited Destroy; | |
| end; | |
| procedure TScreenMainMenuSceneContentRenderPass.TerrainHeightMapGenerationParallelForJobMethod(const aJob:PPasMPJob;const aThreadIndex:TPasMPInt32;const aData:pointer;const aFromIndex,aToIndex:TPasMPNativeInt); | |
| function FBM(st:TpvVector2):TpvFloat; | |
| function Noise(const st:TpvVector2):TpvFloat; | |
| function NoiseRandom(const st:TpvVector2):TpvFloat; | |
| begin | |
| result:=frac(sin(st.Dot(TpvVector2.InlineableCreate(12.9898,78.233)))*43758.5453123); | |
| end; | |
| var i,f,u:TpvVector2; | |
| a,b,c,d:TpvFloat; | |
| begin | |
| i.x:=floor(st.x); | |
| i.y:=floor(st.y); | |
| f.x:=frac(frac(st.x)+1.0); | |
| f.y:=frac(frac(st.y)+1.0); | |
| a:=NoiseRandom(i+TpvVector2.InlineableCreate(0.0,0.0)); | |
| b:=NoiseRandom(i+TpvVector2.InlineableCreate(1.0,0.0)); | |
| c:=NoiseRandom(i+TpvVector2.InlineableCreate(0.0,1.0)); | |
| d:=NoiseRandom(i+TpvVector2.InlineableCreate(1.0,1.0)); | |
| u:=f*f*(TpvVector2.InlineableCreate(3.0,3.0)-(f*2.0)); | |
| result:=((a*(1.0-u.x))+(b*u.x))+ | |
| ((c-a)*u.y*(1.0-u.x))+ | |
| ((d-b)*u.x*u.y); | |
| end; | |
| var Iteration:TpvSizeInt; | |
| Amplitude:TpvFloat; | |
| begin | |
| result:=0; | |
| Amplitude:=0.5; | |
| for Iteration:=0 to 4 do begin | |
| result:=result+(Noise(st)*Amplitude); | |
| st:=st*2.0; | |
| Amplitude:=Amplitude*0.5; | |
| end; | |
| end; | |
| var Index,x,y:TpvSizeInt; | |
| p:TpvVector2; | |
| begin | |
| for Index:=aFromIndex to aToIndex do begin | |
| x:=Index mod HeightMapWidth; | |
| y:=Index div HeightMapWidth; | |
| p:=TpvVector2.InlineableCreate(x-(HeightMapWidth*0.5),y); | |
| //p:=TpvVector2.InlineableCreate(abs(x-(HeightMapWidth*0.5)),y); | |
| fTerrainHeightMap[Index]:=-Mix(8.0, | |
| ((Mix(FBM(p*0.1), | |
| FBM(TpvVector2.InlineableCreate(p.x,(HeightMapHeight-1.0)-p.y)*0.1), | |
| LinearStep(HeightMapHeight*0.875,HeightMapHeight-1.0,y+0.0))-1.0)*24.0)+0.0, | |
| sqr(LinearStep(16.0,64.0,abs(x-(HeightMapWidth*0.5))*GridSize))); | |
| end; | |
| end; | |
| procedure TScreenMainMenuSceneContentRenderPass.TerrainVerticesGenerationParallelForJobMethod(const aJob:PPasMPJob;const aThreadIndex:TPasMPInt32;const aData:pointer;const aFromIndex,aToIndex:TPasMPNativeInt); | |
| var Index,PartIndex,OffsetedIndex,x,y:TpvSizeInt; | |
| begin | |
| for Index:=aFromIndex to aToIndex do begin | |
| x:=Index mod HeightMapWidth; | |
| y:=Index div HeightMapWidth; | |
| for PartIndex:=0 to TerrainParts-1 do begin | |
| OffsetedIndex:=Index+(PartIndex*(HeightMapWidth*HeightMapHeight)); | |
| fTerrainVertices[OffsetedIndex].Position:=TpvVector3.InlineableCreate((x-(HeightMapWidth*0.5))*GridSize, | |
| fTerrainHeightMap[(y*HeightMapWidth)+x], | |
| ((y-((HeightMapHeight-1)*(TerrainParts-1)))+((HeightMapHeight-1)*PartIndex))*GridSize); | |
| fTerrainVertices[OffsetedIndex].TexCoord.x:=x; | |
| fTerrainVertices[OffsetedIndex].TexCoord.y:=y+(PartIndex*HeightMapHeight); | |
| //fTerrainVertices[OffsetedIndex].TexCoord:=TpvVector4.InlineableCreate(x,y+(PartIndex*HeightMapHeight),0.0,0.0); | |
| end; | |
| end; | |
| end; | |
| procedure TScreenMainMenuSceneContentRenderPass.TerrainIndicesGenerationParallelForJobMethod(const aJob:PPasMPJob;const aThreadIndex:TPasMPInt32;const aData:pointer;const aFromIndex,aToIndex:TPasMPNativeInt); | |
| var Index,PartIndex,OffsetedIndex,x,y,a,b,c,d:TpvSizeInt; | |
| begin | |
| for Index:=aFromIndex to aToIndex do begin | |
| x:=Index mod (HeightMapWidth-1); | |
| y:=Index div (HeightMapWidth-1); | |
| for PartIndex:=0 to TerrainParts-1 do begin | |
| OffsetedIndex:=(PartIndex*(HeightMapWidth*HeightMapHeight)); | |
| a:=(((y+0)*HeightMapWidth)+(x+0))+OffsetedIndex; | |
| b:=(((y+0)*HeightMapWidth)+(x+1))+OffsetedIndex; | |
| c:=(((y+1)*HeightMapWidth)+(x+1))+OffsetedIndex; | |
| d:=(((y+1)*HeightMapWidth)+(x+0))+OffsetedIndex; | |
| OffsetedIndex:=Index+(PartIndex*((HeightMapWidth-1)*(HeightMapHeight-1))); | |
| fTerrainIndices[(OffsetedIndex*6)+0]:=a; | |
| fTerrainIndices[(OffsetedIndex*6)+1]:=b; | |
| fTerrainIndices[(OffsetedIndex*6)+2]:=d; | |
| fTerrainIndices[(OffsetedIndex*6)+3]:=b; | |
| fTerrainIndices[(OffsetedIndex*6)+4]:=c; | |
| fTerrainIndices[(OffsetedIndex*6)+5]:=d; | |
| end; | |
| end; | |
| end; | |
| procedure TScreenMainMenuSceneContentRenderPass.Show; | |
| var x,y:TpvSizeInt; | |
| Stream:TStream; | |
| p:PTerrainTexturePixel; | |
| begin | |
| inherited Show; | |
| fVulkanGraphicsCommandBuffer:=TpvVulkanCommandBuffer.Create(FrameGraph.GraphicsQueue.CommandPool,VK_COMMAND_BUFFER_LEVEL_PRIMARY); | |
| fVulkanGraphicsCommandBufferFence:=TpvVulkanFence.Create(pvApplication.VulkanDevice); | |
| fVulkanTransferCommandBuffer:=TpvVulkanCommandBuffer.Create(FrameGraph.TransferQueue.CommandPool,VK_COMMAND_BUFFER_LEVEL_PRIMARY); | |
| fVulkanTransferCommandBufferFence:=TpvVulkanFence.Create(pvApplication.VulkanDevice); | |
| begin | |
| Stream:=pvApplication.Assets.GetAssetStream('shaders/mainmenu_background_vert.spv'); | |
| try | |
| fBackgroundVertexShaderModule:=TpvVulkanShaderModule.Create(pvApplication.VulkanDevice,Stream); | |
| finally | |
| Stream.Free; | |
| end; | |
| Stream:=pvApplication.Assets.GetAssetStream('shaders/mainmenu_background_frag.spv'); | |
| try | |
| fBackgroundFragmentShaderModule:=TpvVulkanShaderModule.Create(pvApplication.VulkanDevice,Stream); | |
| finally | |
| Stream.Free; | |
| end; | |
| fBackgroundVulkanPipelineShaderStageVertex:=TpvVulkanPipelineShaderStage.Create(VK_SHADER_STAGE_VERTEX_BIT,fBackgroundVertexShaderModule,'main'); | |
| fBackgroundVulkanPipelineShaderStageFragment:=TpvVulkanPipelineShaderStage.Create(VK_SHADER_STAGE_FRAGMENT_BIT,fBackgroundFragmentShaderModule,'main'); | |
| fBackgroundVulkanGraphicsPipeline:=nil; | |
| end; | |
| begin | |
| for y:=0 to TerrainTextureSize-1 do begin | |
| for x:=0 to TerrainTextureSize-1 do begin | |
| p:=@fTerrainTextureData[y,x]; | |
| if (x<((TerrainTextureBorderSize+1) shr 1)) or | |
| (x>((TerrainTextureSize-1)-((TerrainTextureBorderSize+1) shr 1))) or | |
| (y<((TerrainTextureBorderSize+1) shr 1)) or | |
| (y>((TerrainTextureSize-1)-((TerrainTextureBorderSize+1) shr 1))) then begin | |
| p^.r:=52; | |
| p^.g:=28; | |
| p^.b:=245; | |
| p^.a:=255; | |
| end else begin | |
| p^.r:=0; | |
| p^.g:=13; | |
| p^.b:=51; | |
| p^.a:=255; | |
| end; | |
| end; | |
| end; | |
| fTerrainTexture:=TpvVulkanTexture.CreateFromMemory(pvApplication.VulkanDevice, | |
| pvApplication.VulkanDevice.GraphicsQueue, | |
| fVulkanGraphicsCommandBuffer, | |
| fVulkanGraphicsCommandBufferFence, | |
| pvApplication.VulkanDevice.TransferQueue, | |
| fVulkanTransferCommandBuffer, | |
| fVulkanTransferCommandBufferFence, | |
| VK_FORMAT_R8G8B8A8_SRGB, | |
| VK_SAMPLE_COUNT_1_BIT, | |
| TerrainTextureSize, | |
| TerrainTextureSize, | |
| 0, | |
| 0, | |
| 1, | |
| -1, | |
| [TpvVulkanTextureUsageFlag.TransferDst,TpvVulkanTextureUsageFlag.Sampled], | |
| @fTerrainTextureData, | |
| SizeOf(fTerrainTextureData), | |
| false, | |
| false, | |
| 1, | |
| true);{} | |
| fTerrainTexture.WrapModeU:=TpvVulkanTextureWrapMode.WrappedRepeat; | |
| fTerrainTexture.WrapModeV:=TpvVulkanTextureWrapMode.WrappedRepeat; | |
| fTerrainTexture.WrapModeW:=TpvVulkanTextureWrapMode.ClampToEdge; | |
| fTerrainTexture.BorderColor:=VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK; | |
| if pvApplication.VulkanDevice.PhysicalDevice.Properties.limits.maxSamplerAnisotropy>1.0 then begin | |
| fTerrainTexture.MaxAnisotropy:=pvApplication.VulkanDevice.PhysicalDevice.Properties.limits.maxSamplerAnisotropy; | |
| end else begin | |
| fTerrainTexture.MaxAnisotropy:=0.0; | |
| end; | |
| fTerrainTexture.UpdateSampler; | |
| Stream:=pvApplication.Assets.GetAssetStream('shaders/mainmenu_terrain_vert.spv'); | |
| try | |
| fTerrainVertexShaderModule:=TpvVulkanShaderModule.Create(pvApplication.VulkanDevice,Stream); | |
| finally | |
| Stream.Free; | |
| end; | |
| Stream:=pvApplication.Assets.GetAssetStream('shaders/mainmenu_terrain_frag.spv'); | |
| try | |
| fTerrainFragmentShaderModule:=TpvVulkanShaderModule.Create(pvApplication.VulkanDevice,Stream); | |
| finally | |
| Stream.Free; | |
| end; | |
| fTerrainVulkanPipelineShaderStageVertex:=TpvVulkanPipelineShaderStage.Create(VK_SHADER_STAGE_VERTEX_BIT,fTerrainVertexShaderModule,'main'); | |
| fTerrainVulkanPipelineShaderStageFragment:=TpvVulkanPipelineShaderStage.Create(VK_SHADER_STAGE_FRAGMENT_BIT,fTerrainFragmentShaderModule,'main'); | |
| fTerrainVulkanGraphicsPipeline:=nil; | |
| fTerrainVulkanVertexBuffer:=TpvVulkanBuffer.Create(pvApplication.VulkanDevice, | |
| SizeOf(fTerrainVertices), | |
| TVkBufferUsageFlags(VK_BUFFER_USAGE_TRANSFER_DST_BIT) or TVkBufferUsageFlags(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT) or TVkBufferUsageFlags(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), | |
| TVkSharingMode(VK_SHARING_MODE_EXCLUSIVE), | |
| FrameGraph.QueueFamilyIndices.Items, | |
| TVkMemoryPropertyFlags(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)); | |
| fTerrainVulkanVertexBuffer.UploadData(FrameGraph.TransferQueue.PhysicalQueue, | |
| fVulkanTransferCommandBuffer, | |
| fVulkanTransferCommandBufferFence, | |
| fTerrainVertices, | |
| 0, | |
| SizeOf(fTerrainVertices), | |
| TpvVulkanBufferUseTemporaryStagingBufferMode.Yes); | |
| fTerrainVulkanIndexBuffer:=TpvVulkanBuffer.Create(pvApplication.VulkanDevice, | |
| SizeOf(fTerrainIndices), | |
| TVkBufferUsageFlags(VK_BUFFER_USAGE_TRANSFER_DST_BIT) or TVkBufferUsageFlags(VK_BUFFER_USAGE_INDEX_BUFFER_BIT) or TVkBufferUsageFlags(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), | |
| TVkSharingMode(VK_SHARING_MODE_EXCLUSIVE), | |
| FrameGraph.QueueFamilyIndices.Items, | |
| TVkMemoryPropertyFlags(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)); | |
| fTerrainVulkanIndexBuffer.UploadData(FrameGraph.TransferQueue.PhysicalQueue, | |
| fVulkanTransferCommandBuffer, | |
| fVulkanTransferCommandBufferFence, | |
| fTerrainIndices, | |
| 0, | |
| SizeOf(fTerrainIndices), | |
| TpvVulkanBufferUseTemporaryStagingBufferMode.Yes); | |
| end; | |
| begin | |
| Stream:=pvApplication.Assets.GetAssetStream('shaders/mainmenu_foreground_vert.spv'); | |
| try | |
| fForegroundVertexShaderModule:=TpvVulkanShaderModule.Create(pvApplication.VulkanDevice,Stream); | |
| finally | |
| Stream.Free; | |
| end; | |
| Stream:=pvApplication.Assets.GetAssetStream('shaders/mainmenu_foreground_frag.spv'); | |
| try | |
| fForegroundFragmentShaderModule:=TpvVulkanShaderModule.Create(pvApplication.VulkanDevice,Stream); | |
| finally | |
| Stream.Free; | |
| end; | |
| fForegroundVulkanPipelineShaderStageVertex:=TpvVulkanPipelineShaderStage.Create(VK_SHADER_STAGE_VERTEX_BIT,fForegroundVertexShaderModule,'main'); | |
| fForegroundVulkanPipelineShaderStageFragment:=TpvVulkanPipelineShaderStage.Create(VK_SHADER_STAGE_FRAGMENT_BIT,fForegroundFragmentShaderModule,'main'); | |
| fForegroundVulkanGraphicsPipeline:=nil; | |
| end; | |
| end; | |
| procedure TScreenMainMenuSceneContentRenderPass.Hide; | |
| begin | |
| FreeAndNil(fForegroundVulkanPipelineShaderStageVertex); | |
| FreeAndNil(fForegroundVulkanPipelineShaderStageFragment); | |
| FreeAndNil(fForegroundFragmentShaderModule); | |
| FreeAndNil(fForegroundVertexShaderModule); | |
| FreeAndNil(fTerrainVulkanIndexBuffer); | |
| FreeAndNil(fTerrainVulkanVertexBuffer); | |
| FreeAndNil(fTerrainVulkanPipelineShaderStageVertex); | |
| FreeAndNil(fTerrainVulkanPipelineShaderStageFragment); | |
| FreeAndNil(fTerrainFragmentShaderModule); | |
| FreeAndNil(fTerrainVertexShaderModule); | |
| FreeAndNil(fTerrainTexture); | |
| FreeAndNil(fBackgroundVulkanPipelineShaderStageVertex); | |
| FreeAndNil(fBackgroundVulkanPipelineShaderStageFragment); | |
| FreeAndNil(fBackgroundFragmentShaderModule); | |
| FreeAndNil(fBackgroundVertexShaderModule); | |
| FreeAndNil(fVulkanTransferCommandBufferFence); | |
| FreeAndNil(fVulkanTransferCommandBuffer); | |
| FreeAndNil(fVulkanGraphicsCommandBufferFence); | |
| FreeAndNil(fVulkanGraphicsCommandBuffer); | |
| inherited Hide; | |
| end; | |
| procedure TScreenMainMenuSceneContentRenderPass.AfterCreateSwapChain; | |
| var SwapChainImageIndex:TpvSizeInt; | |
| begin | |
| inherited AfterCreateSwapChain; | |
| fVulkanRenderPass:=VulkanRenderPass; | |
| begin | |
| for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin | |
| fBackgroundVulkanUniformBuffers[SwapChainImageIndex]:=TpvVulkanBuffer.Create(pvApplication.VulkanDevice, | |
| SizeOf(TScreenMainMenuBackgroundUniformBuffer), | |
| TVkBufferUsageFlags(VK_BUFFER_USAGE_TRANSFER_DST_BIT) or TVkBufferUsageFlags(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT), | |
| TVkSharingMode(VK_SHARING_MODE_EXCLUSIVE), | |
| FrameGraph.QueueFamilyIndices.Items, | |
| TVkMemoryPropertyFlags(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) or TVkMemoryPropertyFlags(VK_MEMORY_PROPERTY_HOST_COHERENT_BIT), | |
| 0, | |
| 0, | |
| 0, | |
| 0, | |
| 0, | |
| [TpvVulkanBufferFlag.PersistentMapped] | |
| ); | |
| fBackgroundVulkanUniformBuffers[SwapChainImageIndex].UploadData(FrameGraph.TransferQueue.PhysicalQueue, | |
| fVulkanTransferCommandBuffer, | |
| fVulkanTransferCommandBufferFence, | |
| fBackgroundUniformBuffers[SwapChainImageIndex], | |
| 0, | |
| SizeOf(TScreenMainMenuBackgroundUniformBuffer), | |
| TpvVulkanBufferUseTemporaryStagingBufferMode.Yes); | |
| end; | |
| fBackgroundVulkanDescriptorPool:=TpvVulkanDescriptorPool.Create(pvApplication.VulkanDevice, | |
| TVkDescriptorPoolCreateFlags(VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT), | |
| MaxSwapChainImages); | |
| fBackgroundVulkanDescriptorPool.AddDescriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,MaxSwapChainImages); | |
| fBackgroundVulkanDescriptorPool.Initialize; | |
| fBackgroundVulkanDescriptorSetLayout:=TpvVulkanDescriptorSetLayout.Create(pvApplication.VulkanDevice); | |
| fBackgroundVulkanDescriptorSetLayout.AddBinding(0, | |
| VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, | |
| 1, | |
| TVkShaderStageFlags(VK_SHADER_STAGE_VERTEX_BIT) or TVkShaderStageFlags(VK_SHADER_STAGE_FRAGMENT_BIT), | |
| []); | |
| fBackgroundVulkanDescriptorSetLayout.Initialize; | |
| for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin | |
| fBackgroundVulkanDescriptorSets[SwapChainImageIndex]:=TpvVulkanDescriptorSet.Create(fBackgroundVulkanDescriptorPool, | |
| fBackgroundVulkanDescriptorSetLayout); | |
| fBackgroundVulkanDescriptorSets[SwapChainImageIndex].WriteToDescriptorSet(0, | |
| 0, | |
| 1, | |
| TVkDescriptorType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER), | |
| [], | |
| [fBackgroundVulkanUniformBuffers[SwapChainImageIndex].DescriptorBufferInfo], | |
| [], | |
| false | |
| ); | |
| fBackgroundVulkanDescriptorSets[SwapChainImageIndex].Flush; | |
| end; | |
| fBackgroundVulkanPipelineLayout:=TpvVulkanPipelineLayout.Create(pvApplication.VulkanDevice); | |
| fBackgroundVulkanPipelineLayout.AddDescriptorSetLayout(fBackgroundVulkanDescriptorSetLayout); | |
| fBackgroundVulkanPipelineLayout.Initialize; | |
| fBackgroundVulkanGraphicsPipeline:=TpvVulkanGraphicsPipeline.Create(pvApplication.VulkanDevice, | |
| pvApplication.VulkanPipelineCache, | |
| 0, | |
| [], | |
| fBackgroundVulkanPipelineLayout, | |
| fVulkanRenderPass, | |
| VulkanRenderPassSubpassIndex, | |
| nil, | |
| 0); | |
| fBackgroundVulkanGraphicsPipeline.AddStage(fBackgroundVulkanPipelineShaderStageVertex); | |
| fBackgroundVulkanGraphicsPipeline.AddStage(fBackgroundVulkanPipelineShaderStageFragment); | |
| fBackgroundVulkanGraphicsPipeline.InputAssemblyState.Topology:=VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; | |
| fBackgroundVulkanGraphicsPipeline.InputAssemblyState.PrimitiveRestartEnable:=false; | |
| fBackgroundVulkanGraphicsPipeline.ViewPortState.AddViewPort(0.0,0.0,pvApplication.VulkanSwapChain.Width,pvApplication.VulkanSwapChain.Height,0.0,1.0); | |
| fBackgroundVulkanGraphicsPipeline.ViewPortState.AddScissor(0,0,pvApplication.VulkanSwapChain.Width,pvApplication.VulkanSwapChain.Height); | |
| fBackgroundVulkanGraphicsPipeline.RasterizationState.DepthClampEnable:=false; | |
| fBackgroundVulkanGraphicsPipeline.RasterizationState.RasterizerDiscardEnable:=false; | |
| fBackgroundVulkanGraphicsPipeline.RasterizationState.PolygonMode:=VK_POLYGON_MODE_FILL; | |
| fBackgroundVulkanGraphicsPipeline.RasterizationState.CullMode:=TVkCullModeFlags(VK_CULL_MODE_NONE); | |
| //fMainMenuBackgroundVulkanGraphicsPipeline.RasterizationState.CullMode:=TVkCullModeFlags(VK_CULL_MODE_BACK_BIT); | |
| fBackgroundVulkanGraphicsPipeline.RasterizationState.FrontFace:=VK_FRONT_FACE_CLOCKWISE; | |
| fBackgroundVulkanGraphicsPipeline.RasterizationState.DepthBiasEnable:=false; | |
| fBackgroundVulkanGraphicsPipeline.RasterizationState.DepthBiasConstantFactor:=0.0; | |
| fBackgroundVulkanGraphicsPipeline.RasterizationState.DepthBiasClamp:=0.0; | |
| fBackgroundVulkanGraphicsPipeline.RasterizationState.DepthBiasSlopeFactor:=0.0; | |
| fBackgroundVulkanGraphicsPipeline.RasterizationState.LineWidth:=1.0; | |
| fBackgroundVulkanGraphicsPipeline.MultisampleState.RasterizationSamples:=fParent.fVulkanSampleCountFlagBits; | |
| fBackgroundVulkanGraphicsPipeline.MultisampleState.SampleShadingEnable:=false; | |
| fBackgroundVulkanGraphicsPipeline.MultisampleState.MinSampleShading:=0.0; | |
| fBackgroundVulkanGraphicsPipeline.MultisampleState.CountSampleMasks:=0; | |
| fBackgroundVulkanGraphicsPipeline.MultisampleState.AlphaToCoverageEnable:=false; | |
| fBackgroundVulkanGraphicsPipeline.MultisampleState.AlphaToOneEnable:=false; | |
| fBackgroundVulkanGraphicsPipeline.ColorBlendState.LogicOpEnable:=false; | |
| fBackgroundVulkanGraphicsPipeline.ColorBlendState.LogicOp:=VK_LOGIC_OP_COPY; | |
| fBackgroundVulkanGraphicsPipeline.ColorBlendState.BlendConstants[0]:=0.0; | |
| fBackgroundVulkanGraphicsPipeline.ColorBlendState.BlendConstants[1]:=0.0; | |
| fBackgroundVulkanGraphicsPipeline.ColorBlendState.BlendConstants[2]:=0.0; | |
| fBackgroundVulkanGraphicsPipeline.ColorBlendState.BlendConstants[3]:=0.0; | |
| fBackgroundVulkanGraphicsPipeline.ColorBlendState.AddColorBlendAttachmentState(false, | |
| VK_BLEND_FACTOR_SRC_ALPHA, | |
| VK_BLEND_FACTOR_DST_ALPHA, | |
| VK_BLEND_OP_ADD, | |
| VK_BLEND_FACTOR_ONE, | |
| VK_BLEND_FACTOR_ZERO, | |
| VK_BLEND_OP_ADD, | |
| TVkColorComponentFlags(VK_COLOR_COMPONENT_R_BIT) or | |
| TVkColorComponentFlags(VK_COLOR_COMPONENT_G_BIT) or | |
| TVkColorComponentFlags(VK_COLOR_COMPONENT_B_BIT) or | |
| TVkColorComponentFlags(VK_COLOR_COMPONENT_A_BIT)); | |
| fBackgroundVulkanGraphicsPipeline.DepthStencilState.DepthTestEnable:=false; | |
| fBackgroundVulkanGraphicsPipeline.DepthStencilState.DepthWriteEnable:=false; | |
| fBackgroundVulkanGraphicsPipeline.DepthStencilState.DepthCompareOp:=VK_COMPARE_OP_ALWAYS; | |
| fBackgroundVulkanGraphicsPipeline.DepthStencilState.DepthBoundsTestEnable:=false; | |
| fBackgroundVulkanGraphicsPipeline.DepthStencilState.StencilTestEnable:=false; | |
| fBackgroundVulkanGraphicsPipeline.Initialize; | |
| fBackgroundVulkanGraphicsPipeline.FreeMemory; | |
| end; | |
| begin | |
| for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin | |
| fTerrainVulkanUniformBuffers[SwapChainImageIndex]:=TpvVulkanBuffer.Create(pvApplication.VulkanDevice, | |
| SizeOf(TScreenMainMenuTerrainUniformBuffer), | |
| TVkBufferUsageFlags(VK_BUFFER_USAGE_TRANSFER_DST_BIT) or TVkBufferUsageFlags(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT), | |
| TVkSharingMode(VK_SHARING_MODE_EXCLUSIVE), | |
| FrameGraph.QueueFamilyIndices.Items, | |
| TVkMemoryPropertyFlags(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) or TVkMemoryPropertyFlags(VK_MEMORY_PROPERTY_HOST_COHERENT_BIT), | |
| 0, | |
| 0, | |
| 0, | |
| 0, | |
| 0, | |
| [TpvVulkanBufferFlag.PersistentMapped] | |
| ); | |
| fTerrainVulkanUniformBuffers[SwapChainImageIndex].UploadData(FrameGraph.TransferQueue.PhysicalQueue, | |
| fVulkanTransferCommandBuffer, | |
| fVulkanTransferCommandBufferFence, | |
| fTerrainUniformBuffers[SwapChainImageIndex], | |
| 0, | |
| SizeOf(TScreenMainMenuTerrainUniformBuffer), | |
| TpvVulkanBufferUseTemporaryStagingBufferMode.Yes); | |
| end; | |
| fTerrainVulkanDescriptorPool:=TpvVulkanDescriptorPool.Create(pvApplication.VulkanDevice, | |
| TVkDescriptorPoolCreateFlags(VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT), | |
| MaxSwapChainImages); | |
| fTerrainVulkanDescriptorPool.AddDescriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,MaxSwapChainImages); | |
| fTerrainVulkanDescriptorPool.AddDescriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,MaxSwapChainImages); | |
| fTerrainVulkanDescriptorPool.AddDescriptorPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,MaxSwapChainImages*2); | |
| fTerrainVulkanDescriptorPool.Initialize; | |
| fTerrainVulkanDescriptorSetLayout:=TpvVulkanDescriptorSetLayout.Create(pvApplication.VulkanDevice); | |
| fTerrainVulkanDescriptorSetLayout.AddBinding(0, | |
| VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, | |
| 1, | |
| TVkShaderStageFlags(VK_SHADER_STAGE_VERTEX_BIT) or TVkShaderStageFlags(VK_SHADER_STAGE_FRAGMENT_BIT), | |
| []); | |
| fTerrainVulkanDescriptorSetLayout.AddBinding(1, | |
| VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, | |
| 1, | |
| TVkShaderStageFlags(VK_SHADER_STAGE_FRAGMENT_BIT), | |
| []); | |
| fTerrainVulkanDescriptorSetLayout.AddBinding(2, | |
| VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, | |
| 1, | |
| TVkShaderStageFlags(VK_SHADER_STAGE_VERTEX_BIT), | |
| []); | |
| fTerrainVulkanDescriptorSetLayout.AddBinding(3, | |
| VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, | |
| 1, | |
| TVkShaderStageFlags(VK_SHADER_STAGE_VERTEX_BIT), | |
| []); | |
| fTerrainVulkanDescriptorSetLayout.Initialize; | |
| for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin | |
| fTerrainVulkanDescriptorSets[SwapChainImageIndex]:=TpvVulkanDescriptorSet.Create(fTerrainVulkanDescriptorPool, | |
| fTerrainVulkanDescriptorSetLayout); | |
| fTerrainVulkanDescriptorSets[SwapChainImageIndex].WriteToDescriptorSet(0, | |
| 0, | |
| 1, | |
| TVkDescriptorType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER), | |
| [], | |
| [fTerrainVulkanUniformBuffers[SwapChainImageIndex].DescriptorBufferInfo], | |
| [], | |
| false | |
| ); | |
| fTerrainVulkanDescriptorSets[SwapChainImageIndex].WriteToDescriptorSet(1, | |
| 0, | |
| 1, | |
| TVkDescriptorType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER), | |
| [fTerrainTexture.DescriptorImageInfo], | |
| [], | |
| [], | |
| false | |
| ); | |
| fTerrainVulkanDescriptorSets[SwapChainImageIndex].WriteToDescriptorSet(2, | |
| 0, | |
| 1, | |
| TVkDescriptorType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER), | |
| [], | |
| [fTerrainVulkanVertexBuffer.DescriptorBufferInfo], | |
| [], | |
| false | |
| ); | |
| fTerrainVulkanDescriptorSets[SwapChainImageIndex].WriteToDescriptorSet(3, | |
| 0, | |
| 1, | |
| TVkDescriptorType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER), | |
| [], | |
| [fTerrainVulkanIndexBuffer.DescriptorBufferInfo], | |
| [], | |
| false | |
| ); | |
| fTerrainVulkanDescriptorSets[SwapChainImageIndex].Flush; | |
| end; | |
| fTerrainVulkanPipelineLayout:=TpvVulkanPipelineLayout.Create(pvApplication.VulkanDevice); | |
| fTerrainVulkanPipelineLayout.AddDescriptorSetLayout(fTerrainVulkanDescriptorSetLayout); | |
| fTerrainVulkanPipelineLayout.Initialize; | |
| fTerrainVulkanGraphicsPipeline:=TpvVulkanGraphicsPipeline.Create(pvApplication.VulkanDevice, | |
| pvApplication.VulkanPipelineCache, | |
| 0, | |
| [], | |
| fTerrainVulkanPipelineLayout, | |
| fVulkanRenderPass, | |
| VulkanRenderPassSubpassIndex, | |
| nil, | |
| 0); | |
| fTerrainVulkanGraphicsPipeline.AddStage(fTerrainVulkanPipelineShaderStageVertex); | |
| fTerrainVulkanGraphicsPipeline.AddStage(fTerrainVulkanPipelineShaderStageFragment); | |
| fTerrainVulkanGraphicsPipeline.InputAssemblyState.Topology:=VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; | |
| fTerrainVulkanGraphicsPipeline.InputAssemblyState.PrimitiveRestartEnable:=false; | |
| fTerrainVulkanGraphicsPipeline.VertexInputState.AddVertexInputBindingDescription(0,SizeOf(TTerrainVertex),VK_VERTEX_INPUT_RATE_VERTEX); | |
| fTerrainVulkanGraphicsPipeline.VertexInputState.AddVertexInputAttributeDescription(0,0,VK_FORMAT_R32G32B32_SFLOAT,TpvPtrUInt(pointer(@PTerrainVertex(nil)^.Position))); | |
| fTerrainVulkanGraphicsPipeline.VertexInputState.AddVertexInputAttributeDescription(1,0,VK_FORMAT_R16G16_SFLOAT,TpvPtrUInt(pointer(@PTerrainVertex(nil)^.TexCoord))); | |
| fTerrainVulkanGraphicsPipeline.ViewPortState.AddViewPort(0.0,0.0,pvApplication.VulkanSwapChain.Width,pvApplication.VulkanSwapChain.Height,0.0,1.0); | |
| fTerrainVulkanGraphicsPipeline.ViewPortState.AddScissor(0,0,pvApplication.VulkanSwapChain.Width,pvApplication.VulkanSwapChain.Height); | |
| fTerrainVulkanGraphicsPipeline.RasterizationState.DepthClampEnable:=false; | |
| fTerrainVulkanGraphicsPipeline.RasterizationState.RasterizerDiscardEnable:=false; | |
| fTerrainVulkanGraphicsPipeline.RasterizationState.PolygonMode:=VK_POLYGON_MODE_FILL; | |
| fTerrainVulkanGraphicsPipeline.RasterizationState.CullMode:=TVkCullModeFlags(VK_CULL_MODE_BACK_BIT); | |
| fTerrainVulkanGraphicsPipeline.RasterizationState.FrontFace:=VK_FRONT_FACE_CLOCKWISE; | |
| fTerrainVulkanGraphicsPipeline.RasterizationState.DepthBiasEnable:=false; | |
| fTerrainVulkanGraphicsPipeline.RasterizationState.DepthBiasConstantFactor:=0.0; | |
| fTerrainVulkanGraphicsPipeline.RasterizationState.DepthBiasClamp:=0.0; | |
| fTerrainVulkanGraphicsPipeline.RasterizationState.DepthBiasSlopeFactor:=0.0; | |
| fTerrainVulkanGraphicsPipeline.RasterizationState.LineWidth:=1.0; | |
| fTerrainVulkanGraphicsPipeline.MultisampleState.RasterizationSamples:=fParent.fVulkanSampleCountFlagBits; | |
| fTerrainVulkanGraphicsPipeline.MultisampleState.SampleShadingEnable:=false; | |
| fTerrainVulkanGraphicsPipeline.MultisampleState.MinSampleShading:=0.0; | |
| fTerrainVulkanGraphicsPipeline.MultisampleState.CountSampleMasks:=0; | |
| fTerrainVulkanGraphicsPipeline.MultisampleState.AlphaToCoverageEnable:=false; | |
| fTerrainVulkanGraphicsPipeline.MultisampleState.AlphaToOneEnable:=false; | |
| fTerrainVulkanGraphicsPipeline.ColorBlendState.LogicOpEnable:=false; | |
| fTerrainVulkanGraphicsPipeline.ColorBlendState.LogicOp:=VK_LOGIC_OP_COPY; | |
| fTerrainVulkanGraphicsPipeline.ColorBlendState.BlendConstants[0]:=0.0; | |
| fTerrainVulkanGraphicsPipeline.ColorBlendState.BlendConstants[1]:=0.0; | |
| fTerrainVulkanGraphicsPipeline.ColorBlendState.BlendConstants[2]:=0.0; | |
| fTerrainVulkanGraphicsPipeline.ColorBlendState.BlendConstants[3]:=0.0; | |
| fTerrainVulkanGraphicsPipeline.ColorBlendState.AddColorBlendAttachmentState(false, | |
| VK_BLEND_FACTOR_SRC_ALPHA, | |
| VK_BLEND_FACTOR_DST_ALPHA, | |
| VK_BLEND_OP_ADD, | |
| VK_BLEND_FACTOR_ONE, | |
| VK_BLEND_FACTOR_ZERO, | |
| VK_BLEND_OP_ADD, | |
| TVkColorComponentFlags(VK_COLOR_COMPONENT_R_BIT) or | |
| TVkColorComponentFlags(VK_COLOR_COMPONENT_G_BIT) or | |
| TVkColorComponentFlags(VK_COLOR_COMPONENT_B_BIT) or | |
| TVkColorComponentFlags(VK_COLOR_COMPONENT_A_BIT)); | |
| fTerrainVulkanGraphicsPipeline.DepthStencilState.DepthTestEnable:=true; | |
| fTerrainVulkanGraphicsPipeline.DepthStencilState.DepthWriteEnable:=true; | |
| fTerrainVulkanGraphicsPipeline.DepthStencilState.DepthCompareOp:=VK_COMPARE_OP_LESS; | |
| fTerrainVulkanGraphicsPipeline.DepthStencilState.DepthBoundsTestEnable:=false; | |
| fTerrainVulkanGraphicsPipeline.DepthStencilState.StencilTestEnable:=false; | |
| fTerrainVulkanGraphicsPipeline.Initialize; | |
| fTerrainVulkanGraphicsPipeline.FreeMemory; | |
| end; | |
| begin | |
| for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin | |
| fForegroundVulkanUniformBuffers[SwapChainImageIndex]:=TpvVulkanBuffer.Create(pvApplication.VulkanDevice, | |
| SizeOf(TScreenMainMenuForegroundUniformBuffer), | |
| TVkBufferUsageFlags(VK_BUFFER_USAGE_TRANSFER_DST_BIT) or TVkBufferUsageFlags(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT), | |
| TVkSharingMode(VK_SHARING_MODE_EXCLUSIVE), | |
| FrameGraph.QueueFamilyIndices.Items, | |
| TVkMemoryPropertyFlags(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) or TVkMemoryPropertyFlags(VK_MEMORY_PROPERTY_HOST_COHERENT_BIT), | |
| 0, | |
| 0, | |
| 0, | |
| 0, | |
| 0, | |
| [TpvVulkanBufferFlag.PersistentMapped] | |
| ); | |
| fForegroundVulkanUniformBuffers[SwapChainImageIndex].UploadData(FrameGraph.TransferQueue.PhysicalQueue, | |
| fVulkanTransferCommandBuffer, | |
| fVulkanTransferCommandBufferFence, | |
| fForegroundUniformBuffers[SwapChainImageIndex], | |
| 0, | |
| SizeOf(TScreenMainMenuForegroundUniformBuffer), | |
| TpvVulkanBufferUseTemporaryStagingBufferMode.Yes); | |
| end; | |
| fForegroundVulkanDescriptorPool:=TpvVulkanDescriptorPool.Create(pvApplication.VulkanDevice, | |
| TVkDescriptorPoolCreateFlags(VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT), | |
| MaxSwapChainImages); | |
| fForegroundVulkanDescriptorPool.AddDescriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,MaxSwapChainImages); | |
| fForegroundVulkanDescriptorPool.Initialize; | |
| fForegroundVulkanDescriptorSetLayout:=TpvVulkanDescriptorSetLayout.Create(pvApplication.VulkanDevice); | |
| fForegroundVulkanDescriptorSetLayout.AddBinding(0, | |
| VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, | |
| 1, | |
| TVkShaderStageFlags(VK_SHADER_STAGE_VERTEX_BIT) or TVkShaderStageFlags(VK_SHADER_STAGE_FRAGMENT_BIT), | |
| []); | |
| fForegroundVulkanDescriptorSetLayout.Initialize; | |
| for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin | |
| fForegroundVulkanDescriptorSets[SwapChainImageIndex]:=TpvVulkanDescriptorSet.Create(fForegroundVulkanDescriptorPool, | |
| fForegroundVulkanDescriptorSetLayout); | |
| fForegroundVulkanDescriptorSets[SwapChainImageIndex].WriteToDescriptorSet(0, | |
| 0, | |
| 1, | |
| TVkDescriptorType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER), | |
| [], | |
| [fForegroundVulkanUniformBuffers[SwapChainImageIndex].DescriptorBufferInfo], | |
| [], | |
| false | |
| ); | |
| fForegroundVulkanDescriptorSets[SwapChainImageIndex].Flush; | |
| end; | |
| fForegroundVulkanPipelineLayout:=TpvVulkanPipelineLayout.Create(pvApplication.VulkanDevice); | |
| fForegroundVulkanPipelineLayout.AddDescriptorSetLayout(fForegroundVulkanDescriptorSetLayout); | |
| fForegroundVulkanPipelineLayout.Initialize; | |
| fForegroundVulkanGraphicsPipeline:=TpvVulkanGraphicsPipeline.Create(pvApplication.VulkanDevice, | |
| pvApplication.VulkanPipelineCache, | |
| 0, | |
| [], | |
| fForegroundVulkanPipelineLayout, | |
| fVulkanRenderPass, | |
| VulkanRenderPassSubpassIndex, | |
| nil, | |
| 0); | |
| fForegroundVulkanGraphicsPipeline.AddStage(fForegroundVulkanPipelineShaderStageVertex); | |
| fForegroundVulkanGraphicsPipeline.AddStage(fForegroundVulkanPipelineShaderStageFragment); | |
| fForegroundVulkanGraphicsPipeline.InputAssemblyState.Topology:=VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; | |
| fForegroundVulkanGraphicsPipeline.InputAssemblyState.PrimitiveRestartEnable:=false; | |
| fForegroundVulkanGraphicsPipeline.ViewPortState.AddViewPort(0.0,0.0,pvApplication.VulkanSwapChain.Width,pvApplication.VulkanSwapChain.Height,0.0,1.0); | |
| fForegroundVulkanGraphicsPipeline.ViewPortState.AddScissor(0,0,pvApplication.VulkanSwapChain.Width,pvApplication.VulkanSwapChain.Height); | |
| fForegroundVulkanGraphicsPipeline.RasterizationState.DepthClampEnable:=false; | |
| fForegroundVulkanGraphicsPipeline.RasterizationState.RasterizerDiscardEnable:=false; | |
| fForegroundVulkanGraphicsPipeline.RasterizationState.PolygonMode:=VK_POLYGON_MODE_FILL; | |
| fForegroundVulkanGraphicsPipeline.RasterizationState.CullMode:=TVkCullModeFlags(VK_CULL_MODE_NONE); | |
| //fMainMenuForegroundVulkanGraphicsPipeline.RasterizationState.CullMode:=TVkCullModeFlags(VK_CULL_MODE_BACK_BIT); | |
| fForegroundVulkanGraphicsPipeline.RasterizationState.FrontFace:=VK_FRONT_FACE_CLOCKWISE; | |
| fForegroundVulkanGraphicsPipeline.RasterizationState.DepthBiasEnable:=false; | |
| fForegroundVulkanGraphicsPipeline.RasterizationState.DepthBiasConstantFactor:=0.0; | |
| fForegroundVulkanGraphicsPipeline.RasterizationState.DepthBiasClamp:=0.0; | |
| fForegroundVulkanGraphicsPipeline.RasterizationState.DepthBiasSlopeFactor:=0.0; | |
| fForegroundVulkanGraphicsPipeline.RasterizationState.LineWidth:=1.0; | |
| fForegroundVulkanGraphicsPipeline.MultisampleState.RasterizationSamples:=fParent.fVulkanSampleCountFlagBits; | |
| fForegroundVulkanGraphicsPipeline.MultisampleState.SampleShadingEnable:=false; | |
| fForegroundVulkanGraphicsPipeline.MultisampleState.MinSampleShading:=0.0; | |
| fForegroundVulkanGraphicsPipeline.MultisampleState.CountSampleMasks:=0; | |
| fForegroundVulkanGraphicsPipeline.MultisampleState.AlphaToCoverageEnable:=false; | |
| fForegroundVulkanGraphicsPipeline.MultisampleState.AlphaToOneEnable:=false; | |
| fForegroundVulkanGraphicsPipeline.ColorBlendState.LogicOpEnable:=false; | |
| fForegroundVulkanGraphicsPipeline.ColorBlendState.LogicOp:=VK_LOGIC_OP_COPY; | |
| fForegroundVulkanGraphicsPipeline.ColorBlendState.BlendConstants[0]:=0.0; | |
| fForegroundVulkanGraphicsPipeline.ColorBlendState.BlendConstants[1]:=0.0; | |
| fForegroundVulkanGraphicsPipeline.ColorBlendState.BlendConstants[2]:=0.0; | |
| fForegroundVulkanGraphicsPipeline.ColorBlendState.BlendConstants[3]:=0.0; | |
| fForegroundVulkanGraphicsPipeline.ColorBlendState.AddColorBlendAttachmentState(true, | |
| VK_BLEND_FACTOR_SRC_ALPHA, | |
| VK_BLEND_FACTOR_DST_ALPHA, | |
| VK_BLEND_OP_ADD, | |
| VK_BLEND_FACTOR_ONE, | |
| VK_BLEND_FACTOR_ZERO, | |
| VK_BLEND_OP_ADD, | |
| TVkColorComponentFlags(VK_COLOR_COMPONENT_R_BIT) or | |
| TVkColorComponentFlags(VK_COLOR_COMPONENT_G_BIT) or | |
| TVkColorComponentFlags(VK_COLOR_COMPONENT_B_BIT) or | |
| TVkColorComponentFlags(VK_COLOR_COMPONENT_A_BIT)); | |
| fForegroundVulkanGraphicsPipeline.DepthStencilState.DepthTestEnable:=true; | |
| fForegroundVulkanGraphicsPipeline.DepthStencilState.DepthWriteEnable:=true; | |
| fForegroundVulkanGraphicsPipeline.DepthStencilState.DepthCompareOp:=VK_COMPARE_OP_LESS; | |
| fForegroundVulkanGraphicsPipeline.DepthStencilState.DepthBoundsTestEnable:=false; | |
| fForegroundVulkanGraphicsPipeline.DepthStencilState.StencilTestEnable:=false; | |
| fForegroundVulkanGraphicsPipeline.Initialize; | |
| fForegroundVulkanGraphicsPipeline.FreeMemory; | |
| end; | |
| end; | |
| procedure TScreenMainMenuSceneContentRenderPass.BeforeDestroySwapChain; | |
| var SwapChainImageIndex:TpvSizeInt; | |
| begin | |
| begin | |
| FreeAndNil(fForegroundVulkanGraphicsPipeline); | |
| FreeAndNil(fForegroundVulkanPipelineLayout); | |
| for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin | |
| FreeAndNil(fForegroundVulkanDescriptorSets[SwapChainImageIndex]); | |
| end; | |
| FreeAndNil(fForegroundVulkanDescriptorSetLayout); | |
| FreeAndNil(fForegroundVulkanDescriptorPool); | |
| for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin | |
| FreeAndNil(fForegroundVulkanUniformBuffers[SwapChainImageIndex]); | |
| end; | |
| end; | |
| begin | |
| FreeAndNil(fTerrainVulkanGraphicsPipeline); | |
| FreeAndNil(fTerrainVulkanPipelineLayout); | |
| for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin | |
| FreeAndNil(fTerrainVulkanDescriptorSets[SwapChainImageIndex]); | |
| end; | |
| FreeAndNil(fTerrainVulkanDescriptorSetLayout); | |
| FreeAndNil(fTerrainVulkanDescriptorPool); | |
| for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin | |
| FreeAndNil(fTerrainVulkanUniformBuffers[SwapChainImageIndex]); | |
| end; | |
| end; | |
| begin | |
| FreeAndNil(fBackgroundVulkanGraphicsPipeline); | |
| FreeAndNil(fBackgroundVulkanPipelineLayout); | |
| for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin | |
| FreeAndNil(fBackgroundVulkanDescriptorSets[SwapChainImageIndex]); | |
| end; | |
| FreeAndNil(fBackgroundVulkanDescriptorSetLayout); | |
| FreeAndNil(fBackgroundVulkanDescriptorPool); | |
| for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin | |
| FreeAndNil(fBackgroundVulkanUniformBuffers[SwapChainImageIndex]); | |
| end; | |
| end; | |
| fVulkanRenderPass:=nil; | |
| inherited BeforeDestroySwapChain; | |
| end; | |
| procedure TScreenMainMenuSceneContentRenderPass.Update(const aUpdateSwapChainImageIndex,aUpdateFrameIndex:TpvSizeInt); | |
| var ModelMatrix, | |
| ViewMatrix, | |
| ViewProjectionMatrix, | |
| InverseViewProjectionMatrix:TpvMatrix4x4; | |
| BackgroundUniformBuffer:PScreenMainMenuBackgroundUniformBuffer; | |
| TerrainUniformBuffer:PScreenMainMenuTerrainUniformBuffer; | |
| ForegroundUniformBuffer:PScreenMainMenuForegroundUniformBuffer; | |
| begin | |
| inherited Update(aUpdateSwapChainImageIndex,aUpdateFrameIndex); | |
| ViewMatrix:=TpvMatrix4x4.CreateFromQuaternion(TpvQuaternion.Create(0.11986792,0.0,0.0,-0.99278980).Normalize); | |
| { | |
| ViewMatrix:=TpvMatrix4x4.CreateTranslation(0.0,0.0,5.0)* | |
| // TpvMatrix4x4.CreateRotateX(fParent.fTime*PI*0.0625)* | |
| TpvMatrix4x4.CreateRotateY(fParent.fTime*PI*0.125)* | |
| TpvMatrix4x4.CreateTranslation(0.0,0.0,-5.0)* | |
| ViewMatrix;{} | |
| ViewProjectionMatrix:=ViewMatrix* | |
| TpvMatrix4x4.CreatePerspectiveRightHandedZeroToOne(53.13010235415598, | |
| pvApplication.VulkanSwapChain.Width/pvApplication.VulkanSwapChain.Height, | |
| 1.0, | |
| 1024.0)* | |
| TpvMatrix4x4.FlipYClipSpace; | |
| InverseViewProjectionMatrix:=ViewProjectionMatrix.Inverse; | |
| BackgroundUniformBuffer:=@fBackgroundUniformBuffers[aUpdateSwapChainImageIndex]; | |
| BackgroundUniformBuffer^.InverseViewProjectionMatrix:=InverseViewProjectionMatrix; | |
| BackgroundUniformBuffer^.Resolution:=TpvVector2.InlineableCreate(pvApplication.VulkanSwapChain.Width,pvApplication.VulkanSwapChain.Height); | |
| BackgroundUniformBuffer^.MusicTick:=fParent.fTime*fParent.fTimeToMusicTickFactor; | |
| BackgroundUniformBuffer^.PressStartOffset:=0.0; | |
| TerrainUniformBuffer:=@fTerrainUniformBuffers[aUpdateSwapChainImageIndex]; | |
| TerrainUniformBuffer^.Offset:=Modulo(BackgroundUniformBuffer^.MusicTick*(100.0/(3.0*64.0)),(HeightMapHeight-1)*GridSize); | |
| ModelMatrix:=TpvMatrix4x4.CreateTranslation(0.0,0.0,TerrainUniformBuffer^.Offset); | |
| TerrainUniformBuffer^.ModelViewMatrix:=ModelMatrix*ViewMatrix; | |
| TerrainUniformBuffer^.ModelViewProjectionMatrix:=ModelMatrix*ViewProjectionMatrix; | |
| ForegroundUniformBuffer:=@fForegroundUniformBuffers[aUpdateSwapChainImageIndex]; | |
| ForegroundUniformBuffer^.ViewProjectionMatrix:=ViewProjectionMatrix; | |
| ForegroundUniformBuffer^.InverseViewProjectionMatrix:=InverseViewProjectionMatrix; | |
| ForegroundUniformBuffer^.Resolution:=TpvVector2.InlineableCreate(pvApplication.VulkanSwapChain.Width,pvApplication.VulkanSwapChain.Height); | |
| ForegroundUniformBuffer^.MusicTick:=fParent.fTime*fParent.fTimeToMusicTickFactor; | |
| ForegroundUniformBuffer^.PressStartOffset:=0.0; | |
| end; | |
| procedure TScreenMainMenuSceneContentRenderPass.Execute(const aCommandBuffer:TpvVulkanCommandBuffer;const aSwapChainImageIndex,aFrameIndex:TpvSizeInt); | |
| var p:pointer; | |
| begin | |
| inherited Execute(aCommandBuffer,aSwapChainImageIndex,aFrameIndex); | |
| begin | |
| p:=fBackgroundVulkanUniformBuffers[aSwapChainImageIndex].Memory.MapMemory(0,SizeOf(TScreenMainMenuBackgroundUniformBuffer)); | |
| if assigned(p) then begin | |
| try | |
| PScreenMainMenuBackgroundUniformBuffer(p)^:=fBackgroundUniformBuffers[aSwapChainImageIndex]; | |
| finally | |
| fBackgroundVulkanUniformBuffers[aSwapChainImageIndex].Memory.UnmapMemory; | |
| end; | |
| end; | |
| aCommandBuffer.CmdBindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS,fBackgroundVulkanPipelineLayout.Handle,0,1,@fBackgroundVulkanDescriptorSets[aSwapChainImageIndex].Handle,0,nil); | |
| aCommandBuffer.CmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS,fBackgroundVulkanGraphicsPipeline.Handle); | |
| aCommandBuffer.CmdDraw(3,1,0,0); | |
| end;{} | |
| begin | |
| p:=fTerrainVulkanUniformBuffers[aSwapChainImageIndex].Memory.MapMemory(0,SizeOf(TScreenMainMenuTerrainUniformBuffer)); | |
| if assigned(p) then begin | |
| try | |
| PScreenMainMenuTerrainUniformBuffer(p)^:=fTerrainUniformBuffers[aSwapChainImageIndex]; | |
| finally | |
| fTerrainVulkanUniformBuffers[aSwapChainImageIndex].Memory.UnmapMemory; | |
| end; | |
| end; | |
| aCommandBuffer.CmdBindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS,fTerrainVulkanPipelineLayout.Handle,0,1,@fTerrainVulkanDescriptorSets[aSwapChainImageIndex].Handle,0,nil); | |
| aCommandBuffer.CmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS,fTerrainVulkanGraphicsPipeline.Handle); | |
| aCommandBuffer.CmdBindVertexBuffers(0,1,@fTerrainVulkanVertexBuffer.Handle,@Offsets); | |
| aCommandBuffer.CmdBindIndexBuffer(fTerrainVulkanIndexBuffer.Handle,0,VK_INDEX_TYPE_UINT32); | |
| aCommandBuffer.CmdDrawIndexed(length(fTerrainIndices),1,0,0,0); | |
| end;{} | |
| begin | |
| p:=fForegroundVulkanUniformBuffers[aSwapChainImageIndex].Memory.MapMemory(0,SizeOf(TScreenMainMenuForegroundUniformBuffer)); | |
| if assigned(p) then begin | |
| try | |
| PScreenMainMenuForegroundUniformBuffer(p)^:=fForegroundUniformBuffers[aSwapChainImageIndex]; | |
| finally | |
| fForegroundVulkanUniformBuffers[aSwapChainImageIndex].Memory.UnmapMemory; | |
| end; | |
| end; | |
| aCommandBuffer.CmdBindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS,fForegroundVulkanPipelineLayout.Handle,0,1,@fForegroundVulkanDescriptorSets[aSwapChainImageIndex].Handle,0,nil); | |
| aCommandBuffer.CmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS,fForegroundVulkanGraphicsPipeline.Handle); | |
| aCommandBuffer.CmdDraw(3,1,0,0); | |
| end;{} | |
| end; | |
| constructor TScreenMainMenuTonemappingRenderPass.Create(const aFrameGraph:TpvFrameGraph); | |
| begin | |
| inherited Create(aFrameGraph); | |
| Name:='Tonemapping'; | |
| Queue:=aFrameGraph.UniversalQueue; | |
| //SeparatePhysicalPass:=true; | |
| //SeparateCommandBuffer:=true; | |
| Size:=TpvFrameGraph.TImageSize.Create(TpvFrameGraph.TImageSize.TKind.SurfaceDependent, | |
| 1.0, | |
| 1.0); | |
| fResourceColor:=AddImageInput('resourcetype_color', | |
| 'scene_color', | |
| VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, | |
| [TpvFrameGraph.TResourceTransition.TFlag.Attachment] | |
| ); | |
| fResourceSurface:=AddImageOutput('resourcetype_color', | |
| 'tonemapping_color', | |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, | |
| TpvFrameGraph.TLoadOp.Create(TpvFrameGraph.TLoadOp.TKind.Clear, | |
| TpvVector4.InlineableCreate(0.0,0.0,0.0,1.0)), | |
| [TpvFrameGraph.TResourceTransition.TFlag.Attachment] | |
| ); | |
| end; | |
| destructor TScreenMainMenuTonemappingRenderPass.Destroy; | |
| begin | |
| inherited Destroy; | |
| end; | |
| procedure TScreenMainMenuTonemappingRenderPass.Show; | |
| var Stream:TStream; | |
| begin | |
| inherited Show; | |
| fVulkanTransferCommandBuffer:=TpvVulkanCommandBuffer.Create(FrameGraph.TransferQueue.CommandPool,VK_COMMAND_BUFFER_LEVEL_PRIMARY); | |
| fVulkanTransferCommandBufferFence:=TpvVulkanFence.Create(pvApplication.VulkanDevice); | |
| Stream:=pvApplication.Assets.GetAssetStream('shaders/tonemapping_vert.spv'); | |
| try | |
| fVulkanVertexShaderModule:=TpvVulkanShaderModule.Create(pvApplication.VulkanDevice,Stream); | |
| finally | |
| Stream.Free; | |
| end; | |
| Stream:=pvApplication.Assets.GetAssetStream('shaders/tonemapping_frag.spv'); | |
| try | |
| fVulkanFragmentShaderModule:=TpvVulkanShaderModule.Create(pvApplication.VulkanDevice,Stream); | |
| finally | |
| Stream.Free; | |
| end; | |
| fVulkanPipelineShaderStageVertex:=TpvVulkanPipelineShaderStage.Create(VK_SHADER_STAGE_VERTEX_BIT,fVulkanVertexShaderModule,'main'); | |
| fVulkanPipelineShaderStageFragment:=TpvVulkanPipelineShaderStage.Create(VK_SHADER_STAGE_FRAGMENT_BIT,fVulkanFragmentShaderModule,'main'); | |
| fVulkanGraphicsPipeline:=nil; | |
| end; | |
| procedure TScreenMainMenuTonemappingRenderPass.Hide; | |
| begin | |
| FreeAndNil(fVulkanPipelineShaderStageVertex); | |
| FreeAndNil(fVulkanPipelineShaderStageFragment); | |
| FreeAndNil(fVulkanFragmentShaderModule); | |
| FreeAndNil(fVulkanVertexShaderModule); | |
| FreeAndNil(fVulkanTransferCommandBufferFence); | |
| FreeAndNil(fVulkanTransferCommandBuffer); | |
| inherited Hide; | |
| end; | |
| procedure TScreenMainMenuTonemappingRenderPass.AfterCreateSwapChain; | |
| var SwapChainImageIndex:TpvSizeInt; | |
| begin | |
| inherited AfterCreateSwapChain; | |
| fVulkanRenderPass:=VulkanRenderPass; | |
| for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin | |
| fVulkanUniformBuffers[SwapChainImageIndex]:=TpvVulkanBuffer.Create(pvApplication.VulkanDevice, | |
| SizeOf(TScreenMainMenuBackgroundUniformBuffer), | |
| TVkBufferUsageFlags(VK_BUFFER_USAGE_TRANSFER_DST_BIT) or TVkBufferUsageFlags(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT), | |
| TVkSharingMode(VK_SHARING_MODE_EXCLUSIVE), | |
| FrameGraph.QueueFamilyIndices.Items, | |
| TVkMemoryPropertyFlags(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) or TVkMemoryPropertyFlags(VK_MEMORY_PROPERTY_HOST_COHERENT_BIT), | |
| 0, | |
| 0, | |
| 0, | |
| 0, | |
| 0, | |
| [TpvVulkanBufferFlag.PersistentMapped] | |
| ); | |
| fVulkanUniformBuffers[SwapChainImageIndex].UploadData(FrameGraph.TransferQueue.PhysicalQueue, | |
| fVulkanTransferCommandBuffer, | |
| fVulkanTransferCommandBufferFence, | |
| fBackgroundUniformBuffers[SwapChainImageIndex], | |
| 0, | |
| SizeOf(TScreenMainMenuBackgroundUniformBuffer), | |
| TpvVulkanBufferUseTemporaryStagingBufferMode.Yes); | |
| end; | |
| fVulkanDescriptorPool:=TpvVulkanDescriptorPool.Create(pvApplication.VulkanDevice, | |
| TVkDescriptorPoolCreateFlags(VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT), | |
| MaxSwapChainImages); | |
| fVulkanDescriptorPool.AddDescriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,MaxSwapChainImages); | |
| fVulkanDescriptorPool.AddDescriptorPoolSize(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,MaxSwapChainImages); | |
| fVulkanDescriptorPool.Initialize; | |
| fVulkanDescriptorSetLayout:=TpvVulkanDescriptorSetLayout.Create(pvApplication.VulkanDevice); | |
| fVulkanDescriptorSetLayout.AddBinding(0, | |
| VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, | |
| 1, | |
| TVkShaderStageFlags(VK_SHADER_STAGE_VERTEX_BIT) or TVkShaderStageFlags(VK_SHADER_STAGE_FRAGMENT_BIT), | |
| []); | |
| fVulkanDescriptorSetLayout.AddBinding(1, | |
| VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, | |
| 1, | |
| TVkShaderStageFlags(VK_SHADER_STAGE_FRAGMENT_BIT), | |
| []); | |
| fVulkanDescriptorSetLayout.Initialize; | |
| for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin | |
| fVulkanDescriptorSets[SwapChainImageIndex]:=TpvVulkanDescriptorSet.Create(fVulkanDescriptorPool, | |
| fVulkanDescriptorSetLayout); | |
| fVulkanDescriptorSets[SwapChainImageIndex].WriteToDescriptorSet(0, | |
| 0, | |
| 1, | |
| TVkDescriptorType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER), | |
| [], | |
| [fVulkanUniformBuffers[SwapChainImageIndex].DescriptorBufferInfo], | |
| [], | |
| false | |
| ); | |
| fVulkanDescriptorSets[SwapChainImageIndex].WriteToDescriptorSet(1, | |
| 0, | |
| 1, | |
| TVkDescriptorType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT), | |
| [TVkDescriptorImageInfo.Create(VK_NULL_HANDLE, | |
| fResourceColor.VulkanImageViews[SwapChainImageIndex].Handle, | |
| fResourceColor.ResourceTransition.Layout)],// TVkImageLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL))], | |
| [fVulkanUniformBuffers[SwapChainImageIndex].DescriptorBufferInfo], | |
| [], | |
| false | |
| ); | |
| fVulkanDescriptorSets[SwapChainImageIndex].Flush; | |
| end; | |
| fVulkanPipelineLayout:=TpvVulkanPipelineLayout.Create(pvApplication.VulkanDevice); | |
| fVulkanPipelineLayout.AddDescriptorSetLayout(fVulkanDescriptorSetLayout); | |
| fVulkanPipelineLayout.Initialize; | |
| fVulkanGraphicsPipeline:=TpvVulkanGraphicsPipeline.Create(pvApplication.VulkanDevice, | |
| pvApplication.VulkanPipelineCache, | |
| 0, | |
| [], | |
| fVulkanPipelineLayout, | |
| fVulkanRenderPass, | |
| VulkanRenderPassSubpassIndex, | |
| nil, | |
| 0); | |
| fVulkanGraphicsPipeline.AddStage(fVulkanPipelineShaderStageVertex); | |
| fVulkanGraphicsPipeline.AddStage(fVulkanPipelineShaderStageFragment); | |
| fVulkanGraphicsPipeline.InputAssemblyState.Topology:=VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; | |
| fVulkanGraphicsPipeline.InputAssemblyState.PrimitiveRestartEnable:=false; | |
| fVulkanGraphicsPipeline.ViewPortState.AddViewPort(0.0,0.0,pvApplication.VulkanSwapChain.Width,pvApplication.VulkanSwapChain.Height,0.0,1.0); | |
| fVulkanGraphicsPipeline.ViewPortState.AddScissor(0,0,pvApplication.VulkanSwapChain.Width,pvApplication.VulkanSwapChain.Height); | |
| fVulkanGraphicsPipeline.RasterizationState.DepthClampEnable:=false; | |
| fVulkanGraphicsPipeline.RasterizationState.RasterizerDiscardEnable:=false; | |
| fVulkanGraphicsPipeline.RasterizationState.PolygonMode:=VK_POLYGON_MODE_FILL; | |
| fVulkanGraphicsPipeline.RasterizationState.CullMode:=TVkCullModeFlags(VK_CULL_MODE_NONE); | |
| //fMainMenuBackgroundVulkanGraphicsPipeline.RasterizationState.CullMode:=TVkCullModeFlags(VK_CULL_MODE_BACK_BIT); | |
| fVulkanGraphicsPipeline.RasterizationState.FrontFace:=VK_FRONT_FACE_CLOCKWISE; | |
| fVulkanGraphicsPipeline.RasterizationState.DepthBiasEnable:=false; | |
| fVulkanGraphicsPipeline.RasterizationState.DepthBiasConstantFactor:=0.0; | |
| fVulkanGraphicsPipeline.RasterizationState.DepthBiasClamp:=0.0; | |
| fVulkanGraphicsPipeline.RasterizationState.DepthBiasSlopeFactor:=0.0; | |
| fVulkanGraphicsPipeline.RasterizationState.LineWidth:=1.0; | |
| fVulkanGraphicsPipeline.MultisampleState.RasterizationSamples:=VK_SAMPLE_COUNT_1_BIT; | |
| fVulkanGraphicsPipeline.MultisampleState.SampleShadingEnable:=false; | |
| fVulkanGraphicsPipeline.MultisampleState.MinSampleShading:=0.0; | |
| fVulkanGraphicsPipeline.MultisampleState.CountSampleMasks:=0; | |
| fVulkanGraphicsPipeline.MultisampleState.AlphaToCoverageEnable:=false; | |
| fVulkanGraphicsPipeline.MultisampleState.AlphaToOneEnable:=false; | |
| fVulkanGraphicsPipeline.ColorBlendState.LogicOpEnable:=false; | |
| fVulkanGraphicsPipeline.ColorBlendState.LogicOp:=VK_LOGIC_OP_COPY; | |
| fVulkanGraphicsPipeline.ColorBlendState.BlendConstants[0]:=0.0; | |
| fVulkanGraphicsPipeline.ColorBlendState.BlendConstants[1]:=0.0; | |
| fVulkanGraphicsPipeline.ColorBlendState.BlendConstants[2]:=0.0; | |
| fVulkanGraphicsPipeline.ColorBlendState.BlendConstants[3]:=0.0; | |
| fVulkanGraphicsPipeline.ColorBlendState.AddColorBlendAttachmentState(false, | |
| VK_BLEND_FACTOR_SRC_ALPHA, | |
| VK_BLEND_FACTOR_DST_ALPHA, | |
| VK_BLEND_OP_ADD, | |
| VK_BLEND_FACTOR_ONE, | |
| VK_BLEND_FACTOR_ZERO, | |
| VK_BLEND_OP_ADD, | |
| TVkColorComponentFlags(VK_COLOR_COMPONENT_R_BIT) or | |
| TVkColorComponentFlags(VK_COLOR_COMPONENT_G_BIT) or | |
| TVkColorComponentFlags(VK_COLOR_COMPONENT_B_BIT) or | |
| TVkColorComponentFlags(VK_COLOR_COMPONENT_A_BIT)); | |
| fVulkanGraphicsPipeline.DepthStencilState.DepthTestEnable:=true; | |
| fVulkanGraphicsPipeline.DepthStencilState.DepthWriteEnable:=true; | |
| fVulkanGraphicsPipeline.DepthStencilState.DepthCompareOp:=VK_COMPARE_OP_ALWAYS; | |
| fVulkanGraphicsPipeline.DepthStencilState.DepthBoundsTestEnable:=false; | |
| fVulkanGraphicsPipeline.DepthStencilState.StencilTestEnable:=false; | |
| fVulkanGraphicsPipeline.Initialize; | |
| fVulkanGraphicsPipeline.FreeMemory; | |
| end; | |
| procedure TScreenMainMenuTonemappingRenderPass.BeforeDestroySwapChain; | |
| var SwapChainImageIndex:TpvSizeInt; | |
| begin | |
| FreeAndNil(fVulkanGraphicsPipeline); | |
| FreeAndNil(fVulkanPipelineLayout); | |
| for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin | |
| FreeAndNil(fVulkanDescriptorSets[SwapChainImageIndex]); | |
| end; | |
| FreeAndNil(fVulkanDescriptorSetLayout); | |
| FreeAndNil(fVulkanDescriptorPool); | |
| for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin | |
| FreeAndNil(fVulkanUniformBuffers[SwapChainImageIndex]); | |
| end; | |
| fVulkanRenderPass:=nil; | |
| inherited BeforeDestroySwapChain; | |
| end; | |
| procedure TScreenMainMenuTonemappingRenderPass.Update(const aUpdateSwapChainImageIndex,aUpdateFrameIndex:TpvSizeInt); | |
| begin | |
| inherited Update(aUpdateSwapChainImageIndex,aUpdateFrameIndex); | |
| end; | |
| procedure TScreenMainMenuTonemappingRenderPass.Execute(const aCommandBuffer:TpvVulkanCommandBuffer;const aSwapChainImageIndex,aFrameIndex:TpvSizeInt); | |
| begin | |
| inherited Execute(aCommandBuffer,aSwapChainImageIndex,aFrameIndex); | |
| aCommandBuffer.CmdBindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS,fVulkanPipelineLayout.Handle,0,1,@fVulkanDescriptorSets[aSwapChainImageIndex].Handle,0,nil); | |
| aCommandBuffer.CmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS,fVulkanGraphicsPipeline.Handle); | |
| aCommandBuffer.CmdDraw(3,1,0,0); | |
| end; | |
| constructor TScreenMainMenuAntialiasingRenderPass.Create(const aFrameGraph:TpvFrameGraph); | |
| begin | |
| inherited Create(aFrameGraph); | |
| Name:='Antialiasing'; | |
| Queue:=aFrameGraph.UniversalQueue; | |
| //SeparatePhysicalPass:=true; | |
| //SeparateCommandBuffer:=true; | |
| Size:=TpvFrameGraph.TImageSize.Create(TpvFrameGraph.TImageSize.TKind.SurfaceDependent, | |
| 1.0, | |
| 1.0); | |
| fResourceColor:=AddImageInput('resourcetype_color', | |
| 'tonemapping_color', | |
| VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, | |
| [] | |
| ); | |
| fResourceSurface:=AddImageOutput('resourcetype_surface', | |
| 'resource_surface', | |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, | |
| TpvFrameGraph.TLoadOp.Create(TpvFrameGraph.TLoadOp.TKind.Clear, | |
| TpvVector4.InlineableCreate(0.0,0.0,0.0,1.0)), | |
| [TpvFrameGraph.TResourceTransition.TFlag.Attachment] | |
| ); | |
| end; | |
| destructor TScreenMainMenuAntialiasingRenderPass.Destroy; | |
| begin | |
| inherited Destroy; | |
| end; | |
| procedure TScreenMainMenuAntialiasingRenderPass.Show; | |
| var Stream:TStream; | |
| begin | |
| inherited Show; | |
| fVulkanTransferCommandBuffer:=TpvVulkanCommandBuffer.Create(FrameGraph.TransferQueue.CommandPool,VK_COMMAND_BUFFER_LEVEL_PRIMARY); | |
| fVulkanTransferCommandBufferFence:=TpvVulkanFence.Create(pvApplication.VulkanDevice); | |
| Stream:=pvApplication.Assets.GetAssetStream('shaders/antialiasing_fxaa_vert.spv'); | |
| try | |
| fVulkanVertexShaderModule:=TpvVulkanShaderModule.Create(pvApplication.VulkanDevice,Stream); | |
| finally | |
| Stream.Free; | |
| end; | |
| Stream:=pvApplication.Assets.GetAssetStream('shaders/antialiasing_fxaa_frag.spv'); | |
| try | |
| fVulkanFragmentShaderModule:=TpvVulkanShaderModule.Create(pvApplication.VulkanDevice,Stream); | |
| finally | |
| Stream.Free; | |
| end; | |
| fVulkanPipelineShaderStageVertex:=TpvVulkanPipelineShaderStage.Create(VK_SHADER_STAGE_VERTEX_BIT,fVulkanVertexShaderModule,'main'); | |
| fVulkanPipelineShaderStageFragment:=TpvVulkanPipelineShaderStage.Create(VK_SHADER_STAGE_FRAGMENT_BIT,fVulkanFragmentShaderModule,'main'); | |
| fVulkanGraphicsPipeline:=nil; | |
| fVulkanSampler:=TpvVulkanSampler.Create(pvApplication.VulkanDevice, | |
| TVkFilter.VK_FILTER_LINEAR, | |
| TVkFilter.VK_FILTER_LINEAR, | |
| TVkSamplerMipmapMode.VK_SAMPLER_MIPMAP_MODE_LINEAR, | |
| VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, | |
| VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, | |
| VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, | |
| 0.0, | |
| false, | |
| 0.0, | |
| false, | |
| VK_COMPARE_OP_ALWAYS, | |
| 0.0, | |
| 0.0, | |
| VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK, | |
| false); | |
| end; | |
| procedure TScreenMainMenuAntialiasingRenderPass.Hide; | |
| begin | |
| FreeAndNil(fVulkanSampler); | |
| FreeAndNil(fVulkanPipelineShaderStageVertex); | |
| FreeAndNil(fVulkanPipelineShaderStageFragment); | |
| FreeAndNil(fVulkanFragmentShaderModule); | |
| FreeAndNil(fVulkanVertexShaderModule); | |
| FreeAndNil(fVulkanTransferCommandBufferFence); | |
| FreeAndNil(fVulkanTransferCommandBuffer); | |
| inherited Hide; | |
| end; | |
| procedure TScreenMainMenuAntialiasingRenderPass.AfterCreateSwapChain; | |
| var SwapChainImageIndex:TpvSizeInt; | |
| begin | |
| inherited AfterCreateSwapChain; | |
| fVulkanRenderPass:=VulkanRenderPass; | |
| for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin | |
| fVulkanUniformBuffers[SwapChainImageIndex]:=TpvVulkanBuffer.Create(pvApplication.VulkanDevice, | |
| SizeOf(TScreenMainMenuBackgroundUniformBuffer), | |
| TVkBufferUsageFlags(VK_BUFFER_USAGE_TRANSFER_DST_BIT) or TVkBufferUsageFlags(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT), | |
| TVkSharingMode(VK_SHARING_MODE_EXCLUSIVE), | |
| FrameGraph.QueueFamilyIndices.Items, | |
| TVkMemoryPropertyFlags(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) or TVkMemoryPropertyFlags(VK_MEMORY_PROPERTY_HOST_COHERENT_BIT), | |
| 0, | |
| 0, | |
| 0, | |
| 0, | |
| 0, | |
| [TpvVulkanBufferFlag.PersistentMapped] | |
| ); | |
| fVulkanUniformBuffers[SwapChainImageIndex].UploadData(FrameGraph.TransferQueue.PhysicalQueue, | |
| fVulkanTransferCommandBuffer, | |
| fVulkanTransferCommandBufferFence, | |
| fBackgroundUniformBuffers[SwapChainImageIndex], | |
| 0, | |
| SizeOf(TScreenMainMenuBackgroundUniformBuffer), | |
| TpvVulkanBufferUseTemporaryStagingBufferMode.Yes); | |
| end; | |
| fVulkanDescriptorPool:=TpvVulkanDescriptorPool.Create(pvApplication.VulkanDevice, | |
| TVkDescriptorPoolCreateFlags(VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT), | |
| MaxSwapChainImages); | |
| fVulkanDescriptorPool.AddDescriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,MaxSwapChainImages); | |
| fVulkanDescriptorPool.AddDescriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,MaxSwapChainImages); | |
| fVulkanDescriptorPool.Initialize; | |
| fVulkanDescriptorSetLayout:=TpvVulkanDescriptorSetLayout.Create(pvApplication.VulkanDevice); | |
| fVulkanDescriptorSetLayout.AddBinding(0, | |
| VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, | |
| 1, | |
| TVkShaderStageFlags(VK_SHADER_STAGE_VERTEX_BIT) or TVkShaderStageFlags(VK_SHADER_STAGE_FRAGMENT_BIT), | |
| []); | |
| fVulkanDescriptorSetLayout.AddBinding(1, | |
| VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, | |
| 1, | |
| TVkShaderStageFlags(VK_SHADER_STAGE_FRAGMENT_BIT), | |
| []); | |
| fVulkanDescriptorSetLayout.Initialize; | |
| for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin | |
| fVulkanDescriptorSets[SwapChainImageIndex]:=TpvVulkanDescriptorSet.Create(fVulkanDescriptorPool, | |
| fVulkanDescriptorSetLayout); | |
| fVulkanDescriptorSets[SwapChainImageIndex].WriteToDescriptorSet(0, | |
| 0, | |
| 1, | |
| TVkDescriptorType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER), | |
| [], | |
| [fVulkanUniformBuffers[SwapChainImageIndex].DescriptorBufferInfo], | |
| [], | |
| false | |
| ); | |
| fVulkanDescriptorSets[SwapChainImageIndex].WriteToDescriptorSet(1, | |
| 0, | |
| 1, | |
| TVkDescriptorType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER), | |
| [TVkDescriptorImageInfo.Create(fVulkanSampler.Handle, | |
| fResourceColor.VulkanImageViews[SwapChainImageIndex].Handle, | |
| fResourceColor.ResourceTransition.Layout)],// TVkImageLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL))], | |
| [fVulkanUniformBuffers[SwapChainImageIndex].DescriptorBufferInfo], | |
| [], | |
| false | |
| ); | |
| fVulkanDescriptorSets[SwapChainImageIndex].Flush; | |
| end; | |
| fVulkanPipelineLayout:=TpvVulkanPipelineLayout.Create(pvApplication.VulkanDevice); | |
| fVulkanPipelineLayout.AddDescriptorSetLayout(fVulkanDescriptorSetLayout); | |
| fVulkanPipelineLayout.Initialize; | |
| fVulkanGraphicsPipeline:=TpvVulkanGraphicsPipeline.Create(pvApplication.VulkanDevice, | |
| pvApplication.VulkanPipelineCache, | |
| 0, | |
| [], | |
| fVulkanPipelineLayout, | |
| fVulkanRenderPass, | |
| VulkanRenderPassSubpassIndex, | |
| nil, | |
| 0); | |
| fVulkanGraphicsPipeline.AddStage(fVulkanPipelineShaderStageVertex); | |
| fVulkanGraphicsPipeline.AddStage(fVulkanPipelineShaderStageFragment); | |
| fVulkanGraphicsPipeline.InputAssemblyState.Topology:=VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; | |
| fVulkanGraphicsPipeline.InputAssemblyState.PrimitiveRestartEnable:=false; | |
| fVulkanGraphicsPipeline.ViewPortState.AddViewPort(0.0,0.0,pvApplication.VulkanSwapChain.Width,pvApplication.VulkanSwapChain.Height,0.0,1.0); | |
| fVulkanGraphicsPipeline.ViewPortState.AddScissor(0,0,pvApplication.VulkanSwapChain.Width,pvApplication.VulkanSwapChain.Height); | |
| fVulkanGraphicsPipeline.RasterizationState.DepthClampEnable:=false; | |
| fVulkanGraphicsPipeline.RasterizationState.RasterizerDiscardEnable:=false; | |
| fVulkanGraphicsPipeline.RasterizationState.PolygonMode:=VK_POLYGON_MODE_FILL; | |
| fVulkanGraphicsPipeline.RasterizationState.CullMode:=TVkCullModeFlags(VK_CULL_MODE_NONE); | |
| //fMainMenuBackgroundVulkanGraphicsPipeline.RasterizationState.CullMode:=TVkCullModeFlags(VK_CULL_MODE_BACK_BIT); | |
| fVulkanGraphicsPipeline.RasterizationState.FrontFace:=VK_FRONT_FACE_CLOCKWISE; | |
| fVulkanGraphicsPipeline.RasterizationState.DepthBiasEnable:=false; | |
| fVulkanGraphicsPipeline.RasterizationState.DepthBiasConstantFactor:=0.0; | |
| fVulkanGraphicsPipeline.RasterizationState.DepthBiasClamp:=0.0; | |
| fVulkanGraphicsPipeline.RasterizationState.DepthBiasSlopeFactor:=0.0; | |
| fVulkanGraphicsPipeline.RasterizationState.LineWidth:=1.0; | |
| fVulkanGraphicsPipeline.MultisampleState.RasterizationSamples:=VK_SAMPLE_COUNT_1_BIT; | |
| fVulkanGraphicsPipeline.MultisampleState.SampleShadingEnable:=false; | |
| fVulkanGraphicsPipeline.MultisampleState.MinSampleShading:=0.0; | |
| fVulkanGraphicsPipeline.MultisampleState.CountSampleMasks:=0; | |
| fVulkanGraphicsPipeline.MultisampleState.AlphaToCoverageEnable:=false; | |
| fVulkanGraphicsPipeline.MultisampleState.AlphaToOneEnable:=false; | |
| fVulkanGraphicsPipeline.ColorBlendState.LogicOpEnable:=false; | |
| fVulkanGraphicsPipeline.ColorBlendState.LogicOp:=VK_LOGIC_OP_COPY; | |
| fVulkanGraphicsPipeline.ColorBlendState.BlendConstants[0]:=0.0; | |
| fVulkanGraphicsPipeline.ColorBlendState.BlendConstants[1]:=0.0; | |
| fVulkanGraphicsPipeline.ColorBlendState.BlendConstants[2]:=0.0; | |
| fVulkanGraphicsPipeline.ColorBlendState.BlendConstants[3]:=0.0; | |
| fVulkanGraphicsPipeline.ColorBlendState.AddColorBlendAttachmentState(false, | |
| VK_BLEND_FACTOR_SRC_ALPHA, | |
| VK_BLEND_FACTOR_DST_ALPHA, | |
| VK_BLEND_OP_ADD, | |
| VK_BLEND_FACTOR_ONE, | |
| VK_BLEND_FACTOR_ZERO, | |
| VK_BLEND_OP_ADD, | |
| TVkColorComponentFlags(VK_COLOR_COMPONENT_R_BIT) or | |
| TVkColorComponentFlags(VK_COLOR_COMPONENT_G_BIT) or | |
| TVkColorComponentFlags(VK_COLOR_COMPONENT_B_BIT) or | |
| TVkColorComponentFlags(VK_COLOR_COMPONENT_A_BIT)); | |
| fVulkanGraphicsPipeline.DepthStencilState.DepthTestEnable:=true; | |
| fVulkanGraphicsPipeline.DepthStencilState.DepthWriteEnable:=true; | |
| fVulkanGraphicsPipeline.DepthStencilState.DepthCompareOp:=VK_COMPARE_OP_ALWAYS; | |
| fVulkanGraphicsPipeline.DepthStencilState.DepthBoundsTestEnable:=false; | |
| fVulkanGraphicsPipeline.DepthStencilState.StencilTestEnable:=false; | |
| fVulkanGraphicsPipeline.Initialize; | |
| fVulkanGraphicsPipeline.FreeMemory; | |
| end; | |
| procedure TScreenMainMenuAntialiasingRenderPass.BeforeDestroySwapChain; | |
| var SwapChainImageIndex:TpvSizeInt; | |
| begin | |
| FreeAndNil(fVulkanGraphicsPipeline); | |
| FreeAndNil(fVulkanPipelineLayout); | |
| for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin | |
| FreeAndNil(fVulkanDescriptorSets[SwapChainImageIndex]); | |
| end; | |
| FreeAndNil(fVulkanDescriptorSetLayout); | |
| FreeAndNil(fVulkanDescriptorPool); | |
| for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin | |
| FreeAndNil(fVulkanUniformBuffers[SwapChainImageIndex]); | |
| end; | |
| fVulkanRenderPass:=nil; | |
| inherited BeforeDestroySwapChain; | |
| end; | |
| procedure TScreenMainMenuAntialiasingRenderPass.Update(const aUpdateSwapChainImageIndex,aUpdateFrameIndex:TpvSizeInt); | |
| begin | |
| inherited Update(aUpdateSwapChainImageIndex,aUpdateFrameIndex); | |
| end; | |
| procedure TScreenMainMenuAntialiasingRenderPass.Execute(const aCommandBuffer:TpvVulkanCommandBuffer;const aSwapChainImageIndex,aFrameIndex:TpvSizeInt); | |
| begin | |
| inherited Execute(aCommandBuffer,aSwapChainImageIndex,aFrameIndex); | |
| aCommandBuffer.CmdBindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS,fVulkanPipelineLayout.Handle,0,1,@fVulkanDescriptorSets[aSwapChainImageIndex].Handle,0,nil); | |
| aCommandBuffer.CmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS,fVulkanGraphicsPipeline.Handle); | |
| aCommandBuffer.CmdDraw(3,1,0,0); | |
| end; | |
| { TScreenMainMenu } | |
| constructor TScreenMainMenu.Create; | |
| const ProjectSampleRate=44100; | |
| BPM=90*100; | |
| TicksPerRow=3; | |
| RowsPerBeat=8; | |
| InaccurateBPM=true; | |
| var WaitSamples:TpvInt64; | |
| WaitSamplesFloat:TpvDouble; | |
| SampleCounts:TVkSampleCountFlags; | |
| begin | |
| inherited Create; | |
| if (RowsPerBeat=0) or (TicksPerRow=0) then begin | |
| WaitSamples:=(TpvInt64(ProjectSampleRate)*6000*TpvInt64($100000000)) div (BPM*6*4); | |
| end else begin | |
| WaitSamples:=(TpvInt64(ProjectSampleRate)*6000*TpvInt64($100000000)) div (BPM*TicksPerRow*RowsPerBeat); | |
| end; | |
| if InaccurateBPM then begin | |
| WaitSamples:=WaitSamples and $ffffffff00000000; | |
| end; | |
| WaitSamplesFloat:=WaitSamples/TpvInt64($100000000); | |
| fTimeToMusicTickFactor:=ProjectSampleRate/WaitSamplesFloat; | |
| fAudioSoundOGGSoundTrack1:=pvApplication.Audio.OGGs.Load('soundtrack1',pvApplication.Assets.GetAssetStream('music/soundtrack1.ogg'),true); | |
| fFrameGraph:=TpvFrameGraph.Create(pvApplication.VulkanDevice); | |
| fFrameGraph.SurfaceIsSwapchain:=true; | |
| SampleCounts:=pvApplication.VulkanDevice.PhysicalDevice.Properties.limits.framebufferColorSampleCounts and | |
| pvApplication.VulkanDevice.PhysicalDevice.Properties.limits.framebufferDepthSampleCounts and | |
| pvApplication.VulkanDevice.PhysicalDevice.Properties.limits.framebufferStencilSampleCounts; | |
| if (SampleCounts and TVkSampleCountFlags(VK_SAMPLE_COUNT_8_BIT))<>0 then begin | |
| fVulkanSampleCountFlagBits:=TVkSampleCountFlagBits(VK_SAMPLE_COUNT_8_BIT); | |
| end else if (SampleCounts and TVkSampleCountFlags(VK_SAMPLE_COUNT_4_BIT))<>0 then begin | |
| fVulkanSampleCountFlagBits:=TVkSampleCountFlagBits(VK_SAMPLE_COUNT_4_BIT); | |
| end else if (SampleCounts and TVkSampleCountFlags(VK_SAMPLE_COUNT_2_BIT))<>0 then begin | |
| fVulkanSampleCountFlagBits:=TVkSampleCountFlagBits(VK_SAMPLE_COUNT_2_BIT); | |
| end else begin | |
| fVulkanSampleCountFlagBits:=TVkSampleCountFlagBits(VK_SAMPLE_COUNT_1_BIT); | |
| end; | |
| fFrameGraph.AddImageResourceType('resourcetype_surface', | |
| true, | |
| VK_FORMAT_B8G8R8A8_SRGB, | |
| TVkSampleCountFlagBits(VK_SAMPLE_COUNT_1_BIT), | |
| TpvFrameGraph.TImageType.Surface, | |
| TpvFrameGraph.TImageSize.Create(TpvFrameGraph.TImageSize.TKind.SurfaceDependent,1.0,1.0), | |
| TVkImageUsageFlags(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) or TVkImageUsageFlags(VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT), | |
| 1 | |
| ); | |
| fFrameGraph.AddImageResourceType('resourcetype_msaa_color', | |
| true, | |
| VK_FORMAT_R16G16B16A16_SFLOAT, | |
| fVulkanSampleCountFlagBits, | |
| TpvFrameGraph.TImageType.Color, | |
| TpvFrameGraph.TImageSize.Create(TpvFrameGraph.TImageSize.TKind.SurfaceDependent,1.0,1.0), | |
| TVkImageUsageFlags(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) or TVkImageUsageFlags(VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) or TVkImageUsageFlags(VK_IMAGE_USAGE_SAMPLED_BIT), | |
| 1 | |
| ); | |
| fFrameGraph.AddImageResourceType('resourcetype_msaa_depth', | |
| true, | |
| pvApplication.VulkanDepthImageFormat, | |
| fVulkanSampleCountFlagBits, | |
| TpvFrameGraph.TImageType.From(pvApplication.VulkanDepthImageFormat), | |
| TpvFrameGraph.TImageSize.Create(TpvFrameGraph.TImageSize.TKind.SurfaceDependent,1.0,1.0), | |
| TVkImageUsageFlags(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) or TVkImageUsageFlags(VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT), | |
| 1 | |
| ); | |
| fFrameGraph.AddImageResourceType('resourcetype_color', | |
| true, | |
| VK_FORMAT_R16G16B16A16_SFLOAT, | |
| TVkSampleCountFlagBits(VK_SAMPLE_COUNT_1_BIT), | |
| TpvFrameGraph.TImageType.Color, | |
| TpvFrameGraph.TImageSize.Create(TpvFrameGraph.TImageSize.TKind.SurfaceDependent,1.0,1.0), | |
| TVkImageUsageFlags(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) or TVkImageUsageFlags(VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) or TVkImageUsageFlags(VK_IMAGE_USAGE_SAMPLED_BIT), | |
| 1 | |
| ); | |
| fFrameGraph.AddImageResourceType('resourcetype_srgb_color', | |
| true, | |
| VK_FORMAT_R8G8B8A8_SRGB, | |
| TVkSampleCountFlagBits(VK_SAMPLE_COUNT_1_BIT), | |
| TpvFrameGraph.TImageType.Color, | |
| TpvFrameGraph.TImageSize.Create(TpvFrameGraph.TImageSize.TKind.SurfaceDependent,1.0,1.0), | |
| TVkImageUsageFlags(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) or TVkImageUsageFlags(VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) or TVkImageUsageFlags(VK_IMAGE_USAGE_SAMPLED_BIT), | |
| 1 | |
| ); | |
| fFrameGraph.AddImageResourceType('resourcetype_depth', | |
| true, | |
| pvApplication.VulkanDepthImageFormat, | |
| TVkSampleCountFlagBits(VK_SAMPLE_COUNT_1_BIT), | |
| TpvFrameGraph.TImageType.From(pvApplication.VulkanDepthImageFormat), | |
| TpvFrameGraph.TImageSize.Create(TpvFrameGraph.TImageSize.TKind.SurfaceDependent,1.0,1.0), | |
| TVkImageUsageFlags(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) or TVkImageUsageFlags(VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT), | |
| 1 | |
| ); | |
| fSceneContentRenderPass:=TScreenMainMenuSceneContentRenderPass.Create(fFrameGraph,self); | |
| fTonemappingRenderPass:=TScreenMainMenuTonemappingRenderPass.Create(fFrameGraph); | |
| fAntialiasingRenderPass:=TScreenMainMenuAntialiasingRenderPass.Create(fFrameGraph); | |
| fFrameGraph.RootPass:=fAntialiasingRenderPass; | |
| fFrameGraph.DoWaitOnSemaphore:=true; | |
| fFrameGraph.DoSignalSemaphore:=true; | |
| fFrameGraph.Compile; | |
| fSelectedIndex:=-1; | |
| fReady:=false; | |
| end; | |
| destructor TScreenMainMenu.Destroy; | |
| begin | |
| FreeAndNil(fFrameGraph); | |
| FreeAndNil(fAudioSoundOGGSoundTrack1); | |
| inherited Destroy; | |
| end; | |
| procedure TScreenMainMenu.Show; | |
| var Index:TpvInt32; | |
| begin | |
| inherited Show; | |
| for Index:=0 to MaxSwapChainImages-1 do begin | |
| fVulkanRenderSemaphores[Index]:=TpvVulkanSemaphore.Create(pvApplication.VulkanDevice); | |
| end; | |
| fFrameGraph.Show; | |
| fTime:=0.0; | |
| fAudioSoundOGGSoundTrack1.Play(0.0,0.0,1.0,true); | |
| end; | |
| procedure TScreenMainMenu.Hide; | |
| var Index:TpvInt32; | |
| begin | |
| fFrameGraph.Hide; | |
| fAudioSoundOGGSoundTrack1.Stop; | |
| for Index:=0 to MaxSwapChainImages-1 do begin | |
| FreeAndNil(fVulkanRenderSemaphores[Index]); | |
| end; | |
| inherited Hide; | |
| end; | |
| procedure TScreenMainMenu.Resume; | |
| begin | |
| inherited Resume; | |
| end; | |
| procedure TScreenMainMenu.Pause; | |
| begin | |
| inherited Pause; | |
| end; | |
| procedure TScreenMainMenu.Resize(const aWidth,aHeight:TpvInt32); | |
| begin | |
| inherited Resize(aWidth,aHeight); | |
| end; | |
| procedure TScreenMainMenu.AfterCreateSwapChain; | |
| begin | |
| inherited AfterCreateSwapChain; | |
| fFrameGraph.SetSwapChain(pvApplication.VulkanSwapChain, | |
| pvApplication.VulkanDepthImageFormat); | |
| fFrameGraph.AfterCreateSwapChain; | |
| end; | |
| procedure TScreenMainMenu.BeforeDestroySwapChain; | |
| begin | |
| fFrameGraph.BeforeDestroySwapChain; | |
| inherited BeforeDestroySwapChain; | |
| end; | |
| function TScreenMainMenu.KeyEvent(const aKeyEvent:TpvApplicationInputKeyEvent):boolean; | |
| begin | |
| result:=false; | |
| if fReady and (aKeyEvent.KeyEventType=TpvApplicationInputKeyEventType.Down) then begin | |
| case aKeyEvent.KeyCode of | |
| KEYCODE_AC_BACK,KEYCODE_ESCAPE:begin | |
| // pvApplication.NextScreen:=TScreenMainMenu.Create; | |
| pvApplication.Terminate; | |
| end; | |
| KEYCODE_UP:begin | |
| if fSelectedIndex<=0 then begin | |
| fSelectedIndex:=0; | |
| end else begin | |
| dec(fSelectedIndex); | |
| end; | |
| end; | |
| KEYCODE_DOWN:begin | |
| if fSelectedIndex>=0 then begin | |
| fSelectedIndex:=0; | |
| end else begin | |
| inc(fSelectedIndex); | |
| end; | |
| end; | |
| KEYCODE_PAGEUP:begin | |
| if fSelectedIndex<0 then begin | |
| fSelectedIndex:=0; | |
| end; | |
| end; | |
| KEYCODE_PAGEDOWN:begin | |
| if fSelectedIndex<0 then begin | |
| fSelectedIndex:=0; | |
| end; | |
| end; | |
| KEYCODE_HOME:begin | |
| fSelectedIndex:=0; | |
| end; | |
| KEYCODE_END:begin | |
| fSelectedIndex:=0 | |
| end; | |
| KEYCODE_RETURN,KEYCODE_SPACE:begin | |
| if fSelectedIndex=0 then begin | |
| // pvApplication.NextScreen:=TScreenMainMenu.Create; | |
| end; | |
| end; | |
| end; | |
| end; | |
| end; | |
| function TScreenMainMenu.PointerEvent(const aPointerEvent:TpvApplicationInputPointerEvent):boolean; | |
| var Index:TpvInt32; | |
| cy:TpvFloat; | |
| begin | |
| result:=false; | |
| {if fReady then begin | |
| case aPointerEvent.PointerEventType of | |
| TpvApplicationInputPointerEventType.Down:begin | |
| fSelectedIndex:=-1; | |
| cy:=fStartY; | |
| for Index:=0 to 0 do begin | |
| if (aPointerEvent.Position.y>=cy) and (aPointerEvent.Position.y<(cy+(Application.TextOverlay.FontCharHeight*FontSize))) then begin | |
| fSelectedIndex:=Index; | |
| if fSelectedIndex=0 then begin | |
| pvApplication.NextScreen:=TScreenMainMenu.Create; | |
| end; | |
| end; | |
| cy:=cy+((Application.TextOverlay.FontCharHeight+4)*FontSize); | |
| end; | |
| end; | |
| TpvApplicationInputPointerEventType.Up:begin | |
| end; | |
| TpvApplicationInputPointerEventType.Motion:begin | |
| fSelectedIndex:=-1; | |
| cy:=fStartY; | |
| for Index:=0 to 0 do begin | |
| if (aPointerEvent.Position.y>=cy) and (aPointerEvent.Position.y<(cy+(Application.TextOverlay.FontCharHeight*FontSize))) then begin | |
| fSelectedIndex:=Index; | |
| end; | |
| cy:=cy+((Application.TextOverlay.FontCharHeight+4)*FontSize); | |
| end; | |
| end; | |
| TpvApplicationInputPointerEventType.Drag:begin | |
| end; | |
| end; | |
| end;} | |
| end; | |
| function TScreenMainMenu.Scrolled(const aRelativeAmount:TpvVector2):boolean; | |
| begin | |
| result:=false; | |
| end; | |
| function TScreenMainMenu.CanBeParallelProcessed:boolean; | |
| begin | |
| result:=true; | |
| end; | |
| procedure TScreenMainMenu.Update(const aDeltaTime:TpvDouble); | |
| begin | |
| inherited Update(aDeltaTime); | |
| fFrameGraph.Update(pvApplication.UpdateSwapChainImageIndex,pvApplication.UpdateFrameCounter); | |
| {Application.TextOverlay.AddText(pvApplication.Width*0.5,Application.TextOverlay.FontCharHeight*1.0,2.0,toaCenter,'MainMenu'); | |
| fStartY:=pvApplication.Height-((((Application.TextOverlay.FontCharHeight+4)*FontSize)*1.25)-(4*FontSize)); | |
| cy:=fStartY; | |
| for Index:=0 to 0 do begin | |
| IsSelected:=fSelectedIndex=Index; | |
| s:=' '+Options[Index]+' '; | |
| if IsSelected then begin | |
| s:='>'+s+'<'; | |
| end; | |
| Application.TextOverlay.AddText(pvApplication.Width*0.5,cy,FontSize,toaCenter,TpvRawByteString(s),MenuColors[IsSelected,0,0],MenuColors[IsSelected,0,1],MenuColors[IsSelected,0,2],MenuColors[IsSelected,0,3],MenuColors[IsSelected,1,0],MenuColors[IsSelected,1,1],MenuColors[IsSelected,1,2],MenuColors[IsSelected,1,3]); | |
| cy:=cy+((Application.TextOverlay.FontCharHeight+4)*FontSize); | |
| end;} | |
| fReady:=true; | |
| fTime:=fTime+aDeltaTime; | |
| end; | |
| procedure TScreenMainMenu.Draw(const aSwapChainImageIndex:TpvInt32;var aWaitSemaphore:TpvVulkanSemaphore;const aWaitFence:TpvVulkanFence=nil); | |
| begin | |
| inherited Draw(aSwapChainImageIndex,aWaitSemaphore,nil); | |
| fFrameGraph.Draw(aSwapChainImageIndex, | |
| pvApplication.DrawFrameCounter, | |
| aWaitSemaphore, | |
| fVulkanRenderSemaphores[aSwapChainImageIndex], | |
| aWaitFence); | |
| aWaitSemaphore:=fVulkanRenderSemaphores[aSwapChainImageIndex]; | |
| end; | |
| end. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment