Files
sanspie 17cb5e4291 Stage 2-5: assets, scene/ECS, editor, 3D, and Aego Script
Stage 2: render pipeline and UI toolkit over gpu/platform.
Stage 3: schema registry, asset pipeline + runtime loader, scene graph and ECS.
Stage 4: editor — docking, inspector, scene/game views, play mode, asset browser, console, profiler; 4.5 adds the 3D foundation (mixed 2D/3D spaces, meshes, depth).
Stage 5: Aego Script — compiler (lexer/parser/types/resolver/checker/asm/compiler), bytecode with verifier and register VM, instance runtime, stdlib, native bindings, and editor/CLI integration (aego run/edit/check/test/dump).
2026-10-08 13:17:28 +03:00

103 lines
2.3 KiB
Go

package render
import (
"aego/core/mathx"
"aego/gpu"
"aego/render/debug"
"aego/render/mesh"
)
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
r.setUniform(p, ctx.View.ViewProjection(r.caps))
for i := range items {
it := &items[i]
m := it.Blend
if int(m) >= blendModes {
m = 0
}
ds := 0
if it.DoubleSided {
ds = 1
}
p.SetPipeline(r.meshPipes[m][ds])
p.SetUniformBuffer(0, r.ub)
r.setDrawUniform(p, it)
p.SetVertexBuffer(0, it.Mesh.VB)
p.SetIndexBuffer(it.Mesh.IB)
p.SetTexture(0, 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(1, 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()
r.setUniform(ctx.Pass, ctx.View.ViewProjection(r.caps))
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.SetUniformBuffer(0, r.ub)
ctx.Pass.SetTexture(0, 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, vp mathx.Mat4, rg debug.Range) {
p.SetPipeline(pipe)
r.setUniform(p, vp)
p.SetVertexBuffer(0, r.dbg.Buffer())
p.Draw(rg.First, rg.Count)
r.stats.DebugVerts += uint32(rg.Count)
}