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

89 lines
2.5 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//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
}