diff --git a/cmd/client/client_gl.go b/cmd/client/client_gl.go index 8eda16b0..fc9f80bc 100644 --- a/cmd/client/client_gl.go +++ b/cmd/client/client_gl.go @@ -217,6 +217,17 @@ func main() { rend.SetAtlas(atlasImg) rend.SetCursorMode(true) + // 光影包(渲染.md §9:未安装 → 默认光影;坏包 → 回退默认) + if sp, err := render.LoadShaderPack(am); err != nil { + log.Warnf("光影包加载失败(使用默认光影):%v", err) + } else if sp != nil { + if err := rend.ApplyShaderPack(sp); err != nil { + log.Warnf("光影包应用失败(使用默认光影):%v", err) + } else { + log.Infof("已加载光影包 %q", sp.ID) + } + } + // UI 层(UI还原.md §3.1:427×240 基准 × 3 缩放 = 1280×720) guiScale := float32(3) uiR, err := ui.New(cfg.Client.WindowWidth, cfg.Client.WindowHeight, guiScale) diff --git a/internal/render/shaderpack.go b/internal/render/shaderpack.go new file mode 100644 index 00000000..fe29f88b --- /dev/null +++ b/internal/render/shaderpack.go @@ -0,0 +1,88 @@ +//go:build gl + +// 光影包加载:type=shader 内容包替换着色器(渲染.md §9.2–§9.3)。 +package render + +import ( + "fmt" + "os" + "path/filepath" + + "mc/internal/assets" + + "github.com/go-gl/gl/v3.3-core/gl" +) + +// ShaderPack 一个光影包(着色器源码集合)。 +type ShaderPack struct { + ID string + Vert string // chunk.vert 源码 + Frag string // chunk.frag 源码 +} + +// LoadShaderPack 扫描内容包管理器,寻找 type=shader 的包并读取着色器。 +// 未安装光影包返回 (nil, nil) → 使用系统默认光影(渲染.md §9.1 默认回退)。 +func LoadShaderPack(am *assets.Manager) (*ShaderPack, error) { + var pack *assets.Pack + for _, p := range am.Packs() { + if p.Type == assets.PackShader { + pack = p + break // 优先级已排序,第一个即最高优先级 + } + } + if pack == nil { + return nil, nil // 默认光影 + } + sp := &ShaderPack{ID: pack.ID} + for _, ns := range []string{"minecraft", pack.ID} { + vertPath := filepath.Join(pack.Root, "assets", ns, "shaders", "chunk.vert") + if b, err := os.ReadFile(vertPath); err == nil { + sp.Vert = string(b) + break + } + } + for _, ns := range []string{"minecraft", pack.ID} { + fragPath := filepath.Join(pack.Root, "assets", ns, "shaders", "chunk.frag") + if b, err := os.ReadFile(fragPath); err == nil { + sp.Frag = string(b) + break + } + } + if sp.Vert == "" || sp.Frag == "" { + return nil, fmt.Errorf("render.LoadShaderPack: 光影包 %q 缺少 chunk.vert/chunk.frag(拒绝加载,回退默认)", pack.ID) + } + return sp, nil +} + +// ApplyShaderPack 用光影包重建着色程序(失败回退默认并返回错误,渲染.md §9.3)。 +func (r *Renderer) ApplyShaderPack(sp *ShaderPack) error { + vertSrc, fragSrc := chunkVertSrc, chunkFragSrc + if sp != nil { + vertSrc, fragSrc = sp.Vert, sp.Frag + } + vs, err := compileShader(gl.VERTEX_SHADER, vertSrc) + if err != nil { + return fmt.Errorf("render.ApplyShaderPack 顶点着色器: %w", err) + } + defer gl.DeleteShader(vs) + fs, err := compileShader(gl.FRAGMENT_SHADER, fragSrc) + if err != nil { + return fmt.Errorf("render.ApplyShaderPack 片元着色器: %w", err) + } + defer gl.DeleteShader(fs) + prog := gl.CreateProgram() + gl.AttachShader(prog, vs) + gl.AttachShader(prog, fs) + gl.LinkProgram(prog) + var ok int32 + gl.GetProgramiv(prog, gl.LINK_STATUS, &ok) + if ok == 0 { + gl.DeleteProgram(prog) + return fmt.Errorf("render.ApplyShaderPack: 链接失败(保留默认光影)") + } + if r.prog != 0 { + gl.DeleteProgram(r.prog) + } + r.prog = prog + return nil +} diff --git a/tools/zig.zip b/tools/zig.zip index 1d25d47f..c60ff3e4 100644 Binary files a/tools/zig.zip and b/tools/zig.zip differ