Jump to content

Render rotating block models as entity


Jay Avery

Recommended Posts

I want to make an entity/tileentity (haven't decided yet) which will look similar to a structure made of blocks. I looked at RenderFallingBlock for ideas and found that it uses BlockModelRenderer#renderModel, passing BlockRendererDispatcher#getModelForState. This looks like what I want, but when I tried it I found limitations - it only renders properly when it's not rotated. When I tried adding a GlStateManager.rotate call before rendering it, the model just goes invisible (with no error messages that I could see). I tried looking through the rendering code to see if I could find the reason, but I don't really understand it.

 

It must be theoretically possible to render a block model at an angle to the world axes, right? Because it's possible to define a model with components which are rotated, so the principle is surely similar. But is there a way to do this in code using the block's IBakedModel itself? Otherwise I'll be stuck trying to manually recreate the block model in the form of a ModelBase and render it that way, which would suck. Can anyone help me understand why the block model disappears when rotated, or suggest an alternative way that I can render a rotated block model?

Link to comment
Share on other sites

Another mystery now. I've got a very basic TESR working - at the moment it just renders one block rotated at 45 degrees. But when I walk around the block, it seems to slide up and down along its axis - here is a gif showing what I mean:

giphy.gif

 

My render method:

    @Override
    public void renderTileEntityAt(TETrunk te, double x, double y,
            double z, float ticks, int damage) {

            GlStateManager.pushMatrix();
            GlStateManager.disableLighting();
            BlockPos pos = te.getPos();
            GlStateManager.rotate(45, 1, 0, 0);
            GlStateManager.translate(x - pos.getX(), y - pos.getY(), z - pos.getZ());
            Tessellator tess = Tessellator.getInstance();
            VertexBuffer vb = tess.getBuffer();
            vb.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
            BlockRendererDispatcher dispatcher = Minecraft.getMinecraft().getBlockRendererDispatcher();
            dispatcher.renderBlock(Blocks.STONE.getDefaultState(), pos, te.getWorld(), vb);
            tess.draw();
            GlStateManager.enableLighting();
            GlStateManager.popMatrix();
    }

 

Link to comment
Share on other sites

As this is a TESR simply translate by x,y and z given to you in the method parameters, they are your position in view-space anyway, you don't need to translate by negative position of your TE in the world. I'll test it a bit more right now and tell you if everything is indeed correct.

 

EDIT: Okay, this took a bit longer than I expected. The problem lies in the way BlockModelRenderer applies transformations relative to the position you give to it, so you have to offset by negative position of your TE to account for that but then you can't rotate properly because the translations are messed up relative to view-space. This took a bit of time to figure. I managed to make it work via a simple "hack" of separating my translations into 2 passes:

First I translate by viewspace xyz(the arguments passed)

Then I rotate

Then I translate again by negative position of my TE to account for BlockModelRenderer's translations.

And then it works. Mostly.

Here is the code I came up with:

 

BlockPos blockpos = te.getPos();
IBlockState iblockstate = Blocks.STONE.getDefaultState();
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder bufferbuilder = tessellator.getBuffer();
BlockRendererDispatcher blockrendererdispatcher = Minecraft.getMinecraft().getBlockRendererDispatcher();
GlStateManager.pushMatrix();
GlStateManager.disableLighting();
this.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE);
bufferbuilder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
GlStateManager.translate(x, y, z);
GlStateManager.rotate(45, 1, 0 , 0);
GlStateManager.translate(-blockpos.getX(), -blockpos.getY(), -blockpos.getZ());
blockrendererdispatcher.getBlockModelRenderer().renderModel(te.getWorld(), blockrendererdispatcher.getModelForState(iblockstate), iblockstate, blockpos, bufferbuilder, false, MathHelper.getPositionRandom(te.getPos()));
tessellator.draw();
GlStateManager.enableLighting();
GlStateManager.popMatrix();

 

Edited by V0idWa1k3r
  • Like 1
Link to comment
Share on other sites

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.