Minecraft(我的世界)中文论坛

 找回密码
 注册(register)
查看: 1406|回复: 1

[Mod开发教程] 1.10.2以上的方块与物品渲染

[复制链接]
金坷居士 当前离线
帖子
主题
精华
贡献
最后登录
1970-1-1
爱心
积分
709
钻石
性别
保密
注册时间
2013-1-18
查看详细资料
发表于 2017-10-18 19:21:41 | 显示全部楼层 |阅读模式

您尚未登录,立即登录享受更好的浏览体验!

您需要 登录 才可以下载或查看,没有帐号?注册(register)

x
本帖最后由 金坷居士 于 2017-10-20 22:56 编辑

难度:中级\进阶

似乎还木有1.10.2级以上的渲染方面的教程,那窝就来弄一个辣~
本教程中介绍的方块和物品渲染技巧完全适用1.10.2和以上的版本,包括1.11.2,1.12.2等,内容部分适用1.8-1.8.9,不过作者并没有接触过1.8-1.8.9而且感觉那些版本很不成熟,于是选择无视,实体Entity由于本人吔木有研究过就不写辣。
1.7.10升级高版本需要特殊渲染技巧的也可以参考本教程w
另外说个题外话,各位modder应该考虑停止为1.7.10开发mod了,应该往前看,Mojang这版本刷的这么辛苦,我们是不是吔要来一起资磁一鉿啊?升级吧升级吧,升级就有大鸡rou腿bang吃哦~
作者比较咸鱼,难免有错误或者不严谨的地方,很难让这里几百个modder一致通过,指出错误窝会很鉿铍的~

1. 首先说下最好升级的TileEntitySpecialRender部分
TileEntitySpecialRender(TESR)是一种高级的方块渲染方式,能用GL一切的功能,当然开销也很大,在1.10.2之后推荐尽可能使用FastTESR代替,对性能可以极大的提高,教程之后会讲。
1.7.10里面可能会出现这种渲染代码
  1. Tessellator t = Tessellator.instance;

  2. ..................................................................................................

  3. GL11.glPushMatrix();
  4. bindTexture(xxx);
  5. t.startDrawingQuads();
  6. t.addVertexWithUV(-maxX / 2, 0, -maxZ / 2, 0, 1);
  7. t.addVertexWithUV(-maxX / 2, 0, maxZ / 2, 1, 1);
  8. t.addVertexWithUV(-maxX / 2, maxY, maxZ / 2, 1, 0);
  9. t.addVertexWithUV(-maxX / 2, maxY, -maxZ / 2, 0, 0);
  10. t.draw();
  11. GL11.glPopMatrix();
复制代码

在1.10.2之后Tessellator这个类biu的一下就变了,那么就需要这么写
  1. public static void startDrawingQuads() {
  2.         Tessellator.getInstance().getBuffer().begin(7, DefaultVertexFormats.POSITION_TEX);
  3.     }

  4.     public static void addVertexWithUV(double x, double y, double z, double u, double v) {
  5.         Tessellator.getInstance().getBuffer().pos(x, y, z).tex(u, v).endVertex();
  6.     }

  7.     public static void draw() {
  8.         Tessellator.getInstance().draw();
  9.     }

  10. ..................................................................................................

  11. GlStateManager.pushMatrix();
  12. bindTexture(xxx);
  13. startDrawingQuads();
  14. addVertexWithUV(-maxX / 2, 0, -maxZ / 2, 0, 1);
  15. addVertexWithUV(-maxX / 2, 0, maxZ / 2, 1, 1);
  16. addVertexWithUV(-maxX / 2, maxY, maxZ / 2, 1, 0);
  17. addVertexWithUV(-maxX / 2, maxY, -maxZ / 2, 0, 0);
  18. draw();
  19. GlStateManager.popMatrix();
复制代码
基本上能一一对应~

2. 方块的渲染
物品和方块是Minecraft的很重要的组成部分。首先来回顾一下物品和方块的定义。方块顾名思义就素在世界里面玩家看到的摆在地上的方块(Block类),比如石头什么的。物品(Item类)指的是一切能放到玩家物品栏里的东西,方块在物品栏中也是以物品的形式呈现的(ItemBlock类)。更准确的说,玩家手中、物品栏里、箱子容器里的是物品堆(ItemStack类,final的不可继承)。值得注意的是被丢掉地上之后方块并不是Item或者ItemStack,而是EntityItem,实体的一种,在本文中不讨论。

在1.8版本之后,MC引入了BlockState的概念,在代码中用IBlockState代表, 一个IBlockState可以包含若干IProperty,就是属性,每个属性有可以设置的值。IBlockState取代了之前的meta在代码中的绝大部分地位,这样最大的好处就是,原来毫无意义的meta数字被封装成了有意义的IProperty属性,提高了代码的可读性。


方块状态,其实是一种所谓的有限状态。每个IProperty都要求声明自己的有效值(参见IProperty#Collection<T> getAllowedValues()),并且有效值的个数是有限的,比如布尔类型的PropertyBool只能有True和False两种状态,PropertyEnum取决于被选用的枚举的数量,而PropertyInteger可以在创建的时候指定有效范围。方块状态的实现会在加载游戏的时候进行实例化,而且在游戏的时候不会变,withProperty返回的是另一个已经存在的实例而不是对当前方块状态的修改,还有就是可以用==判断方块状态是否相等。
meta其实没有消失,在储存的时候依然需要将IBlockState手动映射成meta,参考Block的BlockState getStateFromMeta(int meta)和int getMetaFromState(IBlockState state),这两个映射必须一致不然会鬼畜。IBlockState方块状态除了包装了meta之外还可以包含一些和meta无关的属性,比如栏杆有east,north,south,west四个布尔属性指示和周围方块的连接状态,这些属性不是meta映射来的,在渲染的时候,MC会调用Block的getActualState,在getActualState中modder可以设定这些与meta无关的属性的值。值得注意的是,IBlockAccess (World, WorldClient, WorldServer)的getBlockState以及各种Block函数里传进来的state都只包含和meta相关的属性值,也就是getStateFromMeta里面的,如果需要和meta无关的属性的值,需要手动调用getActualState。


MC的理念是,一种状态对应一种渲染姿势(这个不严谨,本教程会详细讲)。举个例子,熔炉有4个朝向,这就是4种方块状态,对应4种方块模型(IBakedModel)。

下面就开始高能了,首先来看MC渲染方块的流程!(有些地方精简了,为了方便理解,不过关键的类都保留了,看不清的话附件有pdf高清版)
r.png
从左上角开始看。当有方块变动之类的事件发生时,就需要重新根据方块的状态来更新渲染的缓存,这成为编译渲染区块。RendererChunk是一个16x16x16的区域,它把一个普通的区块Chunk分成16个,里面储存的“编译”好的区块渲染指令,游戏会把它送给OpenGL这样玩家就看到这些方块了。RendererChunk首先会遍历这个16x16x16区域内所有的方块位置(MutableBlockPos),用ChunkCache中获取缓存的方块状态IBlockState(只包含meta相关状态的)。然后这个IBlockState被传到BlockRendererDispatcher中(方块渲染分发器),在这里面Block的getActualState被调用,然后这个状态被用来在BlockModelShapes里获取到对应的IBakedModel(用来渲染的模型),之后BlockRendererDispatcher会调用Block的getExtendedState,这时state就包含所有可能需要的信息了。最后IBlockState和IBakedModel一起被传到BlockModelRenderer中进行渲染,在这期间IBakedModel的getQuads方**被多次调用来获取相应的BakedQuad(平面),BlockModelRenderer根据IBakedModel返回的平面来产生int[]然后送到VertexBuffer. 至此渲染区块
编译完成。之后由游戏来每帧渲染各种VertexBuffer就是玩家看到的方块世界。


少女施工中.....






Minecraft方块渲染精通到女装.zip

499.94 KB, 下载次数: 40

评分

参与人数 4人气 +7 金粒 +45 收起 理由
1582952890 + 3 + 25 MCBBS有你更精彩~
?祭酒 + 1 + 15 MCBBS有你更精彩~
ddyy163 + 1 + 5 看样子没有几百个modder啊
luojiarui + 2 先收藏,留着以后研究

查看全部评分

金坷居士 当前离线
帖子
主题
精华
贡献
最后登录
1970-1-1
爱心
积分
709
钻石
性别
保密
注册时间
2013-1-18
查看详细资料
 楼主| 发表于 2017-10-19 18:58:19 | 显示全部楼层
本帖最后由 金坷居士 于 2017-10-20 21:41 编辑

自占沙发的字数补丁
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册(register)

本版积分规则

Archiver|小黑屋|Mcbbs.net ( 京ICP备15023768号-1 ) | 京公网安备 11010502037624号 | 手机版

GMT+8, 2019-8-21 08:56 , Processed in 0.040043 second(s), Total 10, Slave 9 queries , Gzip On, MemCached On.

"Minecraft"以及"我的世界"为Mojang Synergies AB的商标 本站与Mojang以及微软公司没有从属关系

© 2010-2019 我的世界中文论坛 版权所有 本站原创图文内容版权属于原创作者,未经许可不得转载

快速回复 返回顶部 返回列表