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