feat(render): 光影包加载与着色器热替换(type=shader,坏包回退默认)

This commit is contained in:
NianGao Dev
2026-08-15 23:21:48 +08:00
parent 8b6b78d02c
commit 236f7a4b06
3 changed files with 99 additions and 0 deletions

View File

@@ -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.1427×240 基准 × 3 缩放 = 1280×720
guiScale := float32(3)
uiR, err := ui.New(cfg.Client.WindowWidth, cfg.Client.WindowHeight, guiScale)

View File

@@ -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
}

Binary file not shown.