Skip to content

Commit e47edb4

Browse files
committed
- Geo model emissive rendering support.
- Add StructurePreviewDisplayList to improve structure preview performance(may cause many problems). - Fix IngredientItemStackRenderer rendering issue. - Improve TOP tips.
1 parent 2b01a04 commit e47edb4

File tree

9 files changed

+213
-120
lines changed

9 files changed

+213
-120
lines changed

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ dependencies {
154154
implementation("zone.rong:mixinbooter:7.1")
155155

156156
implementation("CraftTweaker2:CraftTweaker2-MC1120-Main:1.12-4.+")
157-
implementation(rfg.deobf("curse.maven:had-enough-items-557549:4506796"))
157+
implementation(rfg.deobf("curse.maven:had-enough-items-557549:4810661"))
158158
implementation(rfg.deobf("curse.maven:zenutil-401178:4816158-sources-4816159"))
159159
implementation(rfg.deobf("curse.maven:RedstoneFlux-270789:2920436"))
160160
implementation(rfg.deobf("curse.maven:CodeChickenLib-242818:2779848"))

src/main/java/github/kasuminova/mmce/client/renderer/MachineControllerRenderer.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,17 @@ public void render(GeoModel model, TileMultiblockMachineController animatable, f
133133

134134
@Optional.Method(modid = "geckolib3")
135135
public void renderRecursively(BufferBuilder builder, GeoBone bone, float red, float green, float blue, float alpha) {
136+
boolean emissive = bone.name.equals("emissive");
137+
float lastBrightnessX = 0;
138+
float lastBrightnessY = 0;
139+
if (emissive) {
140+
Tessellator.getInstance().draw();
141+
lastBrightnessX = OpenGlHelper.lastBrightnessX;
142+
lastBrightnessY = OpenGlHelper.lastBrightnessY;
143+
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
144+
builder.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR_NORMAL);
145+
}
146+
136147
MATRIX_STACK.push();
137148

138149
MATRIX_STACK.translate(bone);
@@ -155,6 +166,12 @@ public void renderRecursively(BufferBuilder builder, GeoBone bone, float red, fl
155166
}
156167

157168
MATRIX_STACK.pop();
169+
170+
if (emissive) {
171+
Tessellator.getInstance().draw();
172+
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, lastBrightnessX, lastBrightnessY);
173+
builder.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR_NORMAL);
174+
}
158175
}
159176

160177
@Optional.Method(modid = "geckolib3")

src/main/java/hellfirepvp/modularmachinery/client/gui/GuiScreenBlueprint.java

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -233,30 +233,30 @@ public void drawScreen(int mouseX, int mouseY, float partialTicks) {
233233
renderContext.releaseSamples();
234234
}
235235

236-
if (renderContext.getPattern().getPattern().size() >= 3500 && renderContext.doesRenderIn3D()) {
237-
ScaledResolution res = new ScaledResolution(Minecraft.getMinecraft());
238-
FontRenderer fr = fontRenderer;
239-
final int[] y = {guiTop + 12};
240-
Stream.of(
241-
I18n.format("gui.preview.error.too_large.tip.0"),
242-
I18n.format("gui.preview.error.too_large.tip.1"),
243-
I18n.format("gui.preview.error.too_large.tip.2"))
244-
.flatMap(str -> fr.listFormattedStringToWidth(str, 160 * res.getScaleFactor()).stream())
245-
.forEach(str -> {
246-
fr.drawStringWithShadow(str, guiLeft + 10, y[0], 0xFFFFFF);
247-
y[0] += 12;
248-
});
249-
} else {
250-
ScaledResolution res = new ScaledResolution(mc);
251-
Rectangle scissorFrame = new Rectangle((guiLeft + 8) * res.getScaleFactor(), (guiTop + 82) * res.getScaleFactor(),
252-
160 * res.getScaleFactor(), 94 * res.getScaleFactor());
253-
GL11.glEnable(GL11.GL_SCISSOR_TEST);
254-
GL11.glScissor(scissorFrame.x, scissorFrame.y, scissorFrame.width, scissorFrame.height);
255-
x = 88;
256-
z = 62;
257-
renderContext.renderAt(this.guiLeft + x, this.guiTop + z, partialTicks);
258-
GL11.glDisable(GL11.GL_SCISSOR_TEST);
259-
}
236+
// if (renderContext.getPattern().getPattern().size() >= 3500 && renderContext.doesRenderIn3D()) {
237+
// ScaledResolution res = new ScaledResolution(Minecraft.getMinecraft());
238+
// FontRenderer fr = fontRenderer;
239+
// final int[] y = {guiTop + 12};
240+
// Stream.of(
241+
// I18n.format("gui.preview.error.too_large.tip.0"),
242+
// I18n.format("gui.preview.error.too_large.tip.1"),
243+
// I18n.format("gui.preview.error.too_large.tip.2"))
244+
// .flatMap(str -> fr.listFormattedStringToWidth(str, 160 * res.getScaleFactor()).stream())
245+
// .forEach(str -> {
246+
// fr.drawStringWithShadow(str, guiLeft + 10, y[0], 0xFFFFFF);
247+
// y[0] += 12;
248+
// });
249+
// } else {
250+
ScaledResolution res = new ScaledResolution(mc);
251+
Rectangle scissorFrame = new Rectangle((guiLeft + 8) * res.getScaleFactor(), (guiTop + 82) * res.getScaleFactor(),
252+
160 * res.getScaleFactor(), 94 * res.getScaleFactor());
253+
GL11.glEnable(GL11.GL_SCISSOR_TEST);
254+
GL11.glScissor(scissorFrame.x, scissorFrame.y, scissorFrame.width, scissorFrame.height);
255+
x = 88;
256+
z = 62;
257+
renderContext.renderAt(this.guiLeft + x, this.guiTop + z, partialTicks);
258+
GL11.glDisable(GL11.GL_SCISSOR_TEST);
259+
// }
260260

261261
renderIngredientList(this, mc, mc.getRenderItem(), ingredientListScrollbar, renderContext, mouseX, mouseY, guiLeft + 8, guiTop + 142);
262262
drawButtons(mouseX, mouseY);
@@ -268,7 +268,7 @@ public void drawScreen(int mouseX, int mouseY, float partialTicks) {
268268
fontRenderer.drawStringWithShadow(reqBlueprint, this.guiLeft + 10, this.guiTop + 106, 0xFFFFFF);
269269
}
270270

271-
Rectangle scissorFrame = new Rectangle(MathHelper.floor(this.guiLeft + 8), MathHelper.floor(this.guiTop + 8), 160, 94);
271+
scissorFrame = new Rectangle(MathHelper.floor(this.guiLeft + 8), MathHelper.floor(this.guiTop + 8), 160, 94);
272272
if (!renderContext.doesRenderIn3D() && scissorFrame.contains(mouseX, mouseY)) {
273273
render2DHover(mouseX, mouseY, x, z);
274274
}

src/main/java/hellfirepvp/modularmachinery/client/util/BlockArrayRenderHelper.java

Lines changed: 125 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,15 @@
99
package hellfirepvp.modularmachinery.client.util;
1010

1111
import hellfirepvp.modularmachinery.client.ClientScheduler;
12+
import hellfirepvp.modularmachinery.common.data.Config;
1213
import hellfirepvp.modularmachinery.common.util.BlockArray;
1314
import hellfirepvp.modularmachinery.common.util.BlockCompatHelper;
1415
import hellfirepvp.modularmachinery.common.util.IBlockStateDescriptor;
1516
import net.minecraft.block.state.IBlockState;
1617
import net.minecraft.client.Minecraft;
1718
import net.minecraft.client.gui.GuiScreen;
1819
import net.minecraft.client.gui.ScaledResolution;
19-
import net.minecraft.client.renderer.BlockRendererDispatcher;
20-
import net.minecraft.client.renderer.BufferBuilder;
21-
import net.minecraft.client.renderer.Tessellator;
20+
import net.minecraft.client.renderer.*;
2221
import net.minecraft.client.renderer.texture.TextureMap;
2322
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
2423
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
@@ -52,6 +51,8 @@
5251
* Date: 09.07.2017 / 20:16
5352
*/
5453
public class BlockArrayRenderHelper {
54+
private static int hash = -1;
55+
private static int batchDList = -1;
5556

5657
private final BlockArray blocks;
5758
private final WorldBlockArrayRenderAccess renderAccess;
@@ -158,72 +159,141 @@ public void render3DGUI(double x, double y, float scaleMultiplier, float pTicks,
158159

159160
GL11.glScaled(-size * mul, -size * mul, -size * mul);
160161

161-
BlockRendererDispatcher brd = Minecraft.getMinecraft().getBlockRendererDispatcher();
162-
VertexFormat blockFormat = DefaultVertexFormats.BLOCK;
163-
164162
renderAccess.respectRenderSlice = slice.isPresent();
165163
renderAccess.currentRenderSlice = slice.orElse(0);
166164

165+
if (Config.enableStructurePreviewDisplayList) {
166+
if (batchDList == -1) {
167+
batchBlocks(slice, pTicks);
168+
hash = hashBlocks();
169+
} else {
170+
int currentHash = hashBlocks();
171+
if (hash != currentHash) {
172+
GLAllocation.deleteDisplayLists(batchDList);
173+
batchBlocks(slice, pTicks);
174+
hash = currentHash;
175+
}
176+
}
177+
GlStateManager.disableDepth();
178+
GlStateManager.callList(batchDList);
179+
GlStateManager.enableDepth();
180+
} else {
181+
batchBlocks(slice, pTicks);
182+
}
183+
184+
renderAccess.respectRenderSlice = false;
185+
renderAccess.currentRenderSlice = 0;
186+
187+
GL11.glPopMatrix();
188+
GL11.glPopAttrib();
189+
}
190+
191+
private void batchBlocks(final Optional<Integer> slice, final float pTicks) {
192+
if (batchDList != -1) {
193+
GlStateManager.glDeleteLists(batchDList, 1);
194+
}
195+
if (Config.enableStructurePreviewDisplayList) {
196+
batchDList = GLAllocation.generateDisplayLists(1);
197+
GlStateManager.glNewList(batchDList, GL11.GL_COMPILE);
198+
}
199+
200+
BlockRendererDispatcher brd = Minecraft.getMinecraft().getBlockRendererDispatcher();
201+
VertexFormat blockFormat = DefaultVertexFormats.BLOCK;
167202
Minecraft.getMinecraft().renderEngine.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE);
168203
Tessellator tes = Tessellator.getInstance();
169204
BufferBuilder vb = tes.getBuffer();
170205

171206
vb.begin(GL11.GL_QUADS, blockFormat);
172-
for (Map.Entry<BlockPos, BakedBlockData> data : renderAccess.blockRenderData.entrySet()) {
173-
BlockPos offset = data.getKey();
174-
if (slice.isPresent()) {
175-
if (slice.get() != offset.getY()) {
176-
continue;
177-
}
178-
}
179-
BakedBlockData renderData = data.getValue();
180-
SampleRenderState state = renderData.getSampleState();
181-
if (state.state.getBlock() != Blocks.AIR) {
182-
TileEntityRenderData terd = state.renderData;
183-
if (terd != null && terd.tileEntity != null) {
184-
terd.tileEntity.setWorld(Minecraft.getMinecraft().world);
185-
terd.tileEntity.setPos(offset);
186-
}
187-
try {
188-
IBlockState actRenderState = state.state;
189-
actRenderState = actRenderState.getBlock().getActualState(actRenderState, renderAccess, offset);
190-
brd.renderBlock(actRenderState, offset, renderAccess, vb);
191-
} catch (Exception exc) {
192-
brd.getBlockModelRenderer().renderModel(
193-
renderAccess,
194-
brd.getBlockModelShapes().getModelManager().getMissingModel(),
195-
state.state,
196-
offset,
197-
vb, true);
198-
}
199-
}
200-
}
207+
//noinspection SimplifyOptionalCallChains
208+
renderAccess.blockRenderData.entrySet().stream()
209+
.filter(data -> !slice.isPresent() || slice.get() == data.getKey().getY())
210+
.sorted(this::comparePos).forEach((data) -> {
211+
BlockPos offset = data.getKey();
212+
BakedBlockData renderData = data.getValue();
213+
SampleRenderState state = renderData.getSampleState();
214+
if (state.state.getBlock() != Blocks.AIR) {
215+
TileEntityRenderData terd = state.renderData;
216+
if (terd != null && terd.tileEntity != null) {
217+
terd.tileEntity.setWorld(Minecraft.getMinecraft().world);
218+
terd.tileEntity.setPos(offset);
219+
}
220+
try {
221+
IBlockState actRenderState = state.state;
222+
actRenderState = actRenderState.getBlock().getActualState(actRenderState, renderAccess, offset);
223+
brd.renderBlock(actRenderState, offset, renderAccess, vb);
224+
} catch (Exception exc) {
225+
brd.getBlockModelRenderer().renderModel(
226+
renderAccess,
227+
brd.getBlockModelShapes().getModelManager().getMissingModel(),
228+
state.state,
229+
offset,
230+
vb, true);
231+
}
232+
}
233+
});
234+
201235
tes.draw();
236+
//noinspection SimplifyOptionalCallChains
237+
renderAccess.blockRenderData.entrySet().stream()
238+
.filter(data -> !slice.isPresent() || slice.get() == data.getKey().getY())
239+
.sorted(this::comparePos)
240+
.forEach(data -> {
241+
BlockPos offset = data.getKey();
242+
SampleRenderState state = data.getValue().getSampleState();
243+
TileEntityRenderData terd = state.renderData;
244+
if (terd != null && terd.tileEntity != null && terd.renderer != null) {
245+
terd.tileEntity.setWorld(Minecraft.getMinecraft().world);
246+
terd.tileEntity.setPos(offset);
247+
try {
248+
terd.renderer.render(terd.tileEntity, offset.getX(), offset.getY(), offset.getZ(), pTicks, 0, 1F);
249+
} catch (Exception ignored) {
250+
}
251+
}
252+
});
253+
254+
if (Config.enableStructurePreviewDisplayList) {
255+
GlStateManager.glEndList();
256+
}
257+
}
202258

203-
for (Map.Entry<BlockPos, BakedBlockData> data : renderAccess.blockRenderData.entrySet()) {
204-
BlockPos offset = data.getKey();
205-
if (slice.isPresent()) {
206-
if (slice.get() != offset.getY()) {
207-
continue;
208-
}
259+
private int hashBlocks() {
260+
int hash = 80238287;
261+
for (Map.Entry<BlockPos, BlockArray.BlockInformation> entry : blocks.getPattern().entrySet()) {
262+
if (Minecraft.getMinecraft().world != null && entry.getValue().matches(Minecraft.getMinecraft().world, entry.getKey(), false)) {
263+
continue;
209264
}
210-
SampleRenderState state = data.getValue().getSampleState();
211-
TileEntityRenderData terd = state.renderData;
212-
if (terd != null && terd.tileEntity != null && terd.renderer != null) {
213-
terd.tileEntity.setWorld(Minecraft.getMinecraft().world);
214-
terd.tileEntity.setPos(offset);
215-
try {
216-
terd.renderer.render(terd.tileEntity, offset.getX(), offset.getY(), offset.getZ(), pTicks, 0, 1F);
217-
} catch (Exception ignored) {
218-
}
265+
int layer = entry.getKey().getY();
266+
if (renderAccess.currentRenderSlice != layer) {
267+
continue;
219268
}
269+
hash = (hash << 4) ^ (hash >> 28) ^ (entry.getKey().getX() * 5449 % 130651);
270+
hash = (hash << 4) ^ (hash >> 28) ^ (entry.getKey().getY() * 5449 % 130651);
271+
hash = (hash << 4) ^ (hash >> 28) ^ (entry.getKey().getZ() * 5449 % 130651);
272+
hash = (hash << 4) ^ (hash >> 28) ^ (entry.getValue().getSampleState(sampleSnap).hashCode() * 5449 % 130651);
220273
}
274+
return hash % 75327403;
275+
}
221276

222-
renderAccess.respectRenderSlice = false;
223-
renderAccess.currentRenderSlice = 0;
224-
225-
GL11.glPopMatrix();
226-
GL11.glPopAttrib();
277+
private int comparePos(Map.Entry<BlockPos, BakedBlockData> o1, Map.Entry<BlockPos, BakedBlockData> o2) {
278+
int yCompare;
279+
if (rotY < 0 && rotX >= 0 && rotX <= 90) {
280+
yCompare = Integer.compare(o2.getKey().getY(), o1.getKey().getY());
281+
} else {
282+
yCompare = Integer.compare(o1.getKey().getY(), o2.getKey().getY());
283+
}
284+
if (yCompare != 0) {
285+
return yCompare;
286+
}
287+
int xCompare;
288+
if (rotX < 0 && rotY < 0) {
289+
xCompare = Integer.compare(o1.getKey().getX(), o2.getKey().getX());
290+
} else {
291+
xCompare = Integer.compare(o2.getKey().getX(), o1.getKey().getX());
292+
}
293+
if (xCompare != 0) {
294+
return xCompare;
295+
}
296+
return Integer.compare(o1.getKey().getZ(), o2.getKey().getZ());
227297
}
228298

229299
static class BakedBlockData {

src/main/java/hellfirepvp/modularmachinery/common/data/Config.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public class Config {
3939
public static boolean enableFluxNetworksIntegration = true;
4040
public static boolean enableFactoryControllerByDefault = false;
4141
public static boolean controllerOutputComparatorSignal = true;
42+
public static boolean enableStructurePreviewDisplayList = false;
4243
public static int machineColor;
4344
public static int maxMachineParallelism = 2048;
4445
public static int defaultFactoryMaxThread = 20;
@@ -84,6 +85,10 @@ private static void load() {
8485
onlyOneMachineController = lastReadConfig.getBoolean("only-one-machine-controller", "general", false,
8586
"When enabled, Modules no longer register a separate controller for each machine, and the modular-controller-compatible-mode option is turned off.");
8687

88+
// Client
89+
enableStructurePreviewDisplayList = lastReadConfig.getBoolean("enable-structure-preview-display-list", "client", false,
90+
"(Experimental) When enabled, Machinery Preview attempts to use optimized rendering to dramatically improve smoothness in the case of large machinery, note that this can cause potential issues such as rendering misalignment.");
91+
8792
// Modular Controller Merge Support
8893
mocCompatibleMode = lastReadConfig.getBoolean(
8994
"modular-controller-compatible-mode", "general", false,

src/main/java/hellfirepvp/modularmachinery/common/integration/ingredient/IngredientItemStackRenderer.java

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -49,24 +49,24 @@ public void render(@Nonnull final Minecraft minecraft, final int xPos, final int
4949
return;
5050
}
5151

52-
IngredientItemStack ingredient = findStack(stack);
53-
if (ingredient == null) {
54-
return;
55-
}
56-
57-
int min = ingredient.min();
58-
int max = ingredient.max();
59-
6052
GlStateManager.enableDepth();
6153
RenderHelper.enableGUIStandardItemLighting();
62-
FontRenderer font = getFontRenderer(minecraft, ingredient.stack());
54+
FontRenderer font = getFontRenderer(minecraft, stack);
6355

64-
minecraft.getRenderItem().renderItemAndEffectIntoGUI(null, ingredient.stack(), xPos, yPos);
65-
if (min != max) {
66-
renderRequirementOverlyIntoGUI(font, xPos, yPos, min, max);
67-
minecraft.getRenderItem().renderItemOverlayIntoGUI(font, ingredient.stack(), xPos, yPos, "");
56+
minecraft.getRenderItem().renderItemAndEffectIntoGUI(null, stack, xPos, yPos);
57+
IngredientItemStack ingredient = findStack(stack);
58+
if (ingredient == null) {
59+
minecraft.getRenderItem().renderItemOverlayIntoGUI(font, stack, xPos, yPos, null);
60+
return;
6861
} else {
69-
minecraft.getRenderItem().renderItemOverlayIntoGUI(font, ingredient.stack(), xPos, yPos, null);
62+
int min = ingredient.min();
63+
int max = ingredient.max();
64+
if (min != max) {
65+
renderRequirementOverlyIntoGUI(font, xPos, yPos, min, max);
66+
minecraft.getRenderItem().renderItemOverlayIntoGUI(font, stack, xPos, yPos, "");
67+
} else {
68+
minecraft.getRenderItem().renderItemOverlayIntoGUI(font, stack, xPos, yPos, null);
69+
}
7070
}
7171

7272
GlStateManager.disableBlend();

0 commit comments

Comments
 (0)