Jump to content

[SOLVED][1.7.10] Custom Block Rendering Help


TheMoleTractor

Recommended Posts

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)

Link to comment
Share on other sites

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();

    }

}

 

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.