Jump to content

[1.4.4] Help with ISimpleBlockRenderingHandler


Narrakan

Recommended Posts

Hi everyone, I've recently started getting into Minecraft modding. I've followed a couple of tutorials on the wiki and Youtube, and I think I have a basic understanding of how Forge works (hooks and whatnot).

What I'm trying to do now is to render a custom block (really simple, just a table made of five boxes), and I've read on the wiki that the correct way to do this is by implementing ISimpleBlockRenderingHandler in a custom renderer. The problem is, I haven't found any documentation on how to do it, and even trying by myself didn't give positive results.

This is briefly what I have right now:

 

mod_Minesona.java

 

 

package narrakan.minesona.common;

import net.minecraft.src.Block;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.Init;
import cpw.mods.fml.common.Mod.Instance;
import cpw.mods.fml.common.Mod.PostInit;
import cpw.mods.fml.common.Mod.PreInit;
import cpw.mods.fml.common.SidedProxy;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.network.NetworkMod;
import cpw.mods.fml.common.network.NetworkRegistry;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.common.registry.LanguageRegistry;

@Mod(modid = "Narrakan.Minesona", name = "Minesona", version = "0.0.1")
@NetworkMod(clientSideRequired = true, serverSideRequired = false)

public class mod_Minesona {

@Instance("Narrakan.Minesona")
public static mod_Minesona instance = new mod_Minesona();

private GuiHandler guiHandler = new GuiHandler();

@SidedProxy(clientSide="narrakan.minesona.client.MinesonaClientProxy", 
		serverSide="narrakan.minesona.common.MinesonaCommonProxy")
public static MinesonaCommonProxy proxy;

/* Blocks */
public static Block velvetTable;

@Init
public void init(FMLInitializationEvent event) {
	/* Blocks */
	velvetTable = (new BlockVelvetTable(538, 1)).setBlockName("blockVelvetTable");

	/* Items */

	/* Language Registry */
	LanguageRegistry.addName(velvetTable, "Velvet Table");

	/* Game Registry */
	GameRegistry.registerTileEntity(TileEntityVelvetTable.class, "tileEntityVelvetTable");
	GameRegistry.registerBlock(velvetTable);

	/* Network Registry */
	NetworkRegistry.instance().registerGuiHandler(this, guiHandler);

	/* Proxy */
	proxy.registerRenderers();
}

}

 

 

 

MinesonaClientProxy.java

 

 

package narrakan.minesona.client;

import cpw.mods.fml.client.registry.RenderingRegistry;
import narrakan.minesona.common.MinesonaCommonProxy;
import net.minecraftforge.client.MinecraftForgeClient;

public class MinesonaClientProxy extends MinesonaCommonProxy {

public void registerRenderers() {
	MinecraftForgeClient.preloadTexture(BLOCKS_PNG);
	MinecraftForgeClient.preloadTexture(ITEMS_PNG);

	RenderingRegistry.instance().registerBlockHandler(new RendererVelvetTable());
}

}

 

 

 

BlockVelvetTable.java

 

 

package narrakan.minesona.common;

import java.util.Random;

import narrakan.minesona.client.RendererVelvetTable;
import net.minecraft.src.BlockContainer;
import net.minecraft.src.CreativeTabs;
import net.minecraft.src.EntityItem;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.IInventory;
import net.minecraft.src.ItemStack;
import net.minecraft.src.Material;
import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.TileEntity;
import net.minecraft.src.World;

public class BlockVelvetTable extends BlockContainer {

private int textureID;

public BlockVelvetTable(int par1, int par2) {
	super(par1, par2, Material.wood);
	textureID = par2;
	this.setCreativeTab(CreativeTabs.tabDecorations);
	this.setHardness(5.0F);
	this.setResistance(80.0F);
	this.setStepSound(soundClothFootstep);
}

public int getBlockTextureFromSide(int i) {

	/*
	 * 0 = bottom
	 * 1 = top
	 * default = side
	 */

	switch (i) {
	case 0:
		return textureID;
	case 1:
		return textureID + 1;
	default:
		return textureID + 2;
	}
}

public String getTextureFile() {
	return MinesonaCommonProxy.BLOCKS_PNG;
}

@Override
public int getRenderType() {
	return RendererVelvetTable.renderID;
}

@Override
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player,
		int i, float f, float g, float t) {
	TileEntity tile_entity = world.getBlockTileEntity(x, y, z);

	if (tile_entity == null || player.isSneaking())
		return false;

	player.openGui(mod_Minesona.instance, 0, world, x, y, z);
	return true;
}

@Override
public void breakBlock(World world, int x, int y, int z, int i, int j) {
	dropItems(world, x, y, z);
	super.breakBlock(world, x, y, z, i, j);
}

private void dropItems(World world, int x, int y, int z) {
	Random rand = new Random();

	TileEntity tile_entity = world.getBlockTileEntity(x, y, z);

	if (!(tile_entity instanceof IInventory))
		return;

	IInventory inventory = (IInventory) tile_entity;

	for (int i = 0; i < inventory.getSizeInventory(); i++) {
		ItemStack stack = inventory.getStackInSlot(i);

		if (stack != null && stack.stackSize > 0) {
			float rx = rand.nextFloat() * 0.6F + 0.1F;
			float ry = rand.nextFloat() * 0.6F + 0.1F;
			float rz = rand.nextFloat() * 0.6F + 0.1F;

			EntityItem entity_item = new EntityItem(world, rx, ry, rz,
					new ItemStack(stack.itemID, stack.stackSize, stack.getItemDamage()));

			if (stack.hasTagCompound())
				entity_item.item.setTagCompound((NBTTagCompound)stack.getTagCompound().copy());

			float factor = 0.5F;

			entity_item.motionX = rand.nextGaussian() * factor;
			entity_item.motionY = rand.nextGaussian() * factor + 0.2F;
			entity_item.motionZ = rand.nextGaussian() * factor;
			world.spawnEntityInWorld(entity_item);
			stack.stackSize = 0;
		}
	}
}

@Override
public TileEntity createNewTileEntity(World var1) {
	return new TileEntityVelvetTable();
}
}

 

 

 

RendererVelvetTable.java

 

 

package narrakan.minesona.client;

import narrakan.minesona.common.TileEntityVelvetTable;
import net.minecraft.src.Block;
import net.minecraft.src.IBlockAccess;
import net.minecraft.src.RenderBlocks;
import net.minecraft.src.Tessellator;
import net.minecraft.src.TileEntity;
import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;
import cpw.mods.fml.client.registry.RenderingRegistry;

public class RendererVelvetTable implements ISimpleBlockRenderingHandler {

public static final int renderID = 	RenderingRegistry.getNextAvailableRenderId();

private ModelVelvetTable modelVelvetTable = new ModelVelvetTable();

@Override
public void renderInventoryBlock(Block block, int metadata, int modelID,
		RenderBlocks renderer) {
	// No need to render inventory block
}

@Override
public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z,
		Block block, int modelId, RenderBlocks renderer) {

	TileEntity ent = world.getBlockTileEntity(x, y, z);

	if (!(ent instanceof TileEntityVelvetTable))
		return false;

	modelVelvetTable.render(0.025F);

	return true;
}

@Override
public boolean shouldRender3DInInventory() {
	return false;
}

@Override
public int getRenderId() {
	return renderID;
}

}

 

 

 

ModelVelvetTable.java

 

 

package narrakan.minesona.client;

import net.minecraft.src.*;

public class ModelVelvetTable extends ModelBase
{
  //fields
    ModelRenderer Leg1;
    ModelRenderer Leg2;
    ModelRenderer Leg3;
    ModelRenderer Leg4;
    ModelRenderer TopTable;
  
  public ModelVelvetTable()
  {
    textureWidth = 64;
    textureHeight = 128;
    
      Leg1 = new ModelRenderer(this, 0, 19);
      Leg1.addBox(-1F, 0F, -1F, 2, 13, 2);
      Leg1.setRotationPoint(-6F, 11F, -6F);
      Leg1.setTextureSize(64, 128);
      Leg1.mirror = true;
      Leg2 = new ModelRenderer(this, 0, 19);
      Leg2.addBox(-1F, 0F, -1F, 2, 13, 2);
      Leg2.setRotationPoint(-6F, 11F, 6F);
      Leg2.setTextureSize(64, 128);
      Leg2.mirror = true;
      Leg3 = new ModelRenderer(this, 0, 19);
      Leg3.addBox(-1F, 0F, -1F, 2, 13, 2);
      Leg3.setRotationPoint(6F, 11F, 6F);
      Leg3.setTextureSize(64, 128);
      Leg3.mirror = true;
      Leg4 = new ModelRenderer(this, 0, 19);
      Leg4.addBox(-1F, 0F, -1F, 2, 13, 2);
      Leg4.setRotationPoint(6F, 11F, -6F);
      Leg4.setTextureSize(64, 128);
      Leg4.mirror = true;
      TopTable = new ModelRenderer(this, 0, 0);
      TopTable.addBox(-8F, 0F, -8F, 16, 3, 16);
      TopTable.setRotationPoint(0F, 8F, 0F);
      TopTable.setTextureSize(64, 128);
      TopTable.mirror = true;
  }
  
  public void render(float scale)
  {
    Leg1.render(scale);
    Leg2.render(scale);
    Leg3.render(scale);
    Leg4.render(scale);
    TopTable.render(scale);
  }
}

 

 

 

(There's more, obviously, like gui handler, tile entity and so on, but I don't think they are quite useful in this case.)

 

The model class has been automatically generated by Techne, I've only removed some parts to make it simpler, but it didn't work even before doing that.

 

Using this code, I get this error when trying to place the block:

 

2012-11-14 13:06:53 [iNFO] [sTDERR] java.lang.IllegalStateException: Already tesselating!
2012-11-14 13:06:53 [iNFO] [sTDERR] 	at net.minecraft.src.Tessellator.startDrawing(Tessellator.java:343)
2012-11-14 13:06:53 [iNFO] [sTDERR] 	at net.minecraft.src.Tessellator.startDrawingQuads(Tessellator.java:333)
2012-11-14 13:06:53 [iNFO] [sTDERR] 	at net.minecraft.src.TexturedQuad.draw(TexturedQuad.java:48)
2012-11-14 13:06:53 [iNFO] [sTDERR] 	at net.minecraft.src.ModelBox.render(ModelBox.java:102)
2012-11-14 13:06:53 [iNFO] [sTDERR] 	at net.minecraft.src.ModelRenderer.compileDisplayList(ModelRenderer.java:298)
2012-11-14 13:06:53 [iNFO] [sTDERR] 	at net.minecraft.src.ModelRenderer.render(ModelRenderer.java:131)
2012-11-14 13:06:53 [iNFO] [sTDERR] 	at narrakan.minesona.client.ModelVelvetTable.render(ModelVelvetTable.java:48)
2012-11-14 13:06:53 [iNFO] [sTDERR] 	at narrakan.minesona.client.RendererVelvetTable.renderWorldBlock(RendererVelvetTable.java:33)
2012-11-14 13:06:53 [iNFO] [sTDERR] 	at cpw.mods.fml.client.registry.RenderingRegistry.renderWorldBlock(RenderingRegistry.java:145)
2012-11-14 13:06:53 [iNFO] [sTDERR] 	at net.minecraft.src.FMLRenderAccessLibrary.renderWorldBlock(FMLRenderAccessLibrary.java:78)
2012-11-14 13:06:53 [iNFO] [sTDERR] 	at net.minecraft.src.RenderBlocks.renderBlockByRenderType(RenderBlocks.java:510)
2012-11-14 13:06:53 [iNFO] [sTDERR] 	at net.minecraft.src.WorldRenderer.updateRenderer(WorldRenderer.java:218)
2012-11-14 13:06:53 [iNFO] [sTDERR] 	at net.minecraft.src.RenderGlobal.updateRenderers(RenderGlobal.java:1457)
2012-11-14 13:06:53 [iNFO] [sTDERR] 	at net.minecraft.src.EntityRenderer.renderWorld(EntityRenderer.java:1075)
2012-11-14 13:06:53 [iNFO] [sTDERR] 	at net.minecraft.src.EntityRenderer.updateCameraAndRender(EntityRenderer.java:947)
2012-11-14 13:06:53 [iNFO] [sTDERR] 	at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:888)
2012-11-14 13:06:53 [iNFO] [sTDERR] 	at net.minecraft.client.Minecraft.run(Minecraft.java:783)
2012-11-14 13:06:53 [iNFO] [sTDERR] 	at java.lang.Thread.run(Unknown Source)

 

But if I remove the line

modelVelvetTable.render(0.025F);

from renderWorldBlock in my renderer, everything works fine (the block is obviously transparent), and if I change it to

renderer.renderStandardBlock(mod_Minesona.velvetTable, x, y, z);

it works just fine, rendering a simple block.

 

Am I missing something?

 

PS: I am more than willing to update the wiki with any information provided in this thread, if it helps solving the problem.

Link to comment
Share on other sites

What I suggest is, since your using a tile entity, to use a custom tile entity renderer instead of the block renderer.

 

Like so:

 

In your Client Proxy:

 

ClientRegistry.bindTileEntitySpecialRenderer(MyTileEntity.class, new MyTileEntityRenderer());

 

From there, you'd just need to render the model in the renderer, something like this:

 

    MyModel model = new MyModel();
    ...
    public void renderTileEntityAt(TileEntity tileentity, double d, double d1, double d2, float f)
    {			
	GL11.glPushMatrix();
	GL11.glTranslatef((float)d + 0.5F, (float)d1 - 0.5F, (float)d2 + 0.5F);
	GL11.glRotatef(180F, 0.0F, 0.0F, 1.0F);
	GL11.glTranslatef(0.0F, -2.0F, 0.0F);								
	bindTextureByName(texturePathHere);			
	model.renderModelAsTileEntity(0.0625F); (or something like that)			
	GL11.glPopMatrix();		
    }

Link to comment
Share on other sites

  • 2 months later...

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.