Skip to content

Commit

Permalink
Unhardcode vertex format indexes
Browse files Browse the repository at this point in the history
  • Loading branch information
embeddedt committed Jan 11, 2024
1 parent 0661158 commit 81e94dc
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package me.jellysquid.mods.sodium.client.render.vertex;

import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.client.renderer.vertex.VertexFormatElement;

import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.locks.StampedLock;

/**
* Inspired by modern Sodium's VertexFormatDescription.
*/
public class VertexFormatDescription {
public enum Element {
POSITION(DefaultVertexFormats.POSITION_3F),
COLOR(DefaultVertexFormats.COLOR_4UB),
TEXTURE(DefaultVertexFormats.TEX_2F),
NORMAL(DefaultVertexFormats.NORMAL_3B);

final VertexFormatElement underlyingElement;
static final Map<VertexFormatElement, Element> VANILLA_TO_COMMON = new Reference2ReferenceOpenHashMap<>();
Element(VertexFormatElement baseElement) {
this.underlyingElement = baseElement;
}

static {
for(Element e : Element.values()) {
VANILLA_TO_COMMON.put(e.underlyingElement, e);
}
}
}

private static final Element[] COMMON_ELEMENTS = Element.values();

private final int[] elementOffsets;
private final VertexFormat format;

private static final Map<VertexFormat, VertexFormatDescription> REGISTRY = new Reference2ReferenceOpenHashMap<>();
private static final StampedLock LOCK = new StampedLock();

VertexFormatDescription(VertexFormat format) {
this.elementOffsets = new int[COMMON_ELEMENTS.length];
Arrays.fill(this.elementOffsets, -1);
this.format = format;
for(int i = 0; i < format.getElementCount(); i++) {
Element commonElement = Element.VANILLA_TO_COMMON.get(format.getElement(i));
if(commonElement != null) {
elementOffsets[commonElement.ordinal()] = format.getOffset(i) / 4;
}
}
}

public static VertexFormatDescription get(VertexFormat format) {
long stamp = LOCK.readLock();
VertexFormatDescription desc;
try {
desc = REGISTRY.get(format);
} finally {
LOCK.unlockRead(stamp);
}

if (desc != null) {
return desc;
}

desc = new VertexFormatDescription(format);

stamp = LOCK.writeLock();

try {
REGISTRY.put(format, desc);
} finally {
LOCK.unlockWrite(stamp);
}

return desc;
}

public int getIndex(VertexFormatDescription.Element element) {
return this.elementOffsets[element.ordinal()];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,21 @@

import me.jellysquid.mods.sodium.client.model.quad.ModelQuadView;
import me.jellysquid.mods.sodium.client.model.quad.properties.ModelQuadFlags;
import me.jellysquid.mods.sodium.client.render.vertex.VertexFormatDescription;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import static me.jellysquid.mods.sodium.client.util.ModelQuadUtil.*;

@Mixin(BakedQuad.class)
public class MixinBakedQuad implements ModelQuadView {
@Shadow
@Final
protected int[] vertexData;

@Shadow
@Final
Expand All @@ -29,36 +26,61 @@ public class MixinBakedQuad implements ModelQuadView {
@Final
protected int tintIndex;

private int cachedFlags;
@Shadow public int[] getVertexData() {
throw new AssertionError();
}

@Shadow @Final protected VertexFormat format;
protected int cachedFlags;

private VertexFormatDescription formatDescription;

@Inject(method = "<init>([IILnet/minecraft/util/EnumFacing;Lnet/minecraft/client/renderer/texture/TextureAtlasSprite;ZLnet/minecraft/client/renderer/vertex/VertexFormat;)V", at = @At("RETURN"))
private void init(int[] vertexData, int colorIndex, EnumFacing face, TextureAtlasSprite sprite, boolean shade, VertexFormat format, CallbackInfo ci) {
this.cachedFlags = ModelQuadFlags.getQuadFlags((BakedQuad) (Object) this);
this.formatDescription = VertexFormatDescription.get(format);
if(!UnpackedBakedQuad.class.isAssignableFrom(this.getClass())) {
this.cachedFlags = ModelQuadFlags.getQuadFlags((BakedQuad) (Object) this);
}
}

private int vertexOffset(int idx) {
return idx * this.format.getIntegerSize();
}

@Override
public float getX(int idx) {
return Float.intBitsToFloat(this.vertexData[vertexOffset(idx) + POSITION_INDEX]);
int positionIndex = this.formatDescription.getIndex(VertexFormatDescription.Element.POSITION);
if (positionIndex == -1) {
return 0;
}
return Float.intBitsToFloat(this.getVertexData()[vertexOffset(idx) + positionIndex]);
}

@Override
public float getY(int idx) {
return Float.intBitsToFloat(this.vertexData[vertexOffset(idx) + POSITION_INDEX + 1]);
int positionIndex = this.formatDescription.getIndex(VertexFormatDescription.Element.POSITION);
if (positionIndex == -1) {
return 0;
}
return Float.intBitsToFloat(this.getVertexData()[vertexOffset(idx) + positionIndex + 1]);
}

@Override
public float getZ(int idx) {
return Float.intBitsToFloat(this.vertexData[vertexOffset(idx) + POSITION_INDEX + 2]);
int positionIndex = this.formatDescription.getIndex(VertexFormatDescription.Element.POSITION);
if (positionIndex == -1) {
return 0;
}
return Float.intBitsToFloat(this.getVertexData()[vertexOffset(idx) + positionIndex + 2]);
}

@Override
public int getColor(int idx) {
if(vertexOffset(idx) + COLOR_INDEX < vertexData.length) {
return this.vertexData[vertexOffset(idx) + COLOR_INDEX];
} else
{
return vertexData.length;
int colorIndex = this.formatDescription.getIndex(VertexFormatDescription.Element.COLOR);
if (colorIndex == -1) {
return 0;
}
return this.getVertexData()[vertexOffset(idx) + colorIndex];
}

@Override
Expand All @@ -68,12 +90,20 @@ public int getColor(int idx) {

@Override
public float getTexU(int idx) {
return Float.intBitsToFloat(this.vertexData[vertexOffset(idx) + TEXTURE_INDEX]);
int textureIndex = this.formatDescription.getIndex(VertexFormatDescription.Element.TEXTURE);
if (textureIndex == -1) {
return 0;
}
return Float.intBitsToFloat(this.getVertexData()[vertexOffset(idx) + textureIndex]);
}

@Override
public float getTexV(int idx) {
return Float.intBitsToFloat(this.vertexData[vertexOffset(idx) + TEXTURE_INDEX + 1]);
int textureIndex = this.formatDescription.getIndex(VertexFormatDescription.Element.TEXTURE);
if (textureIndex == -1) {
return 0;
}
return Float.intBitsToFloat(this.getVertexData()[vertexOffset(idx) + textureIndex + 1]);
}

@Override
Expand All @@ -83,7 +113,11 @@ public int getFlags() {

@Override
public int getNormal(int idx) {
return this.vertexData[vertexOffset(idx) + NORMAL_INDEX];
int normalIndex = this.formatDescription.getIndex(VertexFormatDescription.Element.NORMAL);
if (normalIndex == -1) {
return 0;
}
return this.getVertexData()[vertexOffset(idx) + normalIndex];
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package me.jellysquid.mods.sodium.mixin.core.pipeline;

import me.jellysquid.mods.sodium.client.model.quad.properties.ModelQuadFlags;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(UnpackedBakedQuad.class)
public class MixinUnpackedBakedQuad {
protected int cachedFlags;
@Inject(method = "<init>", at = @At("RETURN"))
private void calculateFlags(CallbackInfo ci) {
this.cachedFlags = ModelQuadFlags.getQuadFlags((BakedQuad) (Object) this);
}
}
1 change: 1 addition & 0 deletions src/main/resources/sodium.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"core.pipeline.MixinBakedQuad",
"core.pipeline.MixinBufferBuilder",
"core.pipeline.MixinVertexFormat",
"core.pipeline.MixinUnpackedBakedQuad",
"features.block.MixinBlockModelRenderer",
"features.block.MixinWorldRenderer",
"features.buffer_builder.fast_advance.MixinVertexFormat",
Expand Down

0 comments on commit 81e94dc

Please sign in to comment.