Posted July 30, 201411 yr Hello! I am trying to make my custom block (a staff) render in hand. Unfortunately, while it renders perfectly when placed, the game is crashing when I try to add the ItemRender class and I have no idea why. I am currently working on two mods and the one mod I have working with in-hand rendering but the newer one is giving a NullPointer on the "this.bindTexture(texture);" line, which I can't figure out why. Does anyone have any ideas? I'd love hear them. I'll paste my Render class below Renderer class package botanyRenderers; import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ResourceLocation; import org.lwjgl.opengl.GL11; import botanyMain.Base; import botanyModels.ModelPowerBulb; import botanyModels.ModelPowerStaff; public class RenderPowerStaff extends TileEntitySpecialRenderer { private static final ResourceLocation stickTexture = new ResourceLocation(Base.modid + ":" + "textures/tileentity/powerStaff.png"); private static final ResourceLocation bulbTexture = new ResourceLocation(Base.modid + ":" + "textures/tileentity/powerBulb.png"); private ModelPowerStaff stick; private ModelPowerBulb bulb; private float yRotateAngle = 0.10F; private float xOffset = -0.25F; private float speed = 1.0F; private boolean goUp = false; public RenderPowerStaff() { this.stick = new ModelPowerStaff(); this.bulb = new ModelPowerBulb(); } @Override public void renderTileEntityAt(TileEntity tileEntity, double x, double y, double z, float scale) { GL11.glPushMatrix(); GL11.glTranslatef((float)x, (float)y, (float)z); GL11.glPushMatrix(); GL11.glTranslatef(0.5F, 1.5F, 0.5F); GL11.glScalef(-1.0F, -1.0F, 1.0F); //Render stick GL11.glPushMatrix(); this.bindTexture(stickTexture); this.stick.renderModel(0.0625F); GL11.glPushMatrix(); GL11.glRotatef(180F, 0.0F, 0.0F, 1.0F); GL11.glPopMatrix(); this.bindTexture(bulbTexture); //Offsets Below GL11.glPushMatrix(); if(!goUp) { xOffset += 0.0005F; if(xOffset >= -0.25F) goUp = true; } else if(goUp) { xOffset -= 0.0005F; if(xOffset <= -0.35F) goUp = false; } GL11.glTranslatef(0.0F, xOffset, 0.0F); //Rotations Below GL11.glPushMatrix(); yRotateAngle += scale * speed; if(yRotateAngle <= 360) yRotateAngle -= 360; GL11.glRotatef(yRotateAngle, 0.0F, 1.0F, 0.0f); this.bulb.renderModel(0.0625F); GL11.glPopMatrix(); GL11.glPopMatrix(); GL11.glPopMatrix(); GL11.glPopMatrix(); GL11.glPopMatrix(); } } Line 44 (this.bindTexture(stickTexture) is throwing the null pointer but it uses the same call as my other mod does and the other mod works fine. All the folders are set up the same as well (resources/assets/*modName*/textures/tileentity/*TESR*.png)
July 30, 201411 yr Can you post the bindTexture code? The null pointer is likely caused by something in it. Whenever you call someObj.someMethod(), see if someObj is null. That's usually what causes null pointers. GitHub|Recipe API Proposal
July 30, 201411 yr Author Can you post the bindTexture code? The null pointer is likely caused by something in it. The line calling the bindTexture method is from a method I did not create and is offered from, I believe, Minecraft Vanilla. I would understand it calling a null if neither the in-hand nor the placed version of my block were not working but the odd part is that if I do not use a special, in-hand renderer, the block is placeable and looks as it should in the world but does not render anything in hand (not blank, but the default missing texture purple and black texture). I'll post the code that my object is calling. It is overriding an existing method so I did not create my own bindTexture method. I'll toss a null check around the bindTexture, and although I'm sure that will remove my crash, I don't believe it will do much more. package net.minecraft.client.renderer.tileentity; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; @SideOnly(Side.CLIENT) public abstract class TileEntitySpecialRenderer { protected TileEntityRendererDispatcher field_147501_a; private static final String __OBFID = "CL_00000964"; public abstract void renderTileEntityAt(TileEntity p_147500_1_, double p_147500_2_, double p_147500_4_, double p_147500_6_, float p_147500_8_); protected void bindTexture(ResourceLocation p_147499_1_) { TextureManager texturemanager = this.field_147501_a.field_147553_e; if (texturemanager != null) { texturemanager.bindTexture(p_147499_1_); } } public void func_147497_a(TileEntityRendererDispatcher p_147497_1_) { this.field_147501_a = p_147497_1_; } public void func_147496_a(World p_147496_1_) {} public FontRenderer func_147498_b() { return this.field_147501_a.getFontRenderer(); } }
July 30, 201411 yr Ah, I see. Your class extends TileEntitySpecialRenderer which has no constructor specified. This means that in your class, you need to instantiate the fields in TileEntitySpecialRenderer in the constructor of your class. In particular, field_147501_a remains null, and that's being used in the bindTexture method. -Nephroid GitHub|Recipe API Proposal
July 30, 201411 yr Author I guess I'm really just confused at why my other mod works perfectly without having to declare/assign the func_147501_a yet this one does. I mean I see exactly what you are talking about and I now know why it is giving the null pointer (thanks a ton for the feedback by the way), I just don't understand why it works in one case but doesn't in another, and because it does not work in this case while the other does, I do not know quite how to solve the issue. I have never worked with the TileEntityRendererDispatcher (the single argument for the func_147497_a method that assigns the above variable) before.
July 31, 201411 yr Can you post the code of the class that works? I can try to compare the two classes to see what's missing. My intuition tells me that the working class probably extends a different class, or it extends the same class, but the relevant field is instantiated somewhere outside the class using a setter method or something. Try initializing the field in the working code to null (in the constructor) and see if it breaks. GitHub|Recipe API Proposal
July 31, 201411 yr Author Well each instance of these blocks that I'm attempting to render in hand has a TileEntity, Render (TESR), Model, ItemRender (rendering in hand class), and Block class associated with them, as well as a Base and ClientProxy class with code to initialize and register them. I'm going to post the Working and Un-Working code classes of Render, ItemRender, TileEntity, and the ClientProxy because I feel those are where something is wonky. I am happy to post any others though. Working Block TileEntity: package lavaInfusionTileEntity; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.NetworkManager; import net.minecraft.network.Packet; import net.minecraft.network.play.server.S35PacketUpdateTileEntity; import net.minecraft.tileentity.TileEntity; public class TileEntityMagmaFoundation extends TileEntity { private int chargeCount = 0; //Number of charges held public int getChargeCount() { return chargeCount; } @Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); this.chargeCount = nbt.getInteger("chargeCount"); } @Override public void writeToNBT(NBTTagCompound nbt) { super.writeToNBT(nbt); nbt.setInteger("chargeCount", chargeCount); } @Override public Packet getDescriptionPacket() { NBTTagCompound nbtTag = new NBTTagCompound(); this.writeToNBT(nbtTag); return new S35PacketUpdateTileEntity(this.xCoord, this.yCoord, this.zCoord, 1, nbtTag); } @Override public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity packet) { readFromNBT(packet.func_148857_g()); } //Non Forge Related Methods Below public void setChargeCount(int that) { this.chargeCount = that; } public void addCharges(int amt) { this.chargeCount += amt; } public void useCharges(int amt) { this.chargeCount -= amt; } } Render: package lavaInfusionRenderers; import lavaInfusionMain.Base; import lavaInfusionModels.ModelMagmaFoundation; import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ResourceLocation; import org.lwjgl.opengl.GL11; public class RenderMagmaFoundation extends TileEntitySpecialRenderer { private static final ResourceLocation texture = new ResourceLocation(Base.MODID + ":" + "textures/tileentity/magmaFoundation.png"); private ModelMagmaFoundation model; public RenderMagmaFoundation() { this.model = new ModelMagmaFoundation(); } @Override public void renderTileEntityAt(TileEntity te, double x, double y, double z, float f) { GL11.glPushMatrix(); //rotations and translates GL11.glTranslatef((float)x + 0.5F, (float)y + 1.5F, (float)z + 0.5F); GL11.glRotatef(180, 0.0F, 0.0F, 1.0F); this.bindTexture(texture); GL11.glPushMatrix(); //rendering model this.model.renderModel(0.0625F); GL11.glPopMatrix(); GL11.glPopMatrix(); } } ItemRenderer: package lavaInfusionRenderers; import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraftforge.client.IItemRenderer; import org.lwjgl.opengl.GL11; public class ItemRenderMagmaFoundation implements IItemRenderer { TileEntitySpecialRenderer render; private TileEntity te; public ItemRenderMagmaFoundation(TileEntitySpecialRenderer render, TileEntity te) { this.render = render; this.te = te; } @Override public boolean handleRenderType(ItemStack item, ItemRenderType type) { return true; } @Override public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item, ItemRendererHelper helper) { return true; } @Override public void renderItem(ItemRenderType type, ItemStack item, Object... data) { if (type == IItemRenderer.ItemRenderType.ENTITY) { GL11.glTranslatef(-0.5F, 0.0F, -0.5F); } GL11.glScalef(1.5F, 1.5F, 1.5F); this.render.renderTileEntityAt(this.te, 0.0D, 0.0D, 0.0D, 0.0F); } } Client Proxy: package lavaInfusionMain; import lavaInfusionRenderers.ItemRenderMagmaFoundation; import lavaInfusionRenderers.ItemRenderStonePedestal; import lavaInfusionRenderers.RenderMagmaFoundation; import lavaInfusionRenderers.RenderStonePedestal; import lavaInfusionTileEntity.TileEntityMagmaFoundation; import lavaInfusionTileEntity.TileEntityStonePedestal; import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; import net.minecraft.item.Item; import net.minecraftforge.client.MinecraftForgeClient; import cpw.mods.fml.client.registry.ClientRegistry; public class ClientProxy extends CommonProxy { public void registerRenderThings() { /**TileEntity Registeries**/ //Stone Pedestal Registry TileEntitySpecialRenderer stonePedestal = new RenderStonePedestal(); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityStonePedestal.class, stonePedestal); MinecraftForgeClient.registerItemRenderer(Item.getItemFromBlock(Base.stonePedestal), new ItemRenderStonePedestal(stonePedestal, new TileEntityStonePedestal())); //Magma Foundation Registry TileEntitySpecialRenderer magmaFoundation = new RenderMagmaFoundation(); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMagmaFoundation.class, magmaFoundation); MinecraftForgeClient.registerItemRenderer(Item.getItemFromBlock(Base.magmaFoundation), new ItemRenderMagmaFoundation(magmaFoundation, new TileEntityMagmaFoundation())); } public void registerTESR() { } } Non-Working Block TileEntity: package botanyTileEntity; import net.minecraft.tileentity.TileEntity; public class TileEntityPowerStaff extends TileEntity {} Render: package botanyRenderers; import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ResourceLocation; import org.lwjgl.opengl.GL11; import botanyMain.Base; import botanyModels.ModelPowerBulb; import botanyModels.ModelPowerStaff; public class RenderPowerStaff extends TileEntitySpecialRenderer { private static final ResourceLocation stickTexture = new ResourceLocation(Base.modid + ":" + "textures/tileentity/powerStaff.png"); private static final ResourceLocation bulbTexture = new ResourceLocation(Base.modid + ":" + "textures/tileentity/powerBulb.png"); private ModelPowerStaff stick; private ModelPowerBulb bulb; private float yRotateAngle = 0.10F; private float xOffset = -0.25F; private float speed = 1.0F; private boolean goUp = false; public RenderPowerStaff() { this.stick = new ModelPowerStaff(); this.bulb = new ModelPowerBulb(); } @Override public void renderTileEntityAt(TileEntity tileEntity, double x, double y, double z, float scale) { GL11.glPushMatrix(); GL11.glTranslatef((float)x, (float)y, (float)z); GL11.glPushMatrix(); GL11.glTranslatef(0.5F, 1.5F, 0.5F); GL11.glScalef(-1.0F, -1.0F, 1.0F); //Render stick GL11.glPushMatrix(); this.bindTexture(stickTexture); this.stick.renderModel(0.0625F); GL11.glPushMatrix(); GL11.glRotatef(180F, 0.0F, 0.0F, 1.0F); GL11.glPopMatrix(); this.bindTexture(bulbTexture); //Offsets Below GL11.glPushMatrix(); if(!goUp) { xOffset += 0.0005F; if(xOffset >= -0.25F) goUp = true; } else if(goUp) { xOffset -= 0.0005F; if(xOffset <= -0.35F) goUp = false; } GL11.glTranslatef(0.0F, xOffset, 0.0F); //Rotations Below GL11.glPushMatrix(); yRotateAngle += scale * speed; if(yRotateAngle <= 360) yRotateAngle -= 360; GL11.glRotatef(yRotateAngle, 0.0F, 1.0F, 0.0f); this.bulb.renderModel(0.0625F); GL11.glPopMatrix(); GL11.glPopMatrix(); GL11.glPopMatrix(); GL11.glPopMatrix(); GL11.glPopMatrix(); } } ItemRenderer: package botanyRenderers; import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraftforge.client.IItemRenderer; import org.lwjgl.opengl.GL11; public class ItemRenderPowerStaff implements IItemRenderer { TileEntitySpecialRenderer render; private TileEntity te; public ItemRenderPowerStaff(TileEntitySpecialRenderer render, TileEntity te) { this.render = render; this.te = te; } @Override public boolean handleRenderType(ItemStack item, ItemRenderType type) { return true; } @Override public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item, ItemRendererHelper helper) { return true; } @Override public void renderItem(ItemRenderType type, ItemStack item, Object... data) { if (type == IItemRenderer.ItemRenderType.ENTITY) { GL11.glTranslatef(-0.5F, 0.0F, -0.5F); } GL11.glScalef(1.5F, 1.5F, 1.5F); this.render.renderTileEntityAt(this.te, 0.0D, 0.0D, 0.0D, 0.0F); } } ClientProxy: package botanyMain; import net.minecraft.client.renderer.entity.RenderSnowball; import botanyEntity.EntityArrowFish; import botanyEntity.EntityBarbedSpike; import botanyEntity.EntityBasilisk; import botanyEntity.EntityFungleCrab; import botanyEntity.EntityGreanBaen; import botanyEntity.EntityMongrel; import botanyEntity.EntityPrizeRunner; import botanyEntity.EntitySapphireBerry; import botanyEntity.EntitySapphireLawncher; import botanyEntity.EntitySporeRay; import botanyEntity.EntityWanderingShoot; import botanyModels.ModelArrowFish; import botanyModels.ModelBarbedSpike; import botanyModels.ModelBasilisk; import botanyModels.ModelFungleCrab; import botanyModels.ModelGreanBaen; import botanyModels.ModelMongrel; import botanyModels.ModelPrizeRunner; import botanyModels.ModelSapphireLawncher; import botanyModels.ModelSporeRay; import botanyModels.ModelWanderingShoot; import botanyRenderers.RenderArrowFish; import botanyRenderers.RenderBarbedSpike; import botanyRenderers.RenderBasilisk; import botanyRenderers.RenderCropStaff; import botanyRenderers.RenderFungleCrab; import botanyRenderers.RenderGreanBaen; import botanyRenderers.RenderLifeBasin; import botanyRenderers.RenderMongrel; import botanyRenderers.RenderPowerBulb; import botanyRenderers.RenderPowerStaff; import botanyRenderers.RenderPrizeRunner; import botanyRenderers.RenderSapphireCrop; import botanyRenderers.RenderSapphireLawncher; import botanyRenderers.RenderSporeRay; import botanyRenderers.RenderWanderingShoot; import botanyTileEntity.TileEntityCropStaff; import botanyTileEntity.TileEntityLifeBasin; import botanyTileEntity.TileEntityPowerBulb; import botanyTileEntity.TileEntityPowerStaff; import botanyTileEntity.TileEntitySapphireCrop; import cpw.mods.fml.client.registry.ClientRegistry; import cpw.mods.fml.client.registry.RenderingRegistry; public class ClientProxy extends CommonProxy { public void registerRenderThings() { /**Mob Rendering**/ RenderingRegistry.registerEntityRenderingHandler(EntityGreanBaen.class, new RenderGreanBaen(new ModelGreanBaen(), 0.5F)); RenderingRegistry.registerEntityRenderingHandler(EntityFungleCrab.class, new RenderFungleCrab(new ModelFungleCrab(), 0.5F)); RenderingRegistry.registerEntityRenderingHandler(EntityPrizeRunner.class, new RenderPrizeRunner(new ModelPrizeRunner(), 0.5F)); RenderingRegistry.registerEntityRenderingHandler(EntityBarbedSpike.class, new RenderBarbedSpike(new ModelBarbedSpike(), 0.5f)); RenderingRegistry.registerEntityRenderingHandler(EntityArrowFish.class, new RenderArrowFish(new ModelArrowFish(), 0.5F)); RenderingRegistry.registerEntityRenderingHandler(EntityMongrel.class, new RenderMongrel(new ModelMongrel(), 0.5F)); RenderingRegistry.registerEntityRenderingHandler(EntitySapphireLawncher.class, new RenderSapphireLawncher(new ModelSapphireLawncher(), 0.5F)); RenderingRegistry.registerEntityRenderingHandler(EntityWanderingShoot.class, new RenderWanderingShoot(new ModelWanderingShoot(), 0.5F)); RenderingRegistry.registerEntityRenderingHandler(EntitySporeRay.class, new RenderSporeRay(new ModelSporeRay(), 0.5F)); RenderingRegistry.registerEntityRenderingHandler(EntityBasilisk.class, new RenderBasilisk(new ModelBasilisk(), 0.5F)); /**Tile Entity Rendering**/ //Power Staff // TileEntitySpecialRenderer powerStaff = new RenderPowerStaff(); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityPowerStaff.class, new RenderPowerStaff()); // MinecraftForgeClient.registerItemRenderer(Item.getItemFromBlock(Base.blockPowerStaff), new ItemRenderPowerStaff(powerStaff, new TileEntityPowerStaff())); //Sapphire Crop // TileEntitySpecialRenderer sapphireCrop = new RenderSapphireCrop(); ClientRegistry.bindTileEntitySpecialRenderer(TileEntitySapphireCrop.class, new RenderSapphireCrop()); // MinecraftForgeClient.registerItemRenderer(Item.getItemFromBlock(Base.blockSapphireCrop), new ItemRenderSapphireCrop(sapphireCrop, new TileEntitySapphireCrop())); //Power Bulb // TileEntitySpecialRenderer powerBulb = new RenderPowerBulb(); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityPowerBulb.class, new RenderPowerBulb()); // MinecraftForgeClient.registerItemRenderer(Item.getItemFromBlock(Base.blockPowerBulb), new ItemRenderPowerBulb(powerBulb, new TileEntityPowerBulb())); //Crop Staff // TileEntitySpecialRenderer cropStaff = new RenderCropStaff(); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityCropStaff.class, new RenderCropStaff()); // MinecraftForgeClient.registerItemRenderer(Item.getItemFromBlock(Base.blockCropStaff), new ItemRenderCropStaff(cropStaff, new TileEntityCropStaff())); //Life Basin // TileEntitySpecialRenderer lifeBasin = new RenderLifeBasin(); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityLifeBasin.class, new RenderLifeBasin()); // MinecraftForgeClient.registerItemRenderer(Item.getItemFromBlock(Base.blockLifeBasin), new ItemRenderLifeBasin(lifeBasin, new TileEntityPowerBulb())); /**Thrown Entity Rendering**/ //Entity Rendering RenderingRegistry.registerEntityRenderingHandler(EntitySapphireBerry.class, new RenderSnowball(Base.itemSapphireBerry)); } @Override public void registerSound() { } } I may just be a little burnt out and missed something. Another note that may be important is the working one I built from scratch on the 1.7.10 gradle system while the not working one has been updated (over the past couple days) to 1.7.10 from 1.6.4. (Didn't use gradle previously) EDIT: Got it working, in my base class I was initializing my full TileEntity before I initialized the two TileEntities I was using in my Render class; resulting in a null for the Rendering Item in the one field. Bit of a further explanation, my block was not placed, a different block was placed and a second block was right clicked and "put on top" to create the TileEntity I was having issues with. Trying to rendering the productions TileEntity before I had initialized the TileEntity for the other two was causing the problems. Anyways, it all works now, solved! Huge thanks for Nephroid for the help pin pointing where and why the problem was occurring.
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.