Brandon's Core

Brandon's Core

78M Downloads

BlockEntityRendererTransparent is not compatible with Embeddium

embeddedt opened this issue ยท 1 comments

commented

The BlockEntityRendererTransparent implementation does not work properly with Sodium ports. Here:

for (LevelRenderer.RenderChunkInfo renderChunkInfo : levelRenderer.renderChunksInFrustum) {
List<BlockEntity> list = renderChunkInfo.chunk.getCompiledChunk().getRenderableBlockEntities();
for (BlockEntity tile : list) {
if (!event.getFrustum().isVisible(tile.getRenderBoundingBox())) continue;
BlockEntityRenderer<BlockEntity> renderer = tileRenderDispatcher.getRenderer(tile);
if (renderer instanceof BlockEntityRendererTransparent<BlockEntity> rendererTransparent) {
BlockPos pos = tile.getBlockPos();
poseStack.pushPose();
poseStack.translate((double) pos.getX() - camX, (double) pos.getY() - camY, (double) pos.getZ() - camZ);
renderTransparent(camera, rendererTransparent, tile, event.getPartialTick(), poseStack, buffers);
poseStack.popPose();
}
}
}
synchronized (levelRenderer.globalBlockEntities) {
for (BlockEntity tile : levelRenderer.globalBlockEntities) {
if (!event.getFrustum().isVisible(tile.getRenderBoundingBox())) continue;
BlockEntityRenderer<BlockEntity> renderer = tileRenderDispatcher.getRenderer(tile);
if (renderer instanceof BlockEntityRendererTransparent<BlockEntity> rendererTransparent) {
BlockPos blockpos3 = tile.getBlockPos();
poseStack.pushPose();
poseStack.translate((double) blockpos3.getX() - camX, (double) blockpos3.getY() - camY, (double) blockpos3.getZ() - camZ);
renderTransparent(camera, rendererTransparent, tile, event.getPartialTick(), poseStack, buffers);
poseStack.popPose();
}
}
}

your code accesses the vanilla world renderer's internal list of block entities, using an access transformer. This does not work with Sodium (and Forge ports, including Embeddium) because we don't populate the vanilla renderer's list of compiled chunks (we use our own internal data structures for tracking this). It's also quite messy since it relies on multiple access transformer entries, and duplicating vanilla's logic for manipulating the PoseStack.

I think this can be done more cleanly by using a global BufferBuilder that block entities render into during the regular vanilla BlockEntityRenderer#render calls (rather than using the VertexConsumer vanilla provides) and then drawing the contents of that BufferBuilder during RenderLevelStageEvent. If you do it this way, it shouldn't require hacking into vanilla internals at all, and should be compatible with rendering optimization mods.

commented

Noted. Brandon can provide some insight into either why it was coded this way or if it was just an oversight.

We accept code contributions if they're well thought out, so if this issue doesn't make it on his plate in time, you can always take that route.