Initial experimental rendering changes
This commit is contained in:
parent
96106f2a9e
commit
c44908b210
6 changed files with 78 additions and 107 deletions
|
@ -1,31 +1,27 @@
|
|||
package com.simibubi.create.foundation.block;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
|
||||
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
|
||||
public abstract class SafeTileEntityRenderer<T extends TileEntity> extends TileEntityRenderer<T> {
|
||||
|
||||
public SafeTileEntityRenderer(TileEntityRendererDispatcher dispatcher) {
|
||||
super(dispatcher);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void render(T te, double x, double y, double z, float partialTicks, int destroyStage) {
|
||||
public void render(T te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) {
|
||||
if (isInvalid(te))
|
||||
return;
|
||||
renderWithGL(te, x, y, z, partialTicks, destroyStage);
|
||||
renderSafe(te, partialTicks, ms, buffer, light, overlay);
|
||||
}
|
||||
|
||||
protected abstract void renderWithGL(T tileEntityIn, double x, double y, double z, float partialTicks, int destroyStage);
|
||||
|
||||
@Override
|
||||
public final void renderTileEntityFast(T te, double x, double y, double z, float partialTicks, int destroyStage,
|
||||
BufferBuilder buffer) {
|
||||
if (isInvalid(te))
|
||||
return;
|
||||
renderFast(te, x, y, z, partialTicks, destroyStage, buffer);
|
||||
}
|
||||
|
||||
protected void renderFast(T tileEntityIn, double x, double y, double z, float partialTicks, int destroyStage, BufferBuilder buffer) {
|
||||
}
|
||||
protected abstract void renderSafe(T te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay);
|
||||
|
||||
public boolean isInvalid(T te) {
|
||||
return te.getBlockState().getBlock() == Blocks.AIR;
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
package com.simibubi.create.foundation.block;
|
||||
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraftforge.client.model.animation.TileEntityRendererFast;
|
||||
|
||||
public abstract class SafeTileEntityRendererFast<T extends TileEntity> extends TileEntityRendererFast<T> {
|
||||
|
||||
@Override
|
||||
public final void renderTileEntityFast(T te, double x, double y, double z, float partialTicks, int destroyStage,
|
||||
BufferBuilder buffer) {
|
||||
if (isInvalid(te))
|
||||
return;
|
||||
renderFast(te, x, y, z, partialTicks, destroyStage, buffer);
|
||||
}
|
||||
|
||||
protected abstract void renderFast(T te, double x, double y, double z, float partialTicks, int destroyStage,
|
||||
BufferBuilder buffer);
|
||||
|
||||
public boolean isInvalid(T te) {
|
||||
return te.getBlockState().getBlock() == Blocks.AIR;
|
||||
}
|
||||
|
||||
}
|
|
@ -2,13 +2,17 @@ package com.simibubi.create.foundation.utility;
|
|||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import javax.vecmath.Matrix4f;
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
||||
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.GLAllocation;
|
||||
import net.minecraft.client.renderer.Matrix4f;
|
||||
import net.minecraft.client.renderer.Vector4f;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
|
||||
|
||||
public class SuperByteBuffer {
|
||||
|
||||
|
@ -21,8 +25,7 @@ public class SuperByteBuffer {
|
|||
protected ByteBuffer mutable;
|
||||
|
||||
// Vertex Position
|
||||
private Matrix4f transforms;
|
||||
private Matrix4f t;
|
||||
private MatrixStack transforms;
|
||||
|
||||
// Vertex Texture Coords
|
||||
private boolean shouldShiftUV;
|
||||
|
@ -38,7 +41,8 @@ public class SuperByteBuffer {
|
|||
private boolean shouldColor;
|
||||
private int r, g, b, a;
|
||||
|
||||
public SuperByteBuffer(ByteBuffer original) {
|
||||
public SuperByteBuffer(BufferBuilder buf) {
|
||||
ByteBuffer original = ObfuscationReflectionHelper.getPrivateValue(BufferBuilder.class, buf, "field_179001_a"); // FIXME speedup
|
||||
original.rewind();
|
||||
this.original = original;
|
||||
|
||||
|
@ -48,28 +52,20 @@ public class SuperByteBuffer {
|
|||
mutable.put(this.original);
|
||||
mutable.rewind();
|
||||
|
||||
t = new Matrix4f();
|
||||
transforms = new Matrix4f();
|
||||
transforms.setIdentity();
|
||||
transforms = new MatrixStack();
|
||||
}
|
||||
|
||||
public ByteBuffer build() {
|
||||
public ByteBuffer build(MatrixStack input) {
|
||||
original.rewind();
|
||||
mutable.rewind();
|
||||
float x, y, z = 0;
|
||||
float x2, y2, z2 = 0;
|
||||
|
||||
Matrix4f t = transforms;
|
||||
Matrix4f t = transforms.peek().getModel();
|
||||
t.multiply(input.peek().getModel());
|
||||
for (int vertex = 0; vertex < vertexCount(original); vertex++) {
|
||||
x = getX(original, vertex);
|
||||
y = getY(original, vertex);
|
||||
z = getZ(original, vertex);
|
||||
|
||||
x2 = t.m00 * x + t.m01 * y + t.m02 * z + t.m03;
|
||||
y2 = t.m10 * x + t.m11 * y + t.m12 * z + t.m13;
|
||||
z2 = t.m20 * x + t.m21 * y + t.m22 * z + t.m23;
|
||||
|
||||
putPos(mutable, vertex, x2, y2, z2);
|
||||
Vector4f pos = new Vector4f(getX(original, vertex), getY(original, vertex), getZ(original, vertex), 1F);
|
||||
|
||||
pos.transform(t);
|
||||
putPos(mutable, vertex, pos.getX(), pos.getY(), pos.getZ());
|
||||
|
||||
if (shouldColor) {
|
||||
byte lumByte = getR(original, vertex);
|
||||
|
@ -86,23 +82,26 @@ public class SuperByteBuffer {
|
|||
if (shouldLight) {
|
||||
if (vertexLighter != null)
|
||||
putLight(mutable, vertex,
|
||||
vertexLighter.getPackedLight(x2 + lightOffsetX, y2 + lightOffsetY, z2 + lightOffsetZ));
|
||||
vertexLighter.getPackedLight(pos.getX() + lightOffsetX, pos.getY() + lightOffsetY, pos.getZ() + lightOffsetZ));
|
||||
else
|
||||
putLight(mutable, vertex, packedLightCoords);
|
||||
}
|
||||
}
|
||||
|
||||
t.setIdentity();
|
||||
transforms = new MatrixStack();
|
||||
shouldShiftUV = false;
|
||||
shouldColor = false;
|
||||
shouldLight = false;
|
||||
return mutable;
|
||||
}
|
||||
|
||||
public void renderInto(BufferBuilder buffer) {
|
||||
public void renderInto(MatrixStack input, IVertexBuilder buffer) {
|
||||
if (original.limit() == 0)
|
||||
return;
|
||||
buffer.putBulkData(build());
|
||||
if (!(buffer instanceof BufferBuilder)) {
|
||||
throw new IllegalArgumentException("Unsupported buffer type!");
|
||||
}
|
||||
((BufferBuilder)buffer).putBulkData(build(input));
|
||||
}
|
||||
|
||||
public SuperByteBuffer translate(double x, double y, double z) {
|
||||
|
@ -110,27 +109,18 @@ public class SuperByteBuffer {
|
|||
}
|
||||
|
||||
public SuperByteBuffer translate(float x, float y, float z) {
|
||||
transforms.m03 += x;
|
||||
transforms.m13 += y;
|
||||
transforms.m23 += z;
|
||||
transforms.translate(x, y, z);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SuperByteBuffer rotate(Axis axis, float angle) {
|
||||
public SuperByteBuffer rotate(Direction axis, float angle) {
|
||||
if (angle == 0)
|
||||
return this;
|
||||
t.setIdentity();
|
||||
if (axis == Axis.X)
|
||||
t.rotX(angle);
|
||||
else if (axis == Axis.Y)
|
||||
t.rotY(angle);
|
||||
else
|
||||
t.rotZ(angle);
|
||||
transforms.mul(t, transforms);
|
||||
transforms.multiply(axis.getUnitVector().getDegreesQuaternion(angle));
|
||||
return this;
|
||||
}
|
||||
|
||||
public SuperByteBuffer rotateCentered(Axis axis, float angle) {
|
||||
public SuperByteBuffer rotateCentered(Direction axis, float angle) {
|
||||
return translate(-.5f, -.5f, -.5f).rotate(axis, angle).translate(.5f, .5f, .5f);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import org.lwjgl.opengl.GL11;
|
|||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.AllBlockPartials;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
|
@ -19,6 +20,7 @@ import net.minecraft.client.renderer.BlockModelRenderer;
|
|||
import net.minecraft.client.renderer.BlockRendererDispatcher;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraftforge.client.model.data.EmptyModelData;
|
||||
|
@ -84,14 +86,16 @@ public class SuperByteBufferCache {
|
|||
BlockModelRenderer blockRenderer = dispatcher.getBlockModelRenderer();
|
||||
BufferBuilder builder = new BufferBuilder(0);
|
||||
Random random = new Random();
|
||||
MatrixStack ms = new MatrixStack();
|
||||
ms.push();
|
||||
ms.translate(0, 1, 0);
|
||||
|
||||
builder.setTranslation(0, 1, 0);
|
||||
builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
|
||||
blockRenderer.renderModelFlat(Minecraft.getInstance().world, model, referenceState, BlockPos.ZERO.down(),
|
||||
builder, true, random, 42, EmptyModelData.INSTANCE);
|
||||
blockRenderer.renderModelFlat(Minecraft.getInstance().world, model, referenceState, BlockPos.ZERO.down(), ms,
|
||||
builder, true, random, 42, OverlayTexture.DEFAULT_UV, EmptyModelData.INSTANCE);
|
||||
builder.finishDrawing();
|
||||
|
||||
return new SuperByteBuffer(builder.getByteBuffer());
|
||||
return new SuperByteBuffer(builder);
|
||||
}
|
||||
|
||||
public void invalidate() {
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
package com.simibubi.create.modules.contraptions.base;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.foundation.block.SafeTileEntityRendererFast;
|
||||
import com.simibubi.create.foundation.block.SafeTileEntityRenderer;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
||||
|
@ -11,33 +13,39 @@ import com.simibubi.create.modules.contraptions.KineticDebugger;
|
|||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.Direction.AxisDirection;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||
|
||||
@EventBusSubscriber(value = Dist.CLIENT)
|
||||
public class KineticTileEntityRenderer extends SafeTileEntityRendererFast<KineticTileEntity> {
|
||||
public class KineticTileEntityRenderer extends SafeTileEntityRenderer<KineticTileEntity> {
|
||||
|
||||
public static final Compartment<BlockState> KINETIC_TILE = new Compartment<>();
|
||||
public static boolean rainbowMode = false;
|
||||
|
||||
|
||||
public KineticTileEntityRenderer(TileEntityRendererDispatcher dispatcher) {
|
||||
super(dispatcher);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderFast(KineticTileEntity te, double x, double y, double z, float partialTicks, int destroyStage,
|
||||
BufferBuilder buffer) {
|
||||
renderRotatingBuffer(te, getWorld(), getRotatedModel(te), x, y, z, buffer);
|
||||
protected void renderSafe(KineticTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
|
||||
int light, int overlay) {
|
||||
renderRotatingBuffer(te, getRotatedModel(te), ms, buffer.getBuffer(RenderType.getSolid()));
|
||||
}
|
||||
|
||||
public static void renderRotatingKineticBlock(KineticTileEntity te, World world, BlockState renderedState, double x,
|
||||
double y, double z, BufferBuilder buffer) {
|
||||
public static void renderRotatingKineticBlock(KineticTileEntity te, BlockState renderedState, MatrixStack ms, BufferBuilder buffer) {
|
||||
SuperByteBuffer superByteBuffer = CreateClient.bufferCache.renderBlockIn(KINETIC_TILE, renderedState);
|
||||
renderRotatingBuffer(te, world, superByteBuffer, x, y, z, buffer);
|
||||
renderRotatingBuffer(te, superByteBuffer, ms, buffer);
|
||||
}
|
||||
|
||||
public static void renderRotatingBuffer(KineticTileEntity te, World world, SuperByteBuffer superBuffer, double x,
|
||||
double y, double z, BufferBuilder buffer) {
|
||||
buffer.putBulkData(standardKineticRotationTransform(superBuffer, te, world).translate(x, y, z).build());
|
||||
public static void renderRotatingBuffer(KineticTileEntity te, SuperByteBuffer superBuffer, MatrixStack ms, IVertexBuilder buffer) {
|
||||
standardKineticRotationTransform(superBuffer, te).renderInto(ms, buffer);
|
||||
}
|
||||
|
||||
public static float getAngleForTe(KineticTileEntity te, final BlockPos pos, Axis axis) {
|
||||
|
@ -47,18 +55,17 @@ public class KineticTileEntityRenderer extends SafeTileEntityRendererFast<Kineti
|
|||
return angle;
|
||||
}
|
||||
|
||||
public static SuperByteBuffer standardKineticRotationTransform(SuperByteBuffer buffer, KineticTileEntity te,
|
||||
World world) {
|
||||
public static SuperByteBuffer standardKineticRotationTransform(SuperByteBuffer buffer, KineticTileEntity te) {
|
||||
final BlockPos pos = te.getPos();
|
||||
Axis axis = ((IRotate) te.getBlockState().getBlock()).getRotationAxis(te.getBlockState());
|
||||
return kineticRotationTransform(buffer, te, axis, getAngleForTe(te, pos, axis), world);
|
||||
return kineticRotationTransform(buffer, te, axis, getAngleForTe(te, pos, axis));
|
||||
}
|
||||
|
||||
public static SuperByteBuffer kineticRotationTransform(SuperByteBuffer buffer, KineticTileEntity te, Axis axis,
|
||||
float angle, World world) {
|
||||
int packedLightmapCoords = te.getBlockState().getPackedLightmapCoords(world, te.getPos());
|
||||
buffer.light(packedLightmapCoords);
|
||||
buffer.rotateCentered(axis, angle);
|
||||
float angle) {
|
||||
int light = te.getBlockState().getLightValue(te.getWorld(), te.getPos());
|
||||
buffer.light((0xF0 << 24) | (light << 4));
|
||||
buffer.rotateCentered(Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis), angle);
|
||||
|
||||
int white = 0xFFFFFF;
|
||||
if (KineticDebugger.isActive()) {
|
||||
|
|
|
@ -111,7 +111,6 @@ public class ContraptionRenderer {
|
|||
Random random = new Random();
|
||||
BufferBuilder builder = new BufferBuilder(0);
|
||||
builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
|
||||
builder.setTranslation(0, 0, 0);
|
||||
|
||||
for (BlockInfo info : c.blocks.values())
|
||||
renderWorld.setBlockState(info.pos, info.state);
|
||||
|
@ -129,7 +128,7 @@ public class ContraptionRenderer {
|
|||
|
||||
builder.finishDrawing();
|
||||
renderWorld.clear();
|
||||
return new SuperByteBuffer(builder.getByteBuffer());
|
||||
return new SuperByteBuffer(builder);
|
||||
}
|
||||
|
||||
private static void renderActors(World world, Contraption c, Consumer<SuperByteBuffer> transform,
|
||||
|
@ -158,7 +157,7 @@ public class ContraptionRenderer {
|
|||
}
|
||||
|
||||
public static int getLight(World world, float lx, float ly, float lz) {
|
||||
MutableBlockPos pos = new MutableBlockPos();
|
||||
BlockPos.Mutable pos = new BlockPos.Mutable();
|
||||
float sky = 0, block = 0;
|
||||
float offset = 1 / 8f;
|
||||
|
||||
|
@ -166,8 +165,8 @@ public class ContraptionRenderer {
|
|||
for (float yOffset = offset; yOffset >= -offset; yOffset -= 2 * offset)
|
||||
for (float xOffset = offset; xOffset >= -offset; xOffset -= 2 * offset) {
|
||||
pos.setPos(lx + xOffset, ly + yOffset, lz + zOffset);
|
||||
sky += world.getLightFor(LightType.SKY, pos) / 8f;
|
||||
block += world.getLightFor(LightType.BLOCK, pos) / 8f;
|
||||
sky += world.getLightLevel(LightType.SKY, pos) / 8f;
|
||||
block += world.getLightLevel(LightType.BLOCK, pos) / 8f;
|
||||
}
|
||||
|
||||
return ((int) sky) << 20 | ((int) block) << 4;
|
||||
|
|
Loading…
Reference in a new issue