Files
ngzz-mc/internal/render/shaderpack.go

89 lines
2.5 KiB
Go
Raw Normal View History

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