• S'inscrire
    • Se connecter
    • Recherche
    • Récent
    • Mots-clés
    • Populaire
    • Utilisateurs
    • Groupes

    Résolu Minerais Custom, problème d'affichage

    1.8.x
    1.8
    3
    15
    3012
    Charger plus de messages
    • Du plus ancien au plus récent
    • Du plus récent au plus ancien
    • Les plus votés
    Répondre
    • Répondre à l'aide d'un nouveau sujet
    Se connecter pour répondre
    Ce sujet a été supprimé. Seuls les utilisateurs avec les droits d'administration peuvent le voir.
    • Spooky
      Spooky dernière édition par

      SOLUTION :

      Ajouter ça à la classe du minerai :

      @Override
      public EnumWorldBlockLayer getBlockLayer() {
      return EnumWorldBlockLayer.CUTOUT_MIPPED;
      }
      

      Enregistrer les textures comme ça :

      @SubscribeEvent
      public void registerOverlays(TextureStitchEvent.Pre e) {
      overlaysLocations.forEach(new BiConsumer<string, resourcelocation="">() {
      @Override
      public void accept(String srt, ResourceLocation location) {
      e.map.registerSprite(location);
      }
      });
      }
      

      #############################################################
      #############################################################

      Salut !

      J’ai implémenté un IModel pour pouvoir afficher des minerais custom qui ont différent background de pierre (géré par le metadata du bloc) avec un overlay du minerai (vanilla ou pas) (1 par instance du bloc).
      Le problème c’est que malgré tout les tutos que je me suis farcis, je comprend toujours pas tout.

      edit : petite précision :
      Il y a 24 types de pierre, coupé en 3*8 pour ne pas dépassé les 16 metadatas.
      Le nombre total d"instances (créée dynamiquement) du minerai custom est égal à 3 fois le nombre de minerais enregistrés (vanilla + mods)

      Le model ressemble à ça :

      public class OreBlockModel implements IModel {
      
      …
      
              public IFlexibleBakedModel bake(IModelState state, VertexFormat format, Function <resourcelocation, textureatlassprite="">bakedTextureGetter) {
      
      ModelResourceLocation stoneModelLocation = new ModelResourceLocation("minecraft:stone", null);
      IModel stoneModel = ModelLoaderRegistry.getModel(stoneModelLocation);
      IBakedModel stoneBakedModel = stoneModel.bake(stoneModel.getDefaultState(), format, bakedTextureGetter);
      Logger.info(stoneBakedModel.getTexture().getIconName()); // -> missing_texture
      
      IFlexibleBakedModel model = new IFlexibleBakedModel() {
      
      @Override
      public boolean isAmbientOcclusion() {
      return true;
      }
      
      @Override
      public boolean isGui3d() {
      return true;
      }
      
      @Override
      public boolean isBuiltInRenderer() {
      return false;
      }
      
      @Override
      public TextureAtlasSprite getTexture() {
      return bakedTextureGetter.apply(stoneModelLocation);
      }
      
      @Override
      public ItemCameraTransforms getItemCameraTransforms() {
      return ItemCameraTransforms.DEFAULT;
      }
      
      @Override
      public List <bakedquad>getFaceQuads(EnumFacing side) {
      return stoneBakedModel.getFaceQuads(side);
      }
      
      @Override
      public List <bakedquad>getGeneralQuads() {
      return stoneBakedModel.getGeneralQuads();
      }
      
      @Override
      public VertexFormat getFormat() {
      return format;
      }
      
      };
      
      return model;
      }
      }
      

      Avec un bloc vanilla ou pas, ça ne change rien, j’ai pas de texture (ou plutôt un jolie damier violet-noir), pourtant le model fonctionne et cette méthode bake() est appelé pour mes minerais, je le vois en jeu si je change isGui3D() par exemple.
      Je pense que le problème vient du bakedTextureGetter qui ne me renvois rien du tout pour une raison inconnue.

      Voici le reste du code, ce qui pourrai être lié du moins :

      public class OreModelLoader implements ICustomModelLoader {
      
         ...
      
      private IResourceManager resourceManager;
      
      @Override
      public void onResourceManagerReload(IResourceManager resourceManager) {
      this.resourceManager = resourceManager;
      }
      
      @Override
      public boolean accepts(ResourceLocation modelLocation) {
      return modelLocation.getResourceDomain().equals(MODID) && modelLocation.getResourcePath().contains(MODEL_NAME);
      }
      
      @Override
      public IModel loadModel(ResourceLocation modelLocation) {
      String modelName = modelLocation.getResourcePath();
      if (modelName.contains(MODEL_NAME)) {
      return new OreBlockModel(resourceManager, modelLocation);
      }
      throw new RuntimeException("A builtin model '" + modelName + "' is not defined.");
      }
      }
      

      Je ne veux pas utiliser ISmartBlockModel, parce qu’il me semble que le model est recalculé à chaque appel de rendu (en fonction du BlockState), c’est un peu overkill pour des minerais qui ne change pas d’état 😉
      Du coup j’ai quand même besoin de savoir la variante de pierre (metadata) et le minerais, pour choisir les bonnes textures, alors je passe ça dans la chaine du nom de model et je le récupère dans chaque instance d’IModel :

      public class UBOre extends Block {
      
      ...
      
      // le modelname est de la forme "modid:model_name_prefix.variant_de_pierre.oremodid:ore_name"
      // model_name_prefix est commun, c'est pour le "accept" dans OreModelLoader
      // oremodid et ore_name c'est pour trouver le bon overlay
      Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(Item.getItemFromBlock(this), i, new ModelResourceLocation(getModelName(i), "inventory"));
      
      ...
      
      }
      

      J’ai ça aussi dans mon client preinit :

      public void preInit(FMLPreInitializationEvent e) {
      super.preInit(e);
      
      StateMapperBase oresModelMapper = new StateMapperBase() {
      @Override
      protected ModelResourceLocation getModelResourceLocation(IBlockState state) {
                                     // Je suis pas sur ce que je doit mettre comme argument ici
                                     // j'hésite entre comme au dessus :
                                     // "modid:model_name_prefix.variant_de_pierre.oremodid:ore_name"
                                     // ou juste "modid:model_name_prefix"
      return new ModelResourceLocation(OreModelLoader.ORE_MODEL);
      }
      };
                     // CUSTOM_ORES = Les instances des blocs
      CUSTOM_ORES.forEach(new Consumer<customore>() {
      @Override
      public void accept(CustomOre ore) {
      ModelLoader.setCustomStateMapper(ore, oresModelMapper);
      }
      });
      ModelLoaderRegistry.registerLoader(new OreModelLoader());
      }
      

      Les topics/tutos qui m’ont aidé, au cas ou j’aurais loupé un truc :

      http://www.minecraftforge.net/forum/index.php?topic=29420.0
      http://www.minecraftforge.net/forum/index.php/topic,28714.0.html
      http://greyminecraftcoder.blogspot.com.au/2015/03/troubleshooting-block-and-item-rendering.html</customore></bakedquad></bakedquad></resourcelocation,></string,>

      1 réponse Dernière réponse Répondre Citer 0
      • Superloup10
        Superloup10 Modérateurs dernière édition par

        Pourquoi utiliser un IModel ? Ce serait plus simple de faire un block extends BlockOre.

        Envoyé de mon Nexus 4 en utilisant Tapatalk

        Si vous souhaitez me faire un don, il vous suffit de cliquer sur le bouton situé en dessous.

        Je suis un membre apprécié et joueur, j'ai déjà obtenu 17 points de réputation.

        1 réponse Dernière réponse Répondre Citer 0
        • Spooky
          Spooky dernière édition par

          Euh non, j’ai besoin de ce système parce que je créer des minerais dynamiquement

          1 réponse Dernière réponse Répondre Citer 0
          • Superloup10
            Superloup10 Modérateurs dernière édition par

            J’ai édité, j’ai fais un miss clic. Le tutoriel que je pensais n’a pas encore été rédiger.

            Envoyé de mon Nexus 4 en utilisant Tapatalk

            Si vous souhaitez me faire un don, il vous suffit de cliquer sur le bouton situé en dessous.

            Je suis un membre apprécié et joueur, j'ai déjà obtenu 17 points de réputation.

            1 réponse Dernière réponse Répondre Citer 0
            • robin4002
              robin4002 Moddeurs confirmés Rédacteurs Administrateurs dernière édition par

              Utilise plutôt Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(“minecraft:blocks/stone”); pour avoir la texture de la stone.

              1 réponse Dernière réponse Répondre Citer 0
              • Spooky
                Spooky dernière édition par

                Alors :
                Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(“modid:blocks/custom”);
                retourne correctement la TextureAtlasSprite donc ça ne vient pas des textures

                C’est vraiment bizarre, parce que les blocs utilise forcément le model retourné par bake() puisque quand je modifie isgui3d() ou isbuiltinrenderer(), je perçois le changement en jeu___Bon ça avance gentiment mais on est pas sortie de l’auberge ^^
                Mes minerais ont leur background de pierre qui s’affiche correctement - dans l’inventaire seulement mais c’est surement du à autre chose je m’en fous pour l’instant.

                public IFlexibleBakedModel bake(IModelState state, VertexFormat format, Function <resourcelocation, textureatlassprite="">bakedTextureGetter) {
                    TextureMap textureMap = Minecraft.getMinecraft().getTextureMapBlocks();
                    HashMap <resourcelocation, textureatlassprite="">txMap = new HashMap<>();
                    Function <resourcelocation, textureatlassprite="">textureGetter;
                    /*
                     * Base stone and ore models
                     */
                    ModelResourceLocation stoneModelLocation = new ModelResourceLocation(MODID + ":" + stoneVariant);
                    IModel stoneModel = ModelLoaderRegistry.getModel(stoneModelLocation);
                    ModelResourceLocation oreModelLocation = new ModelResourceLocation(oreResourcesDomain + ":" + oreType);
                    IModel oreModel = ModelLoaderRegistry.getModel(oreModelLocation);
                    /*
                     * Create the textures map
                     */
                    txMap.put(stoneModelLocation, textureMap.getAtlasSprite(MODID + ":blocks/" + stoneVariant));
                    txMap.put(oreModelLocation, textureMap.getAtlasSprite(oreResourcesDomain + ":blocks/" + providedOverlays[2]));
                    textureGetter = Functions.forMap(txMap);
                    /*
                     * Build the stone background
                     */
                    IBakedModel stoneBakedModel = stoneModel.bake(stoneModel.getDefaultState(), format, textureGetter);
                    Builder b = new Builder(stoneBakedModel, textureGetter.apply(stoneModelLocation));
                    /*
                     * Add the ore overlay
                     */
                    IBakedModel oreBakedModel = oreModel.bake(oreModel.getDefaultState(), format, textureGetter);
                    b.setTexture(textureGetter.apply(oreModelLocation));
                    @SuppressWarnings("unchecked")
                    List <bakedquad>oreBakedQuads = oreBakedModel.getGeneralQuads();
                    for (BakedQuad bq : oreBakedQuads) {
                        b.addGeneralQuad(bq);
                    }
                
                    return new IFlexibleBakedModel.Wrapper(b.makeBakedModel(), format);
                }
                

                Le nouveau problème, c’est que les overlays ne sont pas “enregistrés” dans minecraft, donc je dois trouver un moyen de le faire pour que le textureGetter me renvoie la bonne textures___Bump ! Quelqu’un à une idée pour enregistrer les textures d’overlays ?</bakedquad></resourcelocation,></resourcelocation,></resourcelocation,>

                1 réponse Dernière réponse Répondre Citer 0
                • robin4002
                  robin4002 Moddeurs confirmés Rédacteurs Administrateurs dernière édition par

                  Je fusionne tous tes messages, il faut éviter les boucles posts.

                  Il me semble qu’il faut passer par l’event TextureSwitchEvent

                  1 réponse Dernière réponse Répondre Citer 0
                  • Spooky
                    Spooky dernière édition par

                    Ok merci !
                    Pour enregistrer une méthode pour un event c’est avec l’annotation EventRegister ou un truc comme ça ?

                    1 réponse Dernière réponse Répondre Citer 0
                    • robin4002
                      robin4002 Moddeurs confirmés Rédacteurs Administrateurs dernière édition par

                      http://www.minecraftforgefrance.fr/showthread.php?tid=716

                      1 réponse Dernière réponse Répondre Citer 0
                      • Spooky
                        Spooky dernière édition par

                        C’est bizarre, j’ai l’impression que les textures ne se charge toujours pas.
                        Qu’est-ce que je fait de mal ?

                        @SideOnly(Side.CLIENT)
                        public final class TexturesRegistrationHandler {
                        
                        @SubscribeEvent
                        public void registerOverlays(TextureStitchEvent.Pre e) {
                        oresTexturizer.overlaysLocations.forEach(new BiConsumer<string, resourcelocation="">() {
                        @Override
                        public void accept(String srt, ResourceLocation location) {
                        e.map.registerSprite(location);
                        }
                        });
                        }
                        
                        }
                        
                        

                        overlaysLocation est remplis comme ça :

                        overlaysLocations.put("oreCoal_overlay", new ResourceLocation(MODID + ":blocks/" + "coal_overlay"));
                        

                        et récupéré comme ça :

                        TextureMap textureMap = Minecraft.getMinecraft().getTextureMapBlocks();
                        HashMap <resourcelocation, textureatlassprite="">txMap = new HashMap<>();
                        Function <resourcelocation, textureatlassprite="">textureGetter;
                        /*
                        * Base stone and ore models
                        */
                        ModelResourceLocation stoneModelLocation = new ModelResourceLocation(MODID + ":" + stoneVariant);
                        IModel stoneModel = ModelLoaderRegistry.getModel(stoneModelLocation);
                        ModelResourceLocation oreModelLocation = new ModelResourceLocation(oreResourcesDomain + ":" + oreType);
                        IModel oreModel = ModelLoaderRegistry.getModel(oreModelLocation);
                        /*
                        * Create the map with the useful textures
                        */
                        TextureAtlasSprite stoneTexture = textureMap.getAtlasSprite(MODID + ":blocks/" + stoneVariant);
                        TextureAtlasSprite oreTexture = textureMap.getAtlasSprite(MODID + ":blocks/" + oreType + "_overlay");
                        txMap.put(stoneModelLocation, stoneTexture);
                        txMap.put(oreModelLocation, oreTexture);
                        textureGetter = Functions.forMap(txMap);
                        

                        Et cette ligne :

                        MinecraftForge.EVENT_BUS.register(new TexturesRegistrationHandler());
                        

                        Faut la mettre dans le preInit ou le Init ?</resourcelocation,></resourcelocation,></string,>

                        1 réponse Dernière réponse Répondre Citer 0
                        • robin4002
                          robin4002 Moddeurs confirmés Rédacteurs Administrateurs dernière édition par

                          Il faut utiliser e.map.setTextureEntry(“nom interne au jeu”, new UneClasseExtendsTextureAtlasSprite(“modid:chemin de la texture à partir du dossier textures”);
                          Pour le nom interne au jeu je mets toujours le même nom que l’emplacement de la texture (modid:chemin de la texture à partir du dossier textures) pour ne pas compliquer les choses.
                          Tu ne peux pas utiliser directement TextureAtlasSprite car le constructeur est protected, donc il faut faire une classe fille.

                          1 réponse Dernière réponse Répondre Citer 0
                          • Spooky
                            Spooky dernière édition par

                            Comment je get mon overlay ? avec ça :

                            Function <resourcelocation, textureatlassprite="">bakedTextureGetter
                            

                            ou comme ça :

                            TextureMap textureMap = Minecraft.getMinecraft().getTextureMapBlocks();
                            HashMap <resourcelocation, textureatlassprite="">txMap = new HashMap<>();
                            Function <resourcelocation, textureatlassprite="">textureGetter;
                            
                            ModelResourceLocation oreModelLocation = new ModelResourceLocation(oreResourcesDomain + ":" + oreType);
                            IModel oreModel = ModelLoaderRegistry.getModel(oreModelLocation);
                            
                            TextureAtlasSprite oreTexture = textureMap.getAtlasSprite(MODID + ":blocks/" + overlayName);
                            txMap.put(oreModelLocation, oreTexture);
                            textureGetter = Functions.forMap(txMap);
                            

                            EDIT : la première méthode ne fonctionne pas, la deuxième oui. J’ai enfin la texture de l’overlay, par contre elle s’applique pas sur le model, parce-que faut pas pousser non plus ^^ Et seulement l’item, pas le bloc dans le monde, lui il est violet et noir.
                            Si quelqu’un vois un problème dans ce qui suit, le début marche, c’est la fin où ça se gâte, l’overlay n’a pas l’air d’être ajouté :

                            public IFlexibleBakedModel bake(IModelState state, VertexFormat format, Function <resourcelocation, textureatlassprite="">bakedTextureGetter) {
                            
                               TextureMap textureMap = Minecraft.getMinecraft().getTextureMapBlocks();
                               HashMap <resourcelocation, textureatlassprite="">txMap = new HashMap<>();
                               Function <resourcelocation, textureatlassprite="">textureGetter;
                               /*
                                * Base stone and ore models
                                */
                               ModelResourceLocation stoneModelLocation = new ModelResourceLocation(MODID + ":" + stoneVariant);
                               IModel stoneModel = ModelLoaderRegistry.getModel(stoneModelLocation);
                               ModelResourceLocation oreModelLocation = new ModelResourceLocation(oreResourcesDomain + ":" + oreType);
                               IModel oreModel = ModelLoaderRegistry.getModel(oreModelLocation);
                               /*
                                * Create the map with the useful textures
                                */
                               TextureAtlasSprite stoneTexture = textureMap.getAtlasSprite(MODID + ":blocks/" + stoneVariant);
                               TextureAtlasSprite oreTexture = textureMap.getAtlasSprite(MODID + ":blocks/" + overlayName);
                               //
                               txMap.put(stoneModelLocation, stoneTexture);
                               txMap.put(oreModelLocation, oreTexture);
                               textureGetter = Functions.forMap(txMap);
                               /*
                                * Build the stone "background"
                                */
                               IBakedModel stoneBakedModel = stoneModel.bake(stoneModel.getDefaultState(), format, textureGetter);
                               Builder b = new Builder(stoneBakedModel, textureGetter.apply(stoneModelLocation));
                               /*
                                * Add the ore overlay
                                */
                               IBakedModel oreBakedModel = oreModel.bake(oreModel.getDefaultState(), format, textureGetter);
                               b.setTexture(textureGetter.apply(oreModelLocation));
                               //
                               List <bakedquad>oreBakedQuads = oreBakedModel.getGeneralQuads();
                               for (BakedQuad bq : oreBakedQuads) {
                               b.addGeneralQuad(bq);
                               }
                            
                               return new IFlexibleBakedModel.Wrapper(b.makeBakedModel(), format);
                            }
                            ```</bakedquad></resourcelocation,></resourcelocation,></resourcelocation,></resourcelocation,></resourcelocation,></resourcelocation,>
                            1 réponse Dernière réponse Répondre Citer 0
                            • Spooky
                              Spooky dernière édition par

                              Le problème c’est que oreBakedModel.getGeneralQuads(); retourne que dalle, pourtant, oreModel pointe vers un model de minerai de minecraft vailde !
                              Quelqu’un peut il m’expliquer exactement ce qu’est un BakedQuad, parce-que c’est un peu abstrait pour moi …

                              1 réponse Dernière réponse Répondre Citer 0
                              • robin4002
                                robin4002 Moddeurs confirmés Rédacteurs Administrateurs dernière édition par

                                Honnêtement je ne peux pas t’aider x)
                                Je n’ai jamais utilisé ces méthodes, la seule chose que j’ai utilisé c’est le ISmartBlockModel et je ne comprends pas grand chose non plus au système de rendu de la 1.8 😕

                                1 réponse Dernière réponse Répondre Citer 0
                                • Spooky
                                  Spooky dernière édition par

                                  J’ai posté sur le forum anglais, on m’a envoyé sur ça :

                                  https://github.com/TheGreyGhost/MinecraftByExample/blob/master/src/main/java/minecraftbyexample/mbe15_item_smartitemmodel/ChessboardSmartItemModel.java

                                  Le problème c’est que dans son tuto c’est pour un plateau d’échec, c’est un peu hardcore pour un exemple je trouve.
                                  Je pense avoir compris à peu près en gros un BakedQuad c’est une texture + des coordonnées (relative au bloc), et un bloc de base est composé de 6 BakedQuad. J’ai ajouté 6 autres BakedQuad à mon model (les overlays) en suivant le tuto. Ils sont décalé de 0.001 vers l’extérieur par rapport au autres pour évité les “glitches”.

                                  Mais ce qui m’embete vraiment c’est que j’arrive a ajouté un texture de terre par dessus mes blocs, mais pas un overlay, il doit avoir un problème avec la transparence.

                                  1 réponse Dernière réponse Répondre Citer 0
                                  • 1 / 1
                                  • Premier message
                                    Dernier message
                                  Design by Woryk
                                  Contact / Mentions Légales

                                  MINECRAFT FORGE FRANCE © 2018

                                  Powered by NodeBB