Jump to content

Recommended Posts

Posted

Hi!

 

I want to rotate the textures of some block faces based of the orientation of the block. The problem is, I don't want to setup a texture for every possible state, that would be too much :D

 

I know I can achieve this with using an ISimpleBlockRenderingHandler and registering it with my custom block.

 

But I can't really figure out how to properly write the

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

method in my custom rendering class.

 

More details of what I want to achieve:

The TileEntity can already face in any of the six minecraft directions. Based on its orientation the textures that are not "front" and "back" have to be

rotated properly because of their visuals.

 

I searched a bit here and there but I did not find a source I could work with. Maybe I did not understand something the right way. The problem is, I don't really know

how to setup the renderWorldBlock method. Only thing that I think I am knowing is that I have to use the "uveRotate*" methods of the RenderBlocks class..

 

Regards,

 

Jhary

Posted

That could work. Not really sure what that is though.

 

This question is making me think tessellator. With it you can render a basic cube and depending on the state, start at different points and draw the same texture. Viola, textures rotated. But yeah... That could be inefficient.

We all stuff up sometimes... But I seem to be at the bottom of that pot.

Posted

Hmm ok I can't really wrap my head around this tessellator stuff, but it seems to be exactly what I need.

Sadly I can't find a good example of someone using this with 1.7.

I understand how to first setup the tessellator and that I have to do for each side of a block 4 times the "addVertexWithUV(x, y, z, u, v)" method.

 

But I don't really understand how to setup the parameters.

Lets say my block has the in world coordinates [10 ; 10 ; 10].

 

How would I setup the first four addVertexWithUV calls, lets say for the south side?

 

In this article (http://greyminecraftcoder.blogspot.com.au/2013/08/the-tessellator.html) there are four points  defined as A, B, C and D

 

I would understand this as follows according to the picture in the article :

A: .addVertexWithUV(11, 10, 10, u, v)

B: .addVertexWithUV(11, 11, 10, u, v)

C: .addVertexWithUV(10, 11, 10, u, v)

D: .addVertexWithUV(10, 10, 10, u, v)

 

Would here x, y, z be correct? And if yes, how would I now find out what I have to use for u and v ?

 

Posted

Hi

 

If you are doing the z = 10 positive face (south), then yes that's right, except that in an IBSRH it has already translated the coordinates for you, so you should draw between [0,0,0] and [1,1,1] instead, i.e.

A: .addVertexWithUV(1, 0, 0, u, v)

B: .addVertexWithUV(1, 1, 0, u, v)

etc

regarding u,v: if you have bound the texture yourself and the face is the whole texture, then your u,v coordinates are 0 -> 1 with the v axis pointing in the opposite direction to y, so in your case

A: .addVertexWithUV(1, 0, 0, 1, 1)

B: .addVertexWithUV(1, 1, 0, 1, 0)

etc

 

If each of your faces is an icon (the usual way to do it),  use

icon.getMinU(), icon.getMaxU(), icon.getMinV(), icon.getMaxV()

 

-TGG

Posted

ok I got it now working that it renders correctly. Here is my method so far:

 

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

    	Tessellator tessellator = Tessellator.instance;

    	IIcon up = block.getIcon(world, x, y, z, 1);
    	IIcon down = block.getIcon(world, x, y, z, 0);
    	IIcon north = block.getIcon(world, x, y, z, 2);
    	IIcon south = block.getIcon(world, x, y, z, 3);
    	IIcon west = block.getIcon(world, x, y, z, 4);
    	IIcon east = block.getIcon(world, x, y, z, 5);
    	
    	//Down 0
    	tessellator.addVertexWithUV(x+1, y  , z  , (double)down.getMaxU(), (double)down.getMaxV());
    	tessellator.addVertexWithUV(x+1, y  , z+1, (double)down.getMaxU(), (double)down.getMinV());
    	tessellator.addVertexWithUV(x  , y  , z+1, (double)down.getMinU(), (double)down.getMinV());
    	tessellator.addVertexWithUV(x  , y  , z  , (double)down.getMinU(), (double)down.getMaxV());
    	
    	//Up 1
    	tessellator.addVertexWithUV(x+1, y+1, z+1, (double)up.getMaxU(), (double)up.getMaxV());
    	tessellator.addVertexWithUV(x+1, y+1, z  , (double)up.getMaxU(), (double)up.getMinV());
    	tessellator.addVertexWithUV(x  , y+1, z  , (double)up.getMinU(), (double)up.getMinV());
    	tessellator.addVertexWithUV(x  , y+1, z+1, (double)up.getMinU(), (double)up.getMaxV());
    	
    	//North 2
    	tessellator.addVertexWithUV(x  , y  , z  , (double)north.getMaxU(), (double)north.getMaxV());
    	tessellator.addVertexWithUV(x  , y+1, z  , (double)north.getMaxU(), (double)north.getMinV());
    	tessellator.addVertexWithUV(x+1, y+1, z  , (double)north.getMinU(), (double)north.getMinV());
    	tessellator.addVertexWithUV(x+1, y  , z  , (double)north.getMinU(), (double)north.getMaxV());
    	
    	//South 3
    	tessellator.addVertexWithUV(x+1, y  , z+1, (double)south.getMaxU(), (double)south.getMaxV());
    	tessellator.addVertexWithUV(x+1, y+1, z+1, (double)south.getMaxU(), (double)south.getMinV());
    	tessellator.addVertexWithUV(x  , y+1, z+1, (double)south.getMinU(), (double)south.getMinV());
    	tessellator.addVertexWithUV(x  , y  , z+1, (double)south.getMinU(), (double)south.getMaxV());
    	
    	//West 4
    	tessellator.addVertexWithUV(x  , y  , z+1, (double)west.getMaxU(), (double)west.getMaxV());
    	tessellator.addVertexWithUV(x  , y+1, z+1, (double)west.getMaxU(), (double)west.getMinV());
    	tessellator.addVertexWithUV(x  , y+1, z  , (double)west.getMinU(), (double)west.getMinV());
    	tessellator.addVertexWithUV(x  , y  , z  , (double)west.getMinU(), (double)west.getMaxV());
    	
    	//East 5
    	tessellator.addVertexWithUV(x+1, y  , z  , (double)east.getMaxU(), (double)east.getMaxV());
    	tessellator.addVertexWithUV(x+1, y+1, z  , (double)east.getMaxU(), (double)east.getMinV());
    	tessellator.addVertexWithUV(x+1, y+1, z+1, (double)east.getMinU(), (double)east.getMinV());
    	tessellator.addVertexWithUV(x+1, y  , z+1, (double)east.getMinU(), (double)east.getMaxV());
    	       
        return true;
    }

 

It does not rotate the textures at this point. But it seems to work so far, but with one problem. Depending on different angles when moving around the block,

the textures seem to flicker some times between just a black pane and the expected texture... does anyone know why?

 

Next question would be, where in this method do I have to do the rotation with the renderer.uvRotate* thingy?

 

Edit: the "flickering" does occur on all placed blocks at the same time when looking at them from some angles

Posted

Hi

 

The black is probably because you haven't set up the lighting and brightness, so it is using the settings from the last thing it rendered.

 

This is typically done using something like

            tessellator.setBrightness(par1Block.getMixedBrightnessForBlock(this.blockAccess, wx, wy, wz); // wx,wy,wz = world coordinates
            tessellator.setColorOpaque_F(red, green, blue);  // from 0.0 - 1.0

 

If you want to rotate the faces using uvRotate, you need to call RenderBlocks.renderStandardBlock or  RenderBlocks.render after setting the flags.

 

See vanilla RenderBlocks.renderBlockLog for a good example.  The rotation is a bit strange, sometimes it flips the faces.  But if that doesn't bother you then you don't need the Tessellator at all.

 

-TGG

Posted

Ok finally had the time to give it a try and it works like a charm if I just don't use the tessellator and therefore use the RenderBlocks object.

 

Rotation is easily done and for the lighting is no additional setup neccessary.

 

I will post the code here if anyone else needs a reference :)

 

Thanks again!

 

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

    	IIcon up = block.getIcon(world, x, y, z, 1);
    	IIcon down = block.getIcon(world, x, y, z, 0);
    	IIcon north = block.getIcon(world, x, y, z, 2);
    	IIcon south = block.getIcon(world, x, y, z, 3);
    	IIcon west = block.getIcon(world, x, y, z, 4);
    	IIcon east = block.getIcon(world, x, y, z, 5);
    	
    	renderer.renderFaceXNeg(block, x, y, z, west);
    	renderer.renderFaceXPos(block, x, y, z, east);
    	renderer.renderFaceYNeg(block, x, y, z, down);
    	renderer.renderFaceYPos(block, x, y, z, up);
    	renderer.renderFaceZNeg(block, x, y, z, north);
    	renderer.renderFaceZPos(block, x, y, z, south);
    	
    	TileEntity tile = world.getTileEntity(x, y, z);
    	if(tile instanceof TileEntityMyTile){
    		//wonky rendering incoming
    		switch(((TileEntityMyTile)tile).orientation.ordinal()){
    			case 0: //Bottom
    				renderer.uvRotateNorth=2; //west
    				renderer.uvRotateSouth=1; //east
    				renderer.uvRotateWest=2; //south
    				renderer.uvRotateEast=1; //north
    				break;
    			case 1: //Top
    				renderer.uvRotateNorth=1;
    				renderer.uvRotateSouth=2;
    				renderer.uvRotateWest=1;
    				renderer.uvRotateEast=2;
    				break;				
    			case 2: //North
    				renderer.uvRotateTop = 1;
    				renderer.uvRotateBottom = 2;
    				
    				break;
    			case 3: //South
    				renderer.uvRotateTop=2;
    				renderer.uvRotateBottom=1;
    				renderer.uvRotateNorth=3; 
    				renderer.flipTexture=true; //east
    				break;
    			case 4: //West
    				renderer.uvRotateTop=4;
    				renderer.uvRotateBottom=4;
    				break;
    			case 5: //East
    				renderer.uvRotateTop=3;
    				renderer.uvRotateBottom=3;
    				renderer.flipTexture=true;
    				break;
    		}
    	}
    	
    	boolean flag = renderer.renderStandardBlock(block, x, y, z);
    	//important reset afterwards!
    	renderer.flipTexture=false; 
    	renderer.uvRotateNorth=0; //west
	renderer.uvRotateSouth=0; //east
	renderer.uvRotateWest=0; //south
	renderer.uvRotateEast=0; //north
	renderer.uvRotateTop=0;
	renderer.uvRotateBottom=0;
	return flag;
}

 

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.