diff options
| author | shedaniel <daniel@shedaniel.me> | 2021-04-14 17:33:29 +0800 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2021-04-14 19:29:03 +0800 |
| commit | d892547a9b8a8ae85655900c08b6cc97c6aa2050 (patch) | |
| tree | 2df75febcd6df65ff8d9315c9bd0de81caf9a874 | |
| parent | 5467c2f08da6f3c6dae7ae603e3708d4f6eb1638 (diff) | |
| download | RoughlyEnoughItems-d892547a9b8a8ae85655900c08b6cc97c6aa2050.tar.gz RoughlyEnoughItems-d892547a9b8a8ae85655900c08b6cc97c6aa2050.tar.bz2 RoughlyEnoughItems-d892547a9b8a8ae85655900c08b6cc97c6aa2050.zip | |
Pass the BakedModel as an extra data
Signed-off-by: shedaniel <daniel@shedaniel.me>
3 files changed, 125 insertions, 75 deletions
diff --git a/api/src/main/java/me/shedaniel/rei/api/client/entry/renderer/BatchedEntryRenderer.java b/api/src/main/java/me/shedaniel/rei/api/client/entry/renderer/BatchedEntryRenderer.java index 400ef727c..f5aa5e579 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/entry/renderer/BatchedEntryRenderer.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/entry/renderer/BatchedEntryRenderer.java @@ -29,16 +29,35 @@ import me.shedaniel.rei.api.common.entry.EntryStack; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.MultiBufferSource; -public interface BatchedEntryRenderer<T> extends EntryRenderer<T> { +/** + * A batched renderer for rendering a lot of {@link EntryStack} at once with better performance. + * + * @param <T> the entry type + * @param <E> the type of extra data returned in {@link #getExtraData(EntryStack)} + */ +public interface BatchedEntryRenderer<T, E> extends EntryRenderer<T> { + default boolean isBatched(EntryStack<T> entry) { + return true; + } + + /** + * Returns extra data to be passed to various rendering methods. + * + * @param entry the stack + * @return the extra data + */ + E getExtraData(EntryStack<T> entry); + /** * Returns a batch identifier, stacks with the same batch identifier will be grouped together * into a batch. * - * @param entry the stack - * @param bounds the bounds of the entry + * @param entry the stack + * @param bounds the bounds of the entry + * @param extraData the extra data returned from {@link #getExtraData(EntryStack)} * @return the batch identifier */ - default int getBatchIdentifier(EntryStack<T> entry, Rectangle bounds) { + default int getBatchIdentifier(EntryStack<T> entry, Rectangle bounds, E extraData) { return getClass().hashCode(); } @@ -55,34 +74,37 @@ public interface BatchedEntryRenderer<T> extends EntryRenderer<T> { /** * Starts the batch rendering, used to setup states, only called once with every batch. * - * @param entry the first entry in the batch - * @param matrices the matrix stack - * @param delta the tick delta + * @param entry the first entry in the batch + * @param extraData the extra data returned from {@link #getExtraData(EntryStack)} + * @param matrices the matrix stack + * @param delta the tick delta */ - void startBatch(EntryStack<T> entry, PoseStack matrices, float delta); + void startBatch(EntryStack<T> entry, E extraData, PoseStack matrices, float delta); - void renderBase(EntryStack<T> entry, PoseStack matrices, MultiBufferSource.BufferSource immediate, Rectangle bounds, int mouseX, int mouseY, float delta); + void renderBase(EntryStack<T> entry, E extraData, PoseStack matrices, MultiBufferSource.BufferSource immediate, Rectangle bounds, int mouseX, int mouseY, float delta); - void renderOverlay(EntryStack<T> entry, PoseStack matrices, MultiBufferSource.BufferSource immediate, Rectangle bounds, int mouseX, int mouseY, float delta); + void renderOverlay(EntryStack<T> entry, E extraData, PoseStack matrices, MultiBufferSource.BufferSource immediate, Rectangle bounds, int mouseX, int mouseY, float delta); /** * Ends the batch rendering, used to setup states, only called once with every batch. * - * @param entry the first entry in the batch - * @param matrices the matrix stack - * @param delta the tick delta + * @param entry the first entry in the batch + * @param extraData the extra data returned from {@link #getExtraData(EntryStack)} + * @param matrices the matrix stack + * @param delta the tick delta */ - void endBatch(EntryStack<T> entry, PoseStack matrices, float delta); + void endBatch(EntryStack<T> entry, E extraData, PoseStack matrices, float delta); @Override default void render(EntryStack<T> entry, PoseStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta) { matrices = batchModifyMatrices(matrices); - startBatch(entry, matrices, delta); + E data = getExtraData(entry); + startBatch(entry, data, matrices, delta); MultiBufferSource.BufferSource immediate = Minecraft.getInstance().renderBuffers().bufferSource(); - renderBase(entry, matrices, immediate, bounds, mouseX, mouseY, delta); + renderBase(entry, data, matrices, immediate, bounds, mouseX, mouseY, delta); immediate.endBatch(); - renderOverlay(entry, matrices, immediate, bounds, mouseX, mouseY, delta); + renderOverlay(entry, data, matrices, immediate, bounds, mouseX, mouseY, delta); immediate.endBatch(); - endBatch(entry, matrices, delta); + endBatch(entry, data, matrices, delta); } }
\ No newline at end of file diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/BatchedEntryRendererManager.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/BatchedEntryRendererManager.java index a410a24a3..28bccb49b 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/BatchedEntryRendererManager.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/BatchedEntryRendererManager.java @@ -67,13 +67,17 @@ public class BatchedEntryRendererManager { EntryStack<?> currentEntry = widget.getCurrentEntry(); EntryRenderer<?> renderer = currentEntry.getRenderer(); if (renderer instanceof BatchedEntryRenderer) { - int hash = ((BatchedEntryRenderer<Object>) renderer).getBatchIdentifier(currentEntry.cast(), widget.getBounds()); - List<EntryWidget> entries = grouping.get(hash); - if (entries == null) { - grouping.put(hash, entries = new ArrayList<>()); + BatchedEntryRenderer<Object, Object> batchedRenderer = (BatchedEntryRenderer<Object, Object>) renderer; + EntryStack<Object> cast = currentEntry.cast(); + if (batchedRenderer.isBatched(cast)) { + int hash = batchedRenderer.getBatchIdentifier(cast, widget.getBounds(), batchedRenderer.getExtraData(cast)); + List<EntryWidget> entries = grouping.get(hash); + if (entries == null) { + grouping.put(hash, entries = new ArrayList<>()); + } + entries.add(widget); + return; } - entries.add(widget); - return; } } toRender.add(widget); @@ -90,55 +94,76 @@ public class BatchedEntryRendererManager { } } if (!toRender.isEmpty()) { - renderEntries(debugTime, size, time, fastEntryRendering, matrices, mouseX, mouseY, delta, toRender); + renderSlow(debugTime, size, time, matrices, mouseX, mouseY, delta, toRender); } } + public static <T extends EntryWidget> void renderEntries(boolean debugTime, MutableInt size, MutableLong time, boolean fastEntryRendering, PoseStack matrices, int mouseX, int mouseY, float delta, Collection<T> entries) { + if (fastEntryRendering) { + T firstWidget = Iterables.getFirst(entries, null); + if (firstWidget == null) return; + EntryRenderer<?> renderer = firstWidget.getCurrentEntry().getRenderer(); + if (renderer instanceof BatchedEntryRenderer) { + BatchedEntryRenderer<?, Object> firstRenderer = (BatchedEntryRenderer<?, Object>) renderer; + Object[] extraData = new Object[entries.size()]; + int i = 0; + for (T entry : entries) { + EntryStack<?> currentEntry = entry.getCurrentEntry(); + extraData[i++] = ((BatchedEntryRenderer<Object, Object>) currentEntry.getRenderer()).getExtraData(currentEntry.cast()); + } + renderBatched(debugTime, size, time, matrices, mouseX, mouseY, delta, entries, extraData); + return; + } + } + renderSlow(debugTime, size, time, matrices, mouseX, mouseY, delta, entries); + } - public static <T extends EntryWidget> void renderEntries(boolean debugTime, MutableInt size, MutableLong time, boolean fastEntryRendering, PoseStack matrices, int mouseX, int mouseY, float delta, Iterable<T> entries) { + private static <T extends EntryWidget> void renderBatched(boolean debugTime, MutableInt size, MutableLong time, PoseStack matrices, int mouseX, int mouseY, float delta, Iterable<T> entries, Object[] extraData) { T firstWidget = Iterables.getFirst(entries, null); if (firstWidget == null) return; @SuppressWarnings("rawtypes") EntryStack first = firstWidget.getCurrentEntry(); EntryRenderer<?> renderer = first.getRenderer(); - if (fastEntryRendering && renderer instanceof BatchedEntryRenderer) { - BatchedEntryRenderer<?> firstRenderer = (BatchedEntryRenderer<?>) renderer; - matrices = firstRenderer.batchModifyMatrices(matrices); - firstRenderer.startBatch(first, matrices, delta); - long l = debugTime ? System.nanoTime() : 0; - MultiBufferSource.BufferSource immediate = Minecraft.getInstance().renderBuffers().bufferSource(); - for (T listEntry : entries) { - @SuppressWarnings("rawtypes") - EntryStack currentEntry = listEntry.getCurrentEntry(); - currentEntry.setZ(100); - listEntry.drawBackground(matrices, mouseX, mouseY, delta); - firstRenderer.renderBase(currentEntry, matrices, immediate, listEntry.getInnerBounds(), mouseX, mouseY, delta); - if (debugTime && !currentEntry.isEmpty()) size.increment(); - } - immediate.endBatch(); - for (T listEntry : entries) { - @SuppressWarnings("rawtypes") - EntryStack currentEntry = listEntry.getCurrentEntry(); - firstRenderer.renderOverlay(currentEntry, matrices, immediate, listEntry.getInnerBounds(), mouseX, mouseY, delta); - if (listEntry.containsMouse(mouseX, mouseY)) { - listEntry.queueTooltip(matrices, mouseX, mouseY, delta); - listEntry.drawHighlighted(matrices, mouseX, mouseY, delta); - } - } - immediate.endBatch(); - if (debugTime) time.add(System.nanoTime() - l); - firstRenderer.endBatch(first, matrices, delta); - } else { - for (T entry : entries) { - if (entry.getCurrentEntry().isEmpty()) - continue; - if (debugTime) { - size.increment(); - long l = System.nanoTime(); - entry.render(matrices, mouseX, mouseY, delta); - time.add(System.nanoTime() - l); - } else entry.render(matrices, mouseX, mouseY, delta); + BatchedEntryRenderer<?, Object> firstRenderer = (BatchedEntryRenderer<?, Object>) renderer; + matrices = firstRenderer.batchModifyMatrices(matrices); + firstRenderer.startBatch(first, extraData[0], matrices, delta); + long l = debugTime ? System.nanoTime() : 0; + MultiBufferSource.BufferSource immediate = Minecraft.getInstance().renderBuffers().bufferSource(); + int i = 0; + for (T listEntry : entries) { + @SuppressWarnings("rawtypes") + EntryStack currentEntry = listEntry.getCurrentEntry(); + currentEntry.setZ(100); + listEntry.drawBackground(matrices, mouseX, mouseY, delta); + firstRenderer.renderBase(currentEntry, extraData[i++], matrices, immediate, listEntry.getInnerBounds(), mouseX, mouseY, delta); + if (debugTime && !currentEntry.isEmpty()) size.increment(); + } + immediate.endBatch(); + i = 0; + for (T listEntry : entries) { + @SuppressWarnings("rawtypes") + EntryStack currentEntry = listEntry.getCurrentEntry(); + firstRenderer.renderOverlay(currentEntry, extraData[i++], matrices, immediate, listEntry.getInnerBounds(), mouseX, mouseY, delta); + if (listEntry.containsMouse(mouseX, mouseY)) { + listEntry.queueTooltip(matrices, mouseX, mouseY, delta); + listEntry.drawHighlighted(matrices, mouseX, mouseY, delta); } } + immediate.endBatch(); + if (debugTime) time.add(System.nanoTime() - l); + firstRenderer.endBatch(first, extraData[0], matrices, delta); + } + + private static <T extends EntryWidget> void renderSlow(boolean debugTime, MutableInt size, MutableLong time, PoseStack matrices, int mouseX, int mouseY, float delta, Iterable<T> entries) { + for (T entry : entries) { + if (entry.getCurrentEntry().isEmpty()) + continue; + if (debugTime) { + size.increment(); + long l = System.nanoTime(); + entry.render(matrices, mouseX, mouseY, delta); + time.add(System.nanoTime() - l); + } else entry.render(matrices, mouseX, mouseY, delta); + } } } diff --git a/runtime/src/main/java/me/shedaniel/rei/plugin/client/entry/ItemEntryDefinition.java b/runtime/src/main/java/me/shedaniel/rei/plugin/client/entry/ItemEntryDefinition.java index d3c666b68..8742000eb 100644 --- a/runtime/src/main/java/me/shedaniel/rei/plugin/client/entry/ItemEntryDefinition.java +++ b/runtime/src/main/java/me/shedaniel/rei/plugin/client/entry/ItemEntryDefinition.java @@ -196,18 +196,21 @@ public class ItemEntryDefinition implements EntryDefinition<ItemStack>, EntrySer @SuppressWarnings("deprecation") @Environment(EnvType.CLIENT) - public class ItemEntryRenderer extends AbstractEntryRenderer<ItemStack> implements BatchedEntryRenderer<ItemStack> { + public class ItemEntryRenderer extends AbstractEntryRenderer<ItemStack> implements BatchedEntryRenderer<ItemStack, BakedModel> { + public static final int ITEM_LIGHT = 0xf000f0; + @Override - public int getBatchIdentifier(EntryStack<ItemStack> entry, Rectangle bounds) { - return 1738923 + (getModelFromStack(entry.getValue()).usesBlockLight() ? 1 : 0); + public BakedModel getExtraData(EntryStack<ItemStack> entry) { + return Minecraft.getInstance().getItemRenderer().getModel(entry.getValue(), null, null); } - private BakedModel getModelFromStack(ItemStack stack) { - return Minecraft.getInstance().getItemRenderer().getModel(stack, null, null); + @Override + public int getBatchIdentifier(EntryStack<ItemStack> entry, Rectangle bounds, BakedModel model) { + return 1738923 + (model.usesBlockLight() ? 1 : 0); } @Override - public void startBatch(EntryStack<ItemStack> entry, PoseStack matrices, float delta) { + public void startBatch(EntryStack<ItemStack> entry, BakedModel model, PoseStack matrices, float delta) { Minecraft.getInstance().getTextureManager().bind(TextureAtlas.LOCATION_BLOCKS); Minecraft.getInstance().getTextureManager().getTexture(TextureAtlas.LOCATION_BLOCKS).setFilter(false, false); RenderSystem.pushMatrix(); @@ -217,25 +220,25 @@ public class ItemEntryDefinition implements EntryDefinition<ItemStack>, EntrySer RenderSystem.enableBlend(); RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F); - boolean sideLit = getModelFromStack(entry.getValue()).usesBlockLight(); + boolean sideLit = model.usesBlockLight(); if (!sideLit) Lighting.setupForFlatItems(); } @Override - public void renderBase(EntryStack<ItemStack> entry, PoseStack matrices, MultiBufferSource.BufferSource immediate, Rectangle bounds, int mouseX, int mouseY, float delta) { + public void renderBase(EntryStack<ItemStack> entry, BakedModel model, PoseStack matrices, MultiBufferSource.BufferSource immediate, Rectangle bounds, int mouseX, int mouseY, float delta) { if (!entry.isEmpty()) { ItemStack stack = entry.getValue(); matrices.pushPose(); matrices.translate(bounds.getCenterX(), bounds.getCenterY(), 100.0F + entry.getZ()); matrices.scale(bounds.getWidth(), (bounds.getWidth() + bounds.getHeight()) / -2f, bounds.getHeight()); - Minecraft.getInstance().getItemRenderer().render(stack, ItemTransforms.TransformType.GUI, false, matrices, immediate, 15728880, OverlayTexture.NO_OVERLAY, getModelFromStack(stack)); + Minecraft.getInstance().getItemRenderer().render(stack, ItemTransforms.TransformType.GUI, false, matrices, immediate, ITEM_LIGHT, OverlayTexture.NO_OVERLAY, model); matrices.popPose(); } } @Override - public void renderOverlay(EntryStack<ItemStack> entry, PoseStack matrices, MultiBufferSource.BufferSource immediate, Rectangle bounds, int mouseX, int mouseY, float delta) { + public void renderOverlay(EntryStack<ItemStack> entry, BakedModel model, PoseStack matrices, MultiBufferSource.BufferSource immediate, Rectangle bounds, int mouseX, int mouseY, float delta) { if (!entry.isEmpty()) { Minecraft.getInstance().getItemRenderer().blitOffset = entry.getZ(); Minecraft.getInstance().getItemRenderer().renderGuiItemDecorations(Minecraft.getInstance().font, entry.getValue(), bounds.x, bounds.y, null); @@ -244,11 +247,11 @@ public class ItemEntryDefinition implements EntryDefinition<ItemStack>, EntrySer } @Override - public void endBatch(EntryStack<ItemStack> entry, PoseStack matrices, float delta) { + public void endBatch(EntryStack<ItemStack> entry, BakedModel model, PoseStack matrices, float delta) { RenderSystem.enableDepthTest(); RenderSystem.disableAlphaTest(); RenderSystem.disableRescaleNormal(); - boolean sideLit = getModelFromStack(entry.getValue()).usesBlockLight(); + boolean sideLit = model.usesBlockLight(); if (!sideLit) Lighting.setupFor3DItems(); RenderSystem.popMatrix(); |
