Jump to content

Knockoff Powder Snow Overlay


Syric

Recommended Posts

I'd like to add a custom overlay and fog while the player is inside a particular block, just like powder snow. I have found ForgeIngameGui but do not know how to use it. How should I do so? As for the fog, I have located FogType and FogRenderer, but I'm not sure what the safest way to hijack their processes would be.

In general I'm much less confident interfering in existing systems than making my own, so more basic-level advice would be appreciated. I'd also be happy with links to tutorials elsewhere if necessary.

Link to comment
Share on other sites

7 hours ago, diesieben07 said:

The FogType is determined by Camera#getFluidInCamera. However this is hardcoded to the possible fogs in vanilla. Here is how you can modify the places where it is used:

  • The "clearColor" for the render system. You can see the process for this in FogRenderer#setupColor. EntityViewRenderEvent.FogColors allows you to hook into this process.
  • FogRenderer#setupFog sets the OpenGL fog. You can use EntityViewRenderEvent.RenderFogEvent to hook into this process.
  • GameRenderer#getFov sets the FOV. You can use EntityViewRenderEvent.FieldOfView to hook into this process.
  • LevelRenderer#renderSky renders some additional fog I think. There is no way to hook into this.

So if I'm understanding hooking and events correctly, I set up listeners for RenderFogEvent and FogColors, and on those events I check if the camera is inside my block and if so set fog up with setupFog and setupColor. I think I can do that.

Do you have advice for rendering the overlay?

Thanks for the help!

Link to comment
Share on other sites

59 minutes ago, Syric said:

Do you have advice for rendering the overlay?

you should use an implementation of IIngameOverlay and use one of the register methods of OverlayRegistry to register your IIngameOverlay implementation

you can also take a look at ForgeIngameGui, Forge renders all vanilla Overlays there

Link to comment
Share on other sites

19 minutes ago, Luis_ST said:

you can also take a look at ForgeIngameGui, Forge renders all vanilla Overlays there

As I said above, I have found this but I'm not sure how to use it.

Once I've registered my overlay, how do I render it? I don't know how to insert something into ForgeIngameGui's process like that.

Link to comment
Share on other sites

7 minutes ago, Luis_ST said:
59 minutes ago, Luis_ST said:

Forge renders all vanilla Overlays there

Yes, thank you, I did in fact read your post. I would not be asking follow-up questions if that alone was sufficient for me to understand. Would you mind elaborating, please? Can I just make my own renderer that runs parallel to ForgeIngameGui? Do I have to insert my process into IngameGui somehow?

Edited by Syric
Link to comment
Share on other sites

create a new class implements IIngameOverlay, inside #render you can render the texture
for that you can use the code from Gui#renderTextureOverlay
then you need to register your IIngameOverlay implementation via one of the register methods of OverlayRegistry

  • Thanks 1
Link to comment
Share on other sites

12 hours ago, diesieben07 said:

The FogType is determined by Camera#getFluidInCamera. However this is hardcoded to the possible fogs in vanilla. Here is how you can modify the places where it is used:

  • The "clearColor" for the render system. You can see the process for this in FogRenderer#setupColor. EntityViewRenderEvent.FogColors allows you to hook into this process.
  • FogRenderer#setupFog sets the OpenGL fog. You can use EntityViewRenderEvent.RenderFogEvent to hook into this process.
  • GameRenderer#getFov sets the FOV. You can use EntityViewRenderEvent.FieldOfView to hook into this process.
  • LevelRenderer#renderSky renders some additional fog I think. There is no way to hook into this.

Thank you for this! I can successfully set the fog's color. However, it's rendering as normal fog in the distance, rather than very close by like in powder snow. I believe this is because my attempts to change the fog's distance aren't working: the comments on EntityViewRenderEvent say that the event needs to be cancelled for changes to take effect, and I'm not sure how to handle that.

My current method is to cancel the event, change the distance while it's cancelled, and then uncancel it. This isn't working, even though the print statement says the distance has been updated.

public static void renderFog(final EntityViewRenderEvent.RenderFogEvent event)
    {
        if (event.getCamera().getBlockAtCamera().getBlock().equals(alchemineBlocks.VITA_SLIME.get())) {
            if (event.isCancelable()) {
                event.setCanceled(true);
                event.setFarPlaneDistance(2.0F);
                event.setNearPlaneDistance(0.0F);
                event.setCanceled(false);
//                System.out.println("Fog Far Plane Distance: " + event.getFarPlaneDistance());
            }
//            System.out.println("Fog Type: " + event.getMode().toString());
        }
    }

Do I instead have to cancel the event, copy it into a new event, and then post that to the bus somehow? How would I do that?

Link to comment
Share on other sites

4 hours ago, Luis_ST said:

create a new class implements IIngameOverlay, inside #render you can render the texture
for that you can use the code from Gui#renderTextureOverlay
then you need to register your IIngameOverlay implementation via one of the register methods of OverlayRegistry

I can make a new class that implements IIngameOverlay and override #render just fine. However, I can't register it unless my render method is static, in which case it can't override IIngameOverlay anymore.

Also, where would I put the code that dictates when the overlay is rendered?

The class:

public class VitaSlimeOverlay implements IIngameOverlay {
    protected static final ResourceLocation VITA_SLIME_LOCATION = new ResourceLocation("alchemine:textures/misc/vita_slime_outline.png");
    protected static final Float opacity = 0.9F;

    public void render(ForgeIngameGui gui, PoseStack poseStack, float partialTick, int width, int height) {
        RenderSystem.disableDepthTest();
        RenderSystem.depthMask(false);
        RenderSystem.defaultBlendFunc();
        RenderSystem.setShader(GameRenderer::getPositionTexShader);
        RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, opacity);
        RenderSystem.setShaderTexture(0, VITA_SLIME_LOCATION);
        Tesselator tesselator = Tesselator.getInstance();
        BufferBuilder bufferbuilder = tesselator.getBuilder();
        bufferbuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX);
        bufferbuilder.vertex(0.0D, (double) height, -90.0D).uv(0.0F, 1.0F).endVertex();
        bufferbuilder.vertex((double) width, (double) height, -90.0D).uv(1.0F, 1.0F).endVertex();
        bufferbuilder.vertex((double) width, 0.0D, -90.0D).uv(1.0F, 0.0F).endVertex();
        bufferbuilder.vertex(0.0D, 0.0D, -90.0D).uv(0.0F, 0.0F).endVertex();
        tesselator.end();
        RenderSystem.depthMask(true);
        RenderSystem.enableDepthTest();
        RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
    }

}

The registration:

    // You can use EventBusSubscriber to automatically register all static methods in the class annotated with @SubscribeEvent
    @Mod.EventBusSubscriber(modid = MODID, bus = Mod.EventBusSubscriber.Bus.MOD)
    public static class ClientModEvents
    {
        @SubscribeEvent
        public static void onClientSetup(FMLClientSetupEvent event)
        {
            // Some client setup code
            LOGGER.info("HELLO FROM CLIENT SETUP");
            LOGGER.info("MINECRAFT NAME >> {}", Minecraft.getInstance().getUser().getName());

            ...

            OverlayRegistry.registerOverlayTop("vita_slime_overlay", (gui, poseStack, partialTick, screenWidth, screenHeight) -> {
                gui.setupOverlayRenderState(true, false);
                VitaSlimeOverlay.render(gui, poseStack, partialTick, screenWidth, screenHeight);
            });

        }
    }

The issue is that with this setup, the non-static method VitaSlimeOverlay.render can't be called in the registration code's static context.

Link to comment
Share on other sites

5 hours ago, Luis_ST said:

just create a new instance of your VitaSlimeOverlay, and pass it as parameter of OverlayRegistry.registerOverlayTop

Thanks! That still doesn't solve my static-context problem for registering it, though.

Link to comment
Share on other sites

3 hours ago, Luis_ST said:

why? if you pass in OverlayRegistry.registerOverlayTop a instance of VitaSlimeOverlay this should work fine

Looks like I was registering incorrectly! (Your advice does make it render all the time, but I fixed that by using OverlayRegistry.enableOverlay() in the RenderFogEvent.) My overlays are now working perfectly, thanks so much!

 

Do you know how I can resolve the fog issue? I'm trying to modify a RenderFogEvent's near and far planes, but it isn't working. The documentation says I need to cancel the event for those modifications to take effect. How can I cancel that event without just deleting the fog entirely?

Link to comment
Share on other sites

8 hours ago, diesieben07 said:

You are not cancelling the event... You are cancelling it and then undoing the cancellation.

So I use setCanceled(true), then I modify it, then I use setCanceled(false)?

Or do I modify it, then use setCanceled(true) and setCanceled(false) in succession?

Neither of those worked during my initial round of testing, so I'll go back and try them again, see if I had an error in implementation somewhere.

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.



×
×
  • Create New...

Important Information

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