89 lines
2.5 KiB
Go
89 lines
2.5 KiB
Go
//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
|
||
}
|