Files
ngzz-mc/cmd/client/tint_gl.go
NianGao Dev d52bf1126f feat(client): 植被染色、破坏裂纹叠加、手持方块与实体广告牌渲染;原版 HUD 精灵
- 植被染色(渲染.md §4.1):blocks.json 增 tint 标记,图集构建后按
  colormap/grass|foliage 中心色乘色——原版材质包草顶/树叶为灰度图,不染色全灰
- 破坏裂纹(方块交互与动画.md §4):destroy_stage_0..9 裂纹盒叠加破坏目标方块
- 第一人称手持方块(渲染.md §5.2):选中槽放置方块六面 UV 视图空间立方体
- 实体广告牌(渲染.md §5.3):僵尸/村民/动物按贴图渲染,动物按 ID 轮换外观
- HUD 换原版精灵:crosshair/hotbar/hotbar_selection/heart/food(UI还原.md §3.4)
- 主菜单标题/按钮标签按请求字号光栅化(修复 24px 固定字号);版本角标 CJK
- 恢复背面剔除(相机修复后 '脚下黑块' 误诊解除);ESC 光标请求原子化防竞态
- dev 测试参数:-give/-crackstage/-spawntest/-esctest
2026-08-16 10:08:40 +08:00

71 lines
1.9 KiB
Go
Raw 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
// 图集植被染色(渲染.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
}