Jump to content

[1.10.2] Play texture animation on multiple blocks independent from each other


XFactHD

Recommended Posts

I have a block that can be activated by right clicking an item bound to the block. Once the block is activated, it should play an animated texture and then explode. The length of the animation is equal to the length of a timer in the block's tile entity. The problem is that multiple blocks activated at different points in time play the exact same texture frames at the same time and the animation starts at a random frame because the TextureAtlasSprite of the animation is ticked in the background all the time. Is there a way to get the animation to start on activation of the block and to get the animation to be independent between multiple blocks without using a TESR or swapping the block model every tick? If needed, I will provide the model, the block class and the tile entity class when I am back at my computer.

Link to comment
Share on other sites

  • 2 weeks later...

I finally found time to try this.

This is the code I tried:

package XFactHD.rssmc.client.renderer.tesr;

import XFactHD.rssmc.common.blocks.gadget.BlockThermiteCharge;
import XFactHD.rssmc.common.blocks.gadget.TileEntityThermiteCharge;
import XFactHD.rssmc.common.utils.helper.LogHelper;
import XFactHD.rssmc.common.utils.helper.PropertyHolder;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.VertexBuffer;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import org.lwjgl.opengl.GL11;

public class TESRThermiteCharge extends TileEntitySpecialRenderer<TileEntityThermiteCharge>
{
    @Override
    public void renderTileEntityAt(TileEntityThermiteCharge te, double x, double y, double z, float partialTicks, int destroyStage)
    {
        if (te.hasWorldObj() && te.getWorld().getBlockState(te.getPos()).getBlock() instanceof BlockThermiteCharge && te.isActive())
        {
            GlStateManager.pushMatrix();

            BlockPos pos = te.getPos();
            //LogHelper.info("X=" + x + ", Y=" + y + ", Z=" + z + " | PosX=" + pos.getX() + ", PosY=" + pos.getY() + ", PosZ=" + pos.getZ());

            EnumFacing facing = te.getWorld().getBlockState(te.getPos()).getValue(PropertyHolder.FACING_NOT_UP);
            double posX = pos.getX() + (facing == EnumFacing.EAST ? -(1F / 16F) : facing == EnumFacing.WEST ? 1F / 16F : 0);
            double posY = pos.getY() + (facing == EnumFacing.DOWN ? 1F / 16F : 0);
            double posZ = pos.getZ() + (facing == EnumFacing.NORTH ? -(1F / 16F) : facing == EnumFacing.SOUTH ? 1F / 16F : 0);

            int index = 105 - te.getTime();
            TextureAtlasSprite sprite = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite("rssmc:blocks/block_thermite_charge_burning/block_thermite_charge_burning_" + index);

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

            Tessellator tess = Tessellator.getInstance();
            VertexBuffer buffer = tess.getBuffer();
            buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
            buffer.pos(posX, posY, posZ).tex(sprite.getInterpolatedU(16), sprite.getInterpolatedV(16)).endVertex();
            buffer.pos(posX, posY, posZ).tex(sprite.getInterpolatedU(16), sprite.getInterpolatedV( 0)).endVertex();
            buffer.pos(posX, posY, posZ).tex(sprite.getInterpolatedU( 0), sprite.getInterpolatedV( 0)).endVertex();
            buffer.pos(posX, posY, posZ).tex(sprite.getInterpolatedU( 0), sprite.getInterpolatedV(16)).endVertex();
            tess.draw();

            GlStateManager.popMatrix();
        }
    }
}

As far as I can see, it doesn't render. The currently commented LogHelper call indicates that the renderer is called and the code inside the if statement is active when it is needed. The textures do also exist and are loaded in the TextureStitchEvent.Pre event.

Link to comment
Share on other sites

Why can I not use TASs when I use 105 independent textures as seen in this line:

TextureAtlasSprite sprite = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite("rssmc:blocks/block_thermite_charge_burning/block_thermite_charge_burning_" + index);

 

After adding

bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE);

it still does not render.

 

This code is from another one of my mods and it works flawlessly while doing almost the same thing:

package XFactHD.advtech.client.render;

import XFactHD.advtech.client.utils.ClientUtils;
import XFactHD.advtech.common.blocks.storage.TileEntityFluidTank;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.VertexBuffer;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraftforge.fluids.FluidStack;
import org.lwjgl.opengl.GL11;

public class RenderTileFluidTank extends TileEntitySpecialRenderer<TileEntityFluidTank>
{
    @Override
    public void renderTileEntityAt(TileEntityFluidTank te, double x, double y, double z, float partialTicks, int destroyStage)
    {
        GlStateManager.pushMatrix();
        int capacity = te.getFluidHandler().getCapacity();
        FluidStack fluid = te.getFluidHandler().getFluid();
        if (fluid != null)
        {
            Tessellator tess = Tessellator.getInstance();
            VertexBuffer buffer = tess.getBuffer();

            buffer.setTranslation(x, y, z);

            bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE);
            TextureAtlasSprite still = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(fluid.getFluid().getStill().toString());
            TextureAtlasSprite flow =  Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(fluid.getFluid().getFlowing().toString());

            double posY = .1 + (.8 * ((float) fluid.amount / (float) capacity));
            double topV = 15 - (14 * (.8 * ((float) fluid.amount / (float) capacity)));
            float[] color = ClientUtils.getRGBAFloatArrayFromHexColor(fluid.getFluid().getColor(fluid));

            RenderHelper.disableStandardItemLighting();

            buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR);
            buffer.pos( 4F/16F, posY, 12F/16F).tex(still.getInterpolatedU( 4), still.getInterpolatedV( 4)).color(color[0], color[1], color[2], color[3]).endVertex();
            buffer.pos(12F/16F, posY, 12F/16F).tex(still.getInterpolatedU(12), still.getInterpolatedV( 4)).color(color[0], color[1], color[2], color[3]).endVertex();
            buffer.pos(12F/16F, posY,  4F/16F).tex(still.getInterpolatedU(12), still.getInterpolatedV(12)).color(color[0], color[1], color[2], color[3]).endVertex();
            buffer.pos( 4F/16F, posY,  4F/16F).tex(still.getInterpolatedU( 4), still.getInterpolatedV(12)).color(color[0], color[1], color[2], color[3]).endVertex();
            tess.draw();

            buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR);
            buffer.pos(12F/16F, 1/16F, 12F/16F).tex(flow.getInterpolatedU(12), flow.getInterpolatedV(  15)).color(color[0], color[1], color[2], color[3]).endVertex();
            buffer.pos(12F/16F,  posY, 12F/16F).tex(flow.getInterpolatedU(12), flow.getInterpolatedV(topV)).color(color[0], color[1], color[2], color[3]).endVertex();
            buffer.pos( 4F/16F,  posY, 12F/16F).tex(flow.getInterpolatedU( 4), flow.getInterpolatedV(topV)).color(color[0], color[1], color[2], color[3]).endVertex();
            buffer.pos( 4F/16F, 1/16F, 12F/16F).tex(flow.getInterpolatedU( 4), flow.getInterpolatedV(  15)).color(color[0], color[1], color[2], color[3]).endVertex();
            tess.draw();

            buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR);
            buffer.pos( 4F/16F, 1/16F, 4F/16F).tex(flow.getInterpolatedU(12), flow.getInterpolatedV(  15)).color(color[0], color[1], color[2], color[3]).endVertex();
            buffer.pos( 4F/16F,  posY, 4F/16F).tex(flow.getInterpolatedU(12), flow.getInterpolatedV(topV)).color(color[0], color[1], color[2], color[3]).endVertex();
            buffer.pos(12F/16F,  posY, 4F/16F).tex(flow.getInterpolatedU( 4), flow.getInterpolatedV(topV)).color(color[0], color[1], color[2], color[3]).endVertex();
            buffer.pos(12F/16F, 1/16F, 4F/16F).tex(flow.getInterpolatedU( 4), flow.getInterpolatedV(  15)).color(color[0], color[1], color[2], color[3]).endVertex();
            tess.draw();

            buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR);
            buffer.pos(12F/16F, 1/16F,  4F/16F).tex(flow.getInterpolatedU(12), flow.getInterpolatedV(  15)).color(color[0], color[1], color[2], color[3]).endVertex();
            buffer.pos(12F/16F,  posY,  4F/16F).tex(flow.getInterpolatedU(12), flow.getInterpolatedV(topV)).color(color[0], color[1], color[2], color[3]).endVertex();
            buffer.pos(12F/16F,  posY, 12F/16F).tex(flow.getInterpolatedU( 4), flow.getInterpolatedV(topV)).color(color[0], color[1], color[2], color[3]).endVertex();
            buffer.pos(12F/16F, 1/16F, 12F/16F).tex(flow.getInterpolatedU( 4), flow.getInterpolatedV(  15)).color(color[0], color[1], color[2], color[3]).endVertex();
            tess.draw();

            buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR);
            buffer.pos(4F/16F, 1/16F, 12F/16F).tex(flow.getInterpolatedU(12), flow.getInterpolatedV(  15)).color(color[0], color[1], color[2], color[3]).endVertex();
            buffer.pos(4F/16F,  posY, 12F/16F).tex(flow.getInterpolatedU(12), flow.getInterpolatedV(topV)).color(color[0], color[1], color[2], color[3]).endVertex();
            buffer.pos(4F/16F,  posY,  4F/16F).tex(flow.getInterpolatedU( 4), flow.getInterpolatedV(topV)).color(color[0], color[1], color[2], color[3]).endVertex();
            buffer.pos(4F/16F, 1/16F,  4F/16F).tex(flow.getInterpolatedU( 4), flow.getInterpolatedV(  15)).color(color[0], color[1], color[2], color[3]).endVertex();
            tess.draw();

            RenderHelper.enableStandardItemLighting();

            buffer.setTranslation(0, 0, 0);
        }
        GlStateManager.popMatrix();
    }
}

 

Edited by XFactHD
Link to comment
Share on other sites

I got it to work now. For some reason using the coordinates given by renderTileEntityAt in VertexBuffer#pos() doesn't do the same thing as using them in VertexBuffer#setTranslation and only putting small offsets into VertexBuffer#pos().

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.