Draw ne fonctionne pas avec BackgroundDrawnEvent



  • Yop,

    J'ai fait en sorte de dessiner des têtes de joueurs à coté d'un serveur mais ceux-ci se dessinent au dessus des textures se trouvant en bas et en haut :

    Pour contrer cela, il fallait trouver un moyen de dessiner les têtes avant ces textures. Et c'est ainsi que je découvris le BackgroundDrawnEvent, puisque contrairement à DrawScreenEvent.Post, il va se déclencher une fois que le fond va être dessiné, mais pas les textures du haut et du bas.
    Sauf qu'en utilisant cet event, mes têtes ne sont plus dessinés et je ne sais pas pourquoi  😕 .
    Voici le code utilisé pour les dessiner :

    @SubscribeEvent
    public void drawHeadNextEpicubeServer(BackgroundDrawnEvent e){
    if(e.getGui() instanceof GuiMultiplayer){
        GuiMultiplayer gm = (GuiMultiplayer) e.getGui();
        ServerSelectionList ssl = ObfuscationReflectionHelper.getPrivateValue(GuiMultiplayer.class, gm, 3);
        int slotServer = MugiwaraMod.utils.getSlotServer(gm);
        int yScreen = e.getGui().height;
        int xScreen = e.getGui().width;
        int mouseX = Mouse.getX();
        int mouseY = Mouse.getY();
        if((xScreen == 640 && yScreen == 334) || Minecraft.getMinecraft().isFullScreen()){
            if(!frame.isEmpty() && slotServer > -1){
                for(FrameMember memberFrame : frame){
                    memberFrame.setY(memberFrame.getOriginalY() + (slotServer * 36) + ssl.getAmountScrolled()*-1);
                        Minecraft.getMinecraft().renderEngine.bindTexture(memberFrame.getTheMember().getHeadTextureLocation());
                        e.getGui().drawTexturedModalRect(memberFrame.getX(), memberFrame.getY(), 0, 0, 16, 16);
                }
            }
        }
        x = 0;
        y = 0;
    
        int slotText = slotServer * 36;
        if(!frame.isEmpty()){
            for(FrameMember memberFrame : frame){
                if(memberFrame.isMouseOver16px(e.getMouseX(), e.getMouseY())){
                    String name = memberFrame.getTheMember().getUsername();
                    e.getGui().drawCenteredString(Minecraft.getMinecraft().fontRendererObj, name, memberFrame.getX()+10,                                                                  memberFrame.getY()-10, 
                                                  MugiwaraMod.memUtils.getColorByGrade(memberFrame.getTheMember().getGroup()));
                }
            }
        }
    }
    }
    

    Merci d'avance pour votre aide  ;).


  • Administrateurs

    Salut,
    Je n'ai pas vraiment compris cette phrase x)
    @'Alexandre1156':

    mais ceux-ci se dessinent au dessus des textures se trouvant en bas et en haut :

    Et je ne comprends pas où est le problème avec le screenshot.



  • @'robin4002':

    Salut,
    Je n'ai pas vraiment compris cette phrase x)
    @'Alexandre1156':

    mais ceux-ci se dessinent au dessus des textures se trouvant en bas et en haut :

    Et je ne comprends pas où est le problème avec le screenshot.

    Les "textures se trouvant en haut et en bas" sont celles-ci :

    Le problème est que les têtes à droite du serveur Epicube se superposent à ces textures alors que je veux qu'elles aillent en "dessous", comme les serveurs :

    Donc pour palier ce problème, j'utilise l'event BackgroundDrawnEvent car il est déclenché après avoir dessiner le background mais avant les textures du haut et du bas.
    Mais je ne sais pour qu'elle raison, les têtes ne sont plus dessinés :

    Voilà, j’espère avoir était plus clair !



  • Ah oui d'accord, bah sinon tu peux peut être essayer d'obtenir la position du serveur et ne pas dessiner les têtes si il est trop bah/haut.


  • Administrateurs

    En effet il faudrait tout simplement ne pas le draw si le serveur n'est pas visiblement en se basant sur la position du curseur.

    Autre potentiel solution : mettre le zLevel plus bas avant de draw, mais ça ne fonctionnera que si la partie du bas à un zLevel plus élevé que celle du milieu et je ne crois pas que c'est le cas.



  • @'AymericRed':

    Ah oui d'accord, bah sinon tu peux peut être essayer d'obtenir la position du serveur et ne pas dessiner les têtes si il est trop bah/haut.

    Pourquoi pas, même si la transition apparition/disparition des têtes risque d'être un peu "brutal".

    @'robin4002':

    Autre potentiel solution : mettre le zLevel plus bas avant de draw, mais ça ne fonctionnera que si la partie du bas à un zLevel plus élevé que celle du milieu et je ne crois pas que c'est le cas.

    Et comment fait on cela ?

    Une autre solution, plus radicale, que j'ai eu est de carrément faire un copier/coller du GuiMutliplayer et de rajouter l'affichage de mes têtes. Je vais tester ça tiens.


  • Administrateurs

    Il faut changer la valeur de la variable zLevel du gui avant de faire le rendu.



  • "Une autre solution, plus radicale, que j'ai eu est de carrément faire un copier/coller du GuiMutliplayer et de rajouter l'affichage de mes têtes. Je vais tester ça tiens."
    C'est une bonne idée aussi.


  • Modérateurs

    Si tu t'y connais avec OpenGL, tu peux aussi utiliser le Scissor Test pour ne dessiner que dans le cadre voulu.



  • Eh bien finalement la méthode bourrin fonctionne :

    Pour comprendre comment j'ai réussi, il faut ce dire une chose : *this.drawDefaultBackground(); *n'est pas la méthode qui dessine le fond (vous pouvez la supprimer, vous ne verrez aucun changement) mais *this.serverListSelector.drawScreen(mouseX, mouseY, partialTicks); *et cette même méthode dessine les textures du bas et du haut. Donc j'ai dû faire un copier/coller de cette méthode et y incruster mes lignes de codes permettant de dessiner mes têtes.
    Et donc voici à quoi ressemble finalement ma class :


    Quand je vous avez dis que c'était bourrin !

    Par contre, la barre de défilement ce dessine après, mais je pense qu'il suffit juste de changer de place les lignes de codes qui la dessine.</framemember></framemember>



  • Par contre fait attention, quand tu vas compiler ton mod les field.getDeclaredField vont pas trouver les fields vu qu'il faut leur nom obfusqué (tu peux heureusement lui proposer plusieurs noms à tester).



  • @'AymericRed':

    Par contre fait attention, quand tu vas compiler ton mod les field.getDeclaredField vont pas trouver les fields vu qu'il faut leur nom obfusqué (tu peux heureusement lui proposer plusieurs noms à tester).

    Oui, j'ai eu l'erreur quelques minutes après avoir écrits mon message.
    Maintenant, pour récupérer les fields, j'utilise ObfuscationReflectionHelper.

    Et donc voilà le code final (car j'ai modifié 2-3 petites choses) :

    </framemember></framemember>