gottsch Posted January 7, 2015 Posted January 7, 2015 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. (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. Quote
TheGreyGhost Posted January 8, 2015 Posted January 8, 2015 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 Quote
gottsch Posted January 8, 2015 Author Posted January 8, 2015 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 Quote
Draco18s Posted January 8, 2015 Posted January 8, 2015 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 Quote 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.
gottsch Posted January 8, 2015 Author Posted January 8, 2015 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. Quote
gottsch Posted January 8, 2015 Author Posted January 8, 2015 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. 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; } } Quote
Draco18s Posted January 8, 2015 Posted January 8, 2015 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. Quote 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.
gottsch Posted January 8, 2015 Author Posted January 8, 2015 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. Quote
TheGreyGhost Posted January 8, 2015 Posted January 8, 2015 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 Quote
gottsch Posted January 9, 2015 Author Posted January 9, 2015 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. Quote
brandon3055 Posted January 9, 2015 Posted January 9, 2015 He is saying render your block as you would any standard block that dosnt use a tesr then just use the tesr to draw the overlay Quote I am the author of Draconic Evolution
gottsch Posted January 9, 2015 Author Posted January 9, 2015 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. Quote
brandon3055 Posted January 9, 2015 Posted January 9, 2015 Thats called Z-fighting (i think) caused when you have two rendered layers in the exact same space. To fix it move your overlay out from the block by a VERY small amount. Not enough to be noticed but enough to stop the Z-fighting. Edit: http://en.wikipedia.org/wiki/Z-fighting Quote I am the author of Draconic Evolution
Draco18s Posted January 9, 2015 Posted January 9, 2015 Thats called Z-fighting (i think) Yup, Z-fighting. And by "slightly" an offset of 0.01 is usually enough. Quote 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.
gottsch Posted January 9, 2015 Author Posted January 9, 2015 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! Quote
Recommended Posts
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.