mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-28 16:06:48 +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) {
|
if (te.phase == Phase.EXPORTING) {
|
||||||
int textureIndex = (int) ((te.getCountDownSpeed() / 128f * AnimationTickHolder.ticks));
|
int textureIndex = (int) ((te.getCountDownSpeed() / 128f * AnimationTickHolder.ticks));
|
||||||
beltBuffer.shiftUVtoSheet(AllSpriteShifts.CRAFTER_THINGIES, (textureIndex % 4) / 4f, 0, 1);
|
beltBuffer.shiftUVtoSheet(AllSpriteShifts.CRAFTER_THINGIES, (textureIndex % 4) / 4f, 0, 1);
|
||||||
} else {
|
}
|
||||||
beltBuffer.dontShiftUV();
|
|
||||||
}
|
|
||||||
|
|
||||||
beltBuffer.renderInto(ms, vb);
|
beltBuffer.renderInto(ms, vb);
|
||||||
beltFrameBuffer.renderInto(ms, vb);
|
beltFrameBuffer.renderInto(ms, vb);
|
||||||
|
|
|
@ -109,9 +109,7 @@ public class BeltRenderer extends SafeTileEntityRenderer<BeltTileEntity> {
|
||||||
textureIndex += cycleLength;
|
textureIndex += cycleLength;
|
||||||
|
|
||||||
beltBuffer.shiftUVtoSheet(spriteShift, (textureIndex % 4) / 4f, (textureIndex / 4) / 4f, 4);
|
beltBuffer.shiftUVtoSheet(spriteShift, (textureIndex % 4) / 4f, (textureIndex / 4) / 4f, 4);
|
||||||
} else {
|
}
|
||||||
beltBuffer.dontShiftUV();
|
|
||||||
}
|
|
||||||
|
|
||||||
beltBuffer.renderInto(ms, vb);
|
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.Matrix4f;
|
||||||
import net.minecraft.client.renderer.Vector4f;
|
import net.minecraft.client.renderer.Vector4f;
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.LightType;
|
import net.minecraft.world.LightType;
|
||||||
|
@ -27,16 +26,14 @@ public class SuperByteBuffer {
|
||||||
public int getPackedLight(float x, float y, float z);
|
public int getPackedLight(float x, float y, float z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final int FORMAT_LENGTH = DefaultVertexFormats.BLOCK.getSize();
|
protected ByteBuffer template;
|
||||||
protected ByteBuffer original;
|
protected int formatSize;
|
||||||
protected ByteBuffer mutable;
|
|
||||||
|
|
||||||
// Vertex Position
|
// Vertex Position
|
||||||
private MatrixStack transforms;
|
private MatrixStack transforms;
|
||||||
|
|
||||||
// Vertex Texture Coords
|
// Vertex Texture Coords
|
||||||
private boolean shouldShiftUV;
|
private boolean shouldShiftUV;
|
||||||
private boolean resetUV;
|
|
||||||
private SpriteShiftEntry spriteShift;
|
private SpriteShiftEntry spriteShift;
|
||||||
private float uTarget, vTarget;
|
private float uTarget, vTarget;
|
||||||
|
|
||||||
|
@ -52,81 +49,23 @@ public class SuperByteBuffer {
|
||||||
|
|
||||||
public SuperByteBuffer(BufferBuilder buf) {
|
public SuperByteBuffer(BufferBuilder buf) {
|
||||||
Pair<DrawState, ByteBuffer> state = buf.popData();
|
Pair<DrawState, ByteBuffer> state = buf.popData();
|
||||||
ByteBuffer original = state.getSecond();
|
ByteBuffer rendered = state.getSecond();
|
||||||
original.order(ByteOrder.nativeOrder()); // Vanilla bug, endianness does not carry over into sliced buffers
|
rendered.order(ByteOrder.nativeOrder()); // Vanilla bug, endianness does not carry over into sliced buffers
|
||||||
this.original = original;
|
|
||||||
this.mutable = GLAllocation.createDirectByteBuffer(state.getFirst()
|
formatSize = buf.getVertexFormat()
|
||||||
.getCount()
|
.getSize();
|
||||||
* buf.getVertexFormat()
|
int size = state.getFirst()
|
||||||
.getSize());
|
.getCount() * formatSize;
|
||||||
this.mutable.order(original.order());
|
|
||||||
this.mutable.limit(original.limit());
|
template = GLAllocation.createDirectByteBuffer(size);
|
||||||
mutable.put(this.original);
|
template.order(rendered.order());
|
||||||
mutable.rewind();
|
template.limit(rendered.limit());
|
||||||
|
template.put(rendered);
|
||||||
|
template.rewind();
|
||||||
|
|
||||||
transforms = new MatrixStack();
|
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) {
|
public static float getUnInterpolatedU(TextureAtlasSprite sprite, float u) {
|
||||||
float f = sprite.getMaxU() - sprite.getMinU();
|
float f = sprite.getMaxU() - sprite.getMinU();
|
||||||
return (u - sprite.getMinU()) / f * 16.0F;
|
return (u - sprite.getMinU()) / f * 16.0F;
|
||||||
|
@ -137,31 +76,72 @@ public class SuperByteBuffer {
|
||||||
return (v - sprite.getMinV()) / f * 16.0F;
|
return (v - sprite.getMinV()) / f * 16.0F;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void renderInto(MatrixStack input, IVertexBuilder buffer) {
|
public void renderInto(MatrixStack input, IVertexBuilder builder) {
|
||||||
if (original.limit() == 0)
|
ByteBuffer buffer = template;
|
||||||
|
if (buffer.limit() == 0)
|
||||||
return;
|
return;
|
||||||
if (!(buffer instanceof BufferBuilder)) {
|
buffer.rewind();
|
||||||
Matrix4f t = input.peek()
|
|
||||||
.getModel()
|
|
||||||
.copy();
|
|
||||||
Matrix4f localTransforms = transforms.peek()
|
|
||||||
.getModel();
|
|
||||||
t.multiply(localTransforms);
|
|
||||||
|
|
||||||
ByteBuffer m = mutable;
|
Matrix4f t = input.peek()
|
||||||
for (int v = 0; v < vertexCount(m); v++) {
|
.getModel()
|
||||||
Vector4f pos = new Vector4f(getX(original, v), getY(original, v), getZ(original, v), 1F);
|
.copy();
|
||||||
pos.transform(t);
|
Matrix4f localTransforms = transforms.peek()
|
||||||
buffer.vertex(pos.getX(), pos.getY(), pos.getZ())
|
.getModel();
|
||||||
.color(getR(m, v), getG(m, v), getB(m, v), getA(m, v))
|
t.multiply(localTransforms);
|
||||||
.texture(getU(m, v), getV(m, v))
|
|
||||||
.light(getLight(m, v))
|
for (int i = 0; i < vertexCount(buffer); i++) {
|
||||||
.normal(getNX(m, v), getNY(m, v), getNZ(m, v))
|
float x = getX(buffer, i);
|
||||||
.endVertex();
|
float y = getY(buffer, i);
|
||||||
}
|
float z = getZ(buffer, i);
|
||||||
transforms = new MatrixStack();
|
|
||||||
} else
|
Vector4f pos = new Vector4f(x, y, z, 1F);
|
||||||
((BufferBuilder) buffer).putBulkData(build(input));
|
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) {
|
public SuperByteBuffer translate(double x, double y, double z) {
|
||||||
|
@ -188,7 +168,6 @@ public class SuperByteBuffer {
|
||||||
|
|
||||||
public SuperByteBuffer shiftUV(SpriteShiftEntry entry) {
|
public SuperByteBuffer shiftUV(SpriteShiftEntry entry) {
|
||||||
shouldShiftUV = true;
|
shouldShiftUV = true;
|
||||||
resetUV = false;
|
|
||||||
spriteShift = entry;
|
spriteShift = entry;
|
||||||
uTarget = 0;
|
uTarget = 0;
|
||||||
vTarget = 0;
|
vTarget = 0;
|
||||||
|
@ -198,7 +177,6 @@ public class SuperByteBuffer {
|
||||||
|
|
||||||
public SuperByteBuffer shiftUVtoSheet(SpriteShiftEntry entry, float uTarget, float vTarget, int sheetSize) {
|
public SuperByteBuffer shiftUVtoSheet(SpriteShiftEntry entry, float uTarget, float vTarget, int sheetSize) {
|
||||||
shouldShiftUV = true;
|
shouldShiftUV = true;
|
||||||
resetUV = false;
|
|
||||||
spriteShift = entry;
|
spriteShift = entry;
|
||||||
this.uTarget = uTarget;
|
this.uTarget = uTarget;
|
||||||
this.vTarget = vTarget;
|
this.vTarget = vTarget;
|
||||||
|
@ -206,12 +184,6 @@ public class SuperByteBuffer {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SuperByteBuffer dontShiftUV() {
|
|
||||||
shouldShiftUV = false;
|
|
||||||
resetUV = true;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SuperByteBuffer light(int packedLightCoords) {
|
public SuperByteBuffer light(int packedLightCoords) {
|
||||||
shouldLight = true;
|
shouldLight = true;
|
||||||
lightTransform = null;
|
lightTransform = null;
|
||||||
|
@ -235,11 +207,11 @@ public class SuperByteBuffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int vertexCount(ByteBuffer buffer) {
|
protected int vertexCount(ByteBuffer buffer) {
|
||||||
return buffer.limit() / FORMAT_LENGTH;
|
return buffer.limit() / formatSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int getBufferPosition(int vertexIndex) {
|
protected int getBufferPosition(int vertexIndex) {
|
||||||
return vertexIndex * FORMAT_LENGTH;
|
return vertexIndex * formatSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected float getX(ByteBuffer buffer, int index) {
|
protected float getX(ByteBuffer buffer, int index) {
|
||||||
|
@ -294,32 +266,6 @@ public class SuperByteBuffer {
|
||||||
return buffer.get(getBufferPosition(index) + 30);
|
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) {
|
private static int getLight(World world, Vector4f lightPos) {
|
||||||
BlockPos.Mutable pos = new BlockPos.Mutable();
|
BlockPos.Mutable pos = new BlockPos.Mutable();
|
||||||
float sky = 0, block = 0;
|
float sky = 0, block = 0;
|
||||||
|
|
|
@ -2,7 +2,6 @@ package com.simibubi.create.foundation.utility;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Random;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
@ -110,14 +109,14 @@ public class SuperByteBufferCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
private SuperByteBuffer standardModelRender(IBakedModel model, BlockState referenceState, MatrixStack ms) {
|
private SuperByteBuffer standardModelRender(IBakedModel model, BlockState referenceState, MatrixStack ms) {
|
||||||
BlockRendererDispatcher dispatcher = Minecraft.getInstance()
|
Minecraft mc = Minecraft.getInstance();
|
||||||
.getBlockRendererDispatcher();
|
BlockRendererDispatcher dispatcher = mc.getBlockRendererDispatcher();
|
||||||
BlockModelRenderer blockRenderer = dispatcher.getBlockModelRenderer();
|
BlockModelRenderer blockRenderer = dispatcher.getBlockModelRenderer();
|
||||||
BufferBuilder builder = new BufferBuilder(DefaultVertexFormats.BLOCK.getIntegerSize());
|
BufferBuilder builder = new BufferBuilder(512);
|
||||||
Random random = new Random();
|
|
||||||
builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
|
builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
|
||||||
blockRenderer.renderModelFlat(Minecraft.getInstance().world, model, referenceState, BlockPos.ZERO.up(255), ms,
|
blockRenderer.renderModel(mc.world, model, referenceState, BlockPos.ZERO.up(255), ms, builder, true,
|
||||||
builder, true, random, 42, OverlayTexture.DEFAULT_UV, EmptyModelData.INSTANCE);
|
mc.world.rand, 42, OverlayTexture.DEFAULT_UV, EmptyModelData.INSTANCE);
|
||||||
builder.finishDrawing();
|
builder.finishDrawing();
|
||||||
|
|
||||||
return new SuperByteBuffer(builder);
|
return new SuperByteBuffer(builder);
|
||||||
|
|
Loading…
Reference in a new issue