zworld/engine/render/pass/lines.go
2024-01-14 22:56:06 +08:00

112 lines
2.8 KiB
Go

package pass
import (
"github.com/vkngwrapper/core/v2/core1_0"
"log"
"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/vertex"
"zworld/engine/renderapi/vulkan"
lineShape "zworld/plugins/geometry/lines"
)
type LinePass struct {
app vulkan.App
target vulkan.Target
pass renderpass.T
fbuf framebuffer.Array
materials MaterialCache
meshQuery *object.Query[mesh.Mesh]
}
func NewLinePass(app vulkan.App, target vulkan.Target, depth vulkan.Target) *LinePass {
log.Println("create line pass")
pass := renderpass.New(app.Device(), renderpass.Args{
Name: "Lines",
ColorAttachments: []attachment.Color{
{
Name: OutputAttachment,
Image: attachment.FromImageArray(target.Surfaces()),
LoadOp: core1_0.AttachmentLoadOpLoad,
StoreOp: core1_0.AttachmentStoreOpStore,
InitialLayout: core1_0.ImageLayoutShaderReadOnlyOptimal,
FinalLayout: core1_0.ImageLayoutShaderReadOnlyOptimal,
Blend: attachment.BlendMix,
},
},
DepthAttachment: &attachment.Depth{
Image: attachment.FromImageArray(depth.Surfaces()),
LoadOp: core1_0.AttachmentLoadOpLoad,
InitialLayout: core1_0.ImageLayoutShaderReadOnlyOptimal,
FinalLayout: core1_0.ImageLayoutDepthStencilAttachmentOptimal,
},
Subpasses: []renderpass.Subpass{
{
Name: MainSubpass,
Depth: true,
ColorAttachments: []attachment.Name{OutputAttachment},
},
},
})
fbufs, err := framebuffer.NewArray(target.Frames(), app.Device(), "lines", target.Width(), target.Height(), pass)
if err != nil {
panic(err)
}
lineShape.Debug.Setup(target.Frames())
return &LinePass{
app: app,
target: target,
pass: pass,
fbuf: fbufs,
materials: NewLineMaterialCache(app, pass, target.Frames()),
meshQuery: object.NewQuery[mesh.Mesh](),
}
}
func (p *LinePass) Record(cmds command.Recorder, args renderapi.Args, scene object.Component) {
cmds.Record(func(cmd command.Buffer) {
cmd.CmdBeginRenderPass(p.pass, p.fbuf[args.Frame])
})
lines := p.meshQuery.
Reset().
Where(isDrawLines).
Collect(scene)
// debug lines
debug := lineShape.Debug.Fetch()
lines = append(lines, debug)
cam := CameraFromArgs(args)
groups := MaterialGroups(p.materials, args.Frame, lines)
groups.Draw(cmds, cam, nil)
cmds.Record(func(cmd command.Buffer) {
cmd.CmdEndRenderPass()
})
}
func (p *LinePass) Name() string {
return "Lines"
}
func (p *LinePass) Destroy() {
p.fbuf.Destroy()
p.pass.Destroy()
p.materials.Destroy()
}
func isDrawLines(m mesh.Mesh) bool {
return m.Primitive() == vertex.Lines
}