Récupérer un IIcon d'un bloc pour l'afficher dans un GUI



  • Salut,

    Je bosse actuellement sur mes panneaux pour Road Stuff et j'ai un GUI pour configurer le panneau (choisir quelle forme et quel symbole afficher dessus). Pour le moment je mets tous les symboles sur l'image du GUI (qui fait 256*256 pour rappel) mais je me rend compte que je vais complètement manquer de place. Rien que ces panneaux prennent 1/4 de l'espace, et je suis très loin d'avoir fini.

    Du coup, plutôt que de faire plusieurs blocks et GUIs et de mettre les symboles dessus (en basse définition bien horrible qui plus est), je pensais à directement chopper les textures pour les dessiner sur le GUI.
    Je sais comment récupérer une texture à partir d'une face et d'un metadata avec une fonction getIcon(side, metadata) mais dans mon cas j'applique la texture sur le bloc de manière dynamique, en fonction d'une variable stockée dans le tile entity donc ça ne marche pas vraiment (ça va prendre la dernière texture affichée). Il y a une autre fonction getIcon qui prend plein de paramètres mais ce sont des noms du style "p_149673_1_" et je ne sais pas ce qui correspond.

    Du coup est-il possible de récupérer une variable IIcon d'un block? Ou dois-je ré-enregister les textures dans la classe du GUI? Le but derrière étant de les dessiner sur le GUI.

    Le code source est dispo sur le github du mod: https://github.com/KillerMapper/roadstuff (checkez ce commit pour voir rapidement les fichiers concernés).

    Merci!


  • Administrateurs

    Salut,
    Regardes le code de la classe GuiContainer, il y a forcement le code qui permet de rendre les blocs et item dans un gui.

    La deuxième fonction getIcon avec plus de paramètres c'est getIcon(world, x, y, z, side) si mes souvenir sont bon.



  • J'ai regardé mais je n'ai pas trouvé grand chose. À chaque fois ça part dans des fonctions qui partent dans d'autres fonctions, à la fin ça fini par utiliser des fonctions de dessin et c'est clairement pas de mon niveau 😛

    Au final j'ai testé en faisant plusieurs images et ça marche, en gros il y aura un fichier pour chaque forme de panneau et je stock dedans les symboles, ça sera un peu plus lourd mais bon c'est pas trop grave à ce niveau-là (on parle de quelques ko). Je vais en profiter pour faire un GUI un peu plus classe du coup!



  • Dans ton drawScreen() met ça:

    
    RenderHelper.enableGUIStandardItemLighting();
    GL11.glDisable(GL11.GL_LIGHTING);
    GL11.glEnable(GL12.GL_RESCALE_NORMAL);
    GL11.glEnable(GL11.GL_COLOR_MATERIAL);
    GL11.glEnable(GL11.GL_LIGHTING);
    
    // Afficher la texture des blocks / items comme ils le sont affiché dans l'inventaire
    itemRender.renderItemAndEffectIntoGUI(fontRendererObj, Minecraft.getMinecraft().getTextureManager(), new ItemStack(), posX, posY);
    // Affiche le chiffre indiquant le nombre de blocks (pas utile dans ton cas, tu veux juste la texture du block)
    itemRender.renderItemOverlayIntoGUI(fontRendererObj, Minecraft.getMinecraft().getTextureManager(), new ItemStack(), posX, posY);
    
    GL11.glDisable(GL11.GL_LIGHTING);
    GL11.glDepthMask(true);
    GL11.glEnable(GL11.GL_DEPTH_TEST);
    
    

    J'ai pris ça dans le code du gui achievement il me semble.
    Tu dois bien mettre le RenderHelp et tout les GL11 avant et après comme au dessus, sinon ton rendu sera sombre et buggé, tu verras par toi même au pire ^^

    Voilà



  • Dans un sujet ressent, j'ai réussi à afficher un item dans un gui, avec une taille diffirante que celle de base ( c'est en 1.8.9 mais je pence que c'est pareil en 1.7) :  https://www.minecraftforgefrance.fr/showthread.php?tid=3234&page=5



  • En fait mon GUI se présente sous cette forme:

    Du coup afficher le bloc comme dans un inventaire classique ne le fera pas, surtout que je change la texture d'une face spécifique en fonction d'une variable. Je voulais juste récupérer une IIcon d'une classe (la texture en gros), et l'afficher ici.
    En soit je pourrais charger toutes les textures directement dans la classe du GUI, mais bon autant charger une image de 256*256 au lieu de charger des dizaines de fichiers.



  • Dans ton drawScreen met ça:

    // Le chemin exacte de la texture que tu veux rendre
    mc.renderEngine.bindTexture(new ResourceLocation("mod_id", "textures/blocks/tonpanneau.png"));
    
    func_152125_a(posX, posY, minX, minY, maxX, maxY, textureWidth, textureHeigth, textureWidth, textureHeigth);
    

    Je ne sais plus vraiment comment on l'utilise, mais normalement c'est ça, au pire fait quelques tests:

    minX : c'est à partir de ce point de ton image que tu vas commencer le rendu
    minY : pareille pour Y
    maxX : le rendu sera fait jusqu'à ce point
    maxY : pareille pour Y
    textureWidth et textureHeight : c'est la taille entière de ta texture normalement.
    Si tu ne comprends pas trop fait des testes, tu verras tout de suite ce qui change.

    En 1.8 c'est ça :

       /**
         * Draws a scaled, textured, tiled modal rect at z = 0\. This method isn't used anywhere in vanilla code.
         */
        public static void drawScaledCustomSizeModalRect(int x, int y, float u, float v, int uWidth, int vHeight, int width, int height, float tileWidth, float tileHeight)
        {
            float f = 1.0F / tileWidth;
            float f1 = 1.0F / tileHeight;
            Tessellator tessellator = Tessellator.getInstance();
            WorldRenderer worldrenderer = tessellator.getWorldRenderer();
            worldrenderer.begin(7, DefaultVertexFormats.POSITION_TEX);
            worldrenderer.pos((double)x, (double)(y + height), 0.0D).tex((double)(u * f), (double)((v + (float)vHeight) * f1)).endVertex();
            worldrenderer.pos((double)(x + width), (double)(y + height), 0.0D).tex((double)((u + (float)uWidth) * f), (double)((v + (float)vHeight) * f1)).endVertex();
            worldrenderer.pos((double)(x + width), (double)y, 0.0D).tex((double)((u + (float)uWidth) * f), (double)(v * f1)).endVertex();
            worldrenderer.pos((double)x, (double)y, 0.0D).tex((double)(u * f), (double)(v * f1)).endVertex();
            tessellator.draw();
        }
    


  • Nice, ça marche nickel! Pas testé en 1.8, mais je garde ça de côté quand je passera dessus (enfin en 1.9.4, je verrai si ça marche aussi).

    En soit si je mets 1 pour maxX et maxY, et 1 dans les 2 dernières variables, ça marche aussi bien que mettre 0 en minX/Y et 32 en maxX/Y et 32 aux 2 dernières (prise de tête, je sais!). Pour les 2 avant-derniers paramètres, c'est pour scaler l'image à l'écran, donc en mettant 100 ça fait un scale de 1 (100% de la taille). Toujours galère à comprendre ces fonctions sans noms!

    Je vais pouvoir simplifier mon code grâce à ça, plus besoin que je calcule les lignes et les colones sur une grande image… Merci!