Jump to content

[1.7.10] Custom Tile Entity Renders with Different Shade than Original Texture


Recommended Posts

Posted

Whenever I create a Tile Entity and render it with TileEntitySpecialRenderer, the resultant model is always a different shade than the original texture that is used.

 

Here is an example.  In this case, i'm using OpenGL to render the block with the standard stone texture with an custom overlay for the ore.  For this instance I followed this thread:

http://www.minecraftforge.net/forum/index.php/topic,26033.msg132818.html#msg132818.

 

However, this did not solve my issue.  This also happens when I use a Techne generated model.

 

e3d338ae7f.png

 

(My blocks have the red arrows pointing at them)

 

Here is TESR code I used for this example

public class OreTileEntityRenderer extends TileEntitySpecialRenderer {

private ResourceLocation blockTexture;
private ResourceLocation oreTexture;

/**
 * 
 * @param blockTexture
 * @param oreTexture
 */
public OreTileEntityRenderer(String blockTexture, String oreTexture ) {
	setBlockTexture(new ResourceLocation(blockTexture));
	setOreTexture(new ResourceLocation(oreTexture));
}

@Override
public void renderTileEntityAt(TileEntity tileEntity, double x, double y, double z, float scale) {
	int au = 0;
	int av = 0;
	int bu= 0;
	int bv = 1;
	int cu = 1;
	int cv = 1;
	int du = 1;
	int dv = 0;

	// bind the texture to use
	Minecraft.getMinecraft().renderEngine.bindTexture(getBlockTexture());

	// set up GL
	GL11.glPushMatrix();
	GL11.glTranslated(x, y, z);
	GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
	GL11.glEnable(GL11.GL_ALPHA_TEST);
	GL11.glDisable(GL11.GL_LIGHTING);

	Tessellator t = Tessellator.instance;

	for (int i = 0; i <=1; i++) {
		if (i > 0) {
			Minecraft.getMinecraft().renderEngine.bindTexture(getOreTexture());
			GL11.glEnable(GL11.GL_BLEND);
			GL11.glDepthMask(false);
			GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);		
			GL11.glAlphaFunc(GL11.GL_LESS, 1.0f);
		}

		// draw the opaque block
		t.startDrawingQuads();
		t.setColorOpaque_F(1.0F, 1.0F, 1.0F);
		// add the vertices
		t.addVertexWithUV(0, 0, 0, cu, cv); //A:c
		t.addVertexWithUV(0, 1, 0, du, dv); //B:d
		t.addVertexWithUV(1, 1, 0, au, av); //C:a
		t.addVertexWithUV(1, 0, 0, bu, bv); //D:b
		t.draw();

... // removed rest for brevity 

 

Any help is much appreciated.

 

UPDATE:  And light sources change the color when other blocks (stone) aren't.  This there a block variable I have to set?  This doesn't seem like a rendering problem.

Posted

Hi

 

You haven't set the brightness on the tessellator so the blocklight/skylight settings are ignored.  You also haven't done direction-dependent brightness on the faces.

 

This link might be helpful.  It's basically the same as for 1.7.10.

http://greyminecraftcoder.blogspot.com.au/2014/12/lighting-18.html

 

Have a look in RenderBlocks.renderStandardBlockWithColorMultiplier(), the key parts are

 

        float f3 = 0.5F;

        float f4 = 1.0F;

        float f5 = 0.8F;

        float f6 = 0.6F;

for use with face-dependent brightness eg

            tessellator.setColorOpaque_F(f10, f13, f16);

 

and the setBrightness

eg

            tessellator.setBrightness(block.getMixedBrightnessForBlock(this.blockAccess, x, y- 1, z));  // for the bottom face

            tessellator.setBrightness(block.getMixedBrightnessForBlock(this.blockAccess, x, y+ 1, z));  // for the top face

etc

(Notice that for solid blocks, you have to get the mixedbrightness from the adjacent block.  The mixed brightness of the solid block itself is 0).

 

-TGG

 

 

 

 

-TGG

Posted

Thanks TheGreyGhost,

 

However, following the code for the call

 

tessellator.setBrightness(block.getMixedBrightnessForBlock(this.blockAccess, x, y- 1, z))

 

requires that I pass something that implements IBlockAccess into getMixedBrightnessForBlock().  A TESR doesn't provide that property.  How else can I obtain an IBlockAccess object?

 

Thanks

Posted

requires that I pass something that implements IBlockAccess into getMixedBrightnessForBlock().  A TESR doesn't provide that property.  How else can I obtain an IBlockAccess object?

 

World implements IBlockAccess.

Your TESR should have access to your TE which has a worldObj

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

Thanks! I was digging through the code and saw that WorldClient was being used and couldn't figure out where to get that. I didn't think of checking World. Doh. This should've been more apparent to me. 

Posted

Ok,

I tried doing as you instructed.  You can see the light source affect the block coloring in a chunky gradient fashion, however, they still look nothing like the original stone block. ie not smooth gradient and different color.

 

(I removed my ore overlay to make it clearer)

My blocks are highlighted in red, vanilla in blue.

 

522a1294ea.png

 

i'm posting the whole class:

 

/**
* 
*/
package com.sgs.metals.client.render.tileentity;

import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.EntityRenderer;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;

import org.lwjgl.opengl.GL11;

import com.sgs.metals.Metals;


public class OreTileEntityRenderer extends TileEntitySpecialRenderer {

private ResourceLocation blockTexture;
private ResourceLocation oreTexture;

/**
 * 
 * @param blockTexture
 * @param oreTexture
 */
public OreTileEntityRenderer(String blockTexture, String oreTexture ) {
	setBlockTexture(new ResourceLocation(blockTexture));
	setOreTexture(new ResourceLocation(oreTexture));
}

/* (non-Javadoc)
 * @see net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer#renderTileEntityAt(net.minecraft.tileentity.TileEntity, double, double, double, float)
 */
@Override
public void renderTileEntityAt(TileEntity tileEntity, double x, double y, double z, float scale) {
	int au = 0;
	int av = 0;
	int bu= 0;
	int bv = 1;
	int cu = 1;
	int cv = 1;
	int du = 1;
	int dv = 0;
        
        // get the world from tile entity
        World world = tileEntity.getWorldObj();
        
        // get the x,y,z coords of the tile entity/block
        int bx = tileEntity.xCoord;
        int by = tileEntity.yCoord;
        int bz = tileEntity.zCoord;
        
        // get the block
        Block block = world.getBlock(bx, by, bz);
        
        // get the color multiplier
        int l = block.colorMultiplier(world, bx, by, bz);
        float cf = (float)(l >> 16 & 255) / 255.0F;
        float cf1 = (float)(l >> 8 & 255) / 255.0F;
        float cf2 = (float)(l & 255) / 255.0F;

        if (EntityRenderer.anaglyphEnable) {
            float cf3 = (cf * 30.0F + cf1 * 59.0F + cf2 * 11.0F) / 100.0F;
            float cf4 = (cf * 30.0F + cf1 * 70.0F) / 100.0F;
            float cf5 = (cf * 30.0F + cf2 * 70.0F) / 100.0F;
            cf = cf3;
            cf1 = cf4;
            cf2 = cf5;
        }
        
        ////////////////////
        // opaque colors
        float f3 = 0.5F;
        float f4 = 1.0F;
        float f5 = 0.8F;
        float f6 = 0.6F;
        float f7 = f4 * cf;
        float f8 = f4 * cf1;
        float f9 = f4 * cf2;
        float f10 = f3;
        float f11 = f5;
        float f12 = f6;
        float f13 = f3;
        float f14 = f5;
        float f15 = f6;
        float f16 = f3;
        float f17 = f5;
        float f18 = f6;
        
        f10 = f3 * cf;
        f11 = f5 * cf;
        f12 = f6 * cf;
        f13 = f3 * cf1;
        f14 = f5 * cf1;
        f15 = f6 * cf1;
        f16 = f3 * cf2;
        f17 = f5 * cf2;
        f18 = f6 * cf2;
                
	// bind the texture to use
	Minecraft.getMinecraft().renderEngine.bindTexture(getBlockTexture());

	// set up GL
	GL11.glPushMatrix();
	GL11.glTranslated(x, y, z);
	GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
	GL11.glEnable(GL11.GL_ALPHA_TEST);
	GL11.glDisable(GL11.GL_LIGHTING);

	Tessellator t = Tessellator.instance;

//		for (int i = 0; i <=1; i++) {
//			if (i > 0) {
//				// bind the overlay resource texture
//				Minecraft.getMinecraft().renderEngine.bindTexture(getOreTexture());
//				// set the the alpha settings
//				// these three enable opacity of whole image - not sure that that is what i want
//				GL11.glEnable(GL11.GL_BLEND);
//				GL11.glDepthMask(false);
//				GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);		
//			}

		// draw the opaque block
		// north-face
		// xyz clockwise
		t.startDrawingQuads();
		t.setColorOpaque_F(f11, f14, f17);
		t.setBrightness(block.getMixedBrightnessForBlock(world, bx, by, bz - 1));

		// add the vertices
		t.addVertexWithUV(0, 0, 0, cu, cv); //A:c
		t.addVertexWithUV(0, 1, 0, du, dv); //B:d
		t.addVertexWithUV(1, 1, 0, au, av); //C:a
		t.addVertexWithUV(1, 0, 0, bu, bv); //D:b
		t.draw();

		// south face
		// xyz counter-clockwise; uv hortizontal flip
		t.startDrawingQuads();
		t.setColorOpaque_F(f11, f14, f17);
		t.setBrightness(block.getMixedBrightnessForBlock(world, bx, by, bz + 1));
		t.addVertexWithUV(0, 0, 1, bu, bv); //c
		t.addVertexWithUV(1, 0, 1, cu, cv); //b
		t.addVertexWithUV(1, 1, 1, du, dv); //d
		t.addVertexWithUV(0, 1, 1, au, av); //a
		t.draw();

		// east face
		// xyz clockwise
		t.startDrawingQuads();
		t.setColorOpaque_F(f12, f15, f18);
		t.setBrightness(block.getMixedBrightnessForBlock(world, bx + 1, by, bz));
		t.addVertexWithUV(1, 0, 0, cu, cv);
		t.addVertexWithUV(1, 1, 0, du, dv);
		t.addVertexWithUV(1, 1, 1, au, av);
		t.addVertexWithUV(1,  0, 1, bu, bv);
		t.draw();

		// west face
		// xyz counter-clockwise
		t.startDrawingQuads();
		t.setColorOpaque_F(f12, f15, f18);
		t.setBrightness(block.getMixedBrightnessForBlock(world, bx - 1, by, bz));
		t.addVertexWithUV(0, 0, 0, bu, bv);
		t.addVertexWithUV(0, 0, 1, cu, cv);
		t.addVertexWithUV(0, 1, 1, du, dv);
		t.addVertexWithUV(0, 1, 0, au, av);
		t.draw();

		// top face
		// xyz clockwise
		t.startDrawingQuads();
		t.setColorOpaque_F(f7, f8, f9);
		t.setBrightness(block.getMixedBrightnessForBlock(world, bx, by + 1, bz));
		t.addVertexWithUV(0, 1, 0, cu, cv);
		t.addVertexWithUV(0, 1, 1, du, dv);
		t.addVertexWithUV(1, 1, 1, au, av);
		t.addVertexWithUV(1, 1, 0, bu, bv);
		t.draw();

		// bottom face
		// xyz counter clockwise
		t.startDrawingQuads();
		t.setColorOpaque_F(f10, f13, f16);
		t.setBrightness(block.getMixedBrightnessForBlock(world, bx, by - 1, bz));
		t.addVertexWithUV(0, 0, 0, bu, bv);
		t.addVertexWithUV(1, 0, 0, cu, cv);
		t.addVertexWithUV(1, 0, 1, du, dv);
		t.addVertexWithUV(0, 0, 1, au, av);
		t.draw();
//		}

	// clean up
	GL11.glPopAttrib();
	GL11.glPopMatrix();		
}

/**
 * @return the texture
 */
public ResourceLocation getBlockTexture() {
	return blockTexture;
}

/**
 * @return the texture
 */
public ResourceLocation getOreTexture() {
	return oreTexture;
}

/**
 * @param texture the texture to set
 */
public void setBlockTexture(ResourceLocation texture) {
	this.blockTexture = texture;
}

public synchronized void setOreTexture(ResourceLocation oreTexture) {
	this.oreTexture = oreTexture;
}

}

Posted

Its because you aren't using smooth lighting code.  You're using the fast lighting code (if you turn off smooth lighting in the options I'll bet you can't tell the difference).

 

And heads up: smooth lighting code is a bitch.  I gave up on it when I was doing whateverthehell it was that I was doing that was similar.

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

Totally right! I turned off smooth lighting and everything looked the way I expected.  I guess I'll just go with it as is, as this is only a minor mod and I don't want to dump that much time into it.  Though smooth lighting would've been nice.

Posted

Hi

 

You could perhaps consider using an ordinary block for the base texture, with smooth lighting, and using your TESR just to draw the overlay using the block brightness (like you're doing now).  The Beacon does this, for example.

That way vanilla will do all the hard work for you on the stone texture.  Your TESR won't have smooth lighting but because it's not continuous like the background is, you probably won't be able to tell the difference.

 

-TGG

Posted

I understand the gist of what your suggesting, but I'm not sure how I would accomplish this. (I'm not in a place where I can test it at the moment).  Will my block render itself in the world before my TESR executes()? ie. if i used an empty render() method the TESR would I see the plain block?

 

Or are you suggesting I somehow use the code the renderBlockBeacon() method in the RenderBlocks class? All of it's code is reliant on other methods with RenderBlocks which I'd have to copy or extend.

Posted
You could perhaps consider using an ordinary block for the base texture, with smooth lighting, and using your TESR just to draw the overlay using the block brightness (like you're doing now).  The Beacon does this, for example.

That way vanilla will do all the hard work for you on the stone texture.  Your TESR won't have smooth lighting but because it's not continuous like the background is, you probably won't be able to tell the difference.

-TGG

Ok, I did as you suggested. Make the block render as a normal block and had the TESR render only the overlay with brightness.

It works somewhat... The block renders, but the overlay flickers like crazy unless you stare at one position and not all the overlays are rendered in their entirety.

 

Ex.

1d056de4cb.png

74210350a6.png

b5a16497cb.png

Posted

Thats called Z-fighting (i think)

 

Yup, Z-fighting.  And by "slightly" an offset of 0.01 is usually enough.

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

Indeed, Z-fighting was the culprit.  It all works swimmingly now.  Thanks to all for helping me walk through this.

 

The overlay ore texture on top of the default/resourcepack block texture looks much better than my static ore block.  It can blend in with whatever resourcepack so much easier now.

 

Thanks again!

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.