feat(client): 手持物品渲染 + 动物方块模型 + 实体贴图 alpha test

- 手持非放置物品(工具/食物):实体图集物品图标小四边形(原版倾斜角,
  双面、alpha test),随挥动动画平移;可放置方块仍为六面立方体
- 动物(牛/猪/羊/鸡)改为方块组合模型(身体+头+腿),按原版皮肤布局
  取子矩形贴图,水平面向相机;修复动物 VAO 未捕获 EBO 导致的驱动崩溃
- 僵尸/村民/掉落物广告牌开启 alpha test(透明区域不再显黑块)
This commit is contained in:
NianGao Dev
2026-08-16 23:23:30 +08:00
parent 5d0524ca52
commit b0b632df05
7 changed files with 394 additions and 35 deletions

View File

@@ -35,11 +35,17 @@ type Renderer struct {
// 第一人称手持方块(渲染.md §5.2)
handVao, handVbo, handIbo uint32
// 手持物品图标(非放置物品:实体图集内物品贴图的小四边形)
handItemVao, handItemVbo, handItemIbo uint32
// 实体广告牌(渲染.md §5.3)
entityTex uint32
entityUV map[string][4]float32
billVao, billVbo, billIbo uint32
// 动物方块模型(渲染.md §5.3:身体/头/腿方块组合,动态 VBO)
animalVao, animalVbo, animalIbo uint32
proj [16]float32
view [16]float32
}
@@ -174,6 +180,14 @@ func compileShader(kind uint32, src string) (uint32, error) {
return s, nil
}
// SetWindowIcon 设置窗口图标(素材包 pack.png 原版 logo,构建与发布.md §8)。
func (r *Renderer) SetWindowIcon(img image.Image) {
if img == nil || r.window == nil {
return
}
r.window.SetIcon([]image.Image{img})
}
// SetAtlas 上传纹理图集(最近邻采样 + mipmap,渲染.md §4)。
func (r *Renderer) SetAtlas(img image.Image) {
if r.atlas == 0 {
@@ -213,6 +227,22 @@ func (r *Renderer) Shutdown() {
for _, c := range r.chunks {
c.destroy()
}
for _, v := range [][3]uint32{
{r.handVao, r.handVbo, r.handIbo},
{r.handItemVao, r.handItemVbo, r.handItemIbo},
{r.billVao, r.billVbo, r.billIbo},
{r.animalVao, r.animalVbo, r.animalIbo},
} {
if v[0] != 0 {
gl.DeleteVertexArrays(1, &v[0])
}
if v[1] != 0 {
gl.DeleteBuffers(1, &v[1])
}
if v[2] != 0 {
gl.DeleteBuffers(1, &v[2])
}
}
if r.atlas != 0 {
gl.DeleteTextures(1, &r.atlas)
}