mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-16 07:53:42 +01:00
The Buffer Kerfuffle
- Refactored animated bytebuffers - Fixed animated buffers bleeding vertices and rendering inconsitently when switching from/to optifine shaders
This commit is contained in:
parent
4325cef8dc
commit
f564ce1a33
4 changed files with 89 additions and 148 deletions
|
@ -179,9 +179,7 @@ public class MechanicalCrafterRenderer extends SafeTileEntityRenderer<Mechanical
|
|||
if (te.phase == Phase.EXPORTING) {
|
||||
int textureIndex = (int) ((te.getCountDownSpeed() / 128f * AnimationTickHolder.ticks));
|
||||
beltBuffer.shiftUVtoSheet(AllSpriteShifts.CRAFTER_THINGIES, (textureIndex % 4) / 4f, 0, 1);
|
||||
} else {
|
||||
beltBuffer.dontShiftUV();
|
||||
}
|
||||
}
|
||||
|
||||
beltBuffer.renderInto(ms, vb);
|
||||
beltFrameBuffer.renderInto(ms, vb);
|
||||
|
|
|
@ -109,9 +109,7 @@ public class BeltRenderer extends SafeTileEntityRenderer<BeltTileEntity> {
|
|||
textureIndex += cycleLength;
|
||||
|
||||
beltBuffer.shiftUVtoSheet(spriteShift, (textureIndex % 4) / 4f, (textureIndex / 4) / 4f, 4);
|
||||
} else {
|
||||
beltBuffer.dontShiftUV();
|
||||
}
|
||||
}
|
||||
|
||||
beltBuffer.renderInto(ms, vb);
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@ 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;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.LightType;
|
||||
|
@ -27,16 +26,14 @@ public class SuperByteBuffer {
|
|||
public int getPackedLight(float x, float y, float z);
|
||||
}
|
||||
|
||||
public static final int FORMAT_LENGTH = DefaultVertexFormats.BLOCK.getSize();
|
||||
protected ByteBuffer original;
|
||||
protected ByteBuffer mutable;
|
||||
protected ByteBuffer template;
|
||||
protected int formatSize;
|
||||
|
||||
// Vertex Position
|
||||
private MatrixStack transforms;
|
||||
|
||||
// Vertex Texture Coords
|
||||
private boolean shouldShiftUV;
|
||||
private boolean resetUV;
|
||||
private SpriteShiftEntry spriteShift;
|
||||
private float uTarget, vTarget;
|
||||
|
||||
|
@ -52,81 +49,23 @@ public class SuperByteBuffer {
|
|||
|
||||
public SuperByteBuffer(BufferBuilder buf) {
|
||||
Pair<DrawState, ByteBuffer> state = buf.popData();
|
||||
ByteBuffer original = state.getSecond();
|
||||
original.order(ByteOrder.nativeOrder()); // Vanilla bug, endianness does not carry over into sliced buffers
|
||||
this.original = original;
|
||||
this.mutable = GLAllocation.createDirectByteBuffer(state.getFirst()
|
||||
.getCount()
|
||||
* buf.getVertexFormat()
|
||||
.getSize());
|
||||
this.mutable.order(original.order());
|
||||
this.mutable.limit(original.limit());
|
||||
mutable.put(this.original);
|
||||
mutable.rewind();
|
||||
ByteBuffer rendered = state.getSecond();
|
||||
rendered.order(ByteOrder.nativeOrder()); // Vanilla bug, endianness does not carry over into sliced buffers
|
||||
|
||||
formatSize = buf.getVertexFormat()
|
||||
.getSize();
|
||||
int size = state.getFirst()
|
||||
.getCount() * formatSize;
|
||||
|
||||
template = GLAllocation.createDirectByteBuffer(size);
|
||||
template.order(rendered.order());
|
||||
template.limit(rendered.limit());
|
||||
template.put(rendered);
|
||||
template.rewind();
|
||||
|
||||
transforms = new MatrixStack();
|
||||
}
|
||||
|
||||
public ByteBuffer build(MatrixStack view) {
|
||||
original.rewind();
|
||||
mutable.rewind();
|
||||
|
||||
Matrix4f t = view.peek()
|
||||
.getModel()
|
||||
.copy();
|
||||
Matrix4f localTransforms = transforms.peek()
|
||||
.getModel();
|
||||
|
||||
t.multiply(localTransforms);
|
||||
|
||||
for (int vertex = 0; vertex < vertexCount(original); vertex++) {
|
||||
Vector4f pos = new Vector4f(getX(original, vertex), getY(original, vertex), getZ(original, vertex), 1F);
|
||||
Vector4f lightPos = new Vector4f(pos.getX(), pos.getY(), pos.getZ(), pos.getW());
|
||||
|
||||
pos.transform(t);
|
||||
lightPos.transform(localTransforms);
|
||||
putPos(mutable, vertex, pos.getX(), pos.getY(), pos.getZ());
|
||||
|
||||
if (shouldColor) {
|
||||
byte lumByte = getR(original, vertex);
|
||||
float lum = (lumByte < 0 ? 255 + lumByte : lumByte) / 256f;
|
||||
int r2 = (int) (r * lum);
|
||||
int g2 = (int) (g * lum);
|
||||
int b2 = (int) (b * lum);
|
||||
putColor(mutable, vertex, (byte) r2, (byte) g2, (byte) b2, (byte) a);
|
||||
}
|
||||
|
||||
if (shouldShiftUV) {
|
||||
float u = getU(original, vertex);
|
||||
float v = getV(original, vertex);
|
||||
float targetU = spriteShift.getTarget()
|
||||
.getInterpolatedU((getUnInterpolatedU(spriteShift.getOriginal(), u) / sheetSize) + uTarget * 16);
|
||||
float targetV = spriteShift.getTarget()
|
||||
.getInterpolatedV((getUnInterpolatedV(spriteShift.getOriginal(), v) / sheetSize) + vTarget * 16);
|
||||
putUV(mutable, vertex, targetU, targetV);
|
||||
}
|
||||
|
||||
if (resetUV)
|
||||
putUV(mutable, vertex, getU(original, vertex), getV(original, vertex));
|
||||
|
||||
if (shouldLight) {
|
||||
int light = packedLightCoords;
|
||||
if (lightTransform != null) {
|
||||
lightPos.transform(lightTransform);
|
||||
light = getLight(Minecraft.getInstance().world, lightPos);
|
||||
}
|
||||
putLight(mutable, vertex, light);
|
||||
}
|
||||
}
|
||||
|
||||
transforms = new MatrixStack();
|
||||
shouldShiftUV = false;
|
||||
shouldColor = false;
|
||||
shouldLight = false;
|
||||
mutable.rewind();
|
||||
return mutable;
|
||||
}
|
||||
|
||||
public static float getUnInterpolatedU(TextureAtlasSprite sprite, float u) {
|
||||
float f = sprite.getMaxU() - sprite.getMinU();
|
||||
return (u - sprite.getMinU()) / f * 16.0F;
|
||||
|
@ -137,31 +76,72 @@ public class SuperByteBuffer {
|
|||
return (v - sprite.getMinV()) / f * 16.0F;
|
||||
}
|
||||
|
||||
public void renderInto(MatrixStack input, IVertexBuilder buffer) {
|
||||
if (original.limit() == 0)
|
||||
public void renderInto(MatrixStack input, IVertexBuilder builder) {
|
||||
ByteBuffer buffer = template;
|
||||
if (buffer.limit() == 0)
|
||||
return;
|
||||
if (!(buffer instanceof BufferBuilder)) {
|
||||
Matrix4f t = input.peek()
|
||||
.getModel()
|
||||
.copy();
|
||||
Matrix4f localTransforms = transforms.peek()
|
||||
.getModel();
|
||||
t.multiply(localTransforms);
|
||||
buffer.rewind();
|
||||
|
||||
ByteBuffer m = mutable;
|
||||
for (int v = 0; v < vertexCount(m); v++) {
|
||||
Vector4f pos = new Vector4f(getX(original, v), getY(original, v), getZ(original, v), 1F);
|
||||
pos.transform(t);
|
||||
buffer.vertex(pos.getX(), pos.getY(), pos.getZ())
|
||||
.color(getR(m, v), getG(m, v), getB(m, v), getA(m, v))
|
||||
.texture(getU(m, v), getV(m, v))
|
||||
.light(getLight(m, v))
|
||||
.normal(getNX(m, v), getNY(m, v), getNZ(m, v))
|
||||
.endVertex();
|
||||
}
|
||||
transforms = new MatrixStack();
|
||||
} else
|
||||
((BufferBuilder) buffer).putBulkData(build(input));
|
||||
Matrix4f t = input.peek()
|
||||
.getModel()
|
||||
.copy();
|
||||
Matrix4f localTransforms = transforms.peek()
|
||||
.getModel();
|
||||
t.multiply(localTransforms);
|
||||
|
||||
for (int i = 0; i < vertexCount(buffer); i++) {
|
||||
float x = getX(buffer, i);
|
||||
float y = getY(buffer, i);
|
||||
float z = getZ(buffer, i);
|
||||
|
||||
Vector4f pos = new Vector4f(x, y, z, 1F);
|
||||
Vector4f lightPos = new Vector4f(x, y, z, 1F);
|
||||
pos.transform(t);
|
||||
lightPos.transform(localTransforms);
|
||||
|
||||
builder.vertex(pos.getX(), pos.getY(), pos.getZ());
|
||||
|
||||
byte r = getR(buffer, i);
|
||||
byte g = getG(buffer, i);
|
||||
byte b = getB(buffer, i);
|
||||
byte a = getA(buffer, i);
|
||||
|
||||
if (shouldColor) {
|
||||
float lum = (r < 0 ? 255 + r : r) / 256f;
|
||||
builder.color((int) (this.r * lum), (int) (this.g * lum), (int) (this.b * lum), this.a);
|
||||
} else
|
||||
builder.color(r, g, b, a);
|
||||
|
||||
float u = getU(buffer, i);
|
||||
float v = getV(buffer, i);
|
||||
|
||||
if (shouldShiftUV) {
|
||||
float targetU = spriteShift.getTarget()
|
||||
.getInterpolatedU((getUnInterpolatedU(spriteShift.getOriginal(), u) / sheetSize) + uTarget * 16);
|
||||
float targetV = spriteShift.getTarget()
|
||||
.getInterpolatedV((getUnInterpolatedV(spriteShift.getOriginal(), v) / sheetSize) + vTarget * 16);
|
||||
builder.texture(targetU, targetV);
|
||||
} else
|
||||
builder.texture(u, v);
|
||||
|
||||
if (shouldLight) {
|
||||
int light = packedLightCoords;
|
||||
if (lightTransform != null) {
|
||||
lightPos.transform(lightTransform);
|
||||
light = getLight(Minecraft.getInstance().world, lightPos);
|
||||
}
|
||||
builder.light(light);
|
||||
} else
|
||||
builder.light(getLight(buffer, i));
|
||||
|
||||
builder.normal(getNX(buffer, i), getNY(buffer, i), getNZ(buffer, i))
|
||||
.endVertex();
|
||||
}
|
||||
|
||||
transforms = new MatrixStack();
|
||||
shouldShiftUV = false;
|
||||
shouldColor = false;
|
||||
shouldLight = false;
|
||||
}
|
||||
|
||||
public SuperByteBuffer translate(double x, double y, double z) {
|
||||
|
@ -188,7 +168,6 @@ public class SuperByteBuffer {
|
|||
|
||||
public SuperByteBuffer shiftUV(SpriteShiftEntry entry) {
|
||||
shouldShiftUV = true;
|
||||
resetUV = false;
|
||||
spriteShift = entry;
|
||||
uTarget = 0;
|
||||
vTarget = 0;
|
||||
|
@ -198,7 +177,6 @@ public class SuperByteBuffer {
|
|||
|
||||
public SuperByteBuffer shiftUVtoSheet(SpriteShiftEntry entry, float uTarget, float vTarget, int sheetSize) {
|
||||
shouldShiftUV = true;
|
||||
resetUV = false;
|
||||
spriteShift = entry;
|
||||
this.uTarget = uTarget;
|
||||
this.vTarget = vTarget;
|
||||
|
@ -206,12 +184,6 @@ public class SuperByteBuffer {
|
|||
return this;
|
||||
}
|
||||
|
||||
public SuperByteBuffer dontShiftUV() {
|
||||
shouldShiftUV = false;
|
||||
resetUV = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SuperByteBuffer light(int packedLightCoords) {
|
||||
shouldLight = true;
|
||||
lightTransform = null;
|
||||
|
@ -235,11 +207,11 @@ public class SuperByteBuffer {
|
|||
}
|
||||
|
||||
protected int vertexCount(ByteBuffer buffer) {
|
||||
return buffer.limit() / FORMAT_LENGTH;
|
||||
return buffer.limit() / formatSize;
|
||||
}
|
||||
|
||||
protected int getBufferPosition(int vertexIndex) {
|
||||
return vertexIndex * FORMAT_LENGTH;
|
||||
return vertexIndex * formatSize;
|
||||
}
|
||||
|
||||
protected float getX(ByteBuffer buffer, int index) {
|
||||
|
@ -294,32 +266,6 @@ public class SuperByteBuffer {
|
|||
return buffer.get(getBufferPosition(index) + 30);
|
||||
}
|
||||
|
||||
protected void putPos(ByteBuffer buffer, int index, float x, float y, float z) {
|
||||
int pos = getBufferPosition(index);
|
||||
buffer.putFloat(pos, x);
|
||||
buffer.putFloat(pos + 4, y);
|
||||
buffer.putFloat(pos + 8, z);
|
||||
}
|
||||
|
||||
protected void putUV(ByteBuffer buffer, int index, float u, float v) {
|
||||
int pos = getBufferPosition(index);
|
||||
buffer.putFloat(pos + 16, u);
|
||||
buffer.putFloat(pos + 20, v);
|
||||
}
|
||||
|
||||
protected void putLight(ByteBuffer buffer, int index, int packedLight) {
|
||||
buffer.putShort(getBufferPosition(index) + 24, (short) (packedLight & 0xFF));
|
||||
buffer.putShort(getBufferPosition(index) + 26, (short) ((packedLight >> 16) & 0xFF));
|
||||
}
|
||||
|
||||
protected void putColor(ByteBuffer buffer, int index, byte r, byte g, byte b, byte a) {
|
||||
int bufferPosition = getBufferPosition(index);
|
||||
buffer.put(bufferPosition + 12, r);
|
||||
buffer.put(bufferPosition + 13, g);
|
||||
buffer.put(bufferPosition + 14, b);
|
||||
buffer.put(bufferPosition + 15, a);
|
||||
}
|
||||
|
||||
private static int getLight(World world, Vector4f lightPos) {
|
||||
BlockPos.Mutable pos = new BlockPos.Mutable();
|
||||
float sky = 0, block = 0;
|
||||
|
|
|
@ -2,7 +2,6 @@ package com.simibubi.create.foundation.utility;
|
|||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Supplier;
|
||||
|
@ -110,14 +109,14 @@ public class SuperByteBufferCache {
|
|||
}
|
||||
|
||||
private SuperByteBuffer standardModelRender(IBakedModel model, BlockState referenceState, MatrixStack ms) {
|
||||
BlockRendererDispatcher dispatcher = Minecraft.getInstance()
|
||||
.getBlockRendererDispatcher();
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
BlockRendererDispatcher dispatcher = mc.getBlockRendererDispatcher();
|
||||
BlockModelRenderer blockRenderer = dispatcher.getBlockModelRenderer();
|
||||
BufferBuilder builder = new BufferBuilder(DefaultVertexFormats.BLOCK.getIntegerSize());
|
||||
Random random = new Random();
|
||||
BufferBuilder builder = new BufferBuilder(512);
|
||||
|
||||
builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
|
||||
blockRenderer.renderModelFlat(Minecraft.getInstance().world, model, referenceState, BlockPos.ZERO.up(255), ms,
|
||||
builder, true, random, 42, OverlayTexture.DEFAULT_UV, EmptyModelData.INSTANCE);
|
||||
blockRenderer.renderModel(mc.world, model, referenceState, BlockPos.ZERO.up(255), ms, builder, true,
|
||||
mc.world.rand, 42, OverlayTexture.DEFAULT_UV, EmptyModelData.INSTANCE);
|
||||
builder.finishDrawing();
|
||||
|
||||
return new SuperByteBuffer(builder);
|
||||
|
|
Loading…
Reference in a new issue