//go:build gl // 图集植被染色(渲染.md §4.1): // 原版材质包的草顶/树叶纹理是灰度图,绿色来自生物群系染色表 // (textures/colormap/grass.png、foliage.png)。 // MVP:取染色表中心色(平原绿)对图集内对应纹理乘色;按群系逐顶点着色后置。 package main import ( "image" "image/color" "image/draw" "image/png" "os" "mc/internal/assets" ) // applyAtlasTint 给图集内带染色标记的纹理乘上染色表中心色。 // 返回新图集图像(原地复制后修改);染色表缺失的键保持原样。 func applyAtlasTint(src image.Image, uv map[string]image.Rectangle, am *assets.Manager, tinted map[string][]string) image.Image { b := src.Bounds() dst := image.NewRGBA(image.Rect(0, 0, b.Dx(), b.Dy())) draw.Draw(dst, dst.Bounds(), src, b.Min, draw.Src) for tintName, keys := range tinted { tr, tg, tb, ok := colormapCenter(am, tintName) if !ok { continue } for _, key := range keys { rect, found := uv[key] if !found { continue } for y := rect.Min.Y; y < rect.Max.Y; y++ { for x := rect.Min.X; x < rect.Max.X; x++ { pr, pg, pb, pa := src.At(x, y).RGBA() dst.SetRGBA(x, y, color.RGBA{ R: uint8(uint32(uint8(pr>>8)) * tr / 255), G: uint8(uint32(uint8(pg>>8)) * tg / 255), B: uint8(uint32(uint8(pb>>8)) * tb / 255), A: uint8(pa >> 8), }) } } } } return dst } // colormapCenter 读取染色表中心像素(0–255)。 func colormapCenter(am *assets.Manager, name string) (r, g, b uint32, ok bool) { p, found := am.ResolveTexture("colormap/" + name) if !found { return 0, 0, 0, false } f, err := os.Open(p) if err != nil { return 0, 0, 0, false } defer f.Close() img, err := png.Decode(f) if err != nil { return 0, 0, 0, false } cb := img.Bounds() r, g, b, _ = img.At(cb.Min.X+cb.Dx()/2, cb.Min.Y+cb.Dy()/2).RGBA() return r >> 8, g >> 8, b >> 8, true }