Skip to content

Commit

Permalink
Implement new RenderMaterial, consolidate vertex state, other state r…
Browse files Browse the repository at this point in the history
…efactors
  • Loading branch information
grondag committed Oct 21, 2020
1 parent 933cfdb commit 3dbab93
Show file tree
Hide file tree
Showing 22 changed files with 633 additions and 393 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,40 @@
import net.fabricmc.fabric.api.renderer.v1.material.BlendMode;

public abstract class AbstractMeshMaterial {
protected long bits;

AbstractMeshMaterial(long bits) {
this.bits = bits;
}

public BlendMode blendMode() {
return BLEND_MODE.getValue(bits);
}

public boolean disableColorIndex() {
return DISABLE_COLOR.getValue(bits);
}

public boolean emissive() {
return EMISSIVE.getValue(bits);
}

public boolean disableDiffuse() {
return DISABLE_DIFFUSE.getValue(bits);
}

public boolean disableAo() {
return DISABLE_AO.getValue(bits);
}

public MaterialShaderImpl shader() {
return MaterialShaderManager.INSTANCE.get(SHADER.getValue(bits));
}

public MaterialConditionImpl condition() {
return MaterialConditionImpl.fromIndex(CONDITION.getValue(bits));
}

public static final int SHADER_FLAGS_DISABLE_AO;
static final BlendMode[] LAYERS = new BlendMode[4];
private static final BitPacker64<AbstractMeshMaterial> BITPACKER_0 = new BitPacker64<>(null, null);
Expand Down Expand Up @@ -58,38 +92,4 @@ public abstract class AbstractMeshMaterial {
DEFAULT_BITS = defaultBits;
SHADER_FLAGS_DISABLE_AO = (int) DISABLE_AO.setValue(true, 0);
}

protected long bits;

AbstractMeshMaterial(long bits) {
this.bits = bits;
}

public BlendMode blendMode() {
return BLEND_MODE.getValue(bits);
}

public boolean disableColorIndex() {
return DISABLE_COLOR.getValue(bits);
}

public boolean emissive() {
return EMISSIVE.getValue(bits);
}

public boolean disableDiffuse() {
return DISABLE_DIFFUSE.getValue(bits);
}

public boolean disableAo() {
return DISABLE_AO.getValue(bits);
}

public MaterialShaderImpl shader() {
return MaterialShaderManager.INSTANCE.get(SHADER.getValue(bits));
}

public MaterialConditionImpl condition() {
return MaterialConditionImpl.fromIndex(CONDITION.getValue(bits));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public MaterialConditionImpl condition() {
static final ObjectArrayList<MeshMaterial> LIST = new ObjectArrayList<>();
static final Long2ObjectOpenHashMap<MeshMaterial> MAP = new Long2ObjectOpenHashMap<>();

public static MeshMaterial byIndex(int index) {
public static MeshMaterial fromIndex(int index) {
assert index < LIST.size();
assert index >= 0;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public final MutableQuadViewImpl material(RenderMaterial material) {

data[baseIndex + HEADER_MATERIAL] = ((MeshMaterial) material).index;

assert MeshMaterial.byIndex(data[baseIndex + HEADER_MATERIAL]) == material;
assert MeshMaterial.fromIndex(data[baseIndex + HEADER_MATERIAL]) == material;

return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ public final void toVanilla(int[] target, int targetIndex) {

@Override
public final MeshMaterial material() {
return MeshMaterial.byIndex(data[baseIndex + HEADER_MATERIAL]);
return MeshMaterial.fromIndex(data[baseIndex + HEADER_MATERIAL]);
}

@Override
Expand Down
21 changes: 7 additions & 14 deletions src/main/java/grondag/canvas/mixin/MixinMultiPhase.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
import java.util.Optional;

import grondag.canvas.mixinterface.MultiPhaseExt;
import grondag.canvas.wip.state.WipRenderState;
import grondag.canvas.wip.state.WipVertexState;
import grondag.canvas.wip.state.WipRenderMaterial;
import grondag.canvas.wip.state.WipRenderMaterialFinder;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
Expand All @@ -37,8 +37,7 @@ abstract class MixinMultiPhase extends RenderLayer implements MultiPhaseExt {
@Shadow
private RenderLayer.MultiPhaseParameters phases;

private @Nullable WipRenderState renderState;
private int vertexState;
private @Nullable WipRenderMaterial materialState;

private MixinMultiPhase(String name, VertexFormat vertexFormat, int drawMode, int expectedBufferSize, boolean hasCrumbling, boolean translucent, Runnable startAction, Runnable endAction) {
super(name, vertexFormat, drawMode, expectedBufferSize, hasCrumbling, translucent, startAction, endAction);
Expand All @@ -65,23 +64,17 @@ public AccessMultiPhaseParameters canvas_phases() {
}

@Override
public WipRenderState canvas_renderState() {
WipRenderState result = renderState;
public WipRenderMaterial canvas_materialState() {
WipRenderMaterial result = materialState;

if (result == null) {
result = WipRenderState.finder().copyFromLayer(this);
renderState = result;
vertexState = WipVertexState.finder().copyFromLayer(this).find();
result = WipRenderMaterialFinder.threadLocal().copyFromLayer(this);
materialState = result;
}

return result;
}

@Override
public int canvas_vertexState() {
return vertexState;
}

@Override
public void canvas_startDrawing() {
super.startDrawing();
Expand Down
10 changes: 2 additions & 8 deletions src/main/java/grondag/canvas/mixinterface/MultiPhaseExt.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,11 @@
import java.util.Optional;

import grondag.canvas.mixin.AccessMultiPhaseParameters;
import grondag.canvas.wip.state.WipRenderState;
import grondag.canvas.wip.state.WipRenderMaterial;

import net.minecraft.client.render.RenderLayer;

public interface MultiPhaseExt {

Optional<RenderLayer> canvas_affectedOutline();

boolean canvas_outline();
Expand All @@ -35,12 +34,7 @@ public interface MultiPhaseExt {

AccessMultiPhaseParameters canvas_phases();

WipRenderState canvas_renderState();

/**
* Must be called after {@link #canvas_renderState()}
*/
int canvas_vertexState();
WipRenderMaterial canvas_materialState();

String canvas_name();
}
53 changes: 35 additions & 18 deletions src/main/java/grondag/canvas/render/CanvasParticleRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
import grondag.canvas.mixinterface.ParticleManagerExt;
import grondag.canvas.wip.encoding.WipVertexCollectorImpl;
import grondag.canvas.wip.state.RenderContextState;
import grondag.canvas.wip.state.WipRenderState;
import grondag.canvas.wip.state.WipVertexState;
import grondag.canvas.wip.state.WipRenderMaterial;
import grondag.canvas.wip.state.WipRenderMaterialFinder;
import grondag.canvas.wip.state.property.WipDecal;
import grondag.canvas.wip.state.property.WipDepthTest;
import grondag.canvas.wip.state.property.WipFog;
Expand Down Expand Up @@ -60,6 +60,8 @@ public class CanvasParticleRenderer {
private LightmapTextureManager lightmapTextureManager;
private ParticleManagerExt ext;
private Runnable drawHandler = Runnables.doNothing();
private WipRenderMaterial baseMat;
private WipRenderMaterial emissiveMat;

CanvasParticleRenderer(RenderContextState contextState) {
collector = new WipVertexCollectorImpl(contextState);
Expand Down Expand Up @@ -87,16 +89,16 @@ public void renderParticles(ParticleManager pm, MatrixStack matrixStack, VertexC

if (!particles.hasNext()) continue;

// FEAT: material maps for particles

final VertexConsumer consumer = beginSheet(particleTextureSheet);

while(particles.hasNext()) {
final Particle particle = particles.next();

try {
// FEAT: enhanced material maps for particles - shaders for animation in particular
final RenderMaterial mat = (RenderMaterial) MaterialMap.getForParticle(((ParticleExt) particle).canvas_particleType()).getMapped(null);
collector.vertexState(mat == null || !mat.emissive() ? PARTICLE_VERTEX_STATE : PARTICLE_EMISSIVE_VERTEX_STATE);
collector.vertexState(mat == null || !mat.emissive() ? baseMat : emissiveMat);
particle.buildGeometry(consumer, camera, tickDelta);
} catch (final Throwable exception) {
final CrashReport crashReport = CrashReport.create(exception, "Rendering Particle");
Expand Down Expand Up @@ -137,18 +139,21 @@ private VertexConsumer beginSheet(ParticleTextureSheet particleTextureSheet) {
// PERF: consolidate these draws
if (Configurator.enableExperimentalPipeline) {
if (particleTextureSheet == ParticleTextureSheet.TERRAIN_SHEET) {
collector.prepare(RENDER_STATE_TERRAIN);
collector.vertexState(PARTICLE_VERTEX_STATE);
baseMat = RENDER_STATE_TERRAIN;
emissiveMat = RENDER_STATE_TERRAIN_EMISSIVE;
collector.prepare(baseMat);
drawHandler = () -> collector.drawAndClear();
return collector;
} else if (particleTextureSheet == ParticleTextureSheet.PARTICLE_SHEET_LIT || particleTextureSheet == ParticleTextureSheet.PARTICLE_SHEET_OPAQUE) {
collector.prepare(RENDER_STATE_OPAQUE_OR_LIT);
collector.vertexState(PARTICLE_VERTEX_STATE);
baseMat = RENDER_STATE_OPAQUE_OR_LIT;
emissiveMat = RENDER_STATE_OPAQUE_OR_LIT_EMISSIVE;
collector.prepare(baseMat);
drawHandler = () -> collector.drawAndClear();
return collector;
} else if (particleTextureSheet == ParticleTextureSheet.PARTICLE_SHEET_TRANSLUCENT) {
collector.prepare(RENDER_STATE_TRANSLUCENT);
collector.vertexState(PARTICLE_VERTEX_STATE);
baseMat = RENDER_STATE_TRANSLUCENT;
emissiveMat = RENDER_STATE_TRANSLUCENT_EMISSIVE;
collector.prepare(baseMat);
drawHandler = () -> collector.drawAndClear();
return collector;
}
Expand All @@ -160,8 +165,8 @@ private VertexConsumer beginSheet(ParticleTextureSheet particleTextureSheet) {
return bufferBuilder;
}

private static WipRenderState.Finder baseFinder() {
return WipRenderState.finder()
private static WipRenderMaterialFinder baseFinder() {
return WipRenderMaterialFinder.threadLocal()
.primitive(GL11.GL_QUADS)
.depthTest(WipDepthTest.LEQUAL)
.cull(false)
Expand All @@ -170,26 +175,38 @@ private static WipRenderState.Finder baseFinder() {
.decal(WipDecal.NONE)
.target(WipTarget.PARTICLES)
.lines(false)
.disableAo(true)
.disableDiffuse(true)
.cutout(true)
.translucentCutout(true)
.fog(WipFog.BLACK_FOG);
}

private static final WipRenderState RENDER_STATE_TERRAIN = baseFinder()
private static final WipRenderMaterial RENDER_STATE_TERRAIN = baseFinder()
.texture(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE)
.transparency(WipTransparency.DEFAULT)
.find();

private static final WipRenderMaterial RENDER_STATE_TERRAIN_EMISSIVE = baseFinder().copyFrom(RENDER_STATE_TERRAIN)
.emissive(true)
.find();

// MC has two but they are functionally identical
private static final WipRenderState RENDER_STATE_OPAQUE_OR_LIT = baseFinder()
private static final WipRenderMaterial RENDER_STATE_OPAQUE_OR_LIT = baseFinder()
.transparency(WipTransparency.NONE)
.texture(SpriteAtlasTexture.PARTICLE_ATLAS_TEXTURE)
.find();

private static final WipRenderState RENDER_STATE_TRANSLUCENT = baseFinder()
private static final WipRenderMaterial RENDER_STATE_OPAQUE_OR_LIT_EMISSIVE = baseFinder().copyFrom(RENDER_STATE_OPAQUE_OR_LIT)
.emissive(true)
.find();

private static final WipRenderMaterial RENDER_STATE_TRANSLUCENT = baseFinder()
.transparency(WipTransparency.TRANSLUCENT)
.texture(SpriteAtlasTexture.PARTICLE_ATLAS_TEXTURE)
.find();

// Doesn't strictly match vanilla - which uses 10% threshold vs the 0.03xxx value here.
private static final int PARTICLE_VERTEX_STATE = WipVertexState.finder().disableAo(true).disableDiffuse(true).cutout(true).translucentCutout(true).find();
private static final int PARTICLE_EMISSIVE_VERTEX_STATE = WipVertexState.finder().disableAo(true).disableDiffuse(true).cutout(true).translucentCutout(true).emissive(true).find();
private static final WipRenderMaterial RENDER_STATE_TRANSLUCENT_EMISSIVE = baseFinder().copyFrom(RENDER_STATE_TRANSLUCENT)
.emissive(true)
.find();
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
import grondag.canvas.apiimpl.util.NormalHelper;
import grondag.canvas.mixinterface.SpriteExt;
import grondag.canvas.wip.state.RenderContextState;
import grondag.canvas.wip.state.WipRenderState;
import grondag.canvas.wip.state.WipVertexState;
import grondag.canvas.wip.state.RenderStateData;
import grondag.canvas.wip.state.WipRenderMaterial;

import static grondag.canvas.material.MaterialVertexFormats.MATERIAL_COLOR_INDEX;
import static grondag.canvas.material.MaterialVertexFormats.MATERIAL_LIGHT_INDEX;
Expand All @@ -36,7 +36,7 @@
public abstract class WipAbstractVertexCollector implements WipVertexCollector {
private static final int LAST_VERTEX_BASE_INDEX = MATERIAL_QUAD_STRIDE - MATERIAL_VERTEX_STRIDE;

protected WipRenderState materialState;
protected WipRenderMaterial materialState;
protected final RenderContextState contextState;

protected final int[] vertexData = new int[MATERIAL_QUAD_STRIDE];
Expand All @@ -63,9 +63,9 @@ public WipVertexCollector texture(float u, float v) {
public WipVertexCollector overlay(int u, int v) {
if (v == 3) {
// NB: these are pre-shifted to msb
overlayFlags = WipVertexState.HURT_OVERLAY_FLAG;
overlayFlags = RenderStateData.HURT_OVERLAY_FLAG;
} else if (v == 10) {
overlayFlags = u > 7 ? WipVertexState.FLASH_OVERLAY_FLAG : 0;
overlayFlags = u > 7 ? RenderStateData.FLASH_OVERLAY_FLAG : 0;
} else {
overlayFlags = 0;
}
Expand All @@ -87,9 +87,10 @@ public WipVertexCollector packedLightWithAo(int packedLight, int ao) {
}

@Override
public WipVertexCollector vertexState(int vertexState) {
normalBase = (WipVertexState.shaderFlags(vertexState) << 24);
conditionActive = WipVertexState.condition(vertexState).compute();
public WipVertexCollector vertexState(WipRenderMaterial material) {
// WIP2: should assert collector key doesn't change here but not currently visible
normalBase = (material.shaderFlags << 24);
conditionActive = material.condition().compute();
return this;
}

Expand Down
6 changes: 3 additions & 3 deletions src/main/java/grondag/canvas/wip/encoding/WipImmediate.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ public WipImmediate(BufferBuilder fallbackBuffer, Map<RenderLayer, BufferBuilder

@Override
public VertexConsumer getBuffer(RenderLayer renderLayer) {
final WipVertexCollector result = collectors.get(((MultiPhaseExt) renderLayer).canvas_renderState());
final WipVertexCollector result = collectors.get(((MultiPhaseExt) renderLayer).canvas_materialState());

if (result == null) {
assert AbstractStateFinder.isExcluded(renderLayer) : "Unable to retrieve vertex collector for non-excluded render layer";

return super.getBuffer(renderLayer);
} else {
result.vertexState(((MultiPhaseExt) renderLayer).canvas_vertexState());
result.vertexState(((MultiPhaseExt) renderLayer).canvas_materialState());
return result;
}
}
Expand Down Expand Up @@ -80,7 +80,7 @@ public void draw(RenderLayer layer) {
if (AbstractStateFinder.isExcluded(layer)) {
super.draw(layer);
} else {
final WipVertexCollectorImpl collector = collectors.getIfExists(((MultiPhaseExt) layer).canvas_renderState());
final WipVertexCollectorImpl collector = collectors.getIfExists(((MultiPhaseExt) layer).canvas_materialState());

if (collector != null) {
collector.drawAndClear();
Expand Down
Loading

0 comments on commit 3dbab93

Please sign in to comment.