DynamicBufferSource battle test

This commit is contained in:
DBotThePony 2022-10-08 13:29:16 +07:00
parent f14b6a809e
commit 1c30ce7e8a
Signed by: DBot
GPG Key ID: DCC23B5715498507
5 changed files with 186 additions and 31 deletions

View File

@ -86,7 +86,7 @@ class AtlasSkinElement(
WidgetAtlasHolder.INSTANCE.queueRebuild()
}
val renderTypeGUI by lazy {
val renderTypeNoDepth by lazy {
val builder = RenderType.CompositeState.builder()
builder.setTextureState(TextureStateShard(WidgetAtlasHolder.LOCATION, false, false))
@ -100,7 +100,29 @@ class AtlasSkinElement(
}))
@Suppress("INACCESSIBLE_TYPE")
RenderType.create("gui_element",
RenderType.create("otm_gui_element_no_depth",
DefaultVertexFormat.POSITION_COLOR_TEX,
VertexFormat.Mode.QUADS,
2048,
false,
false,
builder.createCompositeState(false)) as RenderType
}
val renderTypeDepth by lazy {
val builder = RenderType.CompositeState.builder()
builder.setTextureState(TextureStateShard(WidgetAtlasHolder.LOCATION, false, false))
builder.setShaderState(RenderStateShard.ShaderStateShard(GameRenderer::getPositionColorTexShader))
builder.setTransparencyState(RenderStateShard.TransparencyStateShard("normal_blend", {
RenderSystem.enableBlend()
RenderSystem.defaultBlendFunc()
}, {
RenderSystem.disableBlend()
}))
@Suppress("INACCESSIBLE_TYPE")
RenderType.create("otm_gui_element_depth",
DefaultVertexFormat.POSITION_COLOR_TEX,
VertexFormat.Mode.QUADS,
2048,
@ -122,10 +144,10 @@ class AtlasSkinElement(
}))
@Suppress("INACCESSIBLE_TYPE")
RenderType.create("gui_element_world",
RenderType.create("otm_gui_element_world",
DefaultVertexFormat.POSITION_COLOR_TEX,
VertexFormat.Mode.QUADS,
2048,
8192,
false,
false,
builder.createCompositeState(false)) as RenderType

View File

@ -57,56 +57,81 @@ private fun equals(existing: ImmutableList<RenderType>?, types: ImmutableList<Re
return true
}
class DynamicBufferSource : MultiBufferSource {
private class State(
class DynamicBufferSource(val minimalBufferSize: Int = 0) : MultiBufferSource {
private inner class State(
val type: RenderType,
var after: ImmutableList<RenderType>? = null,
val immutableAfter: Boolean = false
immutableAfter: Boolean = false,
chained: Boolean = true
) {
val immutableAfter: Boolean
val chained: Boolean
init {
if (
type.name == "forge_text" ||
type.name == "text_intensity" ||
type.name == "forge_text_see_through"
) {
after = ImmutableList.of(Sheets.signSheet())
this.immutableAfter = true
this.chained = true
} else {
this.immutableAfter = immutableAfter
this.chained = chained
}
}
val dependants = ArrayList<State>(0)
var priority = -1
var dirty: Boolean = false
val builder by lazy {
BufferBuilder(type.bufferSize())
BufferBuilder(type.bufferSize().coerceAtLeast(minimalBufferSize))
}
}
@Suppress("BooleanLiteralArgument")
private val bufferList = ArrayList<State>().also {
var next = State(Sheets.solidBlockSheet(), null, true)
var next = State(Sheets.solidBlockSheet(), null, true, false)
it.add(next)
next = State(Sheets.cutoutBlockSheet(), ImmutableList.of(next.type), true)
next = State(Sheets.cutoutBlockSheet(), ImmutableList.of(next.type), true, false)
it.add(next)
next = State(Sheets.bannerSheet(), ImmutableList.of(next.type), true)
next = State(Sheets.bannerSheet(), ImmutableList.of(next.type), true, false)
it.add(next)
next = State(Sheets.translucentCullBlockSheet(), ImmutableList.of(next.type), true)
next = State(Sheets.translucentCullBlockSheet(), ImmutableList.of(next.type), true, false)
it.add(next)
next = State(Sheets.shieldSheet(), ImmutableList.of(next.type), true)
next = State(Sheets.shieldSheet(), ImmutableList.of(next.type), true, false)
it.add(next)
next = State(Sheets.bedSheet(), ImmutableList.of(next.type), true)
next = State(Sheets.bedSheet(), ImmutableList.of(next.type), true, false)
it.add(next)
next = State(Sheets.shulkerBoxSheet(), ImmutableList.of(next.type), true)
next = State(Sheets.shulkerBoxSheet(), ImmutableList.of(next.type), true, false)
it.add(next)
next = State(Sheets.signSheet(), ImmutableList.of(next.type), true)
next = State(Sheets.signSheet(), ImmutableList.of(next.type), true, false)
it.add(next)
next = State(Sheets.chestSheet(), ImmutableList.of(next.type), true)
next = State(Sheets.chestSheet(), ImmutableList.of(next.type), true, false)
it.add(next)
next = State(RenderType.translucentNoCrumbling(), ImmutableList.of(next.type), true)
next = State(RenderType.translucentNoCrumbling(), ImmutableList.of(next.type), true, false)
it.add(next)
next = State(RenderType.armorGlint(), ImmutableList.of(next.type), true)
next = State(RenderType.armorGlint(), ImmutableList.of(next.type), true, false)
it.add(next)
next = State(RenderType.armorEntityGlint(), ImmutableList.of(next.type), true)
next = State(RenderType.armorEntityGlint(), ImmutableList.of(next.type), true, false)
it.add(next)
next = State(RenderType.glint(), ImmutableList.of(next.type), true)
next = State(RenderType.glint(), ImmutableList.of(next.type), true, false)
it.add(next)
next = State(RenderType.glintDirect(), ImmutableList.of(next.type), true)
next = State(RenderType.glintDirect(), ImmutableList.of(next.type), true, false)
it.add(next)
next = State(RenderType.glintTranslucent(), ImmutableList.of(next.type), true)
next = State(RenderType.glintTranslucent(), ImmutableList.of(next.type), true, false)
it.add(next)
next = State(RenderType.entityGlint(), ImmutableList.of(next.type), true)
next = State(RenderType.entityGlint(), ImmutableList.of(next.type), true, false)
it.add(next)
next = State(RenderType.entityGlintDirect(), ImmutableList.of(next.type), true)
next = State(RenderType.entityGlintDirect(), ImmutableList.of(next.type), true, false)
it.add(next)
next = State(RenderType.waterMask(), ImmutableList.of(next.type), true)
next = State(RenderType.waterMask(), ImmutableList.of(next.type), true, false)
it.add(next)
it.add(State(AtlasSkinElement.renderTypeDepth, ImmutableList.of(RenderType.waterMask()), true))
it.add(State(AtlasSkinElement.renderTypeNoDepth, ImmutableList.of(RenderType.waterMask()), true))
it.add(State(AtlasSkinElement.renderTypeWorld, ImmutableList.of(Sheets.signSheet()), true))
}
private fun determineHeight(input: State, seen: MutableSet<State>) {
@ -125,6 +150,11 @@ class DynamicBufferSource : MultiBufferSource {
}
input.priority = input.priority.coerceAtLeast(input2.priority + 1)
if (input.chained) {
input2.dependants.add(input)
}
break
}
}
@ -139,6 +169,7 @@ class DynamicBufferSource : MultiBufferSource {
private fun sortBufferList() {
for (state in bufferList) {
state.priority = -1
state.dependants.clear()
}
for (state in bufferList) {
@ -156,6 +187,10 @@ class DynamicBufferSource : MultiBufferSource {
for (v in bufferList) it[v.type] = v
}
init {
sortBufferList()
}
override fun getBuffer(renderType: RenderType): VertexConsumer {
var getState = buffers[renderType]
@ -318,7 +353,48 @@ class DynamicBufferSource : MultiBufferSource {
}
}
fun endBatchChain(type: RenderType) {
val state = buffers[type] ?: return
if (state.dirty) {
state.dirty = false
type.end(state.builder, 0, 0, 0)
}
for (ustate in state.dependants) {
endBatchChain(ustate)
}
}
private fun endBatchChain(state: State) {
if (state.dirty) {
state.dirty = false
state.type.end(state.builder, 0, 0, 0)
}
for (ustate in state.dependants) {
endBatchChain(ustate)
}
}
companion object {
val GUI = DynamicBufferSource()
val WORLD = DynamicBufferSource(8192)
/**
* Called from LevelRenderer
*/
@JvmStatic
fun renderHook(type: RenderType) {
WORLD.endBatchChain(type)
}
/**
* Called from LevelRenderer
*/
@JvmStatic
fun renderHook() {
WORLD.endBatch()
}
}
}

View File

@ -13,6 +13,8 @@ import ru.dbotthepony.mc.otm.block.entity.BatteryBankBlockEntity
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity
import ru.dbotthepony.mc.otm.block.entity.matter.MatterCapacitorBankBlockEntity
import ru.dbotthepony.mc.otm.client.render.AbstractSkinElement
import ru.dbotthepony.mc.otm.client.render.AtlasSkinElement
import ru.dbotthepony.mc.otm.client.render.DynamicBufferSource
import ru.dbotthepony.mc.otm.client.render.SkinElement
import ru.dbotthepony.mc.otm.client.render.is3DContext
import ru.dbotthepony.mc.otm.client.screen.widget.MatterGaugePanel
@ -35,9 +37,6 @@ abstract class BankRenderer<T : MatteryBlockEntity>(private val context: BlockEn
is3DContext = true
try {
RenderSystem.enableDepthTest()
RenderSystem.depthFunc(GL_LEQUAL)
stack.pushPose()
val facing = blockEntity.blockState[RotatableMatteryBlock.FACING]
@ -55,7 +54,10 @@ abstract class BankRenderer<T : MatteryBlockEntity>(private val context: BlockEn
val width = 9f
val heightMax = 39.36f
texture.renderPartial(stack,
val buffer = DynamicBufferSource.WORLD.getBuffer(AtlasSkinElement.renderTypeWorld)
texture.uploadOntoPartialColor(stack,
buffer,
x = 25f - width / 2f,
y = 30f,
width = width,
@ -64,7 +66,8 @@ abstract class BankRenderer<T : MatteryBlockEntity>(private val context: BlockEn
stack.mulPose(Vector3f.YP.rotation(PI.toFloat()))
stack.translate(-50.0, 0.0, -101.0)
texture.renderPartial(stack,
texture.uploadOntoPartialColor(stack,
buffer,
x = 25f - width / 2f,
y = 30f,
width = width,

View File

@ -47,3 +47,5 @@ protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen m_9
protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen m_97782_(Lnet/minecraft/world/item/ItemStack;IILjava/lang/String;)V # renderFloatingItem
protected net.minecraft.client.resources.TextureAtlasHolder f_118884_ # textureAtlas
public net.minecraft.client.renderer.RenderStateShard f_110133_ # name

View File

@ -685,6 +685,58 @@ function initializeCoreMod() {
}
},
'LevelRenderer DynamicBufferSource callback': {
'target': {
'type': 'METHOD',
'class': 'net.minecraft.client.renderer.LevelRenderer',
'methodName': ASMAPI.mapMethod('m_109599_'), // renderLevel
'methodDesc': '(Lcom/mojang/blaze3d/vertex/PoseStack;FJZLnet/minecraft/client/Camera;Lnet/minecraft/client/renderer/GameRenderer;Lnet/minecraft/client/renderer/LightTexture;Lcom/mojang/math/Matrix4f;)V'
},
'transformer': function(node) {
var endBatchName = ASMAPI.mapMethod('m_109912_') // net/minecraft/client/renderer/MultiBufferSource$BufferSource#endBatch
var endBatchDesc = '(Lnet/minecraft/client/renderer/RenderType;)V'
var endBatchName2 = ASMAPI.mapMethod('m_109911_') // net/minecraft/client/renderer/MultiBufferSource$BufferSource#endBatch
var endBatchDesc2 = '()V'
var ourLocalIndex = node.maxLocals++
for (i = 0; i < node.instructions.size(); i++) {
var instruction = node.instructions.get(i)
if (instruction.getOpcode() == opcodesRemapped.invokevirtual && instruction.name == endBatchName && instruction.desc == endBatchDesc) {
node.instructions.insert(node.instructions.get(i - 1), new InsnNode(opcodesRemapped.dup_x1))
node.instructions.insert(instruction, new MethodInsnNode(
opcodesRemapped.invokestatic,
'ru/dbotthepony/mc/otm/client/render/DynamicBufferSource',
'renderHook',
'(Lnet/minecraft/client/renderer/RenderType;)V',
false
))
i += 2
continue
}
if (instruction.getOpcode() == opcodesRemapped.invokevirtual && instruction.name == endBatchName2 && instruction.desc == endBatchDesc2) {
node.instructions.insert(instruction, new MethodInsnNode(
opcodesRemapped.invokestatic,
'ru/dbotthepony/mc/otm/client/render/DynamicBufferSource',
'renderHook',
'()V',
false
))
i += 2
continue
}
}
return node
}
},
'EnchantmentHelper#getSweepingDamageRatio patch for energy sword': {
'target': {
'type': 'METHOD',