
SoLegendary
Members-
Posts
95 -
Joined
-
Last visited
Everything posted by SoLegendary
-
[1.18.2] How to use RenderTypes other than lines()
SoLegendary replied to SoLegendary's topic in Modder Support
Ok so if I understand correctly, a vertex is created using this line: vertexConsumer.vertex(matrix4f, x, y, z).color(r, g, b, a).normal(matrix3f, x, y, z).endVertex(); And for a square in my case I just copy with the appropriate coords 4 times. While I see that the .vertex() takes in-world coordinates, the .normal() seems to be just 1, 0 or -1. How does that work? In fact, while we're at it - is there any tutorial or docs you can provide that explain how all of the vertexConsumer functions are used? (namely uv, uv2, overlayCoords and normal) -
I have an existing function which draws a outline over an AABB (usually to highlight mobs or blocks): public static void drawLineBox(PoseStack matrixStack, AABB aabb, float r, float g, float b, float a) { Entity camEntity = MC.getCameraEntity(); double d0 = camEntity.getX(); double d1 = camEntity.getY() + camEntity.getEyeHeight(); double d2 = camEntity.getZ(); RenderSystem.depthMask(false); // disable showing lines through blocks VertexConsumer vertexConsumer = MC.renderBuffers().bufferSource().getBuffer(RenderType.lines()); matrixStack.pushPose(); matrixStack.translate(-d0, -d1, -d2); // because we start at 0,0,0 relative to camera LevelRenderer.renderLineBox(matrixStack, vertexConsumer, aabb, r, g, b, a); matrixStack.popPose(); } I want to adapt this code to draw solid overlays instead of just outlines. See this mockup as an example of what I mean: I've noticed that RenderType.lines() can actually be swapped out for a variety of other types, including notably .solid() and .translucent() which sound like the things that I want. However, when I replace .lines() in my above code with any other RenderType I get this error: java.lang.IllegalStateException: Not filled all elements of the vertex at TRANSFORMER/minecraft@1.18.2/com.mojang.blaze3d.vertex.BufferBuilder.endVertex(BufferBuilder.java:249) at TRANSFORMER/minecraft@1.18.2/net.minecraft.client.renderer.LevelRenderer.renderLineBox(LevelRenderer.java:2313) at TRANSFORMER/minecraft@1.18.2/net.minecraft.client.renderer.LevelRenderer.renderLineBox(LevelRenderer.java:2297) at TRANSFORMER/reignofnether@0.0NONE/com.solegendary.reignofnether.util.MyRenderer.drawLineBox(MyRenderer.java:59) Is there a guide anywhere for how to properly use these RenderTypes? I am also interested in how all of the others are used too as it could be a useful tool in the future.
-
[1.18] Rendering entity with modified vanilla shader
SoLegendary replied to Brunk's topic in Modder Support
I'm looking to do a very similar thing but for blocks instead of entities. Could you please share the code where you actually applied the coloured shading? Also, do you know an event similar to RenderLivingEvent but for blocks instead that I can use to apply this kind of shading? -
Sorry to resurrect this again, but I'm having issues specifically with IllagerModel, where for some reason setting the visibility of all the ModelParts except for the head and root does not result in the arms being made invisible: This is my code to set the visibility of all parts of a model except the head (so far only doing humanoids and hierarchicals, slowly extending to more mtypes): private void setNonHeadModelVisibility(Model model, boolean visibility) { if (model instanceof HumanoidModel) { ((HumanoidModel) model).hat.visible = visibility; ((HumanoidModel) model).body.visible = visibility; ((HumanoidModel) model).rightArm.visible = visibility; ((HumanoidModel) model).leftArm.visible = visibility; ((HumanoidModel) model).rightLeg.visible = visibility; ((HumanoidModel) model).leftLeg.visible = visibility; } else if (model instanceof HierarchicalModel) { ModelPart root = ((HierarchicalModel) model).root(); ModelPart head = root.getChild("head"); root.children.forEach((String name, ModelPart modelPart) -> { if (!modelPart.equals(head)) modelPart.visible = visibility; }); } } This code works so far for villagers, zombies, skeletons, creepers and spiders with no issue (and I'm sure many other mobs I've yet to check). Thanks again for all the help with this feature so far!
-
What's the correct type for the variable that stores the layers (for the restoring step)? I'm declaring it as: List<RenderLayer<? extends LivingEntity, ? extends EntityModel<? extends LivingEntity>>> hudSelectedLayers = null; I use the same type arguments for the LivingEntityRenderer itself and it seems to work fine, but not for the layers. But when I try to assign LivingEntityRenderer.layers to it I get this error: error: incompatible types: List<RenderLayer<CAP#1,CAP#2>> cannot be converted to List<RenderLayer<? extends Entity,? extends Model>> hudSelectedLayers = evt.getRenderer().layers; ^ where CAP#1,CAP#2 are fresh type-variables: CAP#1 extends LivingEntity from capture of ? extends LivingEntity CAP#2 extends EntityModel<CAP#1> from capture of ? extends Model
-
Creepers only have the following parts: public final ModelPart root; public final ModelPart head; public final ModelPart rightHindLeg; public final ModelPart leftHindLeg; public final ModelPart rightFrontLeg; public final ModelPart leftFrontLeg; Their torso section IS the root. This is what it looks like when I set everything except the head and root invisible:
-
Returning to this issue since I never actually solved it... Seems that once the root ModelPart of any HierarchicalModel is set invisible, all of its child parts also are made invisible. Since the root of Creepers and spiders are also theirs torsos, this means I can't set the torso invisible without also making the head invisible. Is there a way to separate the visibility of the root from its children? EDIT: I've upped to 1.18.2 since I originally posted this
-
Ok now I've realised that it is not the fact that the outlines are not being rendered at all, but instead in completely incorrect positions. For some reason, being in spectator mode causes the outlines to be draw up in the sky, in wildly different positions than expected. From what I understood posestacks, once pushed, modified and popped, can't (or at least shouldn't) affect subsequent rendering functions. However, this one seems to. The specific function that causes this to happen is entityrenderdispatcher.render() as if I comment it out this outine-in-the-sky bug doesn't happen, whether in spectator or creative. For the following comparison photos, I draw an outline around every entity in render distance and either enable or disable my renderEntityInInventory function (which draws the creeper at the top left of the screen): Spectator mode render-in-inventory enabled Spectator mode render-in-inventory disabled Creative mode render-in-inventory enabled Creative mode render-in-inventory disabled
-
Ok so finally found out this issue only seems to happen when I'm in spectator mode. Strangely, I can still render either the outlines or the entity on screen separately while in spectator, just never at the same time. Outside of spectator mode I can render whatever I want at the same time. Anyone know how I can resolve this? My mod relies on the player being in spectator mode most of the time.
-
Is there a way to conditionally apply shaders from code onto blocks? I saw this post doing something which could help me for entities Except it relies on the RenderLivingEvent event and I don't see any equivalent event for block rendering.
-
I want to have a fog-of-war feature that classic RTS games have by darkening blocks (separate to their in-world brightness) which are out of range of the player to varying degrees: No change for in range, Medium dark for out of range but previously explored, Very dark/black for out of range and unexplored An example of what I mean from Starcraft would be this: https://blog.gemserk.com/wp-content/uploads/2018/08/SCScrnShot_082518_153611-1024x768.png I want this darkening to apply to ALL blocks in view of the camera (I have a top-down camera in my mod so it's not that many blocks) so I need a solution that is relatively low-performance. My immediately thought of course is shaders and texture packs, except as far as I know those cannot be applied conditionally from code. I also don't want to mess with block world brightness so that light sources can still be seen properly in the fog of war. EDIT: just found this page on the community wiki: https://forge.gemwire.uk/wiki/Tinted_Textures. Would it be possible to manipulate these tint textures to apply the darkening I need (preferably without impacting any original tinting conditions like grass blocks changing colour in specific biomes)
-
I've got this function which is adapted from InventoryScreen.renderEntityInInventory which I'm using to render the model of entities on the screen: https://pastebin.com/2YHWqRW8 In the same class I'm running the code in this event: @SubscribeEvent public static void onRenderOverlay(RenderGameOverlayEvent.Post evt) { if (selectedUnit != null) drawEntityOnScreen(evt.getMatrixStack(), 20, 35, 13, -80, -20, (LivingEntity) selectedUnit, 1.0f); } The model is drawn correctly on screen. However, I also have this code which draws a white box outline around the selectedUnit entity: https://pastebin.com/sJedbRH8 Run in this event: @SubscribeEvent public static void onRenderWorld(RenderLevelLastEvent evt) { if (hudSelectedUnitClass != null) MyRenderer.drawEntityOutline(evt.getPoseStack(), hudSelectedUnitClass, 0.5f); } When my drawEntityOnScreen function is run and draws the model on screen, this outline stops being shown, despite the code still running. When I comment out the RenderSystem.runAsFancy snippet (the bit that has the TODO comment) then the outline reappears. I'm really confused by this behaviour and it also happens when I put the events in different classes.
-
I've got code written up to update and draw a minimap to the screen by creating a DynamicTexture, populating its NativeImage pixels and then rendering it to the screen each frame: https://pastebin.com/izLCeJTW However, I want this texture to be rotated 45 degrees (I'm fine with having it diamond shaped for the time being, I can figure out how to make it circular later). This is what the map looks like right now - my mod uses an isometric camera so that's why I need rotated 45 degrees. If it's simple, I want to also apply this same logic when using GuiComponent.blit() to GUI textures.
-
[1.18.2] Best high level approach to making a minimap mod
SoLegendary replied to SoLegendary's topic in Modder Support
Ok so it's all working now - just one last thing - How can I rotate the rendered map? I just want it to be rotated 45 degrees so it can be rendered diamond-shaped. Similarly I want to blit a background for the map (just the map item texture as held in the players' hands) which also needs to be rotated 45 degrees. EDIT: putting this in a new topic post -
[1.18.2] Best high level approach to making a minimap mod
SoLegendary replied to SoLegendary's topic in Modder Support
Actually if I'm not mistaken, the vanilla map shading just does three things (assuming this map is north facing): 1. if the block directly north is a higher Y, shade it darker 2. if the block directly north is a lower Y, shade it lighter 3. Shade water blocks lighter for shallower, darker for deeper -
[1.18.2] Best high level approach to making a minimap mod
SoLegendary replied to SoLegendary's topic in Modder Support
Regarding the map elevation and shading effects that the vanilla map item has using MapItem.update(), how did you apply this same effect to your map? It's not quite as simple as copying the same function as it seems to be designed for use of a MapItemSavedData object as opposed to an ARGB Array. Did you first convert the array to a MapItemSavedData object or did you rewrite the function to work on an ARGB array? -
[1.18.2] Best high level approach to making a minimap mod
SoLegendary replied to SoLegendary's topic in Modder Support
Ok I tried this flow here and its just producing a fully black square on my screen: The mapRefreshTicksMax timer is just 100ms updateMapColours() is the same as the function I posted above (producing a 40000-size array of ARGB values) and is correctly producing the data updateMapTexture() is the same as your run() function except I don't reinitialise MAP_TEXTURE every call (that was causing a crash) renderMap() is also the same as yours, except I'm not sure what the value of light is supposed to be for putTextureVertex() (I experimented with values ranging 1-255 and found no difference) Just to be sure its not my data causing the issue I also tried hardcoding pixels.setPixelRGBA(0x7F7F7F7F) which should have at least changed the square to a solid grey but no change. Ok I think when removed the initialisation of MAP_TEXTURE every tick I also had to remove the MAP_TEXTURE.close(), and that solved it. Thanks for the reference code, it was really helpful -
[1.18.2] Best high level approach to making a minimap mod
SoLegendary replied to SoLegendary's topic in Modder Support
Ok so I tried the above, but am finding that drawing 40000 rectangles (100 radius square) every tick is so expensive I effectively can't play the game. Is there an alternative to this that I can take? eg. somehow building up the image in memory before calling GuiComponent. Credit to this old post for pointing me to right functions for updateMapColourData. Unfortuantely the post is fairly old and the repo is gone so I can't figure out what that fill function used actually was. This is my current code: private static final Minecraft MC = Minecraft.getInstance(); public static List<Integer> mapColourData = new ArrayList<>(); public static final int RADIUS = 100; private static final int mapRefreshTicksMax = 100; private static int mapRefreshTicksCurrent = 100; public static void updateMapColourData() { if (MC.level == null) return; long timeBefore = System.currentTimeMillis(); mapColourData = new ArrayList<>(); for (int x = (int) MC.player.getX() - RADIUS; x < (int) MC.player.getX() + RADIUS; x++) { for (int z = (int) MC.player.getZ() - RADIUS; z < (int) MC.player.getZ() + RADIUS; z++) { int y = MC.level.getChunkAt(new BlockPos(x,0,z)).getHeight(Heightmap.Types.WORLD_SURFACE, x, z); int col = MC.level.getBlockState(new BlockPos(x,y,z)).getMaterial().getColor().col; // add 0xFF000000 to include 100% transparency mapColourData.add(col + (1677721600)); } } System.out.println("updated in: " + (System.currentTimeMillis() - timeBefore) + "ms"); System.out.println("blocks: " + mapColourData.size()); } public static void renderMap(PoseStack poseStack, int x0, int y0) { int index = 0; for (int x = x0 - RADIUS; x < x0 + RADIUS; x++) { for (int y = y0 - RADIUS; y < y0 + RADIUS; y++) { if (index < mapColourData.size()) { GuiComponent.fill(poseStack, x, y, x+1, y+1, mapColourData.get(index)); index += 1; } } } } @SubscribeEvent public static void renderOverlay(RenderGameOverlayEvent.Post evt) { mapRefreshTicksCurrent -= 1; if (mapRefreshTicksCurrent <= 0) { mapRefreshTicksCurrent = mapRefreshTicksMax; updateMapColourData(); } renderMap(evt.getMatrixStack(), 0,0); } -
I have been looking to incorporate a minimap into my mod for some time, and have been researching other mods including FTBChunks and Xaero's Minimap, except trying to just copy what they do is turning out incredibly difficult due to the huge amount of features and dependencies they have that I don't need. I've decided it's best to avoid creating a black box section of my codebase I don't understand (and have much more feature control) and just start writing my own minimap. The naive approach to this is probably: Look at all the blocks in the vicinity of the player Get the average texture colour for each block Do logic related to elevation, water depth, etc. to adjust colour Blit a rect to the screen of that colour Repeat for every single block in range Except of course this sounds incredibly performance taxing considering there could be 1000s of blocks around you and only gets worse when zooming out the map. What kind of techniques do these mods use to improve performance? I also don't want to use the vanilla map item renderer so that I can have more granular control over textures like these minimap mods do, though if there are useful techniques or helper functions it has I could use those too.
-
[1.18.2] Trying to import a mod library .jar into my project
SoLegendary replied to SoLegendary's topic in Modder Support
Right yeah a gradle dependency refresh fixed it, thanks guys. -
[1.18.2] Trying to import a mod library .jar into my project
SoLegendary replied to SoLegendary's topic in Modder Support
sorry, wrong branch, -
[1.18.2] Trying to import a mod library .jar into my project
SoLegendary replied to SoLegendary's topic in Modder Support
https://github.com/SoLegendary/reignofnether/blob/main/build.gradle -
[1.18.2] Trying to import a mod library .jar into my project
SoLegendary replied to SoLegendary's topic in Modder Support
I followed these links but am getting this note on my build.gradle, and the imports are still not found (though strangely, it still lets me run and doesn't error until I try to use the dependency's classes, at which point it throws a NoClassDefFoundError.