Jump to content

[Solved] [1.7.10] Dynamically combine textures


Namikon

Recommended Posts

Hello,

 

I have this simple texture for my Block (which is not a TileEntity), that is going to be the interior Block of a MultiBlock structure.

What I want to achieve is, that the block changes its color and animation speed while the Multiblock is doing its job.

 

So I have said Texture (16x16) with transparent pixels, and I want to merge that with a couple of other textures (depending on the state of the controller block) for the animation, those are 16x320px pngs with different colors, and animation speeds.

 

Now, how can I combine these textures, so that the main texture is the top layer, and you can see the color change through the transparent pixels?

Sure, I could just copy&paste the transparent top layer to all colored animations, but the interior block is supposed to have connected textures,

so that would result in a massive amount of png files. Not the way I'd like to go.

 

I've been reading all day about Tessellator, ISBRH and that stuff, but all tutorials where either outdated, didn't work for me (No doubt i derped somewhere), or it was way to complicated for me to understand.

Can someone guide me here please? All this rendering stuff is to complicated for my brain somehow.  :-[

 

 

-Namikon

Link to comment
Share on other sites

Blocks can have multiple render layers.

These are also called rendering passes.

In your iicon register method, register icons for all layers.

Now, there's big good method getIICon with world, position and render layer parameters. Here you can check if your block is forming multiblock, and return textures based on rendering pass...

Note: you have to override some methods in order for multiple layers to work...

Link to comment
Share on other sites

Ok, so in my getIIcon method I already have around 20 textures being registered, for all possible combinations of the connected texture feature.

But I must be blind, to me it looks like neither the IIconRegister.registerIcon, nor the IIcon has has a function or property to define the Layer for the texture...?

Same for the Block class. There are a bunch of methods that relate to rendering, but for most of them (Those I let google search for) lead me to the ISBR thing.

Is that the way to go?

Link to comment
Share on other sites

Ok, so in my getIIcon method I already have around 20 textures being registered, for all possible combinations of the connected texture feature.

But I must be blind, to me it looks like neither the IIconRegister.registerIcon, nor the IIcon has has a function or property to define the Layer for the texture...?

Same for the Block class. There are a bunch of methods that relate to rendering, but for most of them (Those I let google search for) lead me to the ISBR thing.

Is that the way to go?

No.

First, there will be no registerIICon method with layer param, here you just register ALL your textures for ALL layers.

Second, here's excact methods that you have to use...

 

Actually, sorry, it is not possible in 1.7.10 without TESR or ISBR...

Altough, mutli layer rendering is possible with items (1.7.10&1.8) and with blocks in 1.8 without TESR or ISBR...

Link to comment
Share on other sites

Aha,  good. I thought I derped hard on this. Well, not a problem. Can you recommend some tutorials for TESR and ISBR? For this case, I'll need something for non tile entities, as only the controller block will be one. So I guess I need ISBR then..?

 

 

Ok, I got it to the point where I managed to have a custom renderer for my Block. (Found the "Diamond in ice" tutorial).

But now I have a problem, the Block does render in both pass 0 and 1, but the Texture that is rendered in pass 1, is always the one that is visible.

My idea was, to draw the background texture in pass 0, and the Texture with transparent pixels on top of that, in pass 1.

But the texture from pass 0 is overwritten with the one from pass 1; The transparent areas show the grass below it, it's completely replaced.

 

 

This is my (messy..) function to render the Block:

CoreBlock tBlock = (CoreBlock)block;

FMLLog.log(Level.INFO, "RenderPass: %d start", tProxy.renderPass);
if(tProxy.renderPass == 0)
{
IIcon tBackL = tBlock.getNormalIcon();
float u = tBackL.getMinU();
float v = tBackL.getMinV();
float U = tBackL.getMaxU();
float V = tBackL.getMaxV();

Tessellator tes = Tessellator.instance;
tes.addTranslation(x, y, z);

tes.addVertexWithUV(0, 1, 1, u, v);
tes.addVertexWithUV(1, 1, 1, u, V);
tes.addVertexWithUV(1, 1, 0, U, V);
tes.addVertexWithUV(0, 1, 0, U, v);

tes.addTranslation(-x, -y, -z);
FMLLog.log(Level.INFO, "RenderPass 0 done");
}
else                    
{
IIcon tTopL = tBlock.getAlpaIcon();
float u = tTopL.getMinU();
float v = tTopL.getMinV();
float U = tTopL.getMaxU();
float V = tTopL.getMaxV();

Tessellator tes = Tessellator.instance;
tes.addTranslation(x, y, z);

tes.addVertexWithUV(0, 1, 1, u, v);
tes.addVertexWithUV(1, 1, 1, u, V);
tes.addVertexWithUV(1, 1, 0, U, V);
tes.addVertexWithUV(0, 1, 0, U, v);

tes.addTranslation(-x, -y, -z);
FMLLog.log(Level.INFO, "RenderPass 1 done");
}

 

This is the actual result:

 

Also, I wonder if that will work with an animated texture. (The one i've tried is not).

The renderer is only called when I place/break something around it, I assume it needs to redraw the texture to

"animate" the background layer?

Link to comment
Share on other sites

Heh, it's always good when you find the solution yourself.

 

Ok, for anyone who is struggling with the same Problem, here is the solution: (Improvements are welcome!)

 

Goal:

A block that has an animated texture as background (That can be swapped dynamically; For example in a multiblock),

and a second texture on top of that, with transparent areas. (Good if you want to fade something in and out)

 

First, you should read this tutorial; It's working with 1.7.10 and explains a lot: http://www.minecraftforge.net/wiki/Multiple_Pass_Render_Blocks

Second, you don't need that "drawDiamond" function:

 

- Set the animated texture as default icon (getIIcon()) in your Block

- In your ISBRH Class, for Render pass 0, let Minecraft render the Block itself (And the animation!) with renderStandardBlockWithAmbientOcclusion

- Then, retrieve the texture with your alpha channel areas, and tell the renderer to draw every face of that Block again, but this time with your new texture.

- Done! There you have your animated block :)

 

 

This is the actual function i'm using now:

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

	ClientProxy tProxy = (ClientProxy)MyMod.proxy;

	CoreBlock tBlock = (CoreBlock)block;
	if(tProxy.renderPass == 0)
	{
		renderer.renderStandardBlockWithAmbientOcclusion(block, x, y, z, 1, 1, 1);

		IIcon ico = tBlock.getAlpaIcon();
		renderer.renderFaceXNeg(block, x, y, z, ico);
		renderer.renderFaceXPos(block, x, y, z, ico);

		renderer.renderFaceYNeg(block, x, y, z, ico);
		renderer.renderFaceYPos(block, x, y, z, ico);

		renderer.renderFaceZNeg(block, x, y, z, ico);
		renderer.renderFaceZPos(block, x, y, z, ico);
	}

	return false;
}

 

If it's a terrible way to do it, please tell me. But it seems to work fine :)

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



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Hi, I want to make a client-only mod, everything is ok, but when I use shaders, none of the textures rendered in RenderLevelStageEvent nor the crow entity model are rendered, I want them to be visible, because it's a horror themed mod Here is how i render the crow model in the CrowEntityRenderer<CrowEntity>, by the time i use this method, i know is not the right method but i don't think this is the cause of the problem, the renderType i'm using is entityCutout @Override public void render(CrowEntity p_entity, float entityYaw, float partialTick, PoseStack poseStack, MultiBufferSource bufferSource, int packedLight) { super.render(p_entity, entityYaw, partialTick, poseStack, bufferSource, packedLight); ClientEventHandler.getClient().crow.renderToBuffer(poseStack, bufferSource.getBuffer(ClientEventHandler.getClient().crow .renderType(TEXTURE)), packedLight, OverlayTexture.NO_OVERLAY, Utils.rgb(255, 255, 255)); } Here renderLevelStage @Override public void renderWorld(RenderLevelStageEvent e) { horrorEvents.draw(e); } Here is how i render every event public void draw(RenderLevelStageEvent e) { for (HorrorEvent event : currentHorrorEvents) { event.tick(e.getPartialTick()); event.draw(e); } } Here is how i render the crow model on the event @Override public void draw(RenderLevelStageEvent e) { if(e.getStage() == RenderLevelStageEvent.Stage.AFTER_ENTITIES) { float arcProgress = getArcProgress(0.25f); int alpha = (int) Mth.lerp(arcProgress, 0, 255); int packedLight = LevelRenderer.getLightColor(Minecraft.getInstance().level, blockPos); VertexConsumer builder = ClientEventHandler.bufferSource.getBuffer(crow); Crow<CreepyBirdHorrorEvent> model = ClientEventHandler .getClient().crow; model.setupAnim(this); RenderHelper.renderModelInWorld(model, position, offset, e.getCamera(), e.getPoseStack(), builder, packedLight, OverlayTexture.NO_OVERLAY, alpha); builder = ClientEventHandler.bufferSource.getBuffer(eyes); RenderHelper.renderModelInWorld(model, position, offset, e.getCamera(), e.getPoseStack(), builder, 15728880, OverlayTexture.NO_OVERLAY, alpha); } } How i render the model public static void renderModelInWorld(Model model, Vector3f pos, Vector3f offset, Camera camera, PoseStack matrix, VertexConsumer builder, int light, int overlay, int alpha) { matrix.pushPose(); Vec3 cameraPos = camera.getPosition(); double finalX = pos.x - cameraPos.x + offset.x; double finalY = pos.y - cameraPos.y + offset.y; double finalZ = pos.z - cameraPos.z + offset.z; matrix.pushPose(); matrix.translate(finalX, finalY, finalZ); matrix.mulPose(Axis.XP.rotationDegrees(180f)); model.renderToBuffer(matrix, builder, light, overlay, Utils .rgba(255, 255, 255, alpha)); matrix.popPose(); matrix.popPose(); } Thanks in advance
    • Here's the link: https://mclo.gs/7L5FibL Here's the link: https://mclo.gs/7L5FibL
    • Also the mod "Connector Extras" modifies Reach-entity-attributes and can cause fatal errors when combined with ValkrienSkies mod. Disable this mod and continue to use Syntra without it.
    • Hi everyone. I was trying modify the vanilla loot of the "short_grass" block, I would like it drops seeds and vegetal fiber (new item of my mod), but I don't found any guide or tutorial on internet. Somebody can help me?
    • On 1.20.1 use ValkrienSkies mod version 2.3.0 Beta 1. I had the same issues as you and it turns out the newer beta versions have tons of unresolved incompatibilities. If you change the version you will not be required to change the versions of eureka or any other additions unless prompted at startup. This will resolve Reach-entity-attributes error sound related error and cowardly errors.
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.