Add the ability to draw outside of the normal draw distance.

Also split up the drawing into multiple calls, allowing for a checkerboard pattern.
This commit is contained in:
BuildTools
2020-04-19 20:48:01 -05:00
parent f24db03c8b
commit b73df07f68
5 changed files with 2521 additions and 58 deletions
+6 -2
View File
@@ -1,5 +1,6 @@
package backsun.lod;
import backsun.lod.proxy.ClientProxy;
import backsun.lod.proxy.CommonProxy;
import backsun.lod.util.Reference;
import net.minecraftforge.common.MinecraftForge;
@@ -23,7 +24,8 @@ public class Main
public static Main instance;
@SidedProxy(clientSide = Reference.CLIENT_PROXY_CLASS, serverSide = Reference.COMMON_PROXY_CLASS)
public static CommonProxy proxy;
public static CommonProxy common_proxy;
public static ClientProxy client_proxy;
@EventHandler
public static void PreInit(FMLPreInitializationEvent event)
@@ -34,7 +36,9 @@ public class Main
@EventHandler
public static void Init(FMLInitializationEvent event)
{
MinecraftForge.EVENT_BUS.register(proxy);
MinecraftForge.EVENT_BUS.register(common_proxy);
client_proxy = new ClientProxy();
}
@EventHandler
@@ -10,11 +10,13 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
public class ClientProxy extends CommonProxy
{
/**
* @param item
* @param meta
* @param id
*/
private CustomRenderer renderer;
public ClientProxy()
{
renderer = new CustomRenderer();
}
@Override
public void registerItemRender(Item item, int meta, String id)
{
@@ -24,6 +26,7 @@ public class ClientProxy extends CommonProxy
@SubscribeEvent
public void renderWorldLastEvent(RenderWorldLastEvent event)
{
CustomRenderer.drawTest(Minecraft.getMinecraft(),event.getPartialTicks());
if(renderer != null)
renderer.drawTest(Minecraft.getMinecraft(),event.getPartialTicks());
}
}
@@ -1,77 +1,151 @@
package backsun.lod.util;
import java.awt.Color;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GLContext;
import org.lwjgl.util.glu.Project;
import net.minecraft.client.Minecraft;
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.util.math.AxisAlignedBB;
/**
*
* @author James Seibel
* @version 04-19-2020
*/
public class CustomRenderer
{
public static void drawTest(Minecraft mc, float partialTicks)
private Minecraft mc;
private float farPlaneDistance;
private Tessellator tessellator;
private BufferBuilder worldRenderer;
/**
* constructor
*/
public CustomRenderer()
{
mc = Minecraft.getMinecraft();
tessellator = Tessellator.getInstance();
worldRenderer = tessellator.getBuffer();
// GL11.GL_MODELVIEW //5888
// GL11.GL_PROJECTION //5889
}
/**
* create a new projection matrix and send it over to the GPU
* @param partialTicks how many ticks into the frame we are
*/
private void setProjectionMatrix(float partialTicks)
{
// update the fov
float fov = mc.entityRenderer.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 * 12.0f);
}
/**
*
* @param mc
* @param partialTicks
*/
public void drawTest(Minecraft mc, float partialTicks)
{
farPlaneDistance = this.mc.gameSettings.renderDistanceChunks * 16;
// TODO add fog
//setupFog();
GlStateManager.disableFog();
// set the new model view matrix
setProjectionMatrix(partialTicks);
// used for debugging
mc.world.profiler.startSection("renderlod");
// set the required open GL settings
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glLineWidth(2.0f);
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glDisable(GL11.GL_CULL_FACE);
GL11.glLineWidth(2.0f);
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glDisable(GL11.GL_CULL_FACE);
GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL);
GL11.glEnable(GL11.GL_BLEND);
// get the camera location
// Entity entity = mc.getRenderViewEntity();
Entity entity = mc.player;
double x = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * partialTicks;
double y = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * partialTicks;
double z = entity.lastTickPosZ + (entity.posZ - entity.lastTickPosZ) * partialTicks;
int bbx = 9;
int bby = 9;
int bbz = 9;
// x y z
AxisAlignedBB bb = new AxisAlignedBB(bbx, bby, bbz, bbx-1, bby-1, bbz-1).offset(-x, -y, -z);
Color grass = new Color(80, 104, 50, 255);
Color black = Color.BLACK;
Color white = Color.WHITE;
GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL);
GL11.glEnable(GL11.GL_BLEND);
// set how big the squares will be and how far they will go
int totalLength = (int) farPlaneDistance * 9;
int singleLength = 160;
int numbOfBoxesWide = totalLength / singleLength;
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder worldRenderer = tessellator.getBuffer();
// size of a single square
int bbx = singleLength;
int bby = 0;
int bbz = singleLength;
worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR);
worldRenderer.pos(bb.minX, bb.minY, bb.minZ).color(255, 255, 255, 255).endVertex();
worldRenderer.pos(bb.maxX, bb.minY, bb.minZ).color(255, 255, 255, 255).endVertex();
worldRenderer.pos(bb.maxX, bb.minY, bb.maxZ).color(255, 255, 255, 255).endVertex();
worldRenderer.pos(bb.minX, bb.minY, bb.maxZ).color(255, 255, 255, 255).endVertex();
if (bb.minY != bb.maxY)
// this where we will start drawing squares
int startXZ = -singleLength * numbOfBoxesWide;
AxisAlignedBB bb;
// this is used to alternate the colors of the drawn squares
boolean alternateColor = false;
// x axis
for (int i = 0; i < numbOfBoxesWide; i++)
{
worldRenderer.pos(bb.minX, bb.maxY, bb.minZ).color(255, 255, 255, 255).endVertex();
worldRenderer.pos(bb.maxX, bb.maxY, bb.minZ).color(255, 255, 255, 255).endVertex();
worldRenderer.pos(bb.maxX, bb.maxY, bb.maxZ).color(255, 255, 255, 255).endVertex();
worldRenderer.pos(bb.minX, bb.maxY, bb.maxZ).color(255, 255, 255, 255).endVertex();
worldRenderer.pos(bb.minX, bb.minY, bb.maxZ).color(255, 255, 255, 255).endVertex();
worldRenderer.pos(bb.minX, bb.maxY, bb.maxZ).color(255, 255, 255, 255).endVertex();
worldRenderer.pos(bb.maxX, bb.maxY, bb.maxZ).color(255, 255, 255, 255).endVertex();
worldRenderer.pos(bb.maxX, bb.minY, bb.maxZ).color(255, 255, 255, 255).endVertex();
worldRenderer.pos(bb.minX, bb.minY, bb.minZ).color(255, 255, 255, 255).endVertex();
worldRenderer.pos(bb.minX, bb.maxY, bb.minZ).color(255, 255, 255, 255).endVertex();
worldRenderer.pos(bb.maxX, bb.maxY, bb.minZ).color(255, 255, 255, 255).endVertex();
worldRenderer.pos(bb.maxX, bb.minY, bb.minZ).color(255, 255, 255, 255).endVertex();
worldRenderer.pos(bb.minX, bb.minY, bb.minZ).color(255, 255, 255, 255).endVertex();
worldRenderer.pos(bb.minX, bb.minY, bb.maxZ).color(255, 255, 255, 255).endVertex();
worldRenderer.pos(bb.minX, bb.maxY, bb.maxZ).color(255, 255, 255, 255).endVertex();
worldRenderer.pos(bb.minX, bb.maxY, bb.minZ).color(255, 255, 255, 255).endVertex();
worldRenderer.pos(bb.maxX, bb.minY, bb.minZ).color(255, 255, 255, 255).endVertex();
worldRenderer.pos(bb.maxX, bb.minY, bb.maxZ).color(255, 255, 255, 255).endVertex();
worldRenderer.pos(bb.maxX, bb.maxY, bb.maxZ).color(255, 255, 255, 255).endVertex();
worldRenderer.pos(bb.maxX, bb.maxY, bb.minZ).color(255, 255, 255, 255).endVertex();
// z axis
for (int j = 0; j < numbOfBoxesWide; j++)
{
// update where this square will be drawn
double xoffset = -x + (singleLength * i * 2) + startXZ;
double yoffset = -y;
double zoffset = -z + (singleLength * j * 2) + startXZ;
// create a new bounding box to store our points
bb = new AxisAlignedBB(bbx, bby, bbz, -bbx, bby, -bbz).offset(xoffset, yoffset, zoffset);
// draw the squares as a black and white checker board
Color c;
if (alternateColor)
c = white;
else
c = black;
alternateColor = !alternateColor;
// draw the square
drawBox(bb, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
}
}
tessellator.draw();
mc.world.profiler.endSection();
// this must be done otherwise other parts of the screen may be drawn with a fog effect
// IE the GUI
GlStateManager.disableFog();
GL11.glDisable(GL11.GL_BLEND);
GL11.glEnable(GL11.GL_POLYGON_OFFSET_LINE);
@@ -79,8 +153,86 @@ public class CustomRenderer
GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL);
GL11.glEnable(GL11.GL_CULL_FACE);
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glEnable(GL11.GL_CULL_FACE);
GL11.glEnable(GL11.GL_TEXTURE_2D);
}
}
/**
* draw an cube (or square) with the given colors
* @param bb the cube to draw
* @param red
* @param green
* @param blue
* @param alpha
*/
private void drawBox(AxisAlignedBB bb, int red, int green, int blue, int alpha)
{
worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR);
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();
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();
}
tessellator.draw();
//TODO are these needed?
// worldRenderer.finishDrawing();
// worldRenderer.reset();
}
/**
* Sets up the fog to be rendered. If the argument passed in is -1 the fog starts at 0 and goes to 80% of far plane
* distance and is used for sky rendering.
*/
private void setupFog()
{
GlStateManager.glNormal3f(0.0F, -1.0F, 0.0F);
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
float f = this.farPlaneDistance * 15.0f; //15 linear
GlStateManager.setFog(GlStateManager.FogMode.LINEAR);
GlStateManager.setFogDensity(0.0f);
GlStateManager.setFogStart(f * 0.7F); // 0.7
GlStateManager.setFogEnd(f);
if (GLContext.getCapabilities().GL_NV_fog_distance)
{
GlStateManager.glFogi(34138, 34139);
}
GlStateManager.enableColorMaterial();
GlStateManager.enableFog();
GlStateManager.colorMaterial(1028, 4608);
}
}
@@ -0,0 +1,112 @@
package backsun.lod.util;
import java.nio.FloatBuffer;
import net.minecraft.client.renderer.GLAllocation;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.culling.ClippingHelper;
import net.minecraft.util.math.MathHelper;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class LodClippingHelper extends ClippingHelper
{
private static final LodClippingHelper instance = new LodClippingHelper();
private final FloatBuffer projectionMatrixBuffer = GLAllocation.createDirectFloatBuffer(16);
private final FloatBuffer modelviewMatrixBuffer = GLAllocation.createDirectFloatBuffer(16);
private final FloatBuffer floatBuffer16 = GLAllocation.createDirectFloatBuffer(16);
/**
* Initializes the ClippingHelper object then returns an instance of it.
*/
public static ClippingHelper getInstance()
{
instance.init();
return instance;
}
private void normalize(float[] vec4)
{
float f = MathHelper.sqrt(vec4[0] * vec4[0] + vec4[1] * vec4[1] + vec4[2] * vec4[2]);
vec4[0] /= f;
vec4[1] /= f;
vec4[2] /= f;
vec4[3] /= f;
}
public void init()
{
projectionMatrixBuffer.clear();
modelviewMatrixBuffer.clear();
floatBuffer16.clear();
GlStateManager.getFloat(2982, modelviewMatrixBuffer); // 2982 = model view matrix location
float[] proj = projectionMatrix;
float[] mvm = modelviewMatrix;
projectionMatrixBuffer.flip().limit(16);
projectionMatrixBuffer.get(proj);
modelviewMatrixBuffer.flip().limit(16);
modelviewMatrixBuffer.get(mvm);
clippingMatrix[0] = mvm[0] * proj[0] + mvm[1] * proj[4] + mvm[2] * proj[8] + mvm[3] * proj[12];
clippingMatrix[1] = mvm[0] * proj[1] + mvm[1] * proj[5] + mvm[2] * proj[9] + mvm[3] * proj[13];
clippingMatrix[2] = mvm[0] * proj[2] + mvm[1] * proj[6] + mvm[2] * proj[10] + mvm[3] * proj[14];
clippingMatrix[3] = mvm[0] * proj[3] + mvm[1] * proj[7] + mvm[2] * proj[11] + mvm[3] * proj[15];
clippingMatrix[4] = mvm[4] * proj[0] + mvm[5] * proj[4] + mvm[6] * proj[8] + mvm[7] * proj[12];
clippingMatrix[5] = mvm[4] * proj[1] + mvm[5] * proj[5] + mvm[6] * proj[9] + mvm[7] * proj[13];
clippingMatrix[6] = mvm[4] * proj[2] + mvm[5] * proj[6] + mvm[6] * proj[10] + mvm[7] * proj[14];
clippingMatrix[7] = mvm[4] * proj[3] + mvm[5] * proj[7] + mvm[6] * proj[11] + mvm[7] * proj[15];
clippingMatrix[8] = mvm[8] * proj[0] + mvm[9] * proj[4] + mvm[10] * proj[8] + mvm[11] * proj[12];
clippingMatrix[9] = mvm[8] * proj[1] + mvm[9] * proj[5] + mvm[10] * proj[9] + mvm[11] * proj[13];
clippingMatrix[10] = mvm[8] * proj[2] + mvm[9] * proj[6] + mvm[10] * proj[10] + mvm[11] * proj[14];
clippingMatrix[11] = mvm[8] * proj[3] + mvm[9] * proj[7] + mvm[10] * proj[11] + mvm[11] * proj[15];
clippingMatrix[12] = mvm[12] * proj[0] + mvm[13] * proj[4] + mvm[14] * proj[8] + mvm[15] * proj[12];
clippingMatrix[13] = mvm[12] * proj[1] + mvm[13] * proj[5] + mvm[14] * proj[9] + mvm[15] * proj[13];
clippingMatrix[14] = mvm[12] * proj[2] + mvm[13] * proj[6] + mvm[14] * proj[10] + mvm[15] * proj[14];
clippingMatrix[15] = mvm[12] * proj[3] + mvm[13] * proj[7] + mvm[14] * proj[11] + mvm[15] * proj[15];
System.out.println(proj[0] + "\t" +proj[1] + "\t" +proj[2] + "\t" +proj[3]);
System.out.println(proj[4] + "\t" +proj[5] + "\t" +proj[6] + "\t" +proj[7]);
System.out.println(proj[8] + "\t" +proj[9] + "\t" +proj[10] + "\t" +proj[11]);
System.out.println(proj[12] + "\t" +proj[13] + "\t" +proj[14] + "\t" +proj[15]);
System.out.println();
float[] afloat2 = frustum[0];
afloat2[0] = clippingMatrix[3] - clippingMatrix[0];
afloat2[1] = clippingMatrix[7] - clippingMatrix[4];
afloat2[2] = clippingMatrix[11] - clippingMatrix[8];
afloat2[3] = clippingMatrix[15] - clippingMatrix[12];
normalize(afloat2);
float[] afloat3 = frustum[1];
afloat3[0] = clippingMatrix[3] + clippingMatrix[0];
afloat3[1] = clippingMatrix[7] + clippingMatrix[4];
afloat3[2] = clippingMatrix[11] + clippingMatrix[8];
afloat3[3] = clippingMatrix[15] + clippingMatrix[12];
normalize(afloat3);
float[] afloat4 = frustum[2];
afloat4[0] = clippingMatrix[3] + clippingMatrix[1];
afloat4[1] = clippingMatrix[7] + clippingMatrix[5];
afloat4[2] = clippingMatrix[11] + clippingMatrix[9];
afloat4[3] = clippingMatrix[15] + clippingMatrix[13];
normalize(afloat4);
float[] afloat5 = frustum[3];
afloat5[0] = clippingMatrix[3] - clippingMatrix[1];
afloat5[1] = clippingMatrix[7] - clippingMatrix[5];
afloat5[2] = clippingMatrix[11] - clippingMatrix[9];
afloat5[3] = clippingMatrix[15] - clippingMatrix[13];
normalize(afloat5);
float[] afloat6 = frustum[4];
afloat6[0] = clippingMatrix[3] - clippingMatrix[2];
afloat6[1] = clippingMatrix[7] - clippingMatrix[6];
afloat6[2] = clippingMatrix[11] - clippingMatrix[10];
afloat6[3] = clippingMatrix[15] - clippingMatrix[14];
normalize(afloat6);
float[] afloat7 = frustum[5];
afloat7[0] = clippingMatrix[3] + clippingMatrix[2];
afloat7[1] = clippingMatrix[7] + clippingMatrix[6];
afloat7[2] = clippingMatrix[11] + clippingMatrix[10];
afloat7[3] = clippingMatrix[15] + clippingMatrix[14];
normalize(afloat7);
}
}
File diff suppressed because it is too large Load Diff