zworld/test/tgraph/pass.go
2024-01-20 18:44:07 +08:00

103 lines
2.6 KiB
Go

package tgraph
import (
"github.com/vkngwrapper/core/v2/core1_0"
"zworld/engine/object"
"zworld/engine/object/mesh"
"zworld/engine/renderapi"
"zworld/engine/renderapi/command"
"zworld/engine/renderapi/framebuffer"
"zworld/engine/renderapi/renderpass"
"zworld/engine/renderapi/renderpass/attachment"
"zworld/engine/renderapi/vulkan"
)
type Pass struct {
app vulkan.App
pass renderpass.T
gbuffer GeometryBuffer
fbuf framebuffer.Array
materials MaterialCache
meshQuery *object.Query[mesh.Mesh]
}
func NewPass(app vulkan.App, target vulkan.Target, gbuffer GeometryBuffer) *Pass {
pass := renderpass.New(app.Device(), renderpass.Args{
Name: "Pass",
ColorAttachments: []attachment.Color{
{
Name: NormalsAttachment,
LoadOp: core1_0.AttachmentLoadOpClear,
StoreOp: core1_0.AttachmentStoreOpStore,
FinalLayout: core1_0.ImageLayoutShaderReadOnlyOptimal,
Image: attachment.FromImageArray(gbuffer.Normal()),
},
{
Name: PositionAttachment,
LoadOp: core1_0.AttachmentLoadOpClear,
StoreOp: core1_0.AttachmentStoreOpStore,
FinalLayout: core1_0.ImageLayoutShaderReadOnlyOptimal,
Image: attachment.FromImageArray(gbuffer.Position()),
},
},
DepthAttachment: &attachment.Depth{
LoadOp: core1_0.AttachmentLoadOpClear,
StencilLoadOp: core1_0.AttachmentLoadOpClear,
StoreOp: core1_0.AttachmentStoreOpStore,
FinalLayout: core1_0.ImageLayoutShaderReadOnlyOptimal,
ClearDepth: 1,
Image: attachment.FromImageArray(target.Surfaces()),
},
Subpasses: []renderpass.Subpass{
{
Name: MainSubpass,
Depth: true,
ColorAttachments: []attachment.Name{NormalsAttachment, PositionAttachment},
},
},
})
fbuf, err := framebuffer.NewArray(target.Frames(), app.Device(), "forward", target.Width(), target.Height(), pass)
if err != nil {
panic(err)
}
return &Pass{
gbuffer: gbuffer,
fbuf: fbuf,
app: app,
pass: pass,
materials: NewMaterialCache(app, pass, gbuffer.Frames()),
meshQuery: object.NewQuery[mesh.Mesh](),
}
}
func (p *Pass) Record(cmds command.Recorder, args renderapi.Args, scene object.Component) {
opaque := p.meshQuery.
Reset().
Collect(scene)
cmds.Record(func(cmd command.Buffer) {
cmd.CmdBeginRenderPass(p.pass, p.fbuf[args.Frame])
})
cam := CameraFromArgs(args)
groups := MaterialGroups(p.materials, args.Frame, opaque)
groups.Draw(cmds, cam, nil)
cmds.Record(func(cmd command.Buffer) {
cmd.CmdEndRenderPass()
})
}
func (p *Pass) Name() string {
return "Pass"
}
func (p *Pass) Destroy() {
p.pass.Destroy()
}