OpenGL sur Minecraft



  • Bonjour encore moi.
    Je veux tracer une ligne dans le jeu et je n'y arrive pas. Voici le code qu'on a obtenu avec un ami:

    		Tessellator tessellator = Tessellator.getInstance();
    		BufferBuilder buffer = tessellator.getBuffer();
    		VertexFormat format = new VertexFormat();
    		buffer.begin(1, format);
    
    		buffer.pos(entity.posX-0.5, entity.posY, entity.posZ-0.5);
    		buffer.endVertex();
    		buffer.pos(entity.posX+0.5, entity.posY, entity.posZ-0.5);
    		buffer.endVertex();
    		buffer.pos(entity.posX+0.5, entity.posY, entity.posZ+0.5);
    		buffer.endVertex();
    		buffer.pos(entity.posX-0.5, entity.posY, entity.posZ+0.5);
    		buffer.endVertex();
    
    		tessellator.draw();
    

    Cela me donne un java.lang.NullPointerException. Quelqu'un sait pourquoi ?



  • yo montre le code en entier stp ainsi que les logs


  • Rédacteurs

    Bonsoir,

    Déjà tu as un soucis avec ton begin. Le premier argument indique ce que tu veux dessiner (utilise les constantes d'OpenGL). Ici tu veux dessiner une ligne, utilise donc GL11.GL_LINES. Pour le second tu dois spécifier le format des données que tu vas envoyer dans le buffer. Pour ce faire, le mieux ici est d'utiliser les constantes de la classe DefaultVertexFormats de Minecraft. Je te conseille d'utilise DefaultVertexFormats.POSITION_COLOR.

    Tu obtiens donc le code suivant :

    Tessellator tessellator = Tessellator.getInstance();
    BufferBuilder buffer = tessellator.getBuffer();
    buffer.begin(GL11.GL_LINES, DefaultVertexFormats.POSITION_COLOR);
    
    tessellator.draw();
    

    Ensuite, il suffit de renseigner tes sommets (vertices) au buffer. Ici comme j'ai utilisé DefaultVertexFormat.POSITION_COLOR il faut, pour chaque vertex, renseigner la position ainsi que la couleur.

    En regardant ton code je n'ai pas compris de où à où devrait aller ta ligne, mais disons qu'elle doit aller de (x1, y1, z1) à (x2, y2, z2) et que tu veuilles qu'elle soit verte alors ton code devrait être :

    Tessellator tessellator = Tessellator.getInstance();
    BufferBuilder buffer = tessellator.getBuffer();
    buffer.begin(GL11.GL_LINES, DefaultVertexFormats.POSITION_COLOR);
    
    buffer.pos(x1, y1, z1).color(0f, 1f, 0f, 1f).endVertex();
    buffer.pos(x2, y2, z2).color(0f, 1f, 0f, 1f).endVertex();
    
    tessellator.draw();
    

    N'hésite pas à demander des informations complémentaires.



  • Ouaous, merci pour ce message clair. On ne savait pas trop quoi mettre dans ce begin^^. J'avais mit cela au hasard et le jeu avait pas direct crash, donc on pensait être sur la bonne voix.

    Donc le jeu crash plus, mais n'affiche pas non plus la ligne verte. Il manque quelque chose ?
    Je début sur Forge, moi je suis plus expert sur l'api Sponge que je trouve plus facile personnellement. Donc veillez me pardonner pour ce bout de code en dessous qui sort de Mcr**t*r.
    Pour le test, la ligne est sensé ce tracer au dessus de la fumé de mon bloc "megatorch":

    	@SideOnly(Side.CLIENT)
    	@Override
    	public void randomDisplayTick(IBlockState state, World world, BlockPos pos, Random random) {
    		super.randomDisplayTick(state, world, pos, random);
    		EntityPlayer entity = Minecraft.getMinecraft().player;
    
    		Tessellator tessellator = Tessellator.getInstance();
    		BufferBuilder buffer = tessellator.getBuffer();
    		buffer.begin(GL11.GL_LINES, DefaultVertexFormats.POSITION_COLOR);
    
    		buffer.pos(pos.getX(), pos.getY()+1.5, pos.getZ()-1.5).color(0f, 1f, 0f, 1f).endVertex();
    		buffer.pos(pos.getX(), pos.getY()+1.5, pos.getZ()+1.5).color(0f, 1f, 0f, 1f).endVertex();
    
    		tessellator.draw();
    
    		int x = pos.getX();
    		int y = pos.getY();
    		int z = pos.getZ();
    		Block block = this;
    		int i = x;
    		int j = y;
    		int k = z;
    		if (true)
    			for (int l = 0; l < 4; ++l) {
    				double d0 = (double) ((float) i + 0.5F) + (double) (random.nextFloat() - 0.5F) * 0.5D;
    				double d1 = ((double) ((float) j + 0.7F) + (double) (random.nextFloat() - 0.5F) * 0.5D) + 0.5D;
    				double d2 = (double) ((float) k + 0.5F) + (double) (random.nextFloat() - 0.5F) * 0.5D;
    				world.spawnParticle(EnumParticleTypes.SMOKE_LARGE, d0 - 0.27000001072883606D, d1 + 0.2199999988079071D, d2, 0.0D, 0.0D, 0.0D);
    				world.spawnParticle(EnumParticleTypes.FLAME, d0 - 0.27000001072883606D, y+1.05, d2, 0.0D, 0.0D, 0.0D);
    			}
    	}
    }


  • tu ne peux pas utiliser cette fonction pour faire du rendu, tu dois faire un rendu custom pour le block dans ce cas



  • C'est pas un bloc que je veux afficher mais une ligne, c'est vraiment mystérieux pour moi. Je pensais pas que ça serait si difficile.


  • Rédacteurs

    Bonjour,

    Tu peux utiliser l'event RenderWorldLastEvent pour dessiner ta ligne. Si tu ne sais pas encore utiliser les événements je te redirige vers ce tutoriel.



  • Grace a un ami qui m'aide aussi un peut et a un mod on a pu modifier un peut pour avoir un truck fonctionnel.

    Le code de base affiche une grille symbolisant le Chunk. J'ai modifié un peut et j'ai réussi a tracer les contours d'un bloc pour tester.
    Quand on tape une commande cela affiche les lignes et au bout d'un certain temps cela s'enlève.
    Le problème pour le moment c'est que les coordonnées sont en local au chunk genre le bloc du coin c'est (0, 70, 0) et pas (100, 70, 150) par exemple.
    On peut modifier cela ? Il faut modifier: GL11.glTranslated(-inChunkPosX, -inChunkPosY, -inChunkPosZ); ?

    J'ai aussi réussi a utiliser un vecteur en paramètre, il me manque donc juste a résoudre ce problème de coordonnées!

    EDIT:

    Le code:

    import net.minecraft.client.Minecraft;
    import net.minecraft.client.renderer.BufferBuilder;
    import net.minecraft.client.renderer.Tessellator;
    import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
    import net.minecraft.entity.Entity;
    import net.minecraftforge.client.event.RenderWorldLastEvent;
    import net.minecraftforge.event.world.WorldEvent;
    import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
    import net.minecraftforge.fml.common.gameevent.TickEvent.PlayerTickEvent;
    import org.lwjgl.opengl.GL11;
    
    import java.sql.Timestamp;
    
    public class opgl 
    {
    	public static int chunkEdgeState = 0;
    
    	public static long timestamp = 0;
    
    	@SubscribeEvent
    	public void resetOverlay(WorldEvent.Load event)
    	{
    		this.chunkEdgeState = 0;
    	}
    
    	@SubscribeEvent
    	public void getKeyPress(PlayerTickEvent event)
    	{
    //		Entity entity = event.player;
    //		if (entity.prevPosX != entity.posX || entity.prevPosZ != entity.posZ)
    //		{
    //			this.chunkEdgeState = 0;
    //		}
    	}
    
    	@SubscribeEvent
    	public void renderChunkEdges(RenderWorldLastEvent event)
    	{
    		if (this.chunkEdgeState == 0) 
    		{
    			return;
    		}
    
    		Timestamp times = new Timestamp(System.currentTimeMillis());
    		long newTimestamp = times.getTime()/1000;
    
    //		System.out.println("fin: " + timestamp + " " + newTimestamp);
    		long calc = newTimestamp - timestamp;
    //		System.out.println("fin: " + calc);
    
    		if (calc >= 10)
    		{
    			this.chunkEdgeState = 0;
    			System.out.println("fin: " + timestamp + " " + newTimestamp + " " + calc);
    			return;
    		}
    		Entity entity = Minecraft.getMinecraft().player;
    		Tessellator tessellator = Tessellator.getInstance();
    		BufferBuilder worldrenderer = tessellator.getBuffer();
    		GL11.glPushMatrix();
    		float frame = event.getPartialTicks();
    		double inChunkPosX = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * frame;
    		double inChunkPosY = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * frame;
    		double inChunkPosZ = entity.lastTickPosZ + (entity.posZ - entity.lastTickPosZ) * frame;
    		GL11.glTranslated(-inChunkPosX, -inChunkPosY, -inChunkPosZ);
    		GL11.glDisable(3553);
    		GL11.glEnable(3042);
    		GL11.glBlendFunc(770, 771);
    		GL11.glLineWidth(5.0F);
    		worldrenderer.begin(1, DefaultVertexFormats.POSITION_COLOR);
    		GL11.glTranslatef(entity.chunkCoordX * 16, 0.0F, entity.chunkCoordZ * 16);
    		double x = 0.0D;
    		double z = 0.0D;
    		float redColourR = 0.9F;
    		float redColourG = 0.0F;
    		float redColourB = 0.0F;
    		float redColourA = 1.0F;
    		float greenColourR = 0.0F;
    		float greenColourG = 0.9F;
    		float greenColourB = 0.0F;
    		float greenColourA = 0.2F;
    
    //		Position du bloc:
    		double blocX = 9;
    		double blocY = 70;
    		double blocZ = 9;
    
    
    //		Un bloc:
    		worldrenderer.pos(blocX+1.0D, blocY+0.0D, blocZ+1.0D).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    		worldrenderer.pos(blocX+1.0D, blocY+1.0D, blocZ+1.0D).color(redColourR, redColourG, redColourB, redColourA).endVertex();
    		worldrenderer.pos(blocX+0.0D, blocY+0.0D, blocZ+1.0D).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    		worldrenderer.pos(blocX+0.0D, blocY+1.0D, blocZ+1.0D).color(redColourR, redColourG, redColourB, redColourA).endVertex();
    		worldrenderer.pos(blocX+1.0D, blocY+0.0D, blocZ+0.0D).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    		worldrenderer.pos(blocX+1.0D, blocY+1.0D, blocZ+0.0D).color(redColourR, redColourG, redColourB, redColourA).endVertex();
    		worldrenderer.pos(blocX+0.0D, blocY+0.0D, blocZ+0.0D).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    		worldrenderer.pos(blocX+0.0D, blocY+1.0D, blocZ+0.0D).color(redColourR, redColourG, redColourB, redColourA).endVertex();
    
    
    		worldrenderer.pos(blocX+0.0D, blocY+0.0D, blocZ+1.0D).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    		worldrenderer.pos(blocX+0.0D, blocY+0.0D, blocZ+0.0D).color(redColourR, redColourG, redColourB, redColourA).endVertex();
    		worldrenderer.pos(blocX+1.0D, blocY+0.0D, blocZ+0.0D).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    		worldrenderer.pos(blocX+1.0D, blocY+0.0D, blocZ+1.0D).color(redColourR, redColourG, redColourB, redColourA).endVertex();
    
    		worldrenderer.pos(blocX+0.0D, blocY+1.0D, blocZ+1.0D).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    		worldrenderer.pos(blocX+0.0D, blocY+1.0D, blocZ+0.0D).color(redColourR, redColourG, redColourB, redColourA).endVertex();
    		worldrenderer.pos(blocX+1.0D, blocY+1.0D, blocZ+0.0D).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    		worldrenderer.pos(blocX+1.0D, blocY+1.0D, blocZ+1.0D).color(redColourR, redColourG, redColourB, redColourA).endVertex();
    
    
    		worldrenderer.pos(blocX+1.0D, blocY+0.0D, blocZ+0.0D).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    		worldrenderer.pos(blocX+0.0D, blocY+0.0D, blocZ+0.0D).color(redColourR, redColourG, redColourB, redColourA).endVertex();
    		worldrenderer.pos(blocX+1.0D, blocY+0.0D, blocZ+1.0D).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    		worldrenderer.pos(blocX+0.0D, blocY+0.0D, blocZ+1.0D).color(redColourR, redColourG, redColourB, redColourA).endVertex();
    
    		worldrenderer.pos(blocX+1.0D, blocY+1.0D, blocZ+0.0D).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    		worldrenderer.pos(blocX+0.0D, blocY+1.0D, blocZ+0.0D).color(redColourR, redColourG, redColourB, redColourA).endVertex();
    		worldrenderer.pos(blocX+1.0D, blocY+1.0D, blocZ+1.0D).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    		worldrenderer.pos(blocX+0.0D, blocY+1.0D, blocZ+1.0D).color(redColourR, redColourG, redColourB, redColourA).endVertex();
    //		Fin du bloc
    
    
    //		Ligne coin du Chunk rouge:
    //		for (int chunkZ = -2; chunkZ <= 2; chunkZ++)
    //		{
    //			for (int chunkX = -2; chunkX <= 2; chunkX++)
    //			{
    //				if ((Math.abs(chunkX) != 2) || (Math.abs(chunkZ) != 2))
    //				{
    //					x = chunkX * 16;
    //					z = chunkZ * 16;
    //					redColourA = (float)Math.round(Math.pow(1.25D, -(chunkX * chunkX + chunkZ * chunkZ)) * 6.0D) / 6.0F;
    //
    //					worldrenderer.pos(x, 0.0D, z).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    //					worldrenderer.pos(x, 256.0D, z).color(redColourR, redColourG, redColourB, redColourA).endVertex();
    //					worldrenderer.pos(x + 16.0D, 0.0D, z).color(redColourR, redColourG, redColourB, redColourA).endVertex();
    //					worldrenderer.pos(x + 16.0D, 256.0D, z).color(redColourR, redColourG, redColourB, redColourA).endVertex();
    //					worldrenderer.pos(x, 0.0D, z + 16.0D).color(redColourR, redColourG, redColourB, redColourA).endVertex();
    //					worldrenderer.pos(x, 256.0D, z + 16.0D).color(redColourR, redColourG, redColourB, redColourA).endVertex();
    //					worldrenderer.pos(x + 16.0D, 0.0D, z + 16.0D).color(redColourR, redColourG, redColourB, redColourA).endVertex();
    //					worldrenderer.pos(x + 16.0D, 256.0D, z + 16.0D).color(redColourR, redColourG, redColourB, redColourA).endVertex();
    //				}
    //			}
    //		}
    		x = z = 0.0D;
    		if (this.chunkEdgeState == 2)
    		{
    			float eyeHeight = (float)(entity.getEyeHeight() + entity.posY);
    			int eyeHeightBlock = (int)Math.floor(eyeHeight);
    
    			int minY = Math.max(0, eyeHeightBlock - 16);
    			int maxY = Math.min(256, eyeHeightBlock + 16);
    			boolean renderedSome = false;
    			for (int y = 0; y < 257; y++)
    			{
    				greenColourA = 0.4F;
    				if (y < minY) 
    				{
    					greenColourA = (float)(greenColourA - Math.pow(minY - y, 2.0D) / 500.0D);
    				}
    				if (y > maxY) 
    				{
    					greenColourA = (float)(greenColourA - Math.pow(y - maxY, 2.0D) / 500.0D);
    				}
    				if (greenColourA < 0.01F)
    				{
    					if (renderedSome) 
    					{
    						break;
    					}
    				}
    				else
    				{
    //					Corec
    					greenColourA = 0.2F;
    					if (y < 256) 
    					{
    						for (int n = 1; n < 16; n++)
    						{
    							worldrenderer.pos(n, y, z).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    							worldrenderer.pos(n, y + 1, z).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    
    							worldrenderer.pos(x, y, n).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    							worldrenderer.pos(x, y + 1, n).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    
    							worldrenderer.pos(n, y, z + 16.0D).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    							worldrenderer.pos(n, y + 1, z + 16.0D).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    
    							worldrenderer.pos(x + 16.0D, y, n).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    							worldrenderer.pos(x + 16.0D, y + 1, n).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    						}
    					}
    //					Ligne coin du Chunk rouge passé en vert:
    					worldrenderer.pos(x, 0.0D, z).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    					worldrenderer.pos(x, 256.0D, z).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    					worldrenderer.pos(x + 16.0D, 0.0D, z).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    					worldrenderer.pos(x + 16.0D, 256.0D, z).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    					worldrenderer.pos(x, 0.0D, z + 16.0D).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    					worldrenderer.pos(x, 256.0D, z + 16.0D).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    					worldrenderer.pos(x + 16.0D, 0.0D, z + 16.0D).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    					worldrenderer.pos(x + 16.0D, 256.0D, z + 16.0D).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    //					Fin
    
    					worldrenderer.pos(0.0D, y, 0.0D).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    					worldrenderer.pos(16.0D, y, 0.0D).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    					worldrenderer.pos(0.0D, y, 0.0D).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    					worldrenderer.pos(0.0D, y, 16.0D).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    					worldrenderer.pos(16.0D, y, 0.0D).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    					worldrenderer.pos(16.0D, y, 16.0D).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    					worldrenderer.pos(0.0D, y, 16.0D).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    					worldrenderer.pos(16.0D, y, 16.0D).color(greenColourR, greenColourG, greenColourB, greenColourA).endVertex();
    					renderedSome = true;
    				}
    			}
    		}
    		tessellator.draw();
    		GL11.glPopMatrix();
    		GL11.glEnable(3553);
    		GL11.glDisable(3042);
    	}
    }
    


  • Encore moi. j'ai décidé de travailler sur un système de conversion de coordonnées vu que les coordonnées du bloc sont en fonction du bloc ou je suis. J'y suis presque c'est pas bien difficile a faire. J'ai pas trouvé d'autre solution pour le moment.
    donc mon mod est presque terminé!!!

    Par contre comment faire pour que la commande tapé dans la console du serveur puisse affecté mon joueur comme si je l'avais tapé moi même ? Je voulais fournir le pseudo et le vecteur que la commande récupérerait, mais je ne sais pas trop comment faire, ça me donne une erreur avec le Tessellator pour le moment car elle doit être tapé par le joueur.

    Merci pour votre aide


Log in to reply