From 7d390a0b229549e8fdb828944abc6bd23c591e17 Mon Sep 17 00:00:00 2001 From: BuildTools Date: Mon, 20 Apr 2020 23:01:08 -0500 Subject: [PATCH] remove the need for a custom EntityRenderer class --- .../java/backsun/lod/util/CustomRenderer.java | 217 +++++++++++++++--- 1 file changed, 185 insertions(+), 32 deletions(-) diff --git a/src/main/java/backsun/lod/util/CustomRenderer.java b/src/main/java/backsun/lod/util/CustomRenderer.java index 707f7a6a4..3187fafd4 100644 --- a/src/main/java/backsun/lod/util/CustomRenderer.java +++ b/src/main/java/backsun/lod/util/CustomRenderer.java @@ -5,12 +5,17 @@ import java.awt.Color; import org.lwjgl.opengl.GL11; import org.lwjgl.util.glu.Project; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.AbstractClientPlayer; +import net.minecraft.client.renderer.ActiveRenderInfo; import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.util.math.AxisAlignedBB; /** @@ -28,6 +33,9 @@ public class CustomRenderer // make sure this is an even number, or else it won't align with the chunk grid public final int viewDistanceMultiplier = 12; + private float fovModifierHandPrev; + private float fovModifierHand; + public boolean debugging = false; /** * constructor @@ -50,13 +58,13 @@ public class CustomRenderer private void setProjectionMatrix(float partialTicks) { // update the fov - float fov = mc.entityRenderer.getFOVModifier(partialTicks, true); + float fov = getFOVModifier(partialTicks, true); // create a new view frustum so that the squares can be drawn outside the normal view distance GlStateManager.matrixMode(GL11.GL_PROJECTION); GlStateManager.loadIdentity(); // farPlaneDistance // 10 chunks = 160 - Project.gluPerspective(fov, (float) this.mc.displayWidth / (float) this.mc.displayHeight, 0.0125f, farPlaneDistance * viewDistanceMultiplier); + Project.gluPerspective(fov, (float) mc.displayWidth / (float) mc.displayHeight, 0.0125f, farPlaneDistance * viewDistanceMultiplier); } /** @@ -66,7 +74,7 @@ public class CustomRenderer */ public void drawTest(Minecraft mc, float partialTicks) { - farPlaneDistance = this.mc.gameSettings.renderDistanceChunks * 16; + farPlaneDistance = mc.gameSettings.renderDistanceChunks * 16; setupFog(); @@ -96,8 +104,8 @@ public class CustomRenderer int playerZChunkOffset = ((int) z / 16) * 16; Color grass = new Color(80, 104, 50, 255); - Color black = grass;//Color.BLACK; - Color white = grass;//Color.WHITE; + Color black = Color.BLACK; + Color white = Color.WHITE; // set how big the squares will be and how far they will go int totalLength = (int) farPlaneDistance * viewDistanceMultiplier; @@ -114,20 +122,27 @@ public class CustomRenderer int startX = (-squareSideLength * (numbOfBoxesWide / 2)) + playerXChunkOffset; int startZ = (-squareSideLength * (numbOfBoxesWide / 2)) + playerZChunkOffset; - AxisAlignedBB bb; - // this is used to alternate the colors of the drawn squares + // this is where we store the LOD objects + AxisAlignedBB lodArray[] = new AxisAlignedBB[numbOfBoxesWide * numbOfBoxesWide]; + // this is where we store the color for each LOD object + Color colorArray[] = new Color[numbOfBoxesWide * numbOfBoxesWide]; + + + // used for debugging + // this is used to draw a checkerboard boolean alternateColor = false; boolean evenWidth = false; - if (numbOfBoxesWide % 2 == 0) - evenWidth = true; + if (debugging && numbOfBoxesWide % 2 == 0) + evenWidth = true; // x axis for (int i = 0; i < numbOfBoxesWide; i++) { - if (evenWidth) + // this is so that the debug pattern will be a checkerboard instead of stripes + if (debugging && evenWidth) alternateColor = !alternateColor; - + // z axis for (int j = 0; j < numbOfBoxesWide; j++) { @@ -137,26 +152,34 @@ public class CustomRenderer double zoffset = -z + (squareSideLength * j) + startZ; + // add the new box to the array + lodArray[i + (j * numbOfBoxesWide)] = new AxisAlignedBB(bbx, bby, bbz, 0, bby, 0).offset(xoffset, yoffset, zoffset); + colorArray[i + (j * numbOfBoxesWide)] = grass; - // create a new bounding box to store our points - bb = new AxisAlignedBB(bbx, bby, bbz, 0, bby, 0).offset(xoffset, yoffset, zoffset); - - // draw the squares as a black and white checker board - Color c; - if (alternateColor) - c = white; - else - c = black; - // draw the first square as green - if (i == 0 && j == 0) - c = grass; - alternateColor = !alternateColor; - - // draw the square - drawBox(bb, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); + // if debugging draw the squares as a black and white checker board + if (debugging) + { + Color c; + if (alternateColor) + c = white; + else + c = black; + // draw the first square as red + if (i == 0 && j == 0) + c = Color.RED; + + colorArray[i + (j * numbOfBoxesWide)] = c; + + alternateColor = !alternateColor; + } } } + // draw the LODs + drawBoxArray(lodArray, colorArray); + + + // end the profile section (so we can see how long it took to draw the LODs) mc.world.profiler.endSection(); // this must be done otherwise other parts of the screen may be drawn with a fog effect @@ -172,9 +195,78 @@ public class CustomRenderer GL11.glEnable(GL11.GL_CULL_FACE); GL11.glEnable(GL11.GL_TEXTURE_2D); } - + /** - * draw an cube (or square) with the given colors + * draw an array of cubes (or squares) with the given colors + * @param bb the cube to draw + * @param red + * @param green + * @param blue + * @param alpha + */ + private void drawBoxArray(AxisAlignedBB[] bbArray, Color[] colorArray) + { + worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR); + + int red; + int green; + int blue; + int alpha; + + int colorIndex = 0; + for (AxisAlignedBB bb : bbArray) + { + // get the color of this LOD object + red = colorArray[colorIndex].getRed(); + green = colorArray[colorIndex].getGreen(); + blue = colorArray[colorIndex].getBlue(); + alpha = colorArray[colorIndex].getAlpha(); + + // TODO which side is this? + worldRenderer.pos(bb.minX, bb.minY, bb.minZ).color(red, green, blue, alpha).endVertex(); + worldRenderer.pos(bb.maxX, bb.minY, bb.minZ).color(red, green, blue, alpha).endVertex(); + worldRenderer.pos(bb.maxX, bb.minY, bb.maxZ).color(red, green, blue, alpha).endVertex(); + worldRenderer.pos(bb.minX, bb.minY, bb.maxZ).color(red, green, blue, alpha).endVertex(); + + // only draw the other 5 sides if there is some thickness to this box + if (bb.minY != bb.maxY) + { + worldRenderer.pos(bb.minX, bb.maxY, bb.minZ).color(red, green, blue, alpha).endVertex(); + worldRenderer.pos(bb.maxX, bb.maxY, bb.minZ).color(red, green, blue, alpha).endVertex(); + worldRenderer.pos(bb.maxX, bb.maxY, bb.maxZ).color(red, green, blue, alpha).endVertex(); + worldRenderer.pos(bb.minX, bb.maxY, bb.maxZ).color(red, green, blue, alpha).endVertex(); + + worldRenderer.pos(bb.minX, bb.minY, bb.maxZ).color(red, green, blue, alpha).endVertex(); + worldRenderer.pos(bb.minX, bb.maxY, bb.maxZ).color(red, green, blue, alpha).endVertex(); + worldRenderer.pos(bb.maxX, bb.maxY, bb.maxZ).color(red, green, blue, alpha).endVertex(); + worldRenderer.pos(bb.maxX, bb.minY, bb.maxZ).color(red, green, blue, alpha).endVertex(); + + worldRenderer.pos(bb.minX, bb.minY, bb.minZ).color(red, green, blue, alpha).endVertex(); + worldRenderer.pos(bb.minX, bb.maxY, bb.minZ).color(red, green, blue, alpha).endVertex(); + worldRenderer.pos(bb.maxX, bb.maxY, bb.minZ).color(red, green, blue, alpha).endVertex(); + worldRenderer.pos(bb.maxX, bb.minY, bb.minZ).color(red, green, blue, alpha).endVertex(); + + worldRenderer.pos(bb.minX, bb.minY, bb.minZ).color(red, green, blue, alpha).endVertex(); + worldRenderer.pos(bb.minX, bb.minY, bb.maxZ).color(red, green, blue, alpha).endVertex(); + worldRenderer.pos(bb.minX, bb.maxY, bb.maxZ).color(red, green, blue, alpha).endVertex(); + worldRenderer.pos(bb.minX, bb.maxY, bb.minZ).color(red, green, blue, alpha).endVertex(); + + worldRenderer.pos(bb.maxX, bb.minY, bb.minZ).color(red, green, blue, alpha).endVertex(); + worldRenderer.pos(bb.maxX, bb.minY, bb.maxZ).color(red, green, blue, alpha).endVertex(); + worldRenderer.pos(bb.maxX, bb.maxY, bb.maxZ).color(red, green, blue, alpha).endVertex(); + worldRenderer.pos(bb.maxX, bb.maxY, bb.minZ).color(red, green, blue, alpha).endVertex(); + } + + // so we can get the next color + colorIndex++; + } + + + tessellator.draw(); + } + + /** + * draw a cube (or square) with the given colors * @param bb the cube to draw * @param red * @param green @@ -222,17 +314,78 @@ public class CustomRenderer tessellator.draw(); } - - + + /** * Sets up and enables the fog to be rendered. */ private void setupFog() { - float f = this.farPlaneDistance * (viewDistanceMultiplier * 0.5f); + float f = farPlaneDistance * (viewDistanceMultiplier * 0.5f); GlStateManager.setFogDensity(0.1f); GlStateManager.setFogStart(farPlaneDistance * (viewDistanceMultiplier * 0.25f)); GlStateManager.setFogEnd(f); GlStateManager.enableFog(); } + + /** + * Originally from Minecraft's EntityRenderer + * Changes the field of view of the player depending on if they are underwater or not + */ + public float getFOVModifier(float partialTicks, boolean useFOVSetting) + { + Entity entity = mc.getRenderViewEntity(); + float f = 70.0F; + + updateFovModifierHand(); + + if (useFOVSetting) + { + f = mc.gameSettings.fovSetting; + f = f * (fovModifierHandPrev + (fovModifierHand - fovModifierHandPrev) * partialTicks); + } + + if (entity instanceof EntityLivingBase && ((EntityLivingBase) entity).getHealth() <= 0.0F) + { + float f1 = ((EntityLivingBase) entity).deathTime + partialTicks; + f /= (1.0F - 500.0F / (f1 + 500.0F)) * 2.0F + 1.0F; + } + + IBlockState iblockstate = ActiveRenderInfo.getBlockStateAtEntityViewpoint(mc.world, entity, partialTicks); + + if (iblockstate.getMaterial() == Material.WATER) + { + f = f * 60.0F / 70.0F; + } + + return f; + } + + /** + * originally from Minecraft's EntityRenderer + * Update FOV modifier hand + */ + private void updateFovModifierHand() + { + float f = 1.0F; + + if (mc.getRenderViewEntity() instanceof AbstractClientPlayer) + { + AbstractClientPlayer abstractclientplayer = (AbstractClientPlayer) mc.getRenderViewEntity(); + f = abstractclientplayer.getFovModifier(); + } + + fovModifierHandPrev = fovModifierHand; + fovModifierHand += (f - fovModifierHand) * 0.5F; + + if (fovModifierHand > 1.5F) + { + fovModifierHand = 1.5F; + } + + if (fovModifierHand < 0.1F) + { + fovModifierHand = 0.1F; + } + } } \ No newline at end of file