feat(render): 光影包加载与着色器热替换(type=shader,坏包回退默认)
This commit is contained in:
@@ -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)
|
||||
|
||||
88
internal/render/shaderpack.go
Normal file
88
internal/render/shaderpack.go
Normal 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
|
||||
}
|
||||
BIN
tools/zig.zip
BIN
tools/zig.zip
Binary file not shown.
Reference in New Issue
Block a user