Jump to content

[SOLVED] [1.10.2] Proper TileEntity rendering


Recommended Posts

Posted

I don't know if this is a bug or my error, but MC freezes, when I pass more than one property to the BlockStateContainer.

 

Example code:

 

public static final PropertyDirection FACING = BlockHorizontal.FACING;
    
public static final PropertyEnum<EnumConnectionType> connectionTop = PropertyEnum.create("connection_top", EnumConnectionType.class);
public static final PropertyEnum<EnumConnectionType> connectionBottom = PropertyEnum.create("connection_bottom", EnumConnectionType.class);
public static final PropertyEnum<EnumConnectionType> connectionNorth = PropertyEnum.create("connection_north", EnumConnectionType.class);
public static final PropertyEnum<EnumConnectionType> connectionWest = PropertyEnum.create("connection_right", EnumConnectionType.class);
public static final PropertyEnum<EnumConnectionType> connectionSouth = PropertyEnum.create("connection_front", EnumConnectionType.class);
public static final PropertyEnum<EnumConnectionType> connectionEast = PropertyEnum.create("connection_back", EnumConnectionType.class);

...

@Override
protected BlockStateContainer createBlockState()
{
     return new BlockStateContainer(this, FACING, connectionTop, connectionBottom, connectionEast, connectionNorth, connectionSouth, connectionWest);
}

 

Am I doing something horribly wrong? If you need to see more code, ask for it.

Posted

I have a suspicion the constructor calls itself because of the varargs:

    public BlockStateContainer(Block blockIn, IProperty<?>... properties)
    {
        this(blockIn, properties, null);
    }

    ...

    protected BlockStateContainer(Block blockIn, IProperty<?>[] properties, ImmutableMap<net.minecraftforge.common.property.IUnlistedProperty<?>, com.google.common.base.Optional<?>> unlistedProperties)
    {
        ...
    }

Posted

You need to pass an array of properties, e.g:

	@Override
protected BlockStateContainer createBlockState() {
	return new BlockStateContainer(this, new IProperty[] {Props.AXEL_ORIENTATION, BlockHorizontal.FACING});
}

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

You need to pass an array of properties, e.g:

	@Override
protected BlockStateContainer createBlockState() {
	return new BlockStateContainer(this, new IProperty[] {Props.AXEL_ORIENTATION, BlockHorizontal.FACING});
}

 

I tried that too before posting, no difference.

Posted

Use your debugger, then.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

Use your debugger, then.

 

Everythings points to the BlockStateContainer class. I noticed the createState method is called repeatedly until I kill java.

 

I noticed it works at 4 - 6 IProperties too, but it takes 5 seconds for 4 props and about a minute for 6 props.

 

EDIT

Wait, does BlockStateContainer on creation generate every single combination of IProperty values? If so, that would be 6 million combinations with 7 Properties (1 side property and 6 properties with 10 different values each).

Posted

I need theese IProperties for my BlockState JSON, or is there a better way of custom side rendering based on TileEntity data? Tesselator is gone if I remember correctly.

Posted

The question is:

Why do you need 10 values for each of 6 different properties?

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

I need theese IProperties for my BlockState JSON, or is there a better way of custom side rendering based on TileEntity data? Tesselator is gone if I remember correctly.

Tesselator is not gone in 1.10.2.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted

So I rewrote most of the model to TESR and it works fine, except the entire block is very very dark. Like white -> dark gray.

 

I often work with LWJGL, but now I am completely lost.

 

private static final int GL11_GL_QUADS = 0x7;

public void renderTileEntityAt(TileEntityMachinePowered te, double x, double y, double z, float partialTicks, int destroyStage)
{
	GlStateManager.pushMatrix();
	GlStateManager.enableLighting();
	GlStateManager.enableDepth();
	GlStateManager.disableBlend();
	GlStateManager.enableTexture2D();
	GlStateManager.translate(x + 0.5, y + 0.5, z + 0.5);			

	Tessellator tessellator = Tessellator.getInstance();

	EnumFacing blockFacing = (EnumFacing) te.getWorld().getBlockState(te.getPos()).getProperties().get(BlockMachineGeneric.FACING);

	Minecraft.getMinecraft().getTextureManager().bindTexture(((BlockMachineSided) te.getBlockType()).getTextureOnSide(EnumFacing.NORTH, blockFacing));		
	drawSide(tessellator.getBuffer());	
	tessellator.draw();
	GlStateManager.rotate(90, 0, 1, 0);
	Minecraft.getMinecraft().getTextureManager().bindTexture(((BlockMachineSided) te.getBlockType()).getTextureOnSide(EnumFacing.WEST, blockFacing));	
	drawSide(tessellator.getBuffer());		
	tessellator.draw();
	GlStateManager.rotate(90, 0, 1, 0);
	Minecraft.getMinecraft().getTextureManager().bindTexture(((BlockMachineSided) te.getBlockType()).getTextureOnSide(EnumFacing.SOUTH, blockFacing));	
	drawSide(tessellator.getBuffer());		
	tessellator.draw();
	GlStateManager.rotate(90, 0, 1, 0);
	Minecraft.getMinecraft().getTextureManager().bindTexture(((BlockMachineSided) te.getBlockType()).getTextureOnSide(EnumFacing.EAST, blockFacing));	
	drawSide(tessellator.getBuffer());		
	tessellator.draw();
	GlStateManager.rotate(90, 0, 1, 0);
	GlStateManager.rotate(90, 1, 0, 0);
	Minecraft.getMinecraft().getTextureManager().bindTexture(((BlockMachineSided) te.getBlockType()).getTextureOnSide(EnumFacing.UP, blockFacing));	
	drawSide(tessellator.getBuffer());		
	tessellator.draw();
	GlStateManager.rotate(180, 1, 0, 0);
	Minecraft.getMinecraft().getTextureManager().bindTexture(((BlockMachineSided) te.getBlockType()).getTextureOnSide(EnumFacing.DOWN, blockFacing));	
	drawSide(tessellator.getBuffer());		
	tessellator.draw();

	GlStateManager.popMatrix();
}

private VertexBuffer drawSide(VertexBuffer buffer)
{
	buffer.begin(GL11_GL_QUADS, DefaultVertexFormats.POSITION_TEX_NORMAL);

	buffer.pos(-0.5, -0.5, -0.5).tex(0, 1).normal(-1, 1, -1).endVertex();
	buffer.pos(-0.5, 0.5, -0.5).tex(0, 0).normal(-1, 1, 1).endVertex();
	buffer.pos(0.5, 0.5, -0.5).tex(1, 0).normal(1, 1, 1).endVertex();
	buffer.pos(0.5, -0.5, -0.5).tex(1, 1).normal(1, 1, -1).endVertex();

	return buffer;
}

UPDATE

It seems the less light the block has, the brighter it is.

That was just an optical illusion.

The block doesn't get lit at all.

Posted

So I rewrote most of the model to TESR and it works fine, except the entire block is very very dark. Like white -> dark gray.

 

I often work with LWJGL, but now I am completely lost.

 

private static final int GL11_GL_QUADS = 0x7;

public void renderTileEntityAt(TileEntityMachinePowered te, double x, double y, double z, float partialTicks, int destroyStage)
{
	GlStateManager.pushMatrix();
	GlStateManager.enableLighting();
	GlStateManager.enableDepth();
	GlStateManager.disableBlend();
	GlStateManager.enableTexture2D();
	GlStateManager.translate(x + 0.5, y + 0.5, z + 0.5);			

	Tessellator tessellator = Tessellator.getInstance();

	EnumFacing blockFacing = (EnumFacing) te.getWorld().getBlockState(te.getPos()).getProperties().get(BlockMachineGeneric.FACING);

	Minecraft.getMinecraft().getTextureManager().bindTexture(((BlockMachineSided) te.getBlockType()).getTextureOnSide(EnumFacing.NORTH, blockFacing));		
	drawSide(tessellator.getBuffer());	
	tessellator.draw();
	GlStateManager.rotate(90, 0, 1, 0);
	Minecraft.getMinecraft().getTextureManager().bindTexture(((BlockMachineSided) te.getBlockType()).getTextureOnSide(EnumFacing.WEST, blockFacing));	
	drawSide(tessellator.getBuffer());		
	tessellator.draw();
	GlStateManager.rotate(90, 0, 1, 0);
	Minecraft.getMinecraft().getTextureManager().bindTexture(((BlockMachineSided) te.getBlockType()).getTextureOnSide(EnumFacing.SOUTH, blockFacing));	
	drawSide(tessellator.getBuffer());		
	tessellator.draw();
	GlStateManager.rotate(90, 0, 1, 0);
	Minecraft.getMinecraft().getTextureManager().bindTexture(((BlockMachineSided) te.getBlockType()).getTextureOnSide(EnumFacing.EAST, blockFacing));	
	drawSide(tessellator.getBuffer());		
	tessellator.draw();
	GlStateManager.rotate(90, 0, 1, 0);
	GlStateManager.rotate(90, 1, 0, 0);
	Minecraft.getMinecraft().getTextureManager().bindTexture(((BlockMachineSided) te.getBlockType()).getTextureOnSide(EnumFacing.UP, blockFacing));	
	drawSide(tessellator.getBuffer());		
	tessellator.draw();
	GlStateManager.rotate(180, 1, 0, 0);
	Minecraft.getMinecraft().getTextureManager().bindTexture(((BlockMachineSided) te.getBlockType()).getTextureOnSide(EnumFacing.DOWN, blockFacing));	
	drawSide(tessellator.getBuffer());		
	tessellator.draw();

	GlStateManager.popMatrix();
}

private VertexBuffer drawSide(VertexBuffer buffer)
{
	buffer.begin(GL11_GL_QUADS, DefaultVertexFormats.POSITION_TEX_NORMAL);

	buffer.pos(-0.5, -0.5, -0.5).tex(0, 1).normal(-1, 1, -1).endVertex();
	buffer.pos(-0.5, 0.5, -0.5).tex(0, 0).normal(-1, 1, 1).endVertex();
	buffer.pos(0.5, 0.5, -0.5).tex(1, 0).normal(1, 1, 1).endVertex();
	buffer.pos(0.5, -0.5, -0.5).tex(1, 1).normal(1, 1, -1).endVertex();

	return buffer;
}

UPDATE

It seems the less light the block has, the brighter it is.

That was just an optical illusion.

The block doesn't get lit at all.

Try disabling the lightning instead of enabling it. And you take into account somethings before using a TESR. Is it supposed to be rendered dynamically? Can it be made using JSONs, can it be made using OBJ models, can you make it using IBakedModels? If it cannot and is not fulling dynamic you need to find a way to render it not every frame, but only when it needs to be rendered.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted

And even if you do need a TESR, don't do

Minecraft.getMinecraft().getTextureManager()

a lot. Save the reference to a variable and that'll clean up your code A LOT.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

And even if you do need a TESR, don't do

Minecraft.getMinecraft().getTextureManager()

a lot. Save the reference to a variable and that'll clean up your code A LOT.

That was a temporary solution. Otherwise I am very tidy with my code.

Try disabling the lightning instead of enabling it. And you take into account somethings before using a TESR. Is it supposed to be rendered dynamically? Can it be made using JSONs, can it be made using OBJ models, can you make it using IBakedModels? If it cannot and is not fulling dynamic you need to find a way to render it not every frame, but only when it needs to be rendered.

I forgot to explain what I am trying to achieve. I have a full, opaque block and I want to draw overlay on each side similar to EnderIO reconfigurable sides. I already rewrote the system again to render the original block normally (using JSON) and then draw the overlay quads with TESR.

It works except for the lighting problem.

Anyway, it's 11 44 PM in my country, so I will check other options you suggested and post my new render code tommorrow.

Posted

So, update.

I was looking for a solution somewhere else and I found a solution for the dark shading:

int li = te.getWorld().getCombinedLight(te.getPos(), 15728640);
int u = li % 65536;
int v = li / 65536;
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, u, v);

Not sure what it does, because it is not documented.

There is one problem, it ignores block lighting and uses only sky lighting.

My new render code:

 

private static final int GL11_GL_QUADS = 0x7;
protected final ResourceLocation frontTex = new ResourceLocation(SECore.MOD_ID, "textures/blocks/machines/overlay.png");

public void renderTileEntityAt(TileEntityMachinePowered te, double x, double y, double z, float partialTicks, int destroyStage)
{
GlStateManager.pushMatrix();
GlStateManager.translate(x + 0.5, y + 0.5, z + 0.5);		
GlStateManager.disableLighting();
GlStateManager.color(1, 1, 1, 1);
GlStateManager.disableCull();

int li = te.getWorld().getCombinedLight(te.getPos(), 15728640);
int u = li % 65536;
int v = li / 65536;
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, u, v);

Tessellator tessellator = Tessellator.getInstance();

Minecraft.getMinecraft().getTextureManager().bindTexture(frontTex);		

if(te.connectionType[EnumFacing.NORTH.getIndex()] != EnumConnectionType.DEFAULT)
{
	storeSide(tessellator.getBuffer(), te.connectionType[EnumFacing.NORTH.getIndex()].getFloatUVs());	
	tessellator.draw();			
}

GlStateManager.rotate(90, 0, 1, 0);

if(te.connectionType[EnumFacing.WEST.getIndex()] != EnumConnectionType.DEFAULT)
{
	storeSide(tessellator.getBuffer(), te.connectionType[EnumFacing.WEST.getIndex()].getFloatUVs());	
	tessellator.draw();			
}

GlStateManager.rotate(90, 0, 1, 0);

if(te.connectionType[EnumFacing.SOUTH.getIndex()] != EnumConnectionType.DEFAULT)
{
	storeSide(tessellator.getBuffer(), te.connectionType[EnumFacing.SOUTH.getIndex()].getFloatUVs());	
	tessellator.draw();			
}

GlStateManager.rotate(90, 0, 1, 0);

if(te.connectionType[EnumFacing.EAST.getIndex()] != EnumConnectionType.DEFAULT)
{
	storeSide(tessellator.getBuffer(), te.connectionType[EnumFacing.EAST.getIndex()].getFloatUVs());	
	tessellator.draw();			
}

GlStateManager.rotate(90, 0, 1, 0);
GlStateManager.rotate(90, 1, 0, 0);

if(te.connectionType[EnumFacing.UP.getIndex()] != EnumConnectionType.DEFAULT)
{
	storeSide(tessellator.getBuffer(), te.connectionType[EnumFacing.UP.getIndex()].getFloatUVs());	
	tessellator.draw();			
}

GlStateManager.rotate(180, 1, 0, 0);

if(te.connectionType[EnumFacing.DOWN.getIndex()] != EnumConnectionType.DEFAULT)
{
	storeSide(tessellator.getBuffer(), te.connectionType[EnumFacing.DOWN.getIndex()].getFloatUVs());	
	tessellator.draw();			
}

GlStateManager.popMatrix();
}

private VertexBuffer storeSide(VertexBuffer buffer, float[] uvs)
{
buffer.begin(GL11_GL_QUADS, DefaultVertexFormats.POSITION_TEX);
double smallShift = .01;

buffer.pos(-0.5, -0.5, -0.5 - smallShift).tex(uvs[0], uvs[3]).endVertex();
buffer.pos(-0.5, 0.5, -0.5 - smallShift).tex(uvs[0], uvs[1]).endVertex();
buffer.pos(0.5, 0.5, -0.5 - smallShift).tex(uvs[2], uvs[1]).endVertex();
buffer.pos(0.5, -0.5, -0.5 - smallShift).tex(uvs[2], uvs[3]).endVertex();

return buffer;
}

 

Posted

Not sure what it does, because it is not documented.

There is one problem, it ignores block lighting and uses only sky lighting.

 

Gets the light value at the block coordinates the TE is at, in a combined manner:

i << 20 | j << 4

where i is SkyLight and j is BlockLight.

 

"15728640" is just a "if the actual block light is less than this value, use this value" value.  This means that regardless of the total light in the space, this value will be used pretty much guaranteed (as 15728640 is definitely more than 15).

 

Because of the way the math works, you may as well replace the function call with the value 15728655 (and ignore all lighting).  Which you could then divide and modulo by 65536 yourself.

 

There is one problem, it ignores block lighting and uses only sky lighting.

(...wasn't that the whole point? To ignore lighting conditions?)

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

Not sure what it does, because it is not documented.

There is one problem, it ignores block lighting and uses only sky lighting.

 

Gets the light value at the block coordinates the TE is at, in a combined manner:

i << 20 | j << 4

where i is SkyLight and j is BlockLight.

 

"15728640" is just a "if the actual block light is less than this value, use this value" value.  This means that regardless of the total light in the space, this value will be used pretty much guaranteed (as 15728640 is definitely more than 15).

 

Because of the way the math works, you may as well replace the function call with the value 15728640 (and ignore all lighting).  Which you could then divide and modulo by 65536 yourself.

 

There is one problem, it ignores block lighting and uses only sky lighting.

(...wasn't that the whole point? To ignore lighting conditions?)

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

I didn't intend to make the overlay fully bright, but it looks cool, so I will keep it like that:

OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240);

Had to look at how the lightmap works, that's the reason I didn't understand it before.

U4sj22O.png

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.