Code-based item/block rendering with Minecraft Forge 1.11.2
从1.8开始MC引入了一套新的图形系统,相比与1.7.10的变化很大,导致了很多mod的更新困难。本贴以1.11.2为例演示新图形系统的使用,之所以选用1.11.2是因为MC和Forge都比1.8时候的成熟了。
首先对比下1.7.10和1.11.2的渲染方法:
1.7.10
1. 简单方块/物品
@Override
@SideOnly(Side.CLIENT)
public void registerIcons(IIconRegister r) {
itemIcon = r.registerIcon("modID:TextureName");
}
这个方法允许modder注册自定义的贴图,得到的IIcon对象可以用于各种渲染
2. 复杂点的方块渲染
有些方块不是简单的立方体,这时原版的就不够用了,于是forge引入了ISimpleBlockRenderingHandler(ISBRH,简单方块渲染器),在这里面能自定义方块的形状,最好的例子是各种楼梯和Buildcraft的管道。这种方式不支持动画,这种渲染方式是以区块为单位的,单个方块更新需要刷新区块。
3. 有动画的方块渲染
TileEntitySpecialRenderer,比如原版的箱子,BC的流体管道,BC管道里面的物品。这是最高级的渲染方法,允许调用一切OpenGL手段,但是代价是性能的降低,而且需要相应的方块有TileEntity。一般不推荐大量使用。
1.11.2
新的图形系统取消了IIcon的概念,并且引入了BlockState(暂时叫方块状态吧)和Model(模型)。新的系统性能更好,因为不需要每次渲染都从头生成渲染指令,但是代价就是编程麻烦了,而且理解整个系统也变得困难了。
1. 方块
BlockState可以简单理解为对1.7.10之前meta(方块附加值,0-15之间的一个数字)的封装。BlockState可以包含多个属性,原版属性有EnumFacing(方向,相当于1.7.10的ForgeDirection),整数(Integer)和布尔(Boolean,是或非)。BlockState的属性可以和meta挂钩,也可以是动态生成的(从TileEntity或者临近方块读取)。在默认情况下,MC在启动的时候会自动生成一个方块所有可能的BlockState,比如熔炉有4个朝向,每个朝向有着火和熄灭两种,于是一共有2x4=6种BlockState。每种可能的BlockState可以对应多种外观也可以只有一种,这些外观叫做Variant,每种Variant对应一种模型。如果有多个Variant那么MC会随机选择一种,比如原版的草,会看起来稍微不一样。
2. 物品
物品没有BlockState的概念但是还是有Variant的概念的
3. ISimpleBlockRenderingHandler永远远离我们而去了,但是TileEntitySpecialRenderer还在而且没有任何变化
ISimpleBlockRenderingHandler的代替品大概是IPerspectiveAwareModel,它允许我们根据方块状态返回渲染指令(BakedQuads,其实Quads是面的意思),这些可以由已加载的IBakedModel提供也可以是动态生成的。
4. 模型
有两种模型,用接口表示一种是IModel,另一种是IBakedModel(烧烤过的模型),MC从JSon文件或者代码加载IModel,在启动的时候烧烤(实在不知道怎么说了2333333)这些模型产生IBakedModel,IBakedModel储存的是经过优化的渲染指令(计算好的矩阵之类的),渲染的时候直接送给显示设备就好了。一般来讲是用JSON描述模型,比如采用的父模型(block/cube_all对应石头矿石一类6面贴图的玩意,item/generated对应普通物品比如铁定之类),详细的可以参考https://mcforge.readthedocs.io/en/latest/blockstates/forgeBlockstates/#sub-models ,http://greyminecraftcoder.blogspot.com.au/2014/12/block-models-texturing-quads-faces.html
JSON文件提供了不通过代码修改3D模型的可能,但是对有些特定场合不太适用。最近在做一个mod,里面可能有上百种物品和数十方块(都是矿物矿石之类的),每种物品或者方块都对应唯一一张贴图,如果每个都写JSON那是重复的巨大工作量...而且没人会想弄出台阶形状的矿石对吧2333 于是就有必要研究一种不通过手动写Json创建并加载模型的方法。最终实现的效果是不写任何json直接根据方块或者物品名字加载贴图。
代码已经写好,https://github.com/rikka0w0/Material_Warehouse @尤里的猫
本贴未完待续
从1.8开始MC引入了一套新的图形系统,相比与1.7.10的变化很大,导致了很多mod的更新困难。本贴以1.11.2为例演示新图形系统的使用,之所以选用1.11.2是因为MC和Forge都比1.8时候的成熟了。
首先对比下1.7.10和1.11.2的渲染方法:
1.7.10
1. 简单方块/物品
@Override
@SideOnly(Side.CLIENT)
public void registerIcons(IIconRegister r) {
itemIcon = r.registerIcon("modID:TextureName");
}
这个方法允许modder注册自定义的贴图,得到的IIcon对象可以用于各种渲染
2. 复杂点的方块渲染
有些方块不是简单的立方体,这时原版的就不够用了,于是forge引入了ISimpleBlockRenderingHandler(ISBRH,简单方块渲染器),在这里面能自定义方块的形状,最好的例子是各种楼梯和Buildcraft的管道。这种方式不支持动画,这种渲染方式是以区块为单位的,单个方块更新需要刷新区块。
3. 有动画的方块渲染
TileEntitySpecialRenderer,比如原版的箱子,BC的流体管道,BC管道里面的物品。这是最高级的渲染方法,允许调用一切OpenGL手段,但是代价是性能的降低,而且需要相应的方块有TileEntity。一般不推荐大量使用。
1.11.2
新的图形系统取消了IIcon的概念,并且引入了BlockState(暂时叫方块状态吧)和Model(模型)。新的系统性能更好,因为不需要每次渲染都从头生成渲染指令,但是代价就是编程麻烦了,而且理解整个系统也变得困难了。
1. 方块
BlockState可以简单理解为对1.7.10之前meta(方块附加值,0-15之间的一个数字)的封装。BlockState可以包含多个属性,原版属性有EnumFacing(方向,相当于1.7.10的ForgeDirection),整数(Integer)和布尔(Boolean,是或非)。BlockState的属性可以和meta挂钩,也可以是动态生成的(从TileEntity或者临近方块读取)。在默认情况下,MC在启动的时候会自动生成一个方块所有可能的BlockState,比如熔炉有4个朝向,每个朝向有着火和熄灭两种,于是一共有2x4=6种BlockState。每种可能的BlockState可以对应多种外观也可以只有一种,这些外观叫做Variant,每种Variant对应一种模型。如果有多个Variant那么MC会随机选择一种,比如原版的草,会看起来稍微不一样。
2. 物品
物品没有BlockState的概念但是还是有Variant的概念的
3. ISimpleBlockRenderingHandler永远远离我们而去了,但是TileEntitySpecialRenderer还在而且没有任何变化
ISimpleBlockRenderingHandler的代替品大概是IPerspectiveAwareModel,它允许我们根据方块状态返回渲染指令(BakedQuads,其实Quads是面的意思),这些可以由已加载的IBakedModel提供也可以是动态生成的。
4. 模型
有两种模型,用接口表示一种是IModel,另一种是IBakedModel(烧烤过的模型),MC从JSon文件或者代码加载IModel,在启动的时候烧烤(实在不知道怎么说了2333333)这些模型产生IBakedModel,IBakedModel储存的是经过优化的渲染指令(计算好的矩阵之类的),渲染的时候直接送给显示设备就好了。一般来讲是用JSON描述模型,比如采用的父模型(block/cube_all对应石头矿石一类6面贴图的玩意,item/generated对应普通物品比如铁定之类),详细的可以参考https://mcforge.readthedocs.io/en/latest/blockstates/forgeBlockstates/#sub-models ,http://greyminecraftcoder.blogspot.com.au/2014/12/block-models-texturing-quads-faces.html
JSON文件提供了不通过代码修改3D模型的可能,但是对有些特定场合不太适用。最近在做一个mod,里面可能有上百种物品和数十方块(都是矿物矿石之类的),每种物品或者方块都对应唯一一张贴图,如果每个都写JSON那是重复的巨大工作量...而且没人会想弄出台阶形状的矿石对吧2333 于是就有必要研究一种不通过手动写Json创建并加载模型的方法。最终实现的效果是不写任何json直接根据方块或者物品名字加载贴图。
代码已经写好,https://github.com/rikka0w0/Material_Warehouse @尤里的猫
本贴未完待续
哇竟然没人回复
我想知道2x4=6是什么鬼