WIP: Start adding in world rendering, currently heavily borrowed (uncredited thus far) from Schematica. Needs cleanup and rework

This commit is contained in:
Jason Mitchell committed 2024-09-19 10:21:39 -07:00
1 parent 813f8a93c4
commit b9a346b002
13 files changed
+1463 -6

No files matched your search

+9 -3
View File
@@ -1,9 +1,9 @@
// Add your dependencies here
dependencies {
api("com.github.GTNewHorizons:GTNHLib:0.3.2:dev")
api("com.github.GTNewHorizons:GTNHLib:0.4.0:dev")
// Now a hard dep for the NEI Handlers
api("com.github.GTNewHorizons:NotEnoughItems:2.6.14-GTNH:dev")
api("com.github.GTNewHorizons:NotEnoughItems:2.6.22-GTNH:dev")
compileOnly("com.github.GTNewHorizons:NotEnoughEnergistics:1.6.0:dev")
testImplementation(platform('org.junit:junit-bom:5.9.2'))
@@ -11,10 +11,16 @@ dependencies {
// Temporary
api("com.github.GTNewHorizons:GT5-Unofficial:5.09.48.64:dev") {
api("com.github.GTNewHorizons:GT5-Unofficial:5.09.48.150:dev") {
exclude group:"com.github.GTNewHorizons", module:"StructureLib"
}
runtimeOnlyNonPublishable("com.github.GTNewHorizons:StructureCompat:0.6.3:dev") {
exclude group:"com.github.GTNewHorizons", module:"StructureLib"
}
compileOnly('org.jetbrains:annotations:24.0.1')
compileOnly("org.projectlombok:lombok:1.18.22") {transitive = false }
annotationProcessor("org.projectlombok:lombok:1.18.22")
runtimeOnlyNonPublishable(rfg.deobf("CoreTweaks:CoreTweaks:0.3.3.2"))
}
+2 -2
View File
@@ -86,7 +86,7 @@ accessTransformersFile = structurelib_at.cfg
usesMixins = true
# Adds some debug arguments like verbose output and class export.
usesMixinDebug = false
usesMixinDebug = true
# Specify the location of your implementation of IMixinConfigPlugin. Leave it empty otherwise.
mixinPlugin =
@@ -163,7 +163,7 @@ curseForgeRelations =
# Optional parameter to have the build automatically fail if an illegal version is used.
# This can be useful if you e.g. only want to allow versions in the form of '1.1.xxx'.
# The check is ONLY performed if the version is a git ta.
# The check is ONLY performed if the version is a git tag.
# Note: the specified string must be escaped, so e.g. 1\\.1\\.\\d+ instead of 1\.1\.\d+
# versionPattern =
+18
View File
@@ -1,4 +1,22 @@
// Add any additional repositiroes for your dependencies here
repositories {
exclusiveContent {
forRepository {
ivy {
name = 'CoreTweaks releases'
url = 'https://github.com/makamys/CoreTweaks/releases/download/'
patternLayout {
artifact '[revision]/[module]-1.7.10-[revision]+nomixin(-[classifier])(.[ext])'
}
metadataSources {
artifact()
}
}
}
filter {
includeGroup('CoreTweaks')
}
}
mavenLocal()
}
@@ -11,6 +11,7 @@ import java.util.Map;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.gui.GuiNewChat;
import net.minecraft.client.particle.EntityFX;
import net.minecraft.client.renderer.Tessellator;
@@ -24,16 +25,20 @@ import net.minecraft.profiler.Profiler;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.IChatComponent;
import net.minecraft.util.IIcon;
import net.minecraft.util.MathHelper;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
import net.minecraftforge.client.event.RenderWorldLastEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.event.world.WorldEvent;
import org.lwjgl.opengl.GL11;
import com.gtnewhorizon.structurelib.client.nei.IMCForNEI;
import com.gtnewhorizon.structurelib.client.nei.InputHandler;
import com.gtnewhorizon.structurelib.client.renderer.RenderStructureGlobal;
import com.gtnewhorizon.structurelib.client.world.StructureWorld;
import com.gtnewhorizon.structurelib.entity.fx.WeightlessParticleFX;
import com.gtnewhorizon.structurelib.net.SetChannelDataMessage;
@@ -48,9 +53,17 @@ import cpw.mods.fml.common.gameevent.TickEvent.Phase;
public class ClientProxy extends CommonProxy {
// Structure Renderer
private static final Minecraft minecraft = Minecraft.getMinecraft();
private static StructureWorld structureWorld = null;
private static final ThreadLocal<RenderStructureGlobal> renderStructureGlobal = ThreadLocal
.withInitial(RenderStructureGlobal::new);
// End Structure Renderer
private static final short[] RGBA_NO_TINT = { 255, 255, 255, 255 };
private static final short[] RGBA_RED_TINT = { 255, 128, 128, 0 };
private static final Map<HintParticleInfo, HintGroup> allHints = new HashMap<>();
/**
* All batches of hints.
*/
@@ -86,6 +99,14 @@ public class ClientProxy extends CommonProxy {
*/
private static final Map<Object, Long> localThrottleMap = new HashMap<>();
public static StructureWorld getStructureWorld() {
return structureWorld;
}
public static void setStructureWorld(StructureWorld structureWorld) {
ClientProxy.structureWorld = structureWorld;
}
@Override
public void hintParticleTinted(World w, int x, int y, int z, IIcon[] icons, short[] RGBa) {
ensureHinting();
@@ -266,6 +287,27 @@ public class ClientProxy extends CommonProxy {
MinecraftForge.EVENT_BUS.register(new EventHandler());
}
private static ForgeDirection getOrientation(EntityPlayer player) {
if (player.rotationPitch > 45) {
return ForgeDirection.DOWN;
} else if (player.rotationPitch < -45) {
return ForgeDirection.UP;
} else {
switch (MathHelper.floor_double(player.rotationYaw / 90.0 + 0.5) & 3) {
case 0:
return ForgeDirection.SOUTH;
case 1:
return ForgeDirection.WEST;
case 2:
return ForgeDirection.NORTH;
case 3:
return ForgeDirection.EAST;
}
}
return ForgeDirection.UNKNOWN;
}
static void markTextureUsed(IIcon icon) {
if (StructureLib.COMPAT instanceof IStructureCompat)
((IStructureCompat) StructureLib.COMPAT).markTextureUsed(icon);
@@ -523,6 +565,29 @@ public class ClientProxy extends CommonProxy {
@SubscribeEvent
public void onRenderWorldLast(RenderWorldLastEvent e) {
renderParticlePreview(e);
renderNewPreview(e);
}
private void renderNewPreview(RenderWorldLastEvent e) {
EntityPlayerSP player = minecraft.thePlayer;
if (player == null || structureWorld == null || !structureWorld.isRendering()) return;
final RenderStructureGlobal renderStructureGlobal = ClientProxy.renderStructureGlobal.get();
renderStructureGlobal.setPlayerPosition(
player.lastTickPosX + (player.posX - player.lastTickPosX) * e.partialTicks,
player.lastTickPosY + (player.posY - player.lastTickPosY) * e.partialTicks,
player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * e.partialTicks);
renderStructureGlobal.setOrientation(getOrientation(player));
renderStructureGlobal.setRotationRender(MathHelper.floor_double(player.rotationYaw / 90) & 3);
minecraft.mcProfiler.startSection("structlibRenderPreview");
renderStructureGlobal.render(structureWorld);
minecraft.mcProfiler.endSection();
}
private void renderParticlePreview(RenderWorldLastEvent e) {
if (allHintsForRender.isEmpty()) return;
// seriously, I'm not a OpenGL expert, so I'm probably doing a lot of very stupid stuff here.
@@ -591,4 +656,5 @@ public class ClientProxy extends CommonProxy {
p.endSection();
}
}
}
@@ -0,0 +1,71 @@
package com.gtnewhorizon.structurelib.client.nei.integration.gregtech;
import com.gtnewhorizon.structurelib.alignment.constructable.IConstructable;
import com.gtnewhorizon.structurelib.client.nei.GUI_MultiblockHandler;
public class GT_GUI_MultiblockHandler extends GUI_MultiblockHandler<IConstructable> {
public GT_GUI_MultiblockHandler() {
super();
}
// spotless:off
// TODO: Move this into a non GUI multi block handler class
// @Override
// protected void placeMultiblock() {
// if (GT_Runnable_MachineBlockUpdate.isCurrentThreadEnabled()) {
// GT_Runnable_MachineBlockUpdate.setCurrentThreadEnabled(false);
// }
//
// IConstructable constructable = null;
// ItemStack copy = stackForm.copy();
// copy.getItem().onItemUse(
// copy,
// renderer.world.getFakeMultiblockBuilder(),
// renderer.world,
// PLACE_POSITION.x,
// PLACE_POSITION.y,
// PLACE_POSITION.z,
// 0,
// PLACE_POSITION.x,
// PLACE_POSITION.y,
// PLACE_POSITION.z);
//
// TileEntity tTileEntity = renderer.world.getTileEntity(PLACE_POSITION.x, PLACE_POSITION.y, PLACE_POSITION.z);
// ((ITurnable) tTileEntity).setFrontFacing(ForgeDirection.SOUTH);
// IMetaTileEntity mte = ((IGregTechTileEntity) tTileEntity).getMetaTileEntity();
//
// if (!StructureLibAPI.isInstrumentEnabled()) {
// StructureLibAPI.enableInstrument(StructureLibAPI.MOD_ID);
// }
// structureElements.clear();
//
// This seems relevant because the .construct() call ignores hatches, etc. Needs an optimized CreativeItemSource
// if (mte instanceof ISurvivalConstructable survivalConstructable) {
// int result, iterations = 0;
// do {
// result = survivalConstructable.survivalConstruct(
// getBuildTriggerStack(),
// Integer.MAX_VALUE,
// ISurvivalBuildEnvironment.create(CreativeItemSource.instance, renderer.world.getFakeMultiblockBuilder()));
// iterations++;
// } while (result > 0 && iterations < MAX_PLACE_ROUNDS);
// } else if (tTileEntity instanceof IConstructableProvider iConstructableProvider) {
// constructable = iConstructableProvider.getConstructable();
// } else if (tTileEntity instanceof IConstructable iConstructable) {
// constructable = iConstructable;
// }
// if (constructable != null) {
// constructable.construct(getBuildTriggerStack(), false);
// }
//
// if (StructureLibAPI.isInstrumentEnabled()) {
// StructureLibAPI.disableInstrument();
// }
//
// if (!GT_Runnable_MachineBlockUpdate.isCurrentThreadEnabled()) {
// GT_Runnable_MachineBlockUpdate.setCurrentThreadEnabled(true);
// }
// }
// spotless:on
}
@@ -0,0 +1,57 @@
package com.gtnewhorizon.structurelib.client.nei.integration.gregtech;
import static com.gtnewhorizon.structurelib.client.nei.IMCForNEI.GT_NEI_MB_HANDLER_NAME;
import static gregtech.api.GregTech_API.METATILEENTITIES;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.item.ItemStack;
import com.gtnewhorizon.structurelib.alignment.constructable.IConstructable;
import com.gtnewhorizon.structurelib.client.nei.MultiblockHandler;
import codechicken.nei.NEIClientUtils;
import codechicken.nei.recipe.TemplateRecipeHandler;
import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
public class GT_NEI_MultiblockHandler extends MultiblockHandler {
public static List<IConstructable> multiblocksList = new ArrayList<>();
private static final GT_GUI_MultiblockHandler baseHandler = new GT_GUI_MultiblockHandler();
public GT_NEI_MultiblockHandler() {
super(baseHandler);
for (IMetaTileEntity mte : METATILEENTITIES) {
if (mte instanceof IConstructable) {
multiblocksList.add((IConstructable) mte);
}
}
}
@Override
public String getOverlayIdentifier() {
return GT_NEI_MB_HANDLER_NAME;
}
@Override
public TemplateRecipeHandler newInstance() {
return new GT_NEI_MultiblockHandler();
}
@Override
protected void tryLoadingMultiblock(ItemStack candidate) {
for (IConstructable multiblock : multiblocksList) {
ItemStack stackForm = ((IMetaTileEntity) multiblock).getStackForm(1);
if (NEIClientUtils.areStacksSameType(stackForm, candidate)) {
baseHandler.setOnIngredientChanged(ingredients -> {
this.ingredients = ingredients;
resetPositionedIngredients();
});
baseHandler.setOnCandidateChanged(this::setResults);
baseHandler.loadMultiblock(multiblock, stackForm);
return;
}
}
}
}
@@ -0,0 +1,488 @@
package com.gtnewhorizon.structurelib.client.renderer;
import java.nio.FloatBuffer;
import org.joml.Vector3f;
import org.lwjgl.BufferUtils;
public class RenderHelper {
public static final int QUAD_DOWN = 0x01;
public static final int QUAD_UP = 0x02;
public static final int QUAD_NORTH = 0x04;
public static final int QUAD_SOUTH = 0x08;
public static final int QUAD_WEST = 0x10;
public static final int QUAD_EAST = 0x20;
public static final int QUAD_ALL = QUAD_DOWN | QUAD_UP | QUAD_NORTH | QUAD_SOUTH | QUAD_WEST | QUAD_EAST;
public static final int LINE_DOWN_WEST = 0x11;
public static final int LINE_UP_WEST = 0x12;
public static final int LINE_DOWN_EAST = 0x21;
public static final int LINE_UP_EAST = 0x22;
public static final int LINE_DOWN_NORTH = 0x05;
public static final int LINE_UP_NORTH = 0x06;
public static final int LINE_DOWN_SOUTH = 0x09;
public static final int LINE_UP_SOUTH = 0x0A;
public static final int LINE_NORTH_WEST = 0x14;
public static final int LINE_NORTH_EAST = 0x24;
public static final int LINE_SOUTH_WEST = 0x18;
public static final int LINE_SOUTH_EAST = 0x28;
public static final int LINE_ALL = LINE_DOWN_WEST | LINE_UP_WEST
| LINE_DOWN_EAST
| LINE_UP_EAST
| LINE_DOWN_NORTH
| LINE_UP_NORTH
| LINE_DOWN_SOUTH
| LINE_UP_SOUTH
| LINE_NORTH_WEST
| LINE_NORTH_EAST
| LINE_SOUTH_WEST
| LINE_SOUTH_EAST;
public static final Vector3f VEC_ZERO = new Vector3f(0, 0, 0);
private static int quadSize = 0;
private static float[] quadVertexBuffer = null;
private static float[] quadColorBuffer = null;
private static int quadVertexIndex = 0;
private static int quadColorIndex = 0;
private static int quadCount = 0;
private static int lineSize = 0;
private static float[] lineVertexBuffer = null;
private static float[] lineColorBuffer = null;
private static int lineVertexIndex = 0;
private static int lineColorIndex = 0;
private static int lineCount = 0;
private static final Vector3f vecZero = new Vector3f();
private static final Vector3f vecSize = new Vector3f();
public static void createBuffers() {
quadSize = 240;
quadVertexBuffer = new float[quadSize * 3];
quadColorBuffer = new float[quadSize * 4];
lineSize = 240;
lineVertexBuffer = new float[lineSize * 3];
lineColorBuffer = new float[lineSize * 4];
initBuffers();
}
public static void initBuffers() {
quadVertexIndex = 0;
quadColorIndex = 0;
quadCount = 0;
lineVertexIndex = 0;
lineColorIndex = 0;
lineCount = 0;
}
public static void destroyBuffers() {
quadSize = 0;
quadVertexBuffer = null;
quadColorBuffer = null;
lineSize = 0;
lineVertexBuffer = null;
lineColorBuffer = null;
}
public static FloatBuffer getQuadVertexBuffer() {
FloatBuffer buffer = BufferUtils.createFloatBuffer(quadVertexBuffer.length).put(quadVertexBuffer);
buffer.flip();
return buffer;
}
public static FloatBuffer getQuadColorBuffer() {
FloatBuffer buffer = BufferUtils.createFloatBuffer(quadColorBuffer.length).put(quadColorBuffer);
buffer.flip();
return buffer;
}
public static int getQuadCount() {
return quadCount;
}
public static FloatBuffer getLineVertexBuffer() {
FloatBuffer buffer = BufferUtils.createFloatBuffer(lineVertexBuffer.length).put(lineVertexBuffer);
buffer.flip();
return buffer;
}
public static FloatBuffer getLineColorBuffer() {
FloatBuffer buffer = BufferUtils.createFloatBuffer(lineColorBuffer.length).put(lineColorBuffer);
buffer.flip();
return buffer;
}
public static int getLineCount() {
return lineCount;
}
private static float[] createAndCopyBuffer(int newSize, float[] oldBuffer) {
float[] tempBuffer = new float[newSize];
System.arraycopy(oldBuffer, 0, tempBuffer, 0, oldBuffer.length);
return tempBuffer;
}
final static double BLOCK_DELTA = 0.005;
public static void drawCuboidSurface(Vector3f zero, Vector3f size, int sides, float red, float green, float blue,
float alpha) {
vecZero.set(zero.x - BLOCK_DELTA, zero.y - BLOCK_DELTA, zero.z - BLOCK_DELTA);
vecSize.set(size.x + BLOCK_DELTA, size.y + BLOCK_DELTA, size.z + BLOCK_DELTA);
if (quadCount + 24 >= quadSize) {
quadSize *= 2;
quadVertexBuffer = createAndCopyBuffer(quadSize * 3, quadVertexBuffer);
quadColorBuffer = createAndCopyBuffer(quadSize * 4, quadColorBuffer);
}
int total = 0;
if ((sides & QUAD_DOWN) != 0) {
quadVertexBuffer[quadVertexIndex++] = vecSize.x;
quadVertexBuffer[quadVertexIndex++] = vecZero.y;
quadVertexBuffer[quadVertexIndex++] = vecZero.z;
quadCount++;
quadVertexBuffer[quadVertexIndex++] = vecSize.x;
quadVertexBuffer[quadVertexIndex++] = vecZero.y;
quadVertexBuffer[quadVertexIndex++] = vecSize.z;
quadCount++;
quadVertexBuffer[quadVertexIndex++] = vecZero.x;
quadVertexBuffer[quadVertexIndex++] = vecZero.y;
quadVertexBuffer[quadVertexIndex++] = vecSize.z;
quadCount++;
quadVertexBuffer[quadVertexIndex++] = vecZero.x;
quadVertexBuffer[quadVertexIndex++] = vecZero.y;
quadVertexBuffer[quadVertexIndex++] = vecZero.z;
quadCount++;
total += 4;
}
if ((sides & QUAD_UP) != 0) {
quadVertexBuffer[quadVertexIndex++] = vecSize.x;
quadVertexBuffer[quadVertexIndex++] = vecSize.y;
quadVertexBuffer[quadVertexIndex++] = vecZero.z;
quadCount++;
quadVertexBuffer[quadVertexIndex++] = vecZero.x;
quadVertexBuffer[quadVertexIndex++] = vecSize.y;
quadVertexBuffer[quadVertexIndex++] = vecZero.z;
quadCount++;
quadVertexBuffer[quadVertexIndex++] = vecZero.x;
quadVertexBuffer[quadVertexIndex++] = vecSize.y;
quadVertexBuffer[quadVertexIndex++] = vecSize.z;
quadCount++;
quadVertexBuffer[quadVertexIndex++] = vecSize.x;
quadVertexBuffer[quadVertexIndex++] = vecSize.y;
quadVertexBuffer[quadVertexIndex++] = vecSize.z;
quadCount++;
total += 4;
}
if ((sides & QUAD_NORTH) != 0) {
quadVertexBuffer[quadVertexIndex++] = vecSize.x;
quadVertexBuffer[quadVertexIndex++] = vecZero.y;
quadVertexBuffer[quadVertexIndex++] = vecZero.z;
quadCount++;
quadVertexBuffer[quadVertexIndex++] = vecZero.x;
quadVertexBuffer[quadVertexIndex++] = vecZero.y;
quadVertexBuffer[quadVertexIndex++] = vecZero.z;
quadCount++;
quadVertexBuffer[quadVertexIndex++] = vecZero.x;
quadVertexBuffer[quadVertexIndex++] = vecSize.y;
quadVertexBuffer[quadVertexIndex++] = vecZero.z;
quadCount++;
quadVertexBuffer[quadVertexIndex++] = vecSize.x;
quadVertexBuffer[quadVertexIndex++] = vecSize.y;
quadVertexBuffer[quadVertexIndex++] = vecZero.z;
quadCount++;
total += 4;
}
if ((sides & QUAD_SOUTH) != 0) {
quadVertexBuffer[quadVertexIndex++] = vecZero.x;
quadVertexBuffer[quadVertexIndex++] = vecZero.y;
quadVertexBuffer[quadVertexIndex++] = vecSize.z;
quadCount++;
quadVertexBuffer[quadVertexIndex++] = vecSize.x;
quadVertexBuffer[quadVertexIndex++] = vecZero.y;
quadVertexBuffer[quadVertexIndex++] = vecSize.z;
quadCount++;
quadVertexBuffer[quadVertexIndex++] = vecSize.x;
quadVertexBuffer[quadVertexIndex++] = vecSize.y;
quadVertexBuffer[quadVertexIndex++] = vecSize.z;
quadCount++;
quadVertexBuffer[quadVertexIndex++] = vecZero.x;
quadVertexBuffer[quadVertexIndex++] = vecSize.y;
quadVertexBuffer[quadVertexIndex++] = vecSize.z;
quadCount++;
total += 4;
}
if ((sides & QUAD_WEST) != 0) {
quadVertexBuffer[quadVertexIndex++] = vecZero.x;
quadVertexBuffer[quadVertexIndex++] = vecZero.y;
quadVertexBuffer[quadVertexIndex++] = vecZero.z;
quadCount++;
quadVertexBuffer[quadVertexIndex++] = vecZero.x;
quadVertexBuffer[quadVertexIndex++] = vecZero.y;
quadVertexBuffer[quadVertexIndex++] = vecSize.z;
quadCount++;
quadVertexBuffer[quadVertexIndex++] = vecZero.x;
quadVertexBuffer[quadVertexIndex++] = vecSize.y;
quadVertexBuffer[quadVertexIndex++] = vecSize.z;
quadCount++;
quadVertexBuffer[quadVertexIndex++] = vecZero.x;
quadVertexBuffer[quadVertexIndex++] = vecSize.y;
quadVertexBuffer[quadVertexIndex++] = vecZero.z;
quadCount++;
total += 4;
}
if ((sides & QUAD_EAST) != 0) {
quadVertexBuffer[quadVertexIndex++] = vecSize.x;
quadVertexBuffer[quadVertexIndex++] = vecZero.y;
quadVertexBuffer[quadVertexIndex++] = vecSize.z;
quadCount++;
quadVertexBuffer[quadVertexIndex++] = vecSize.x;
quadVertexBuffer[quadVertexIndex++] = vecZero.y;
quadVertexBuffer[quadVertexIndex++] = vecZero.z;
quadCount++;
quadVertexBuffer[quadVertexIndex++] = vecSize.x;
quadVertexBuffer[quadVertexIndex++] = vecSize.y;
quadVertexBuffer[quadVertexIndex++] = vecZero.z;
quadCount++;
quadVertexBuffer[quadVertexIndex++] = vecSize.x;
quadVertexBuffer[quadVertexIndex++] = vecSize.y;
quadVertexBuffer[quadVertexIndex++] = vecSize.z;
quadCount++;
total += 4;
}
for (int i = 0; i < total; i++) {
quadColorBuffer[quadColorIndex++] = red;
quadColorBuffer[quadColorIndex++] = green;
quadColorBuffer[quadColorIndex++] = blue;
quadColorBuffer[quadColorIndex++] = alpha;
}
}
public static void drawCuboidOutline(Vector3f zero, Vector3f size, int sides, float red, float green, float blue,
float alpha) {
vecZero.set(zero.x - BLOCK_DELTA, zero.y - BLOCK_DELTA, zero.z - BLOCK_DELTA);
vecSize.set(size.x + BLOCK_DELTA, size.y + BLOCK_DELTA, size.z + BLOCK_DELTA);
if (lineCount + 24 >= lineSize) {
lineSize *= 2;
lineVertexBuffer = createAndCopyBuffer(lineSize * 3, lineVertexBuffer);
lineColorBuffer = createAndCopyBuffer(lineSize * 4, lineColorBuffer);
}
int total = 0;
if ((sides & LINE_DOWN_WEST) != 0) {
lineVertexBuffer[lineVertexIndex++] = vecZero.x;
lineVertexBuffer[lineVertexIndex++] = vecZero.y;
lineVertexBuffer[lineVertexIndex++] = vecZero.z;
lineCount++;
lineVertexBuffer[lineVertexIndex++] = vecZero.x;
lineVertexBuffer[lineVertexIndex++] = vecZero.y;
lineVertexBuffer[lineVertexIndex++] = vecSize.z;
lineCount++;
total += 2;
}
if ((sides & LINE_UP_WEST) != 0) {
lineVertexBuffer[lineVertexIndex++] = vecZero.x;
lineVertexBuffer[lineVertexIndex++] = vecSize.y;
lineVertexBuffer[lineVertexIndex++] = vecZero.z;
lineCount++;
lineVertexBuffer[lineVertexIndex++] = vecZero.x;
lineVertexBuffer[lineVertexIndex++] = vecSize.y;
lineVertexBuffer[lineVertexIndex++] = vecSize.z;
lineCount++;
total += 2;
}
if ((sides & LINE_DOWN_EAST) != 0) {
lineVertexBuffer[lineVertexIndex++] = vecSize.x;
lineVertexBuffer[lineVertexIndex++] = vecZero.y;
lineVertexBuffer[lineVertexIndex++] = vecZero.z;
lineCount++;
lineVertexBuffer[lineVertexIndex++] = vecSize.x;
lineVertexBuffer[lineVertexIndex++] = vecZero.y;
lineVertexBuffer[lineVertexIndex++] = vecSize.z;
lineCount++;
total += 2;
}
if ((sides & LINE_UP_EAST) != 0) {
lineVertexBuffer[lineVertexIndex++] = vecSize.x;
lineVertexBuffer[lineVertexIndex++] = vecSize.y;
lineVertexBuffer[lineVertexIndex++] = vecZero.z;
lineCount++;
lineVertexBuffer[lineVertexIndex++] = vecSize.x;
lineVertexBuffer[lineVertexIndex++] = vecSize.y;
lineVertexBuffer[lineVertexIndex++] = vecSize.z;
lineCount++;
total += 2;
}
if ((sides & LINE_DOWN_NORTH) != 0) {
lineVertexBuffer[lineVertexIndex++] = vecZero.x;
lineVertexBuffer[lineVertexIndex++] = vecZero.y;
lineVertexBuffer[lineVertexIndex++] = vecZero.z;
lineCount++;
lineVertexBuffer[lineVertexIndex++] = vecSize.x;
lineVertexBuffer[lineVertexIndex++] = vecZero.y;
lineVertexBuffer[lineVertexIndex++] = vecZero.z;
lineCount++;
total += 2;
}
if ((sides & LINE_UP_NORTH) != 0) {
lineVertexBuffer[lineVertexIndex++] = vecZero.x;
lineVertexBuffer[lineVertexIndex++] = vecSize.y;
lineVertexBuffer[lineVertexIndex++] = vecZero.z;
lineCount++;
lineVertexBuffer[lineVertexIndex++] = vecSize.x;
lineVertexBuffer[lineVertexIndex++] = vecSize.y;
lineVertexBuffer[lineVertexIndex++] = vecZero.z;
lineCount++;
total += 2;
}
if ((sides & LINE_DOWN_SOUTH) != 0) {
lineVertexBuffer[lineVertexIndex++] = vecZero.x;
lineVertexBuffer[lineVertexIndex++] = vecZero.y;
lineVertexBuffer[lineVertexIndex++] = vecSize.z;
lineCount++;
lineVertexBuffer[lineVertexIndex++] = vecSize.x;
lineVertexBuffer[lineVertexIndex++] = vecZero.y;
lineVertexBuffer[lineVertexIndex++] = vecSize.z;
lineCount++;
total += 2;
}
if ((sides & LINE_UP_SOUTH) != 0) {
lineVertexBuffer[lineVertexIndex++] = vecZero.x;
lineVertexBuffer[lineVertexIndex++] = vecSize.y;
lineVertexBuffer[lineVertexIndex++] = vecSize.z;
lineCount++;
lineVertexBuffer[lineVertexIndex++] = vecSize.x;
lineVertexBuffer[lineVertexIndex++] = vecSize.y;
lineVertexBuffer[lineVertexIndex++] = vecSize.z;
lineCount++;
total += 2;
}
if ((sides & LINE_NORTH_WEST) != 0) {
lineVertexBuffer[lineVertexIndex++] = vecZero.x;
lineVertexBuffer[lineVertexIndex++] = vecZero.y;
lineVertexBuffer[lineVertexIndex++] = vecZero.z;
lineCount++;
lineVertexBuffer[lineVertexIndex++] = vecZero.x;
lineVertexBuffer[lineVertexIndex++] = vecSize.y;
lineVertexBuffer[lineVertexIndex++] = vecZero.z;
lineCount++;
total += 2;
}
if ((sides & LINE_NORTH_EAST) != 0) {
lineVertexBuffer[lineVertexIndex++] = vecSize.x;
lineVertexBuffer[lineVertexIndex++] = vecZero.y;
lineVertexBuffer[lineVertexIndex++] = vecZero.z;
lineCount++;
lineVertexBuffer[lineVertexIndex++] = vecSize.x;
lineVertexBuffer[lineVertexIndex++] = vecSize.y;
lineVertexBuffer[lineVertexIndex++] = vecZero.z;
lineCount++;
total += 2;
}
if ((sides & LINE_SOUTH_WEST) != 0) {
lineVertexBuffer[lineVertexIndex++] = vecZero.x;
lineVertexBuffer[lineVertexIndex++] = vecZero.y;
lineVertexBuffer[lineVertexIndex++] = vecSize.z;
lineCount++;
lineVertexBuffer[lineVertexIndex++] = vecZero.x;
lineVertexBuffer[lineVertexIndex++] = vecSize.y;
lineVertexBuffer[lineVertexIndex++] = vecSize.z;
lineCount++;
total += 2;
}
if ((sides & LINE_SOUTH_EAST) != 0) {
lineVertexBuffer[lineVertexIndex++] = vecSize.x;
lineVertexBuffer[lineVertexIndex++] = vecZero.y;
lineVertexBuffer[lineVertexIndex++] = vecSize.z;
lineCount++;
lineVertexBuffer[lineVertexIndex++] = vecSize.x;
lineVertexBuffer[lineVertexIndex++] = vecSize.y;
lineVertexBuffer[lineVertexIndex++] = vecSize.z;
lineCount++;
total += 2;
}
for (int i = 0; i < total; i++) {
lineColorBuffer[lineColorIndex++] = red;
lineColorBuffer[lineColorIndex++] = green;
lineColorBuffer[lineColorIndex++] = blue;
lineColorBuffer[lineColorIndex++] = alpha;
}
}
}
@@ -0,0 +1,182 @@
package com.gtnewhorizon.structurelib.client.renderer;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.culling.Frustrum;
import net.minecraft.profiler.Profiler;
import net.minecraftforge.common.util.ForgeDirection;
import org.joml.Vector3d;
import org.lwjgl.opengl.GL11;
import com.gtnewhorizon.structurelib.client.world.StructureWorld;
public class RenderStructureGlobal {
private final Vector3d playerPosition = new Vector3d();
private ForgeDirection orientation = ForgeDirection.UNKNOWN;
private int rotationRender = 0;
private final Frustrum frustrum = new Frustrum();
public RenderBlocks renderBlocks = null;
public final List<RendererStructureChunk> sortedRendererStructureChunk = new ArrayList<>();
private final RendererStructureChunkComparator rendererStructureChunkComparator = new RendererStructureChunkComparator();
public void setPlayerPosition(Vector3d playerPosistion) {
this.playerPosition.set(playerPosistion);
}
public void setPlayerPosition(double x, double y, double z) {
this.playerPosition.set(x, y, z);
}
public void setOrientation(ForgeDirection orientation) {
this.orientation = orientation;
}
public void setRotationRender(int rotationRender) {
this.rotationRender = rotationRender;
}
public void render(StructureWorld structureWorld) {
final Minecraft minecraft = Minecraft.getMinecraft();
final Profiler profiler = minecraft.mcProfiler;
GL11.glPushMatrix();
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glEnable(GL11.GL_BLEND);
Vector3d extra = new Vector3d();
if (structureWorld != null) {
extra.add(
structureWorld.renderPosition.x,
structureWorld.renderPosition.y,
structureWorld.renderPosition.z);
playerPosition.sub(extra);
}
GL11.glTranslated(-playerPosition.x, -playerPosition.y, -playerPosition.z);
profiler.startSection("schematic");
if (structureWorld != null && structureWorld.isRendering()) {
profiler.startSection("updateFrustrum");
updateFrustrum(structureWorld);
profiler.endStartSection("sortAndUpdate");
if (RendererStructureChunk.getCanUpdate()) {
sortAndUpdate(structureWorld);
}
profiler.endStartSection("render");
int pass;
for (pass = 0; pass < 3; pass++) {
for (RendererStructureChunk renderer : this.sortedRendererStructureChunk) {
renderer.render(playerPosition, pass);
}
}
profiler.endSection();
}
profiler.endStartSection("guide");
RenderHelper.createBuffers();
profiler.startSection("dataPrep");
int quadCount = RenderHelper.getQuadCount();
int lineCount = RenderHelper.getLineCount();
if (quadCount > 0 || lineCount > 0) {
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glLineWidth(1.5f);
GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);
profiler.endStartSection("quad");
if (quadCount > 0) {
GL11.glVertexPointer(3, 0, RenderHelper.getQuadVertexBuffer());
GL11.glColorPointer(4, 0, RenderHelper.getQuadColorBuffer());
GL11.glDrawArrays(GL11.GL_QUADS, 0, quadCount);
}
profiler.endStartSection("line");
if (lineCount > 0) {
GL11.glVertexPointer(3, 0, RenderHelper.getLineVertexBuffer());
GL11.glColorPointer(4, 0, RenderHelper.getLineColorBuffer());
GL11.glDrawArrays(GL11.GL_LINES, 0, lineCount);
}
profiler.endSection();
GL11.glDisableClientState(GL11.GL_COLOR_ARRAY);
GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);
GL11.glEnable(GL11.GL_TEXTURE_2D);
}
profiler.endSection();
GL11.glDisable(GL11.GL_BLEND);
GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
GL11.glPopMatrix();
}
private void updateFrustrum(StructureWorld schematic) {
this.frustrum.setPosition(
playerPosition.x - schematic.renderPosition.x,
playerPosition.y - schematic.renderPosition.y,
playerPosition.z - schematic.renderPosition.z);
for (RendererStructureChunk RendererStructureChunk : this.sortedRendererStructureChunk) {
RendererStructureChunk.isInFrustrum = this.frustrum
.isBoundingBoxInFrustum(RendererStructureChunk.getBoundingBox());
}
}
private void sortAndUpdate(StructureWorld world) {
this.rendererStructureChunkComparator.setPosition(playerPosition, world.renderPosition);
this.sortedRendererStructureChunk.sort(this.rendererStructureChunkComparator);
for (RendererStructureChunk RendererStructureChunk : this.sortedRendererStructureChunk) {
if (RendererStructureChunk.getDirty()) {
RendererStructureChunk.updateRenderer(renderBlocks);
break;
}
}
}
public void createRendererStructureChunks(StructureWorld structureWorld) {
int width = (structureWorld.getWidth() - 1) / 16 + 1;
int height = (structureWorld.getHeight() - 1) / 16 + 1;
int length = (structureWorld.getLength() - 1) / 16 + 1;
destroyRendererStructureChunks();
this.renderBlocks = new RenderBlocks(structureWorld);
for (int y = 0; y < height; y++) {
for (int z = 0; z < length; z++) {
for (int x = 0; x < width; x++) {
this.sortedRendererStructureChunk.add(new RendererStructureChunk(structureWorld, x, y, z));
}
}
}
}
public void destroyRendererStructureChunks() {
this.renderBlocks = null;
while (!this.sortedRendererStructureChunk.isEmpty()) {
this.sortedRendererStructureChunk.remove(0).delete();
}
}
public void refresh() {
for (RendererStructureChunk renderer : this.sortedRendererStructureChunk) {
renderer.setDirty();
}
}
}
@@ -0,0 +1,414 @@
package com.gtnewhorizon.structurelib.client.renderer;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.profiler.Profiler;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.world.IBlockAccess;
import org.joml.Vector3d;
import org.joml.Vector3f;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;
import com.gtnewhorizon.gtnhlib.client.renderer.shader.ShaderProgram;
import com.gtnewhorizon.structurelib.StructureLib;
import com.gtnewhorizon.structurelib.client.world.StructureWorld;
public class RendererStructureChunk {
private static final ShaderProgram alphaShader = initAlphaShader();
private static final int alphaUniform = GL20.glGetUniformLocation(alphaShader.getProgram(), "alpha_multiplier");
private static boolean canUpdate = false;
public boolean isInFrustrum = false;
public final Vector3d centerPosition = new Vector3d();
private final Minecraft minecraft = Minecraft.getMinecraft();
private final Profiler profiler = this.minecraft.mcProfiler;
private final StructureWorld world;
private final List<TileEntity> tileEntities = new ArrayList<>();
private final Vector3d distance = new Vector3d();
private final AxisAlignedBB boundingBox = AxisAlignedBB.getBoundingBox(0, 0, 0, 0, 0, 0);
private boolean needsUpdate = true;
private int glList = -1;
// TODO: move this away from GL lists
private int glListHighlight = -1;
private static ShaderProgram initAlphaShader() {
ShaderProgram shader;
try {
shader = new ShaderProgram("structurelib", null, "shaders/alpha.frag");
shader.use();
GL20.glUniform1i(GL20.glGetUniformLocation(shader.getProgram(), "texture"), 0);
ShaderProgram.clear();
} catch (Exception e) {
shader = null;
}
return shader;
}
private static final int SUBCHUNK_SIZE = 16;
public RendererStructureChunk(StructureWorld world, int x, int y, int z) {
this.world = world;
this.boundingBox.setBounds(
x * SUBCHUNK_SIZE,
y * SUBCHUNK_SIZE,
z * SUBCHUNK_SIZE,
(x + 1) * SUBCHUNK_SIZE,
(y + 1) * SUBCHUNK_SIZE,
(z + 1) * SUBCHUNK_SIZE);
this.centerPosition.set(
(int) ((x + 0.5) * SUBCHUNK_SIZE),
(int) ((y + 0.5) * SUBCHUNK_SIZE),
(int) ((z + 0.5) * SUBCHUNK_SIZE));
// TODO: Replace this with something less stupid
int tx, ty, tz;
for (TileEntity tileEntity : this.world.getTileEntities()) {
tx = tileEntity.xCoord;
ty = tileEntity.yCoord;
tz = tileEntity.zCoord;
if (tx < this.boundingBox.minX || tx >= this.boundingBox.maxX) {
continue;
} else if (tz < this.boundingBox.minZ || tz >= this.boundingBox.maxZ) {
continue;
} else if (ty < this.boundingBox.minY || ty >= this.boundingBox.maxY) {
continue;
}
this.tileEntities.add(tileEntity);
}
}
public void delete() {
// Deallocate VBOs
}
public void updateRenderer(RenderBlocks renderBlocks) {
if (this.needsUpdate) {
this.needsUpdate = false;
setCanUpdate(false);
RenderHelper.createBuffers();
for (int pass = 0; pass < 3; pass++) {
RenderHelper.initBuffers();
int minX, maxX, minY, maxY, minZ, maxZ;
minX = (int) this.boundingBox.minX;
maxX = (int) this.boundingBox.maxX;
minY = (int) this.boundingBox.minY;
maxY = (int) this.boundingBox.maxY;
minZ = (int) this.boundingBox.minZ;
maxZ = (int) this.boundingBox.maxZ;
// TODO: Rendering layer
// int renderingLayer = this.world.renderingLayer;
// if (this.world.isRenderingLayer) {
// if (renderingLayer >= minY && renderingLayer < maxY) {
// minY = renderingLayer;
// maxY = renderingLayer + 1;
// } else {
// minY = maxY = 0;
// }
// }
GL11.glNewList(this.glList + pass, GL11.GL_COMPILE);
renderBlocks(renderBlocks, pass, minX, minY, minZ, maxX, maxY, maxZ);
GL11.glEndList();
GL11.glNewList(this.glListHighlight + pass, GL11.GL_COMPILE);
int quadCount = RenderHelper.getQuadCount();
int lineCount = RenderHelper.getLineCount();
if (quadCount > 0 || lineCount > 0) {
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glLineWidth(1.5f);
GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);
if (quadCount > 0) {
GL11.glVertexPointer(3, 0, RenderHelper.getQuadVertexBuffer());
GL11.glColorPointer(4, 0, RenderHelper.getQuadColorBuffer());
GL11.glDrawArrays(GL11.GL_QUADS, 0, quadCount);
}
if (lineCount > 0) {
GL11.glVertexPointer(3, 0, RenderHelper.getLineVertexBuffer());
GL11.glColorPointer(4, 0, RenderHelper.getLineColorBuffer());
GL11.glDrawArrays(GL11.GL_LINES, 0, lineCount);
}
GL11.glDisableClientState(GL11.GL_COLOR_ARRAY);
GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);
GL11.glEnable(GL11.GL_TEXTURE_2D);
}
GL11.glEndList();
}
RenderHelper.destroyBuffers();
}
}
public void render(Vector3d playerPosition, int renderPass) {
if (!this.isInFrustrum) {
return;
}
if (this.distance.set(playerPosition)
.sub(this.world.renderPosition.x, this.world.renderPosition.y, this.world.renderPosition.z)
.sub(this.centerPosition).lengthSquared() > 25600) {
return;
}
// some mods enable this, beats me why - it's supposed to be disabled!
GL11.glDisable(GL11.GL_LIGHTING);
this.profiler.startSection("blocks");
this.minecraft.renderEngine.bindTexture(TextureMap.locationBlocksTexture);
GL20.glUseProgram(alphaShader.getProgram());
GL20.glUniform1f(alphaUniform, ALPHA);
GL11.glCallList(this.glList + renderPass);
GL20.glUseProgram(0);
this.profiler.endStartSection("highlight");
GL11.glCallList(this.glListHighlight + renderPass);
this.profiler.endStartSection("tileEntities");
renderTileEntities(renderPass);
// re-enable blending... spawners disable it, somewhere...
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
// re-set alpha func... beacons set it to (GL_GREATER, 0.5f)
// EntityRenderer sets it to (GL_GREATER, 0.1f) before dispatching the event
GL11.glAlphaFunc(GL11.GL_GREATER, 0.1F);
this.profiler.endSection();
}
public void renderBlocks(RenderBlocks renderBlocks, int renderPass, int minX, int minY, int minZ, int maxX,
int maxY, int maxZ) {
IBlockAccess mcWorld = this.minecraft.theWorld;
int x, y, z, wx, wy, wz;
int sides;
Block block, mcBlock;
Vector3f zero = new Vector3f();
Vector3f size = new Vector3f();
int ambientOcclusion = this.minecraft.gameSettings.ambientOcclusion;
this.minecraft.gameSettings.ambientOcclusion = 0;
Tessellator.instance.startDrawingQuads();
for (y = minY; y < maxY; y++) {
for (z = minZ; z < maxZ; z++) {
for (x = minX; x < maxX; x++) {
try {
block = this.world.getBlock(x, y, z);
wx = this.world.renderPosition.x + x;
wy = this.world.renderPosition.y + y;
wz = this.world.renderPosition.z + z;
mcBlock = mcWorld.getBlock(wx, wy, wz);
sides = 0;
if (block != null) {
if (block.shouldSideBeRendered(this.world, x, y - 1, z, 0)) {
sides |= RenderHelper.QUAD_DOWN;
}
if (block.shouldSideBeRendered(this.world, x, y + 1, z, 1)) {
sides |= RenderHelper.QUAD_UP;
}
if (block.shouldSideBeRendered(this.world, x, y, z - 1, 2)) {
sides |= RenderHelper.QUAD_NORTH;
}
if (block.shouldSideBeRendered(this.world, x, y, z + 1, 3)) {
sides |= RenderHelper.QUAD_SOUTH;
}
if (block.shouldSideBeRendered(this.world, x - 1, y, z, 4)) {
sides |= RenderHelper.QUAD_WEST;
}
if (block.shouldSideBeRendered(this.world, x + 1, y, z, 5)) {
sides |= RenderHelper.QUAD_EAST;
}
}
boolean isAirBlock = this.world.isAirBlock(x, y, z);
boolean isMcAirBlock = mcWorld.isAirBlock(wx, wy, wz);
if (!isMcAirBlock) {
// if ConfigurationHandler.highlight
if (renderPass == 2) {
// if ConfigurationHandler.highlightAir
if (isAirBlock) {
zero.set(x, y, z);
size.set(x + 1, y + 1, z + 1);
// if (ConfigurationHandler.drawQuads)
RenderHelper.drawCuboidSurface(
zero,
size,
RenderHelper.QUAD_ALL,
0.75f,
0.0f,
0.75f,
0.25f);
// if (ConfigurationHandler.drawLines)
RenderHelper.drawCuboidOutline(
zero,
size,
RenderHelper.LINE_ALL,
0.75f,
0.0f,
0.75f,
0.25f);
} else if (block != mcBlock) {
zero.set(x, y, z);
size.set(x + 1, y + 1, z + 1);
// if (ConfigurationHandler.drawQuads)
RenderHelper.drawCuboidSurface(zero, size, sides, 1.0f, 0.0f, 0.0f, 0.25f);
// if (ConfigurationHandler.drawLines)
RenderHelper.drawCuboidOutline(zero, size, sides, 1.0f, 0.0f, 0.0f, 0.25f);
} else
if (this.world.getBlockMetadata(x, y, z) != mcWorld.getBlockMetadata(wx, wy, wz)) {
zero.set(x, y, z);
size.set(x + 1, y + 1, z + 1);
// if (ConfigurationHandler.drawQuads)
RenderHelper.drawCuboidSurface(zero, size, sides, 0.75f, 0.35f, 0.0f, 0.25f);
// if (ConfigurationHandler.drawLines)
RenderHelper.drawCuboidOutline(zero, size, sides, 0.75f, 0.35f, 0.0f, 0.25f);
}
}
} else if (!isAirBlock) {
// if ConfigurationHandler.highlight
if (renderPass == 2) {
zero.set(x, y, z);
size.set(x + 1, y + 1, z + 1);
// if (ConfigurationHandler.drawQuads)
RenderHelper.drawCuboidSurface(zero, size, sides, 0.0f, 0.75f, 1.0f, 0.25f);
// if (ConfigurationHandler.drawLines)
RenderHelper.drawCuboidOutline(zero, size, sides, 0.0f, 0.75f, 1.0f, 0.25f);
}
if (block != null && block.canRenderInPass(renderPass)) {
renderBlocks.renderBlockByRenderType(block, x, y, z);
}
}
} catch (Exception e) {
StructureLib.LOGGER.error("Failed to render block!", e);
}
}
}
}
Tessellator.instance.draw();
this.minecraft.gameSettings.ambientOcclusion = ambientOcclusion;
}
public static float ALPHA = 0.75f;
public void renderTileEntities(int renderPass) {
if (renderPass != 0) {
return;
}
IBlockAccess mcWorld = this.minecraft.theWorld;
int x, y, z;
GL11.glColor4f(1.0f, 1.0f, 1.0f, ALPHA);
try {
for (TileEntity tileEntity : this.tileEntities) {
x = tileEntity.xCoord;
y = tileEntity.yCoord;
z = tileEntity.zCoord;
// TODO: Rendering layer
// if (this.world.isRenderingLayer && this.world.renderingLayer != y) {
// continue;
// }
final boolean isAirBlock = mcWorld.isAirBlock(
x + this.world.renderPosition.x,
y + this.world.renderPosition.y,
z + this.world.renderPosition.z);
if (isAirBlock) {
TileEntitySpecialRenderer tileEntitySpecialRenderer = TileEntityRendererDispatcher.instance
.getSpecialRenderer(tileEntity);
if (tileEntitySpecialRenderer != null) {
try {
tileEntitySpecialRenderer.renderTileEntityAt(tileEntity, x, y, z, 0);
OpenGlHelper.setActiveTexture(OpenGlHelper.lightmapTexUnit);
GL11.glDisable(GL11.GL_TEXTURE_2D);
OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit);
} catch (Exception e) {
StructureLib.LOGGER.error("Failed to render a tile entity!", e);
}
GL11.glColor4f(1.0f, 1.0f, 1.0f, ALPHA);
}
}
}
} catch (Exception ex) {
StructureLib.LOGGER.error("Failed to render tile entities!", ex);
}
}
public static void setCanUpdate(boolean parCanUpdate) {
canUpdate = parCanUpdate;
}
public static boolean getCanUpdate() {
return canUpdate;
}
public void setDirty() {
this.needsUpdate = true;
}
public boolean getDirty() {
return this.needsUpdate;
}
public AxisAlignedBB getBoundingBox() {
return boundingBox;
}
}
@@ -0,0 +1,31 @@
package com.gtnewhorizon.structurelib.client.renderer;
import java.util.Comparator;
import org.joml.Vector3d;
import org.joml.Vector3i;
public class RendererStructureChunkComparator implements Comparator<RendererStructureChunk> {
private final Vector3d position = new Vector3d();
private final Vector3d renderPosition = new Vector3d();
@Override
public int compare(RendererStructureChunk RendererStructureChunk1, RendererStructureChunk RendererStructureChunk2) {
if (RendererStructureChunk1.isInFrustrum && !RendererStructureChunk2.isInFrustrum) {
return -1;
} else if (!RendererStructureChunk1.isInFrustrum && RendererStructureChunk2.isInFrustrum) {
return 1;
} else {
final double dist1 = position.distanceSquared(RendererStructureChunk1.centerPosition);
final double dist2 = position.distanceSquared(RendererStructureChunk2.centerPosition);
return Double.compare(dist1, dist2);
}
}
public void setPosition(Vector3d playerPosition, Vector3i position) {
this.renderPosition.set(position);
this.position.set(playerPosition).sub(this.renderPosition.set(position));
}
}
@@ -0,0 +1,73 @@
package com.gtnewhorizon.structurelib.client.world;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.world.IWorldAccess;
import org.joml.Vector3i;
import com.gtnewhorizon.structurelib.ClientProxy;
public class StructurePreviewUpdater implements IWorldAccess {
public static final StructurePreviewUpdater INSTANCE = new StructurePreviewUpdater();
@Override
public void markBlockForUpdate(int x, int y, int z) {
markBlocksForUpdate(x - 1, y - 1, z - 1, x + 1, y + 1, z + 1);
}
@Override
public void markBlockForRenderUpdate(int x, int y, int z) {
markBlocksForUpdate(x - 1, y - 1, z - 1, x + 1, y + 1, z + 1);
}
@Override
public void markBlockRangeForRenderUpdate(int x0, int y0, int z0, int x1, int y1, int z1) {
markBlocksForUpdate(x0 - 1, y0 - 1, z0 - 1, x1 + 1, y1 + 1, z1 + 1);
}
private final AxisAlignedBB box = AxisAlignedBB.getBoundingBox(0, 0, 0, 0, 0, 0);
private void markBlocksForUpdate(int x0, int y0, int z0, int x1, int y1, int z1) {
final StructureWorld structure = ClientProxy.getStructureWorld();
if (structure == null) return;
final Vector3i loc = structure.getRenderLocation();
box.setBounds(x0 - loc.x, y0 - loc.y, z0 - loc.z, x1 - loc.x, y1 - loc.y, z1 - loc.z);
// TODO: Update chunk renderers
}
@Override
public void playSound(String soundName, double x, double y, double z, float volume, float pitch) {}
@Override
public void playSoundToNearExcept(EntityPlayer player, String soundName, double x, double y, double z, float volume,
float piatch) {}
@Override
public void spawnParticle(final String type, double x, double y, double z, double velX, double velY, double velZ) {}
@Override
public void onEntityCreate(Entity entity) {}
@Override
public void onEntityDestroy(Entity entity) {}
@Override
public void playRecord(String recordName, int x, int y, int z) {}
@Override
public void broadcastSound(int id, int x, int y, int z, int par5) {}
@Override
public void playAuxSFX(EntityPlayer player, int od, int x, int y, int z, int par6) {}
@Override
public void destroyBlockPartially(int id, int x, int y, int z, int partialDamage) {}
@Override
public void onStaticEntitiesChanged() {}
}
@@ -1,6 +1,8 @@
package com.gtnewhorizon.structurelib.client.world;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import net.minecraft.block.Block;
@@ -42,6 +44,7 @@ public class StructureWorld extends World {
// Static variables
public static final Vector3i PLACE_POSITION = new Vector3i(0, 64, 0);
public static final int MAX_PLACE_ROUNDS = 2000;
public final Vector3i renderPosition = new Vector3i(0, 0, 0);
private static final ISaveHandler STRUCTURE_SAVE_HANDLER = new StructureSaveHandler();
private static final WorldSettings WORLD_SETTINGS = new WorldSettings(
@@ -52,7 +55,9 @@ public class StructureWorld extends World {
WorldType.FLAT);
// Instance variables
private StructureFakePlayer fakeMultiblockBuilder;
private boolean rendering = false;
private final StructureFakePlayer fakeMultiblockBuilder;
private final Vector3i renderLocation = new Vector3i();
public final LongSet placedBlocks = new LongOpenHashSet();
private final Vector3f minPos = new Vector3f(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);
@@ -60,15 +65,52 @@ public class StructureWorld extends World {
private final Vector3f size = new Vector3f();
public boolean isRendering() {
return rendering;
}
public void setRendering(boolean rendering) {
rendering = rendering;
}
public StructureFakePlayer getFakeMultiblockBuilder() {
return fakeMultiblockBuilder;
}
public List<TileEntity> getTileEntities() {
// TODO: Replace this with something less stupid
return new ArrayList<>();
}
private void updateSize() {
size.set(maxPos.x - minPos.x + 1, maxPos.y - minPos.y + 1, maxPos.z - minPos.z + 1);
}
public int getWidth() {
return (int) size.x;
}
public int getHeight() {
return (int) size.y;
}
public int getLength() {
return (int) size.z;
}
public Vector3i getRenderLocation() {
return renderLocation;
}
public void setRenderLocation(Vector3i renderLocation) {
this.renderLocation.set(renderLocation);
}
public void setRenderLocation(int x, int y, int z) {
this.renderLocation.set(x, y, z);
}
public Vector3f getSize() {
return size;
}
@@ -0,0 +1,9 @@
#version 120
uniform sampler2D texture;
uniform float alpha_multiplier;
void main() {
vec4 tex = texture2D(texture, gl_TexCoord[0].xy) * gl_Color;
gl_FragColor = vec4(tex.r, tex.g, tex.b, tex.a * alpha_multiplier);
}