89 lines
2.1 KiB
Go
89 lines
2.1 KiB
Go
package pass
|
|
|
|
import (
|
|
"zworld/engine/object/light"
|
|
"zworld/engine/object/mesh"
|
|
"zworld/engine/render/uniform"
|
|
"zworld/engine/renderapi/command"
|
|
"zworld/engine/renderapi/material"
|
|
)
|
|
|
|
type DrawGroup struct {
|
|
ID material.ID
|
|
Material Material
|
|
Meshes []mesh.Mesh
|
|
}
|
|
|
|
type DrawGroups []DrawGroup
|
|
|
|
func (groups DrawGroups) Draw(cmds command.Recorder, camera uniform.Camera, lights []light.T) {
|
|
for _, group := range groups {
|
|
// there could be multiple instances of the same material
|
|
// however, as long as there are no calls in between draws we should be okay
|
|
group.Material.Begin(camera, lights)
|
|
}
|
|
|
|
for _, group := range groups {
|
|
group.Material.Bind(cmds)
|
|
for _, msh := range group.Meshes {
|
|
group.Material.Draw(cmds, msh)
|
|
}
|
|
}
|
|
|
|
for _, group := range groups {
|
|
// can happen multiple times - similar to BeginFrame it should be ok
|
|
// it is wasted work though
|
|
group.Material.End()
|
|
}
|
|
}
|
|
|
|
// Sort meshes by material according to depth.
|
|
// Consecutive meshes in the depth order are grouped if they have the same material
|
|
func OrderedGroups(cache MaterialCache, frame int, meshes []mesh.Mesh) DrawGroups {
|
|
groups := make(DrawGroups, 0, 16)
|
|
var group *DrawGroup
|
|
for _, msh := range meshes {
|
|
mats, ready := cache.TryFetch(msh.Material())
|
|
if !ready {
|
|
continue
|
|
}
|
|
|
|
id := msh.MaterialID()
|
|
if group == nil || id != group.Material.ID() {
|
|
groups = append(groups, DrawGroup{
|
|
Material: mats[frame],
|
|
Meshes: make([]mesh.Mesh, 0, 32),
|
|
})
|
|
group = &groups[len(groups)-1]
|
|
}
|
|
group.Meshes = append(group.Meshes, msh)
|
|
}
|
|
return groups
|
|
}
|
|
|
|
// Sort meshes by material
|
|
func MaterialGroups(cache MaterialCache, frame int, meshes []mesh.Mesh) DrawGroups {
|
|
groups := make(DrawGroups, 0, 16)
|
|
matGroups := map[material.ID]*DrawGroup{}
|
|
|
|
for _, msh := range meshes {
|
|
mats, ready := cache.TryFetch(msh.Material())
|
|
if !ready {
|
|
continue
|
|
}
|
|
|
|
group, exists := matGroups[msh.MaterialID()]
|
|
if !exists {
|
|
groups = append(groups, DrawGroup{
|
|
Material: mats[frame],
|
|
Meshes: make([]mesh.Mesh, 0, 32),
|
|
})
|
|
group = &groups[len(groups)-1]
|
|
matGroups[msh.MaterialID()] = group
|
|
}
|
|
group.Meshes = append(group.Meshes, msh)
|
|
}
|
|
|
|
return groups
|
|
}
|