Files
aego/render/pass3d.go
T
sanspie 5eb1832907
ci-platforms / darwin amd64 smoke (push) Skipped
ci / build (amd64, linux, ubuntu-24.04) (push) Failing after 15m28s
ci / release (push) Skipped
ci-platforms / windows amd64 smoke (push) Skipped
ci-platforms / darwin arm64 smoke (push) Skipped
ci / checks (push) Successful in 7m47s
Complete Stage 12 for v0.12.0
2026-11-05 11:46:53 +03:00

116 lines
2.8 KiB
Go

package render
import (
"aego/core/mathx"
"aego/gpu"
"aego/render/debug"
"aego/render/mesh"
"aego/render/shader"
)
type meshOpaquePass struct{}
func (meshOpaquePass) Execute(ctx *PassContext) {
ctx.Renderer.drawMeshes(ctx, ctx.Renderer.meshes.Opaque())
}
type meshBlendPass struct{}
func (meshBlendPass) Execute(ctx *PassContext) {
ctx.Renderer.drawMeshes(ctx, ctx.Renderer.meshes.Transparent())
}
func (r *Renderer) drawMeshes(ctx *PassContext, items []mesh.Item) {
if len(items) == 0 {
return
}
p := ctx.Pass
for i := range items {
it := &items[i]
m := it.Blend
if int(m) >= blendModes {
m = 0
}
ds := 0
if it.DoubleSided {
ds = 1
}
if it.Material != nil {
if !r.mats.BindDomain(p, it.Material, shader.DomainMesh2D) || !r.mats.BindLanes(p, it.Material, it.Lanes) {
continue
}
if it.Material.Shader().Features&shader.FeatureLighting != 0 {
channels := it.Material.Shader().Features&shader.FeatureSurfaceChannels != 0
if !r.bindLighting(p, it.LightSet, it.Normal.Texture, it.Emission.Region.Texture, channels) {
continue
}
mode := it.Emission.Mode
if !it.Emission.Valid() {
mode = 0
}
r.bindSurface(p, it.Normal, it.Emission, mode)
}
} else {
p.SetPipeline(r.meshPipes[m][ds])
}
r.setDrawUniform(p, it)
p.SetVertexBuffer(0, it.Mesh.VB)
p.SetIndexBuffer(it.Mesh.IB)
p.SetTexture(shader.TexMain, it.Texture.Texture, it.Sampler)
p.DrawIndexed(it.Mesh.Count, 0)
r.stats.MeshDraws++
}
}
func (r *Renderer) setDrawUniform(p gpu.Pass, it *mesh.Item) {
b := r.drawBuf
for i, v := range it.World {
putF32(b[i*4:], v)
}
c := it.Color
if c == (mathx.Color{}) {
c = mathx.Color{R: 1, G: 1, B: 1, A: 1}
}
c = c.Premultiplied()
putF32(b[64:], c.R)
putF32(b[68:], c.G)
putF32(b[72:], c.B)
putF32(b[76:], c.A)
putF32(b[80:], it.Texture.UVMin.X)
putF32(b[84:], it.Texture.UVMin.Y)
putF32(b[88:], it.Texture.UVMax.X)
putF32(b[92:], it.Texture.UVMax.Y)
r.dev.UpdateBuffer(r.ubDraw, 0, b)
p.SetUniformBuffer(shader.SlotDraw, r.ubDraw)
}
type sprite3DPass struct{}
func (sprite3DPass) Execute(ctx *PassContext) {
r := ctx.Renderer
batches := r.sprites3d.Build()
if len(batches) == 0 {
return
}
r.sprites3d.Upload()
for i := range batches {
b := &batches[i]
if b.Texture.IsZero() {
continue
}
ctx.Pass.SetPipeline(r.sprite3dPipes[b.Blend])
ctx.Pass.SetVertexBufferAt(0, r.sprites3d.Buffer(), b.First*sprite3DStride)
ctx.Pass.SetTexture(shader.TexMain, b.Texture, b.Sampler)
ctx.Pass.DrawInstanced(4, b.Count)
r.stats.Batches++
r.stats.Instances += uint32(b.Count)
}
}
func (r *Renderer) drawLines(p gpu.Pass, pipe gpu.PipelineHandle, rg debug.Range) {
p.SetPipeline(pipe)
p.SetVertexBuffer(0, r.dbg.Buffer())
p.Draw(rg.First, rg.Count)
r.stats.DebugVerts += uint32(rg.Count)
}