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 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