bxz2311196368
参照mcjty的教程:这个崩溃日志:日志
全部代码:GitHub
目的在于动态渲染贴图,类似EIO电容库能在每个面显示能量收发状态的那种。
出错可能是模型构建出问题了,如果身上或者世界没这个方块就不会崩溃。一旦开始渲染物品就崩溃。
错误可能在这几处:
1、教程只使用了一个贴图,而我使用了两个:代码
  1. public static final ModelResourceLocation POWER_BLOCK_BAKED_MODEL = new ModelResourceLocation(
  2.                         Info.MODID + ":powerblock");

  3.         private TextureAtlasSprite sprite[] = new TextureAtlasSprite[2];
  4.         private VertexFormat format;

  5.         public PowerBlockBakedModel(IModelState state, VertexFormat format,
  6.                         Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter)
  7.         {
  8.                 this.format = format;
  9.                 sprite[0] = bakedTextureGetter.apply(new ResourceLocation(Info.MODID, "blocks/power_block_in"));
  10.                 sprite[1] = bakedTextureGetter.apply(new ResourceLocation(Info.MODID, "blocks/power_block_out"));
  11.         }
复制代码
代码
  1. @Override
  2.         public Collection<ResourceLocation> getTextures()
  3.         {
  4.                 return ImmutableSet.of(new ResourceLocation(Info.MODID, "blocks/power_block_in"),
  5.                                 new ResourceLocation(Info.MODID, "blocks/power_block_out"));
  6.         }
复制代码


2、模型的一个方法返回值是贴图而不是贴图数组,所以我只能返回一个贴图:代码
  1. @Override
  2.         public TextureAtlasSprite getParticleTexture()
  3.         {
  4.                 return sprite[0];
  5.         }
复制代码
具体,由于不知道这个自定义模型是怎么工作的,我也弄不清楚崩溃日志的含义,请大佬帮忙看看。
如果有人知道有关这方面的教程或者其他东西也请帮忙回复一下,谢谢。




金坷居士
就方块的模型代码来说,粗略看了看就发现一个问题
IBakedModel里面的List<BakedQuad> getQuads(IBlockState state, EnumFacing side, long rand)
里面参数的含义如下:
1. state代表方块的状态,如果有ExtendedBlockState那就可以cast成ExtendedBlockState然后读取,完全没问题。不过如果这个IBakedModel同时作为了物品的渲染,那么在渲染物品的时候state就素null,这时候对state的访问就会爆炸了。因此需要检查state是否为null。
2. side这个参数告诉getQuads的实现需要返回哪个面相关的quads,这些quads叫Side Quads。side也可以为null,当为null的时候getQuads需要返回General Quads。Side Quads和General Quads的区别就是,Side Quads是顶着1x1x1方块空间的那些面,比如矿石方块那6个面就素Side Quads。General Quads是在这1x1x1中间的面,比如栏杆那些。Side Quads的存在意义是face culling(面剔除),用来少渲染一些quads来提高性能(对窝萌这种烂脑笔记本玩家很重要QAQ),也就是说Side Quads可能不会被显示,而General Quads永远显示,因为Minecraft认为总能够看到这些不是完整方块的地方x
3. rand就素一个随机数之类的玩意,forget about it

以上适用与1.10.2之后的全部版本
希望能帮到乃/w\

bxz2311196368
金坷居士 发表于 2017-10-18 18:40
就方块的模型代码来说,粗略看了看就发现一个问题
IBakedModel里面的List getQuads(IBlockState state, Enu ...

哇,大佬就是6,经过修改,模型正常工作了,但是我发现我的UnlistedProperty有问题
这是代码UnlistedByteArrayProperty.java具体是字节数组貌似没法存入和取出,调用的时候是null。
还有,物品渲染怎么让这个BakedModel去实现(json里面是启用forge state的BlockStates json),现在在世界放置是正常的,但是物品形式直接崩溃。
崩溃日志:日志
还有一点是,方块渲染,顶部贴图很暗,而底部很亮:

这个是这里设置不对吗?代码(这一部分代码是从mcjty的教程扣过来的,不是很明白具体都是参与哪些工作的)
  1. private BakedQuad createQuad(Vec3d v1, Vec3d v2, Vec3d v3, Vec3d v4, int num)
  2.         {
  3.                 Vec3d normal = v1.subtract(v2).crossProduct(v3.subtract(v2));
  4.                 UnpackedBakedQuad.Builder builder = new UnpackedBakedQuad.Builder(format);
  5.                 builder.setTexture(sprite[num]);
  6.                 putVertex(builder, normal, v1.xCoord, v1.yCoord, v1.zCoord, 0, 0, num);
  7.                 putVertex(builder, normal, v2.xCoord, v2.yCoord, v2.zCoord, 0, 16, num);
  8.                 putVertex(builder, normal, v3.xCoord, v3.yCoord, v3.zCoord, 16, 16, num);
  9.                 putVertex(builder, normal, v4.xCoord, v4.yCoord, v4.zCoord, 16, 0, num);
  10.                 return builder.build();
  11.         }

  12.         private void putVertex(UnpackedBakedQuad.Builder builder, Vec3d normal, double x, double y, double z, float u,
  13.                         float v, int num)
  14.         {
  15.                 for (int e = 0; e < format.getElementCount(); e++)
  16.                 {
  17.                         switch (format.getElement(e).getUsage())
  18.                         {
  19.                         case POSITION:
  20.                                 builder.put(e, (float) x, (float) y, (float) z, 1.0f);
  21.                                 break;
  22.                         case COLOR:
  23.                                 builder.put(e, 1.0f, 1.0f, 1.0f, 1.0f);
  24.                                 break;
  25.                         case UV:
  26.                                 if (format.getElement(e).getIndex() == 0)
  27.                                 {
  28.                                         u = sprite[num].getInterpolatedU(u);
  29.                                         v = sprite[num].getInterpolatedV(v);
  30.                                         builder.put(e, u, v, 0f, 1f);
  31.                                         break;
  32.                                 }
  33.                         case NORMAL:
  34.                                 builder.put(e, (float) normal.xCoord, (float) normal.yCoord, (float) normal.zCoord, 0f);
  35.                                 break;
  36.                         default:
  37.                                 builder.put(e);
  38.                                 break;
  39.                         }
  40.                 }
  41.         }
复制代码
希望大佬能够解答,谢谢!

bxz2311196368
金坷居士 发表于 2017-10-18 18:40
就方块的模型代码来说,粗略看了看就发现一个问题
IBakedModel里面的List getQuads(IBlockState state, Enu ...

大佬大佬,经过你的指点,我的Property已经能正常保存了,但是BlockState在退出存档重新进入时就没了,导致崩溃。
方块物品的渲染我已经找到问题了,使用forge state就要覆写IBakedModel中
  1. @Override
  2. public ItemOverrideList getOverrides()
复制代码
这个方法,返回一个ItemOverrideList,而使用原版的加载方式就不用。我改回原版加载方式就正常了。
但是还有一个让我非常懵逼的问题,如下图,如果在方块任意一面放上不透光方块,那么对面就直接黑掉不显示了,Quad我测试了一下,对应方向应该没错


,这个方法应该就是控制每个面的显示方式的,具体是哪个控制这个光亮的渲染我就搞不懂了,希望能帮忙看看,谢谢!
这一部分的代码
  1. private void putVertex(UnpackedBakedQuad.Builder builder, Vec3d normal, double x, double y, double z, float u,
  2.                         float v, int num)
  3.         {
  4.                 for (int e = 0; e < format.getElementCount(); e++)
  5.                 {
  6.                         switch (format.getElement(e).getUsage())
  7.                         {
  8.                         case POSITION:
  9.                                 builder.put(e, (float) x, (float) y, (float) z, 1.0f);
  10.                                 break;
  11.                         case COLOR:
  12.                                 builder.put(e, 1.0f, 1.0f, 1.0f, 1.0f);
  13.                                 break;
  14.                         case UV:
  15.                                 if (format.getElement(e).getIndex() == 0)
  16.                                 {
  17.                                         u = sprite[num].getInterpolatedU(u);
  18.                                         v = sprite[num].getInterpolatedV(v);
  19.                                         builder.put(e, u, v, 0f, 1f);
  20.                                         break;
  21.                                 }
  22.                         case NORMAL:
  23.                                 builder.put(e, (float) normal.xCoord, (float) normal.yCoord, (float) normal.zCoord, 0f);
  24.                                 break;
  25.                         default:
  26.                                 builder.put(e);
  27.                                 break;
  28.                         }
  29.                 }
  30.         }
复制代码



金坷居士
在泥的https://github.com/bxz2311196368 ... cks/PowerBlock.java里面,s.withProperty(SIDE_CONFIG, te.getByte()).withProperty(FACING, state.getValue(FACING));这个其实返回的是新的IBlockState,而原来的IBlockState不会改变
改成这样就对了
  1. @Override
  2. public IBlockState getExtendedState(IBlockState state, IBlockAccess world, BlockPos pos)
  3. {
  4. IExtendedBlockState s = (IExtendedBlockState) state;
  5. PowerBlockTileEntity te = (PowerBlockTileEntity) world.getTileEntity(pos);
  6. return s.withProperty(SIDE_CONFIG, te.getByte()).withProperty(FACING, state.getValue(FACING));
  7. }
复制代码

bxz2311196368
金坷居士 发表于 2017-10-20 21:40
在泥的https://github.com/bxz2311196368 ... cks/PowerBlock.java里面,s.withProperty(SIDE_CONFIG, te.g ...

大佬这里已经改了,模型已经可以工作了,但是一旦退出存档再进,这个extend block state又GG了。

bxz2311196368
具体就是
  1. Caused by: java.lang.ArrayIndexOutOfBoundsException: 0
  2.         at com.bxzmod.energyconversion.blocks.blockmodel.PowerBlockBakedModel.func_188616_a(PowerBlockBakedModel.java:142) ~[PowerBlockBakedModel.class:?]
复制代码

代码
  1. byte[] a = extendedBlockState.getValue(PowerBlock.SIDE_CONFIG);
  2. quads.add(this.setQuad(side, a[side.getIndex()]));
复制代码

这里报错,没获取到正确的side type
是在世界加载的过程中,模型是先于TileEntity加载么?

金坷居士
bxz2311196368 发表于 2017-10-19 14:16
哇,大佬就是6,经过修改,模型正常工作了,但是我发现我的UnlistedProperty有问题
这是代码UnlistedByte ...

UnpackedBakedQuad.Builder这个窝不懂
不过窝知道DefaultVertexFormats.ITEM格式的BakedQuad的每个节点含义如下
一个BakedQuad包括4个点来定义一个面,每个定点有7个参数,分别是:
0,1,2: XYZ,Float的RawInt形式,代表定点在坐标系里的绝对坐标
3: 定点的颜色,一般素Color.WHITE.getRGB(),否则可能会染上颜色
4,5:UV,这个点在UV贴图上对应的位置
6: 压缩格式储存的法线,??XXYYZZ

什么是法线呢,法线是垂直于这个平面的一条直线,法线的方向就是面的朝向,mc靠这个用来进行面计算。
这四个顶点和UV的排布需要按一定顺序,不然会看不到
法线那个需要自己算一下,具体怎么算看
https://github.com/rikka0w0/libr ... akedQuadHelper.java
里的calculatePackedNormal()

完整的栗子https://github.com/rikka0w0/libr ... er/RawQuadCube.java
这个也素弄了好久弄出来的QAQ

最近准备发个mc方块渲染从入门到女装(手动划掉

金坷居士

有可能,因为getActualState和getExtendedState都可能从别的线程被call
所以在getExtendedState里需要检查state是否为IExtendedBlockState然后还有检查获取到的tileEntity不素null

3TUSK
如果只是显示能量的输入和输出面,用六个 PropertyEnum 分别对应每一个面就可以了... 没必要自己重新实现BakedModel。