Various clean up

- Color component methods in vertex lists now use floats instead of
bytes
- VertexList no longer implements PointSet
- Return better defaults for unused attributes in vertex list
implementations
- Slightly optimize vertex list implementations
- Fix ModelUtil#convertBlockBuffer allocating wrong number of bytes for
destination data
- Remove combined color methods in vertex lists
- Remove ReusableVertexList#vertexStride
- Remove default methods in VertexType
- Rename Mesh#close to Mesh#delete
This commit is contained in:
PepperCode1 2023-03-25 20:35:17 -07:00
parent 9a88bb96ab
commit 6add6c43b1
25 changed files with 362 additions and 337 deletions

View file

@ -7,20 +7,13 @@ public interface MutableVertexList extends VertexList {
void z(int index, float z);
void r(int index, byte r);
void r(int index, float r);
void g(int index, byte g);
void g(int index, float g);
void b(int index, byte b);
void b(int index, float b);
void a(int index, byte a);
default void color(int index, int color) {
a(index, (byte) (color >> 24 & 0xFF));
r(index, (byte) (color >> 16 & 0xFF));
g(index, (byte) (color >> 8 & 0xFF));
b(index, (byte) (color & 0xFF));
}
void a(int index, float a);
void u(int index, float u);

View file

@ -5,7 +5,5 @@ public interface ReusableVertexList extends MutableVertexList {
void ptr(long ptr);
int vertexStride();
void vertexCount(int vertexCount);
}

View file

@ -1,7 +1,5 @@
package com.jozufozu.flywheel.api.vertex;
import com.dreizak.miniball.model.PointSet;
/**
* A read only view of a vertex buffer.
*
@ -11,24 +9,20 @@ import com.dreizak.miniball.model.PointSet;
* </p>
* TODO: more flexible elements?
*/
public interface VertexList extends PointSet {
public interface VertexList {
float x(int index);
float y(int index);
float z(int index);
byte r(int index);
float r(int index);
byte g(int index);
float g(int index);
byte b(int index);
float b(int index);
byte a(int index);
default int color(int index) {
return a(index) << 24 | r(index) << 16 | g(index) << 8 | b(index);
}
float a(int index);
float u(int index);
@ -80,24 +74,4 @@ public interface VertexList extends PointSet {
default boolean isEmpty() {
return vertexCount() == 0;
}
@Override
default int size() {
return vertexCount();
}
@Override
default int dimension() {
return 3;
}
@Override
default double coord(int i, int j) {
return switch (j) {
case 0 -> x(i);
case 1 -> y(i);
case 2 -> z(i);
default -> throw new IllegalArgumentException("Invalid dimension: " + j);
};
}
}

View file

@ -14,12 +14,4 @@ public interface VertexType extends VertexListProvider {
BufferLayout getLayout();
FileResolution getLayoutShader();
default int getStride() {
return getLayout().getStride();
}
default int byteOffset(int vertexIndex) {
return getStride() * vertexIndex;
}
}

View file

@ -36,7 +36,7 @@ public class BatchedMeshPool {
public BatchedMeshPool(VertexFormat vertexFormat) {
this.vertexFormat = vertexFormat;
vertexList = VertexListProvider.get(vertexFormat).createVertexList();
growthMargin = vertexList.vertexStride() * 32;
growthMargin = vertexFormat.getVertexSize() * 32;
}
/**
@ -47,7 +47,7 @@ public class BatchedMeshPool {
*/
public BufferedMesh alloc(Mesh mesh) {
return meshes.computeIfAbsent(mesh, m -> {
BufferedMesh bufferedMesh = new BufferedMesh(m, byteSize, m.getVertexCount() * vertexList.vertexStride());
BufferedMesh bufferedMesh = new BufferedMesh(m, byteSize);
byteSize += bufferedMesh.size();
allBuffered.add(bufferedMesh);
pendingUpload.add(bufferedMesh);
@ -150,19 +150,50 @@ public class BatchedMeshPool {
public class BufferedMesh {
private final Mesh mesh;
private final int byteSize;
private final int vertexCount;
private long byteIndex;
private int byteSize;
private boolean deleted;
private BufferedMesh(Mesh mesh, long byteIndex, int byteSize) {
private BufferedMesh(Mesh mesh, long byteIndex) {
this.mesh = mesh;
vertexCount = mesh.getVertexCount();
byteSize = vertexCount * vertexFormat.getVertexSize();
this.byteIndex = byteIndex;
this.byteSize = byteSize;
}
public int size() {
return byteSize;
}
public int getVertexCount() {
return vertexCount;
}
public VertexFormat getVertexFormat() {
return vertexFormat;
}
public boolean isDeleted() {
return deleted;
}
private boolean isEmpty() {
return mesh.isEmpty() || isDeleted();
}
private long ptr() {
return BatchedMeshPool.this.memory.ptr() + byteIndex;
}
private void buffer(ReusableVertexList vertexList) {
if (isEmpty()) {
return;
}
vertexList.ptr(ptr());
vertexList.vertexCount(mesh.getVertexCount());
vertexList.vertexCount(vertexCount);
mesh.write(vertexList);
}
@ -175,34 +206,10 @@ public class BatchedMeshPool {
MemoryUtil.memCopy(ptr(), ptr, byteSize);
}
private boolean isEmpty() {
return mesh.isEmpty() || isDeleted();
}
private long ptr() {
return BatchedMeshPool.this.memory.ptr() + byteIndex;
}
public void delete() {
deleted = true;
BatchedMeshPool.this.dirty = true;
BatchedMeshPool.this.anyToRemove = true;
}
public Mesh getMesh() {
return mesh;
}
public int size() {
return byteSize;
}
public VertexFormat getVertexFormat() {
return vertexFormat;
}
public boolean isDeleted() {
return deleted;
}
}
}

View file

@ -39,10 +39,10 @@ public class BatchingEngine implements Engine {
// TODO: async task engine barriers
taskEngine.syncPoint();
submitTasks(taskEngine, stack, context.level());
submitTasks(taskEngine, stack.last(), context.level());
}
public void submitTasks(TaskEngine taskEngine, PoseStack stack, ClientLevel level) {
public void submitTasks(TaskEngine taskEngine, PoseStack.Pose matrices, ClientLevel level) {
for (var transformSetEntry : transformManager.getTransformSetsView().entrySet()) {
var stage = transformSetEntry.getKey();
var transformSet = transformSetEntry.getValue();
@ -65,7 +65,7 @@ public class BatchingEngine implements Engine {
int startVertex = 0;
for (var transformCall : transformCalls) {
transformCall.submitTasks(taskEngine, buffer, startVertex, stack, level);
transformCall.submitTasks(taskEngine, buffer, startVertex, matrices, level);
startVertex += transformCall.getTotalVertexCount();
}
}

View file

@ -72,7 +72,7 @@ public class DrawBuffer {
}
ReusableVertexList vertexList = provider.createVertexList();
vertexList.ptr(memory.ptr() + startVertex * vertexList.vertexStride());
vertexList.ptr(memory.ptr() + startVertex * stride);
vertexList.vertexCount(vertexCount);
return vertexList;
}

View file

@ -9,7 +9,6 @@ import com.jozufozu.flywheel.api.vertex.MutableVertexList;
import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
import com.jozufozu.flywheel.backend.instancing.TaskEngine;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexFormat;
import com.mojang.math.Matrix3f;
import com.mojang.math.Matrix4f;
import com.mojang.math.Vector3f;
@ -20,23 +19,25 @@ import net.minecraft.client.multiplayer.ClientLevel;
public class TransformCall<D extends InstancedPart> {
private final CPUInstancer<D> instancer;
private final Material material;
private final BatchedMeshPool.BufferedMesh bufferedMesh;
private final BatchedMeshPool.BufferedMesh mesh;
private final int meshVertexCount;
private final int meshByteSize;
public TransformCall(CPUInstancer<D> instancer, Material material, BatchedMeshPool.BufferedMesh mesh) {
this.instancer = instancer;
this.material = material;
this.bufferedMesh = mesh;
this.mesh = mesh;
meshVertexCount = mesh.getVertexCount();
meshByteSize = mesh.size();
}
public Material getMaterial() {
return material;
public int getTotalVertexCount() {
return meshVertexCount * instancer.getInstanceCount();
}
public VertexFormat getVertexFormat() {
return bufferedMesh.getVertexFormat();
}
void submitTasks(TaskEngine pool, DrawBuffer buffer, int startVertex, PoseStack stack, ClientLevel level) {
void submitTasks(TaskEngine pool, DrawBuffer buffer, int startVertex, PoseStack.Pose matrices, ClientLevel level) {
instancer.setup();
int instances = instancer.getInstanceCount();
@ -46,34 +47,32 @@ public class TransformCall<D extends InstancedPart> {
instances -= 512;
int start = Math.max(instances, 0);
int vertexCount = bufferedMesh.getMesh().getVertexCount() * (end - start);
int vertexCount = meshVertexCount * (end - start);
ReusableVertexList sub = buffer.slice(startVertex, vertexCount);
startVertex += vertexCount;
pool.submit(() -> transformRange(sub, start, end, stack, level));
pool.submit(() -> transformRange(sub, start, end, matrices, level));
}
}
private void transformRange(ReusableVertexList vertexList, int from, int to, PoseStack stack, ClientLevel level) {
transformList(vertexList, instancer.getRange(from, to), stack, level);
private void transformRange(ReusableVertexList vertexList, int from, int to, PoseStack.Pose matrices, ClientLevel level) {
transformList(vertexList, instancer.getRange(from, to), matrices, level);
}
void transformAll(ReusableVertexList vertexList, PoseStack stack, ClientLevel level) {
transformList(vertexList, instancer.getAll(), stack, level);
void transformAll(ReusableVertexList vertexList, PoseStack.Pose matrices, ClientLevel level) {
transformList(vertexList, instancer.getAll(), matrices, level);
}
private void transformList(ReusableVertexList vertexList, List<D> parts, PoseStack stack, ClientLevel level) {
private void transformList(ReusableVertexList vertexList, List<D> parts, PoseStack.Pose matrices, ClientLevel level) {
long anchorPtr = vertexList.ptr();
int totalVertexCount = vertexList.vertexCount();
int meshVertexCount = bufferedMesh.getMesh().getVertexCount();
int meshByteSize = bufferedMesh.size();
vertexList.vertexCount(meshVertexCount);
StructType.VertexTransformer<D> structVertexTransformer = instancer.type.getVertexTransformer();
for (D d : parts) {
bufferedMesh.copyTo(vertexList.ptr());
mesh.copyTo(vertexList.ptr());
structVertexTransformer.transform(vertexList, d, level);
@ -83,15 +82,15 @@ public class TransformCall<D extends InstancedPart> {
vertexList.ptr(anchorPtr);
vertexList.vertexCount(totalVertexCount);
material.getVertexTransformer().transform(vertexList, level);
applyPoseStack(vertexList, stack);
applyPoseStack(vertexList, matrices);
}
private static void applyPoseStack(MutableVertexList vertexList, PoseStack stack) {
private static void applyPoseStack(MutableVertexList vertexList, PoseStack.Pose matrices) {
Vector4f pos = new Vector4f();
Vector3f normal = new Vector3f();
Matrix4f modelMatrix = stack.last().pose();
Matrix3f normalMatrix = stack.last().normal();
Matrix4f modelMatrix = matrices.pose();
Matrix3f normalMatrix = matrices.normal();
for (int i = 0; i < vertexList.vertexCount(); i++) {
pos.set(
@ -117,8 +116,4 @@ public class TransformCall<D extends InstancedPart> {
vertexList.normalZ(i, normal.z());
}
}
public int getTotalVertexCount() {
return bufferedMesh.getMesh().getVertexCount() * instancer.getInstanceCount();
}
}

View file

@ -34,7 +34,7 @@ public class IndirectMeshPool {
public IndirectMeshPool(VertexType type, int vertexCapacity) {
vertexType = type;
vbo = glCreateBuffers();
var byteCapacity = type.byteOffset(vertexCapacity);
var byteCapacity = type.getLayout().getStride() * vertexCapacity;
glNamedBufferStorage(vbo, byteCapacity, GL_DYNAMIC_STORAGE_BIT);
clientStorage = MemoryBlock.malloc(byteCapacity);
}

View file

@ -37,7 +37,7 @@ public class InstancedMeshPool {
*/
public InstancedMeshPool(VertexType vertexType) {
this.vertexType = vertexType;
int stride = vertexType.getStride();
int stride = vertexType.getLayout().getStride();
this.vbo = new GlBuffer(GlBufferType.ARRAY_BUFFER);
this.vbo.setGrowthMargin(stride * 32);
@ -183,6 +183,26 @@ public class InstancedMeshPool {
this.ebo = mesh.createEBO();
}
public int size() {
return mesh.size();
}
public VertexType getVertexType() {
return vertexType;
}
public int getAttributeCount() {
return vertexType.getLayout().getAttributeCount();
}
public boolean isDeleted() {
return deleted;
}
private boolean isEmpty() {
return mesh.isEmpty() || isDeleted();
}
private void buffer(long ptr) {
mesh.write(ptr + byteIndex);
@ -203,10 +223,6 @@ public class InstancedMeshPool {
draw(instanceCount);
}
private boolean isEmpty() {
return mesh.isEmpty() || isDeleted();
}
private void setup(GlVertexArray vao) {
if (boundTo.add(vao)) {
vao.enableArrays(getAttributeCount());
@ -229,25 +245,5 @@ public class InstancedMeshPool {
InstancedMeshPool.this.dirty = true;
InstancedMeshPool.this.anyToRemove = true;
}
public Mesh getMesh() {
return mesh;
}
public int size() {
return mesh.size();
}
public VertexType getVertexType() {
return vertexType;
}
public int getAttributeCount() {
return vertexType.getLayout().getAttributeCount();
}
public boolean isDeleted() {
return deleted;
}
}
}

View file

@ -14,7 +14,6 @@ import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.Sheets;
import net.minecraft.client.renderer.texture.AbstractTexture;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth;
import net.minecraft.world.inventory.InventoryMenu;
public final class Materials {
@ -26,9 +25,9 @@ public final class Materials {
DiffuseLightCalculator diffuseCalc = DiffuseLightCalculator.forLevel(level);
for (int i = 0; i < vertexList.vertexCount(); i++) {
float diffuse = diffuseCalc.getDiffuse(vertexList.normalX(i), vertexList.normalY(i), vertexList.normalZ(i), true);
vertexList.r(i, (byte) Mth.clamp((int) (Byte.toUnsignedInt(vertexList.r(i)) * diffuse), 0, 255));
vertexList.g(i, (byte) Mth.clamp((int) (Byte.toUnsignedInt(vertexList.g(i)) * diffuse), 0, 255));
vertexList.b(i, (byte) Mth.clamp((int) (Byte.toUnsignedInt(vertexList.b(i)) * diffuse), 0, 255));
vertexList.r(i, vertexList.r(i) * diffuse);
vertexList.g(i, vertexList.g(i) * diffuse);
vertexList.b(i, vertexList.b(i) * diffuse);
}
};

View file

@ -16,8 +16,8 @@ public class ModelPart implements Mesh {
private final int vertexCount;
private final MemoryBlock contents;
private final ReusableVertexList vertexList;
private final String name;
private final Vector4f boundingSphere;
private final String name;
public ModelPart(List<PartBuilder.CuboidBuilder> cuboids, String name) {
this.name = name;
@ -63,7 +63,12 @@ public class ModelPart implements Mesh {
}
@Override
public void close() {
public Vector4fc getBoundingSphere() {
return boundingSphere;
}
@Override
public void delete() {
contents.free();
}
@ -72,11 +77,6 @@ public class ModelPart implements Mesh {
return name;
}
@Override
public Vector4fc getBoundingSphere() {
return boundingSphere;
}
private static int countVertices(List<PartBuilder.CuboidBuilder> cuboids) {
int vertices = 0;
for (PartBuilder.CuboidBuilder cuboid : cuboids) {

View file

@ -13,8 +13,6 @@ public interface Mesh {
VertexType getVertexType();
Vector4fc getBoundingSphere();
/**
* @return The number of vertices this mesh has.
*/
@ -32,7 +30,7 @@ public interface Mesh {
* The size in bytes that this mesh's data takes up.
*/
default int size() {
return getVertexType().byteOffset(getVertexCount());
return getVertexType().getLayout().getStride() * getVertexCount();
}
/**
@ -64,7 +62,9 @@ public interface Mesh {
.quads2Tris(getVertexCount() / 4);
}
void close();
Vector4fc getBoundingSphere();
void delete();
/**
* A name uniquely identifying this mesh.

View file

@ -3,11 +3,11 @@ package com.jozufozu.flywheel.core.model;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.lwjgl.system.MemoryUtil;
import com.dreizak.miniball.highdim.Miniball;
import com.dreizak.miniball.model.PointSet;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.material.Material;
import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
@ -58,7 +58,7 @@ public class ModelUtil {
VertexType dstVertexType = Formats.BLOCK;
ByteBuffer src = pair.getSecond();
MemoryBlock dst = MemoryBlock.malloc(src.capacity());
MemoryBlock dst = MemoryBlock.malloc(vertexCount * dstVertexType.getLayout().getStride());
long srcPtr = MemoryUtil.memAddress(src);
long dstPtr = dst.ptr();
@ -94,11 +94,34 @@ public class ModelUtil {
return null;
}
@NotNull
public static Vector4f computeBoundingSphere(VertexList reader) {
var miniball = new Miniball(reader);
double[] center = miniball.center();
double radius = miniball.radius();
return new Vector4f((float) center[0], (float) center[1], (float) center[2], (float) radius);
}
public static Vector4f computeBoundingSphere(VertexList vertexList) {
return computeBoundingSphere(new PointSet() {
@Override
public int size() {
return vertexList.vertexCount();
}
@Override
public int dimension() {
return 3;
}
@Override
public double coord(int i, int j) {
return switch (j) {
case 0 -> vertexList.x(i);
case 1 -> vertexList.y(i);
case 2 -> vertexList.z(i);
default -> throw new IllegalArgumentException("Invalid dimension: " + j);
};
}
});
}
public static Vector4f computeBoundingSphere(PointSet points) {
var miniball = new Miniball(points);
double[] center = miniball.center();
double radius = miniball.radius();
return new Vector4f((float) center[0], (float) center[1], (float) center[2], (float) radius);
}
}

View file

@ -30,7 +30,7 @@ public class SimpleLazyModel implements Model {
@Override
public void delete() {
supplier.ifPresent(Mesh::close);
supplier.ifPresent(Mesh::delete);
}
public int getVertexCount() {
@ -40,7 +40,7 @@ public class SimpleLazyModel implements Model {
@Override
public String toString() {
return "BasicModelSupplier{" + supplier.map(Mesh::name)
return "SimpleLazyModel{" + supplier.map(Mesh::name)
.orElse("Uninitialized") + '}';
}
}

View file

@ -12,8 +12,8 @@ public class SimpleMesh implements Mesh {
private final int vertexCount;
private final MemoryBlock contents;
private final ReusableVertexList vertexList;
private final String name;
private final Vector4f boundingSphere;
private final String name;
public SimpleMesh(VertexType vertexType, MemoryBlock contents, String name) {
this.vertexType = vertexType;
@ -21,7 +21,7 @@ public class SimpleMesh implements Mesh {
this.name = name;
int bytes = (int) contents.size();
int stride = vertexType.getStride();
int stride = vertexType.getLayout().getStride();
if (bytes % stride != 0) {
throw new IllegalArgumentException("MemoryBlock contains non-whole amount of vertices!");
}
@ -55,7 +55,12 @@ public class SimpleMesh implements Mesh {
}
@Override
public void close() {
public Vector4fc getBoundingSphere() {
return boundingSphere;
}
@Override
public void delete() {
contents.free();
}
@ -64,11 +69,6 @@ public class SimpleMesh implements Mesh {
return name;
}
@Override
public Vector4fc getBoundingSphere() {
return boundingSphere;
}
@Override
public String toString() {
return "SimpleMesh{" + "name='" + name + "',vertexType='" + vertexType + "}";

View file

@ -22,7 +22,7 @@ public class TessellatedModel implements Model {
@Override
public void delete() {
meshes.values()
.forEach(Mesh::close);
.forEach(Mesh::delete);
}
public boolean isShadeSeparated() {

View file

@ -6,6 +6,7 @@ import com.jozufozu.flywheel.core.Components;
import com.jozufozu.flywheel.core.layout.BufferLayout;
import com.jozufozu.flywheel.core.layout.CommonItems;
import com.jozufozu.flywheel.core.source.FileResolution;
import com.jozufozu.flywheel.util.RenderMath;
import com.mojang.math.Matrix3f;
import com.mojang.math.Matrix4f;
import com.mojang.math.Quaternion;
@ -58,7 +59,12 @@ public class OrientedType implements StructType<OrientedPart> {
Matrix3f normalMatrix = new Matrix3f(q);
float r = RenderMath.uf(struct.r);
float g = RenderMath.uf(struct.g);
float b = RenderMath.uf(struct.b);
float a = RenderMath.uf(struct.a);
int light = struct.getPackedLight();
for (int i = 0; i < vertexList.vertexCount(); i++) {
pos.set(
vertexList.x(i),
@ -82,10 +88,10 @@ public class OrientedType implements StructType<OrientedPart> {
vertexList.normalY(i, normal.y());
vertexList.normalZ(i, normal.z());
vertexList.r(i, struct.r);
vertexList.g(i, struct.g);
vertexList.b(i, struct.b);
vertexList.a(i, struct.a);
vertexList.r(i, r);
vertexList.g(i, g);
vertexList.b(i, b);
vertexList.a(i, a);
vertexList.light(i, light);
}
};

View file

@ -6,6 +6,7 @@ import com.jozufozu.flywheel.core.Components;
import com.jozufozu.flywheel.core.layout.BufferLayout;
import com.jozufozu.flywheel.core.layout.CommonItems;
import com.jozufozu.flywheel.core.source.FileResolution;
import com.jozufozu.flywheel.util.RenderMath;
import com.mojang.math.Vector3f;
import com.mojang.math.Vector4f;
@ -44,13 +45,18 @@ public class TransformedType implements StructType<TransformedPart> {
Vector4f pos = new Vector4f();
Vector3f normal = new Vector3f();
float r = RenderMath.uf(struct.r);
float g = RenderMath.uf(struct.g);
float b = RenderMath.uf(struct.b);
float a = RenderMath.uf(struct.a);
int light = struct.getPackedLight();
for (int i = 0; i < vertexList.vertexCount(); i++) {
pos.set(
vertexList.x(i),
vertexList.y(i),
vertexList.z(i),
1F
1f
);
pos.transform(struct.model);
vertexList.x(i, pos.x());
@ -68,10 +74,10 @@ public class TransformedType implements StructType<TransformedPart> {
vertexList.normalY(i, normal.y());
vertexList.normalZ(i, normal.z());
vertexList.r(i, struct.r);
vertexList.g(i, struct.g);
vertexList.b(i, struct.b);
vertexList.a(i, struct.a);
vertexList.r(i, r);
vertexList.g(i, g);
vertexList.b(i, b);
vertexList.a(i, a);
vertexList.light(i, light);
}
};

View file

@ -2,60 +2,57 @@ package com.jozufozu.flywheel.core.vertex;
import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
import com.jozufozu.flywheel.util.RenderMath;
import net.minecraft.client.renderer.texture.OverlayTexture;
public class BlockVertexList extends AbstractVertexList {
protected static final int STRIDE = 32;
protected long idxPtr(int index) {
return ptr + index * STRIDE;
}
private static final int STRIDE = 32;
@Override
public float x(int index) {
return MemoryUtil.memGetFloat(idxPtr(index));
return MemoryUtil.memGetFloat(ptr + index * STRIDE);
}
@Override
public float y(int index) {
return MemoryUtil.memGetFloat(idxPtr(index) + 4);
return MemoryUtil.memGetFloat(ptr + index * STRIDE + 4);
}
@Override
public float z(int index) {
return MemoryUtil.memGetFloat(idxPtr(index) + 8);
return MemoryUtil.memGetFloat(ptr + index * STRIDE + 8);
}
@Override
public byte r(int index) {
return MemoryUtil.memGetByte(idxPtr(index) + 12);
public float r(int index) {
return RenderMath.uf(MemoryUtil.memGetByte(ptr + index * STRIDE + 12));
}
@Override
public byte g(int index) {
return MemoryUtil.memGetByte(idxPtr(index) + 13);
public float g(int index) {
return RenderMath.uf(MemoryUtil.memGetByte(ptr + index * STRIDE + 13));
}
@Override
public byte b(int index) {
return MemoryUtil.memGetByte(idxPtr(index) + 14);
public float b(int index) {
return RenderMath.uf(MemoryUtil.memGetByte(ptr + index * STRIDE + 14));
}
@Override
public byte a(int index) {
return MemoryUtil.memGetByte(idxPtr(index) + 15);
public float a(int index) {
return RenderMath.uf(MemoryUtil.memGetByte(ptr + index * STRIDE + 15));
}
@Override
public float u(int index) {
return MemoryUtil.memGetFloat(idxPtr(index) + 16);
return MemoryUtil.memGetFloat(ptr + index * STRIDE + 16);
}
@Override
public float v(int index) {
return MemoryUtil.memGetFloat(idxPtr(index) + 20);
return MemoryUtil.memGetFloat(ptr + index * STRIDE + 20);
}
@Override
@ -65,67 +62,67 @@ public class BlockVertexList extends AbstractVertexList {
@Override
public int light(int index) {
return MemoryUtil.memGetInt(idxPtr(index) + 24) << 4;
return MemoryUtil.memGetInt(ptr + index * STRIDE + 24) << 4;
}
@Override
public float normalX(int index) {
return RenderMath.f(MemoryUtil.memGetByte(idxPtr(index) + 28));
return RenderMath.f(MemoryUtil.memGetByte(ptr + index * STRIDE + 28));
}
@Override
public float normalY(int index) {
return RenderMath.f(MemoryUtil.memGetByte(idxPtr(index) + 29));
return RenderMath.f(MemoryUtil.memGetByte(ptr + index * STRIDE + 29));
}
@Override
public float normalZ(int index) {
return RenderMath.f(MemoryUtil.memGetByte(idxPtr(index) + 30));
return RenderMath.f(MemoryUtil.memGetByte(ptr + index * STRIDE + 30));
}
@Override
public void x(int index, float x) {
MemoryUtil.memPutFloat(idxPtr(index), x);
MemoryUtil.memPutFloat(ptr + index * STRIDE, x);
}
@Override
public void y(int index, float y) {
MemoryUtil.memPutFloat(idxPtr(index) + 4, y);
MemoryUtil.memPutFloat(ptr + index * STRIDE + 4, y);
}
@Override
public void z(int index, float z) {
MemoryUtil.memPutFloat(idxPtr(index) + 8, z);
MemoryUtil.memPutFloat(ptr + index * STRIDE + 8, z);
}
@Override
public void r(int index, byte r) {
MemoryUtil.memPutByte(idxPtr(index) + 12, r);
public void r(int index, float r) {
MemoryUtil.memPutByte(ptr + index * STRIDE + 12, RenderMath.unb(r));
}
@Override
public void g(int index, byte g) {
MemoryUtil.memPutByte(idxPtr(index) + 13, g);
public void g(int index, float g) {
MemoryUtil.memPutByte(ptr + index * STRIDE + 13, RenderMath.unb(g));
}
@Override
public void b(int index, byte b) {
MemoryUtil.memPutByte(idxPtr(index) + 14, b);
public void b(int index, float b) {
MemoryUtil.memPutByte(ptr + index * STRIDE + 14, RenderMath.unb(b));
}
@Override
public void a(int index, byte a) {
MemoryUtil.memPutByte(idxPtr(index) + 15, a);
public void a(int index, float a) {
MemoryUtil.memPutByte(ptr + index * STRIDE + 15, RenderMath.unb(a));
}
@Override
public void u(int index, float u) {
MemoryUtil.memPutFloat(idxPtr(index) + 16, u);
MemoryUtil.memPutFloat(ptr + index * STRIDE + 16, u);
}
@Override
public void v(int index, float v) {
MemoryUtil.memPutFloat(idxPtr(index) + 20, v);
MemoryUtil.memPutFloat(ptr + index * STRIDE + 20, v);
}
@Override
@ -134,26 +131,51 @@ public class BlockVertexList extends AbstractVertexList {
@Override
public void light(int index, int light) {
MemoryUtil.memPutInt(idxPtr(index) + 24, light >> 4);
MemoryUtil.memPutInt(ptr + index * STRIDE + 24, light >> 4);
}
@Override
public void normalX(int index, float normalX) {
MemoryUtil.memPutByte(idxPtr(index) + 28, RenderMath.nb(normalX));
MemoryUtil.memPutByte(ptr + index * STRIDE + 28, RenderMath.nb(normalX));
}
@Override
public void normalY(int index, float normalY) {
MemoryUtil.memPutByte(idxPtr(index) + 29, RenderMath.nb(normalY));
MemoryUtil.memPutByte(ptr + index * STRIDE + 29, RenderMath.nb(normalY));
}
@Override
public void normalZ(int index, float normalZ) {
MemoryUtil.memPutByte(idxPtr(index) + 30, RenderMath.nb(normalZ));
MemoryUtil.memPutByte(ptr + index * STRIDE + 30, RenderMath.nb(normalZ));
}
@Override
public int vertexStride() {
return STRIDE;
public void write(MutableVertexList dst, int srcIndex, int dstIndex) {
if (getClass() == dst.getClass()) {
long dstPtr = ((BlockVertexList) dst).ptr;
MemoryUtil.memCopy(ptr + srcIndex * STRIDE, dstPtr + dstIndex * STRIDE, STRIDE);
} else {
super.write(dst, srcIndex, dstIndex);
}
}
@Override
public void write(MutableVertexList dst, int srcStartIndex, int dstStartIndex, int vertexCount) {
if (getClass() == dst.getClass()) {
long dstPtr = ((BlockVertexList) dst).ptr;
MemoryUtil.memCopy(ptr + srcStartIndex * STRIDE, dstPtr + dstStartIndex * STRIDE, vertexCount * STRIDE);
} else {
super.write(dst, srcStartIndex, dstStartIndex, vertexCount);
}
}
@Override
public void writeAll(MutableVertexList dst) {
if (getClass() == dst.getClass()) {
long dstPtr = ((BlockVertexList) dst).ptr;
MemoryUtil.memCopy(ptr, dstPtr, vertexCount * STRIDE);
} else {
super.writeAll(dst);
}
}
}

View file

@ -1,11 +1,11 @@
package com.jozufozu.flywheel.core.vertex;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import com.mojang.blaze3d.vertex.VertexFormat;
import com.mojang.blaze3d.vertex.VertexFormatElement;
public class InferredVertexFormatInfo {
public final VertexFormat format;
public final int stride;
public final int positionOffset;
public final int colorOffset;
@ -16,7 +16,6 @@ public class InferredVertexFormatInfo {
public InferredVertexFormatInfo(VertexFormat format) {
this.format = format;
stride = format.getVertexSize();
int positionOffset = -1;
int colorOffset = -1;
@ -27,17 +26,18 @@ public class InferredVertexFormatInfo {
int offset = 0;
for (VertexFormatElement element : format.getElements()) {
switch (element.getUsage()) {
case POSITION -> positionOffset = offset;
case NORMAL -> normalOffset = offset;
case COLOR -> colorOffset = offset;
case UV -> {
switch (element.getIndex()) {
case 0 -> textureOffset = offset;
case 1 -> overlayOffset = offset;
case 2 -> lightOffset = offset;
}
}
if (element == DefaultVertexFormat.ELEMENT_POSITION) {
positionOffset = offset;
} else if (element == DefaultVertexFormat.ELEMENT_COLOR) {
colorOffset = offset;
} else if (element == DefaultVertexFormat.ELEMENT_UV0) {
textureOffset = offset;
} else if (element == DefaultVertexFormat.ELEMENT_UV1) {
overlayOffset = offset;
} else if (element == DefaultVertexFormat.ELEMENT_UV2) {
lightOffset = offset;
} else if (element == DefaultVertexFormat.ELEMENT_NORMAL) {
normalOffset = offset;
}
offset += element.getByteSize();

View file

@ -6,6 +6,7 @@ import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
import com.jozufozu.flywheel.util.RenderMath;
import com.mojang.blaze3d.vertex.VertexFormat;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.texture.OverlayTexture;
public class InferredVertexListImpl extends AbstractVertexList implements ReusableVertexList {
@ -21,7 +22,7 @@ public class InferredVertexListImpl extends AbstractVertexList implements Reusab
public InferredVertexListImpl(InferredVertexFormatInfo formatInfo) {
format = formatInfo.format;
stride = formatInfo.stride;
stride = format.getVertexSize();
positionOffset = formatInfo.positionOffset;
colorOffset = formatInfo.colorOffset;
textureOffset = formatInfo.textureOffset;
@ -30,180 +31,171 @@ public class InferredVertexListImpl extends AbstractVertexList implements Reusab
normalOffset = formatInfo.normalOffset;
}
protected long idxPtr(int index) {
return ptr + index * stride;
}
@Override
public float x(int index) {
if (positionOffset < 0) return 0;
return MemoryUtil.memGetFloat(idxPtr(index) + positionOffset);
return MemoryUtil.memGetFloat(ptr + index * stride + positionOffset);
}
@Override
public float y(int index) {
if (positionOffset < 0) return 0;
return MemoryUtil.memGetFloat(idxPtr(index) + positionOffset + 4);
return MemoryUtil.memGetFloat(ptr + index * stride + positionOffset + 4);
}
@Override
public float z(int index) {
if (positionOffset < 0) return 0;
return MemoryUtil.memGetFloat(idxPtr(index) + positionOffset + 8);
return MemoryUtil.memGetFloat(ptr + index * stride + positionOffset + 8);
}
@Override
public byte r(int index) {
if (colorOffset < 0) return 0;
return MemoryUtil.memGetByte(idxPtr(index) + colorOffset);
public float r(int index) {
if (colorOffset < 0) return 1;
return RenderMath.uf(MemoryUtil.memGetByte(ptr + index * stride + colorOffset));
}
@Override
public byte g(int index) {
if (colorOffset < 0) return 0;
return MemoryUtil.memGetByte(idxPtr(index) + colorOffset + 1);
public float g(int index) {
if (colorOffset < 0) return 1;
return RenderMath.uf(MemoryUtil.memGetByte(ptr + index * stride + colorOffset + 1));
}
@Override
public byte b(int index) {
if (colorOffset < 0) return 0;
return MemoryUtil.memGetByte(idxPtr(index) + colorOffset + 2);
public float b(int index) {
if (colorOffset < 0) return 1;
return RenderMath.uf(MemoryUtil.memGetByte(ptr + index * stride + colorOffset + 2));
}
@Override
public byte a(int index) {
if (colorOffset < 0) return 0;
return MemoryUtil.memGetByte(idxPtr(index) + colorOffset + 3);
public float a(int index) {
if (colorOffset < 0) return 1;
return RenderMath.uf(MemoryUtil.memGetByte(ptr + index * stride + colorOffset + 3));
}
@Override
public float u(int index) {
if (textureOffset < 0) return 0;
return MemoryUtil.memGetFloat(idxPtr(index) + textureOffset);
return MemoryUtil.memGetFloat(ptr + index * stride + textureOffset);
}
@Override
public float v(int index) {
if (textureOffset < 0) return 0;
return MemoryUtil.memGetFloat(idxPtr(index) + textureOffset + 4);
return MemoryUtil.memGetFloat(ptr + index * stride + textureOffset + 4);
}
@Override
public int overlay(int index) {
if (overlayOffset < 0) return OverlayTexture.NO_OVERLAY;
return MemoryUtil.memGetInt(idxPtr(index) + overlayOffset);
return MemoryUtil.memGetInt(ptr + index * stride + overlayOffset);
}
@Override
public int light(int index) {
if (lightOffset < 0) return 0;
return MemoryUtil.memGetInt(idxPtr(index) + lightOffset);
if (lightOffset < 0) return LightTexture.FULL_BRIGHT;
return MemoryUtil.memGetInt(ptr + index * stride + lightOffset);
}
@Override
public float normalX(int index) {
if (normalOffset < 0) return 0;
return RenderMath.f(MemoryUtil.memGetByte(idxPtr(index) + normalOffset));
return RenderMath.f(MemoryUtil.memGetByte(ptr + index * stride + normalOffset));
}
@Override
public float normalY(int index) {
if (normalOffset < 0) return 0;
return RenderMath.f(MemoryUtil.memGetByte(idxPtr(index) + normalOffset + 1));
return RenderMath.f(MemoryUtil.memGetByte(ptr + index * stride + normalOffset + 1));
}
@Override
public float normalZ(int index) {
if (normalOffset < 0) return 0;
return RenderMath.f(MemoryUtil.memGetByte(idxPtr(index) + normalOffset + 2));
return RenderMath.f(MemoryUtil.memGetByte(ptr + index * stride + normalOffset + 2));
}
@Override
public void x(int index, float x) {
if (positionOffset < 0) return;
MemoryUtil.memPutFloat(idxPtr(index) + positionOffset, x);
MemoryUtil.memPutFloat(ptr + index * stride + positionOffset, x);
}
@Override
public void y(int index, float y) {
if (positionOffset < 0) return;
MemoryUtil.memPutFloat(idxPtr(index) + positionOffset + 4, y);
MemoryUtil.memPutFloat(ptr + index * stride + positionOffset + 4, y);
}
@Override
public void z(int index, float z) {
if (positionOffset < 0) return;
MemoryUtil.memPutFloat(idxPtr(index) + positionOffset + 8, z);
MemoryUtil.memPutFloat(ptr + index * stride + positionOffset + 8, z);
}
@Override
public void r(int index, byte r) {
public void r(int index, float r) {
if (colorOffset < 0) return;
MemoryUtil.memPutByte(idxPtr(index) + colorOffset, r);
MemoryUtil.memPutByte(ptr + index * stride + colorOffset, RenderMath.unb(r));
}
@Override
public void g(int index, byte g) {
public void g(int index, float g) {
if (colorOffset < 0) return;
MemoryUtil.memPutByte(idxPtr(index) + colorOffset + 1, g);
MemoryUtil.memPutByte(ptr + index * stride + colorOffset + 1, RenderMath.unb(g));
}
@Override
public void b(int index, byte b) {
public void b(int index, float b) {
if (colorOffset < 0) return;
MemoryUtil.memPutByte(idxPtr(index) + colorOffset + 2, b);
MemoryUtil.memPutByte(ptr + index * stride + colorOffset + 2, RenderMath.unb(b));
}
@Override
public void a(int index, byte a) {
public void a(int index, float a) {
if (colorOffset < 0) return;
MemoryUtil.memPutByte(idxPtr(index) + colorOffset + 3, a);
MemoryUtil.memPutByte(ptr + index * stride + colorOffset + 3, RenderMath.unb(a));
}
@Override
public void u(int index, float u) {
if (textureOffset < 0) return;
MemoryUtil.memPutFloat(idxPtr(index) + textureOffset, u);
MemoryUtil.memPutFloat(ptr + index * stride + textureOffset, u);
}
@Override
public void v(int index, float v) {
if (textureOffset < 0) return;
MemoryUtil.memPutFloat(idxPtr(index) + textureOffset + 4, v);
MemoryUtil.memPutFloat(ptr + index * stride + textureOffset + 4, v);
}
@Override
public void overlay(int index, int overlay) {
if (overlayOffset < 0) return;
MemoryUtil.memPutInt(idxPtr(index) + overlayOffset, overlay);
MemoryUtil.memPutInt(ptr + index * stride + overlayOffset, overlay);
}
@Override
public void light(int index, int light) {
if (lightOffset < 0) return;
MemoryUtil.memPutInt(idxPtr(index) + lightOffset, light);
MemoryUtil.memPutInt(ptr + index * stride + lightOffset, light);
}
@Override
public void normalX(int index, float normalX) {
if (normalOffset < 0) return;
MemoryUtil.memPutByte(idxPtr(index) + normalOffset, RenderMath.nb(normalX));
MemoryUtil.memPutByte(ptr + index * stride + normalOffset, RenderMath.nb(normalX));
}
@Override
public void normalY(int index, float normalY) {
if (normalOffset < 0) return;
MemoryUtil.memPutByte(idxPtr(index) + normalOffset + 1, RenderMath.nb(normalY));
MemoryUtil.memPutByte(ptr + index * stride + normalOffset + 1, RenderMath.nb(normalY));
}
@Override
public void normalZ(int index, float normalZ) {
if (normalOffset < 0) return;
MemoryUtil.memPutByte(idxPtr(index) + normalOffset + 2, RenderMath.nb(normalZ));
}
@Override
public int vertexStride() {
return stride;
MemoryUtil.memPutByte(ptr + index * stride + normalOffset + 2, RenderMath.nb(normalZ));
}
}

View file

@ -2,60 +2,58 @@ package com.jozufozu.flywheel.core.vertex;
import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
import com.jozufozu.flywheel.util.RenderMath;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.texture.OverlayTexture;
public class PosTexNormalVertexList extends AbstractVertexList {
protected static final int STRIDE = 23;
protected long idxPtr(long idx) {
return ptr + idx * STRIDE;
}
private static final int STRIDE = 23;
@Override
public float x(int index) {
return MemoryUtil.memGetFloat(idxPtr(index));
return MemoryUtil.memGetFloat(ptr + index * STRIDE);
}
@Override
public float y(int index) {
return MemoryUtil.memGetFloat(idxPtr(index) + 4);
return MemoryUtil.memGetFloat(ptr + index * STRIDE + 4);
}
@Override
public float z(int index) {
return MemoryUtil.memGetFloat(idxPtr(index) + 8);
return MemoryUtil.memGetFloat(ptr + index * STRIDE + 8);
}
@Override
public byte r(int index) {
return (byte) 0xFF;
public float r(int index) {
return 1;
}
@Override
public byte g(int index) {
return (byte) 0xFF;
public float g(int index) {
return 1;
}
@Override
public byte b(int index) {
return (byte) 0xFF;
public float b(int index) {
return 1;
}
@Override
public byte a(int index) {
return (byte) 0xFF;
public float a(int index) {
return 1;
}
@Override
public float u(int index) {
return MemoryUtil.memGetFloat(idxPtr(index) + 12);
return MemoryUtil.memGetFloat(ptr + index * STRIDE + 12);
}
@Override
public float v(int index) {
return MemoryUtil.memGetFloat(idxPtr(index) + 16);
return MemoryUtil.memGetFloat(ptr + index * STRIDE + 16);
}
@Override
@ -65,63 +63,63 @@ public class PosTexNormalVertexList extends AbstractVertexList {
@Override
public int light(int index) {
return 0;
return LightTexture.FULL_BRIGHT;
}
@Override
public float normalX(int index) {
return RenderMath.f(MemoryUtil.memGetByte(idxPtr(index) + 20));
return RenderMath.f(MemoryUtil.memGetByte(ptr + index * STRIDE + 20));
}
@Override
public float normalY(int index) {
return RenderMath.f(MemoryUtil.memGetByte(idxPtr(index) + 21));
return RenderMath.f(MemoryUtil.memGetByte(ptr + index * STRIDE + 21));
}
@Override
public float normalZ(int index) {
return RenderMath.f(MemoryUtil.memGetByte(idxPtr(index) + 22));
return RenderMath.f(MemoryUtil.memGetByte(ptr + index * STRIDE + 22));
}
@Override
public void x(int index, float x) {
MemoryUtil.memPutFloat(idxPtr(index), x);
MemoryUtil.memPutFloat(ptr + index * STRIDE, x);
}
@Override
public void y(int index, float y) {
MemoryUtil.memPutFloat(idxPtr(index) + 4, y);
MemoryUtil.memPutFloat(ptr + index * STRIDE + 4, y);
}
@Override
public void z(int index, float z) {
MemoryUtil.memPutFloat(idxPtr(index) + 8, z);
MemoryUtil.memPutFloat(ptr + index * STRIDE + 8, z);
}
@Override
public void r(int index, byte r) {
public void r(int index, float r) {
}
@Override
public void g(int index, byte g) {
public void g(int index, float g) {
}
@Override
public void b(int index, byte b) {
public void b(int index, float b) {
}
@Override
public void a(int index, byte a) {
public void a(int index, float a) {
}
@Override
public void u(int index, float u) {
MemoryUtil.memPutFloat(idxPtr(index) + 12, u);
MemoryUtil.memPutFloat(ptr + index * STRIDE + 12, u);
}
@Override
public void v(int index, float v) {
MemoryUtil.memPutFloat(idxPtr(index) + 16, v);
MemoryUtil.memPutFloat(ptr + index * STRIDE + 16, v);
}
@Override
@ -134,21 +132,46 @@ public class PosTexNormalVertexList extends AbstractVertexList {
@Override
public void normalX(int index, float normalX) {
MemoryUtil.memPutByte(idxPtr(index) + 20, RenderMath.nb(normalX));
MemoryUtil.memPutByte(ptr + index * STRIDE + 20, RenderMath.nb(normalX));
}
@Override
public void normalY(int index, float normalY) {
MemoryUtil.memPutByte(idxPtr(index) + 21, RenderMath.nb(normalY));
MemoryUtil.memPutByte(ptr + index * STRIDE + 21, RenderMath.nb(normalY));
}
@Override
public void normalZ(int index, float normalZ) {
MemoryUtil.memPutByte(idxPtr(index) + 22, RenderMath.nb(normalZ));
MemoryUtil.memPutByte(ptr + index * STRIDE + 22, RenderMath.nb(normalZ));
}
@Override
public int vertexStride() {
return STRIDE;
public void write(MutableVertexList dst, int srcIndex, int dstIndex) {
if (getClass() == dst.getClass()) {
long dstPtr = ((PosTexNormalVertexList) dst).ptr;
MemoryUtil.memCopy(ptr + srcIndex * STRIDE, dstPtr + dstIndex * STRIDE, STRIDE);
} else {
super.write(dst, srcIndex, dstIndex);
}
}
@Override
public void write(MutableVertexList dst, int srcStartIndex, int dstStartIndex, int vertexCount) {
if (getClass() == dst.getClass()) {
long dstPtr = ((PosTexNormalVertexList) dst).ptr;
MemoryUtil.memCopy(ptr + srcStartIndex * STRIDE, dstPtr + dstStartIndex * STRIDE, vertexCount * STRIDE);
} else {
super.write(dst, srcStartIndex, dstStartIndex, vertexCount);
}
}
@Override
public void writeAll(MutableVertexList dst) {
if (getClass() == dst.getClass()) {
long dstPtr = ((PosTexNormalVertexList) dst).ptr;
MemoryUtil.memCopy(ptr, dstPtr, vertexCount * STRIDE);
} else {
super.writeAll(dst);
}
}
}

View file

@ -25,7 +25,6 @@ import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.RenderBuffers;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.common.MinecraftForge;
@Mixin(value = LevelRenderer.class, priority = 1001) // Higher priority to go after Sodium

View file

@ -5,31 +5,31 @@ import net.minecraftforge.client.model.pipeline.LightUtil;
public class RenderMath {
/**
* Convert a signed, normalized floating point value into a normalized byte.
*/
public static byte nb(float f) {
return (byte) (f * 127);
}
/**
* Convert a signed byte into a normalized float.
* Convert a signed byte into a signed, normalized float.
*/
public static float f(byte b) {
return b / 127f;
}
/**
* Convert an unsigned byte into a normalized float.
* Convert a signed, normalized float into a signed byte.
*/
public static byte nb(float f) {
return (byte) (f * 127);
}
/**
* Convert an unsigned byte into an unsigned, normalized float.
*/
public static float uf(byte b) {
return (float) (Byte.toUnsignedInt(b)) / 255f;
}
/**
* Convert an unsigned, normalized float into an unsigned normalized byte.
* Convert an unsigned, normalized float into an unsigned byte.
*/
public static byte unb(float f) {
return (byte) Math.floor(f * 255);
return (byte) (int) (f * 255);
}
public static int nextPowerOf2(int a) {