Stuff renders again

- RenderContext doesn't need to have RenderType
 - Pass RenderTypes separately, clean up refactor
This commit is contained in:
Jozufozu 2022-04-24 17:22:22 -07:00
parent 80017b1559
commit ea78574869
15 changed files with 124 additions and 128 deletions

View file

@ -12,8 +12,6 @@ import com.jozufozu.flywheel.core.RenderContext;
import com.jozufozu.flywheel.core.shader.WorldProgram;
import com.jozufozu.flywheel.event.BeginFrameEvent;
import com.jozufozu.flywheel.util.ClientLevelExtension;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Matrix4f;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
@ -118,11 +116,22 @@ public class InstanceWorld {
/**
* Draw the given layer.
*/
public void renderLayer(RenderContext context) {
public void renderSpecificType(RenderContext context, RenderType type) {
taskEngine.syncPoint();
context.pushPose();
context.translateBack(context.camX(), context.camY(), context.camZ());
engine.render(taskEngine, context);
engine.renderSpecificType(taskEngine, context, type);
context.popPose();
}
/**
* Draw the given layer.
*/
public void renderAllRemaining(RenderContext context) {
taskEngine.syncPoint();
context.pushPose();
context.translateBack(context.camX(), context.camY(), context.camZ());
engine.renderAllRemaining(taskEngine, context);
context.popPose();
}

View file

@ -6,15 +6,15 @@ import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.config.FlwCommands;
import com.jozufozu.flywheel.config.FlwConfig;
import com.jozufozu.flywheel.core.RenderContext;
import com.jozufozu.flywheel.event.BeginFrameEvent;
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
import com.jozufozu.flywheel.event.RenderLayerEvent;
import com.jozufozu.flywheel.util.AnimationTickHolder;
import com.jozufozu.flywheel.util.WorldAttached;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.Sheets;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.entity.BlockEntity;
@ -97,12 +97,18 @@ public class InstancedRenderDispatcher {
}
}
@SubscribeEvent
public static void renderLayer(RenderLayerEvent event) {
ClientLevel world = event.getWorld();
public static void renderSpecificType(RenderContext context, RenderType type) {
ClientLevel world = context.level();
if (!Backend.canUseInstancing(world)) return;
instanceWorlds.get(world).renderLayer(event.context);//.withRenderType(Sheets.chestSheet()));
instanceWorlds.get(world).renderSpecificType(context, type);
}
public static void renderAllRemaining(RenderContext context) {
ClientLevel world = context.level();
if (!Backend.canUseInstancing(world)) return;
instanceWorlds.get(world).renderAllRemaining(context);
}
@SubscribeEvent

View file

@ -1,18 +1,15 @@
package com.jozufozu.flywheel.backend.instancing;
import com.jozufozu.flywheel.core.RenderContext;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Matrix4f;
import net.minecraft.client.Camera;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.RenderType;
public interface RenderDispatcher {
/**
* Render every model for every material.
*/
void render(TaskEngine taskEngine, RenderContext context);
void renderAllRemaining(TaskEngine taskEngine, RenderContext context);
void renderSpecificType(TaskEngine taskEngine, RenderContext context, RenderType type);
/**
* Maintain the integer origin coordinate to be within a certain distance from the camera in all directions.

View file

@ -15,6 +15,7 @@ import com.mojang.blaze3d.platform.Lighting;
import com.mojang.math.Matrix4f;
import net.minecraft.client.Camera;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Vec3i;
@ -39,7 +40,12 @@ public class BatchingEngine implements Engine {
}
@Override
public void render(TaskEngine taskEngine, RenderContext context) {
public void renderSpecificType(TaskEngine taskEngine, RenderContext context, RenderType type) {
}
@Override
public void renderAllRemaining(TaskEngine taskEngine, RenderContext context) {
// vertexCount = 0;
// instanceCount = 0;

View file

@ -1,5 +1,6 @@
package com.jozufozu.flywheel.backend.instancing.instancing;
import java.util.Collections;
import java.util.Map;
import org.lwjgl.system.MemoryUtil;
@ -16,7 +17,6 @@ import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer;
import com.jozufozu.flywheel.backend.gl.versioned.GlCompat;
import com.jozufozu.flywheel.backend.instancing.AbstractInstancer;
import com.jozufozu.flywheel.backend.instancing.Renderable;
import com.jozufozu.flywheel.backend.model.BufferedModel;
import com.jozufozu.flywheel.backend.model.ModelAllocator;
import com.jozufozu.flywheel.core.ModelSupplier;
@ -68,16 +68,8 @@ public class GPUInstancer<D extends InstanceData> extends AbstractInstancer<D> {
return deleted || model == null;
}
public boolean shouldRenderIn(RenderType renderType) {
return modelData.getRenderType() == renderType;
}
public void renderIn(RenderType renderType) {
render();
}
public void init(ModelAllocator modelAllocator) {
if (isInitialized()) return;
public Map<RenderType, Renderable> init(ModelAllocator modelAllocator) {
if (isInitialized()) return Collections.emptyMap();
initialized = true;
@ -90,6 +82,8 @@ public class GPUInstancer<D extends InstanceData> extends AbstractInstancer<D> {
vao.bind();
vao.enableArrays(model.getAttributeCount() + instanceFormat.getAttributeCount());
return ImmutableMap.of(modelData.getRenderType(), this::render);
}
public boolean isInitialized() {

View file

@ -6,6 +6,8 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import com.jozufozu.flywheel.api.InstanceData;
import com.jozufozu.flywheel.api.Instancer;
import com.jozufozu.flywheel.api.Material;
@ -26,6 +28,8 @@ public class InstancedMaterial<D extends InstanceData> implements Material<D> {
protected final List<GPUInstancer<D>> uninitialized = new ArrayList<>();
protected final Multimap<RenderType, Renderable> renderables = ArrayListMultimap.create();
public InstancedMaterial(Instanced<D> type) {
this.type = type;
}
@ -56,6 +60,7 @@ public class InstancedMaterial<D extends InstanceData> implements Material<D> {
public void delete() {
models.values().forEach(GPUInstancer::delete);
models.clear();
renderables.clear();
}
/**
@ -72,25 +77,18 @@ public class InstancedMaterial<D extends InstanceData> implements Material<D> {
public void init(ModelAllocator allocator) {
for (GPUInstancer<?> instancer : uninitialized) {
instancer.init(allocator);
var map = instancer.init(allocator);
map.forEach((type, renderable) -> renderables.get(type).add(renderable));
}
uninitialized.clear();
}
public void renderIn(RenderType layer) {
for (GPUInstancer<?> instancer : models.values()) {
if (instancer.shouldRenderIn(layer)) {
instancer.renderIn(layer);
}
}
renderables.get(layer).forEach(Renderable::render);
}
public boolean anythingToRender(RenderType type) {
for (GPUInstancer<?> instancer : models.values()) {
if (instancer.shouldRenderIn(type)) {
return true;
}
}
return false;
return renderables.get(type).size() > 0;
}
}

View file

@ -1,11 +1,17 @@
package com.jozufozu.flywheel.backend.instancing.instancing;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nonnull;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.jozufozu.flywheel.api.InstanceData;
import com.jozufozu.flywheel.api.struct.Instanced;
import com.jozufozu.flywheel.api.struct.StructType;
@ -43,6 +49,8 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
protected final Map<Instanced<? extends InstanceData>, InstancedMaterial<?>> materials = new HashMap<>();
protected final Set<RenderType> toRender = new HashSet<>();
private final WeakHashSet<OriginShiftListener> listeners;
private int vertexCount;
private int instanceCount;
@ -65,7 +73,23 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
}
@Override
public void render(TaskEngine taskEngine, RenderContext context) {
public void renderAllRemaining(TaskEngine taskEngine, RenderContext context) {
var camX = context.camX() - originCoordinate.getX();
var camY = context.camY() - originCoordinate.getY();
var camZ = context.camZ() - originCoordinate.getZ();
// don't want to mutate viewProjection
var vp = context.viewProjection().copy();
vp.multiply(Matrix4f.createTranslateMatrix((float) -camX, (float) -camY, (float) -camZ));
for (RenderType renderType : toRender) {
render(renderType, camX, camY, camZ, vp);
}
toRender.clear();
}
@Override
public void renderSpecificType(TaskEngine taskEngine, RenderContext context, RenderType type) {
var camX = context.camX() - originCoordinate.getX();
var camY = context.camY() - originCoordinate.getY();
@ -75,7 +99,9 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
var vp = context.viewProjection().copy();
vp.multiply(Matrix4f.createTranslateMatrix((float) -camX, (float) -camY, (float) -camZ));
render(context.type(), camX, camY, camZ, vp);
if (toRender.remove(type)) {
render(type, camX, camY, camZ, vp);
}
}
protected void render(RenderType type, double camX, double camY, double camZ, Matrix4f viewProjection) {
@ -88,7 +114,7 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
for (Map.Entry<Instanced<? extends InstanceData>, InstancedMaterial<?>> entry : materials.entrySet()) {
InstancedMaterial<?> material = entry.getValue();
//if (material.anythingToRender(type)) {
if (material.anythingToRender(type)) {
Instanced<? extends InstanceData> instanceType = entry.getKey();
setup(type, camX, camY, camZ, viewProjection, instanceType.getProgramSpec());
@ -97,7 +123,7 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
vertexCount += material.getVertexCount();
material.renderIn(type);
//}
}
}
type.clearRenderState();
@ -147,6 +173,8 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
for (InstancedMaterial<?> material : materials.values()) {
material.init(allocator);
toRender.addAll(material.renderables.keySet());
}
if (allocator instanceof ModelPool pool) {

View file

@ -0,0 +1,6 @@
package com.jozufozu.flywheel.backend.instancing.instancing;
public interface Renderable {
void render();
}

View file

@ -8,17 +8,12 @@ import com.mojang.math.Quaternion;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.RenderBuffers;
import net.minecraft.client.renderer.RenderType;
public record RenderContext(ClientLevel level, RenderType type, PoseStack stack, Matrix4f viewProjection, RenderBuffers buffers,
public record RenderContext(ClientLevel level, PoseStack stack, Matrix4f viewProjection, RenderBuffers buffers,
double camX, double camY, double camZ) implements TransformStack {
public static RenderContext CURRENT;
public RenderContext withRenderType(RenderType renderType) {
return new RenderContext(level, renderType, stack, viewProjection, buffers, camX, camY, camZ);
}
@Override
public TransformStack multiply(Quaternion quaternion) {
return TransformStack.cast(stack).multiply(quaternion);

View file

@ -66,7 +66,7 @@ public class CrumblingRenderer {
State state = STATE.get();
var instanceManager = state.instanceManager;
var materials = state.materialManager;
var engine = state.materialManager;
TextureManager textureManager = Minecraft.getInstance().getTextureManager();
Camera info = Minecraft.getInstance().gameRenderer.getMainCamera();
@ -79,11 +79,11 @@ public class CrumblingRenderer {
stage.getValue().forEach(instanceManager::add);
instanceManager.beginFrame(SerialTaskEngine.INSTANCE, info);
materials.beginFrame(info);
engine.beginFrame(info);
var ctx = new RenderContext(level, _currentLayer, stack, viewProjection, null, x, y, z);
var ctx = new RenderContext(level, stack, viewProjection, null, x, y, z);
materials.render(SerialTaskEngine.INSTANCE, ctx);
engine.renderAllRemaining(SerialTaskEngine.INSTANCE, ctx);
instanceManager.invalidate();
}

View file

@ -44,7 +44,7 @@ public class BlockModel implements Model {
.withPoseStack(ms), referenceState.toString());
}
public BlockModel(BakedModelBuilder builder, String name) {
public BlockModel(Bufferable builder, String name) {
this(Formats.BLOCK.createReader(builder.build()), name);
}

View file

@ -1,48 +0,0 @@
package com.jozufozu.flywheel.core.model;
import java.util.Collection;
import com.jozufozu.flywheel.api.vertex.VertexList;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.core.Formats;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
public class WorldModel implements Model {
private final VertexList reader;
private final String name;
/**
* It is expected that {@code renderWorld.getShade(...)} returns a constant.
*/
public WorldModel(BlockAndTintGetter renderWorld, RenderType layer, Collection<StructureTemplate.StructureBlockInfo> blocks, String name) {
reader = Formats.BLOCK.createReader(ModelUtil.worldLayer(layer)
.withBlocks(blocks)
.withRenderWorld(renderWorld)
.build());
this.name = name;
}
@Override
public String name() {
return name;
}
@Override
public VertexType getType() {
return Formats.BLOCK;
}
@Override
public int vertexCount() {
return reader.getVertexCount();
}
@Override
public VertexList getReader() {
return reader;
}
}

View file

@ -14,14 +14,11 @@ import net.minecraftforge.eventbus.api.Event;
public class RenderLayerEvent extends Event {
public final RenderContext context;
public final RenderType type;
public RenderLayerEvent(RenderContext context) {
public RenderLayerEvent(RenderContext context, RenderType type) {
this.context = context;
}
public RenderLayerEvent(ClientLevel world, RenderType type, PoseStack stack, RenderBuffers buffers, double camX, double camY, double camZ) {
context = new RenderContext(world, type, stack, createViewProjection(stack), buffers, camX, camY, camZ);
this.type = type;
}
@NotNull
@ -43,7 +40,7 @@ public class RenderLayerEvent extends Event {
}
public RenderType getType() {
return context.type();
return type;
}
public PoseStack getStack() {

View file

@ -3,9 +3,7 @@ package com.jozufozu.flywheel.mixin;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Group;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@ -18,7 +16,6 @@ import com.jozufozu.flywheel.event.BeginFrameEvent;
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
import com.jozufozu.flywheel.event.RenderLayerEvent;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.BufferUploader;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Matrix4f;
@ -29,7 +26,6 @@ import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.RenderBuffers;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.culling.Frustum;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3;
@ -47,25 +43,28 @@ public class LevelRendererMixin {
@Shadow
@Final
private RenderBuffers renderBuffers;
//
// @Inject(at = @At("HEAD"), method = "setupRender")
// private void setupRender(Camera camera, Frustum frustum, boolean queue, boolean isSpectator, CallbackInfo ci) {
//
// GlStateTracker.State restoreState = GlStateTracker.getRestoreState();
// MinecraftForge.EVENT_BUS.post(new BeginFrameEvent(level, camera, frustum));
// restoreState.restore();
// }
@Inject(at = @At("HEAD"), method = "renderLevel")
private void beginRender(PoseStack pPoseStack, float pPartialTick, long pFinishNanoTime, boolean pRenderBlockOutline, Camera pCamera, GameRenderer pGameRenderer, LightTexture pLightTexture, Matrix4f pProjectionMatrix, CallbackInfo ci) {
Vec3 position = pCamera.getPosition();
RenderContext.CURRENT = new RenderContext(level, null, pPoseStack, RenderLayerEvent.createViewProjection(pPoseStack), renderBuffers, position.x, position.y, position.z);
RenderContext.CURRENT = new RenderContext(level, pPoseStack, RenderLayerEvent.createViewProjection(pPoseStack), renderBuffers, position.x, position.y, position.z);
GlStateTracker.State restoreState = GlStateTracker.getRestoreState();
MinecraftForge.EVENT_BUS.post(new BeginFrameEvent(level, pCamera, null));
restoreState.restore();
}
@Inject(at = @At("TAIL"), method = "renderChunkLayer")
private void renderChunkLayer(RenderType pRenderType, PoseStack pPoseStack, double pCamX, double pCamY, double pCamZ, Matrix4f pProjectionMatrix, CallbackInfo ci) {
GlStateTracker.State restoreState = GlStateTracker.getRestoreState();
// TODO: Is this necessary?
InstancedRenderDispatcher.renderSpecificType(RenderContext.CURRENT, pRenderType);
MinecraftForge.EVENT_BUS.post(new RenderLayerEvent(RenderContext.CURRENT, pRenderType));
restoreState.restore();
}
@Inject(at = @At("TAIL"), method = "renderLevel")
private void endRender(PoseStack pPoseStack, float pPartialTick, long pFinishNanoTime, boolean pRenderBlockOutline, Camera pCamera, GameRenderer pGameRenderer, LightTexture pLightTexture, Matrix4f pProjectionMatrix, CallbackInfo ci) {
RenderContext.CURRENT = null;

View file

@ -7,13 +7,11 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
import com.jozufozu.flywheel.core.RenderContext;
import com.jozufozu.flywheel.event.RenderLayerEvent;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderBuffers;
import net.minecraft.client.renderer.RenderType;
import net.minecraftforge.common.MinecraftForge;
@Mixin(MultiBufferSource.BufferSource.class)
public class MultiBufferSourceMixin {
@ -23,7 +21,18 @@ public class MultiBufferSourceMixin {
if (RenderContext.CURRENT != null && Backend.isGameActive() && Backend.isOn()) {
GlStateTracker.State restoreState = GlStateTracker.getRestoreState();
MinecraftForge.EVENT_BUS.post(new RenderLayerEvent(RenderContext.CURRENT.withRenderType(renderType)));
InstancedRenderDispatcher.renderSpecificType(RenderContext.CURRENT, renderType);
restoreState.restore();
}
}
@Inject(method = "endBatch()V", at = @At("TAIL"))
private void endBatch(CallbackInfo ci) {
if (RenderContext.CURRENT != null && Backend.isGameActive() && Backend.isOn()) {
GlStateTracker.State restoreState = GlStateTracker.getRestoreState();
InstancedRenderDispatcher.renderAllRemaining(RenderContext.CURRENT);
restoreState.restore();
}