add support for shader wind effects
This commit is contained in:
@@ -1,64 +1,54 @@
|
||||
package mods.betterfoliage.render
|
||||
|
||||
import mods.betterfoliage.BetterFoliage
|
||||
import mods.betterfoliage.util.get
|
||||
import net.minecraft.block.BlockRenderType
|
||||
import net.minecraft.block.BlockRenderType.MODEL
|
||||
import mods.betterfoliage.render.lighting.getBufferBuilder
|
||||
import mods.betterfoliage.util.getAllMethods
|
||||
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext
|
||||
import net.minecraft.block.BlockRenderLayer
|
||||
import net.minecraft.block.BlockRenderLayer.CUTOUT_MIPPED
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.block.Blocks
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.ExtendedBlockView
|
||||
import org.apache.logging.log4j.Level.INFO
|
||||
import net.minecraft.client.render.BufferBuilder
|
||||
|
||||
/**
|
||||
* Integration for ShadersMod.
|
||||
*/
|
||||
/*
|
||||
object ShadersModIntegration {
|
||||
|
||||
@JvmStatic val isAvailable = allAvailable(SVertexBuilder, SVertexBuilder.pushState, SVertexBuilder.pushNum, SVertexBuilder.pop)
|
||||
val BufferBuilder_SVertexBuilder = BufferBuilder::class.java.fields.find { it.name == "sVertexBuilder" }
|
||||
val SVertexBuilder_pushState = getAllMethods("net.optifine.shaders.SVertexBuilder", "pushEntity").find { it.parameterCount == 1 }
|
||||
val SVertexBuilder_popState = getAllMethods("net.optifine.shaders.SVertexBuilder", "popEntity").find { it.parameterCount == 0 }
|
||||
val BlockAliases_getAliasBlockId = getAllMethods("net.optifine.shaders.BlockAliases", "getAliasBlockId").firstOrNull()
|
||||
|
||||
@JvmStatic val isAvailable =
|
||||
listOf(BufferBuilder_SVertexBuilder).all { it != null } &&
|
||||
listOf(SVertexBuilder_pushState, SVertexBuilder_popState, BlockAliases_getAliasBlockId).all { it != null }
|
||||
|
||||
val defaultLeaves = Blocks.OAK_LEAVES.defaultState
|
||||
val defaultGrass = Blocks.TALL_GRASS.defaultState
|
||||
|
||||
/**
|
||||
* Called from transformed ShadersMod code.
|
||||
* @see mods.betterfoliage.loader.BetterFoliageTransformer
|
||||
*/
|
||||
@JvmStatic fun getBlockStateOverride(state: BlockState, world: ExtendedBlockView, pos: BlockPos): BlockState {
|
||||
// if (LeafRegistry[state, world, pos] != null) return defaultLeaves
|
||||
if (BetterFoliage.blockConfig.crops.matchesClass(state.block)) return defaultGrass
|
||||
return state
|
||||
}
|
||||
|
||||
init {
|
||||
BetterFoliage.log(INFO, "ShadersMod integration is ${if (isAvailable) "enabled" else "disabled" }")
|
||||
BetterFoliage.logger.info("[BetterFoliage] ShadersMod integration is ${if (isAvailable) "enabled" else "disabled" }")
|
||||
}
|
||||
|
||||
inline fun renderAs(ctx: CombinedContext, renderType: BlockRenderType, enabled: Boolean = true, func: ()->Unit) =
|
||||
renderAs(ctx, ctx.state, renderType, enabled, func)
|
||||
|
||||
/** Quads rendered inside this block will use the given block entity data in shader programs. */
|
||||
inline fun renderAs(ctx: CombinedContext, state: BlockState, renderType: BlockRenderType, enabled: Boolean = true, func: ()->Unit) {
|
||||
inline fun renderAs(ctx: RenderContext, state: BlockState, layer: BlockRenderLayer, enabled: Boolean = true, func: ()->Unit) {
|
||||
if (isAvailable && enabled) {
|
||||
val buffer = ctx.renderCtx.renderBuffer
|
||||
val sVertexBuilder = buffer[BufferBuilder_sVertexBuilder]
|
||||
SVertexBuilder.pushState.invoke(sVertexBuilder!!, ctx.state, ctx.pos, ctx.world, buffer)
|
||||
val sVertexBuilder = BufferBuilder_SVertexBuilder!!.get(ctx.getBufferBuilder(layer))
|
||||
val aliasBlockId = BlockAliases_getAliasBlockId!!.invoke(null, state)
|
||||
SVertexBuilder_pushState!!.invoke(sVertexBuilder, aliasBlockId)
|
||||
func()
|
||||
SVertexBuilder.pop.invoke(sVertexBuilder)
|
||||
SVertexBuilder_popState!!.invoke(sVertexBuilder)
|
||||
} else {
|
||||
func()
|
||||
}
|
||||
}
|
||||
|
||||
/** Quads rendered inside this block will behave as tallgrass blocks in shader programs. */
|
||||
inline fun grass(ctx: CombinedContext, enabled: Boolean = true, func: ()->Unit) =
|
||||
renderAs(ctx, defaultGrass, MODEL, enabled, func)
|
||||
inline fun grass(ctx: RenderContext, enabled: Boolean = true, func: ()->Unit) =
|
||||
renderAs(ctx, defaultGrass, CUTOUT_MIPPED, enabled, func)
|
||||
|
||||
/** Quads rendered inside this block will behave as leaf blocks in shader programs. */
|
||||
inline fun leaves(ctx: CombinedContext, enabled: Boolean = true, func: ()->Unit) =
|
||||
renderAs(ctx, defaultLeaves, MODEL, enabled, func)
|
||||
inline fun leaves(ctx: RenderContext, enabled: Boolean = true, func: ()->Unit) =
|
||||
renderAs(ctx, defaultLeaves, CUTOUT_MIPPED, enabled, func)
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,7 @@ import mods.betterfoliage.BetterFoliage
|
||||
import mods.betterfoliage.chunk.BasicBlockCtx
|
||||
import mods.betterfoliage.render.DIRT_BLOCKS
|
||||
import mods.betterfoliage.render.SALTWATER_BIOMES
|
||||
import mods.betterfoliage.render.ShadersModIntegration
|
||||
import mods.betterfoliage.render.lighting.withLighting
|
||||
import mods.betterfoliage.render.lighting.grassTuftLighting
|
||||
import mods.betterfoliage.render.lighting.reedLighting
|
||||
@@ -66,12 +67,16 @@ class DirtModel(wrapped: BakedModel) : WrappedBakedModel(wrapped) {
|
||||
|
||||
val random = randomSupplier.get()
|
||||
if (BetterFoliage.config.algae.enabled(random) && isDeepWater) {
|
||||
context.withLighting(algaeLighting) {
|
||||
it.accept(algaeModels[random])
|
||||
ShadersModIntegration.grass(context, BetterFoliage.config.algae.shaderWind) {
|
||||
context.withLighting(algaeLighting) {
|
||||
it.accept(algaeModels[random])
|
||||
}
|
||||
}
|
||||
} else if (BetterFoliage.config.reed.enabled(random) && isShallowWater && !isSaltWater) {
|
||||
context.withLighting(reedLighting) {
|
||||
it.accept(reedModels[random])
|
||||
ShadersModIntegration.grass(context, BetterFoliage.config.reed.shaderWind) {
|
||||
context.withLighting(reedLighting) {
|
||||
it.accept(reedModels[random])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package mods.betterfoliage.render.block.vanilla
|
||||
import mods.betterfoliage.BetterFoliage
|
||||
import mods.betterfoliage.chunk.BasicBlockCtx
|
||||
import mods.betterfoliage.render.SNOW_MATERIALS
|
||||
import mods.betterfoliage.render.ShadersModIntegration
|
||||
import mods.betterfoliage.render.lighting.withLighting
|
||||
import mods.betterfoliage.render.lighting.grassTuftLighting
|
||||
import mods.betterfoliage.util.Atlas
|
||||
@@ -78,8 +79,10 @@ class GrassBlockModel(val key: Key, wrapped: BakedModel) : WrappedBakedModel(wra
|
||||
}
|
||||
|
||||
if (BetterFoliage.config.shortGrass.enabled(random) && !ctx.isNeighborSolid(UP)) {
|
||||
context.withLighting(tuftLighting) {
|
||||
it.accept(if (isSnowed) tuftSnowed[random] else tuftNormal[random])
|
||||
ShadersModIntegration.grass(context, BetterFoliage.config.shortGrass.shaderWind) {
|
||||
context.withLighting(tuftLighting) {
|
||||
it.accept(if (isSnowed) tuftSnowed[random] else tuftNormal[random])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package mods.betterfoliage.render.block.vanilla
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectFunction
|
||||
import mods.betterfoliage.BetterFoliage
|
||||
import mods.betterfoliage.chunk.BasicBlockCtx
|
||||
import mods.betterfoliage.render.SNOW_MATERIALS
|
||||
import mods.betterfoliage.render.ShadersModIntegration
|
||||
import mods.betterfoliage.render.lighting.getBufferBuilder
|
||||
import mods.betterfoliage.render.lighting.withLighting
|
||||
import mods.betterfoliage.render.lighting.roundLeafLighting
|
||||
import mods.betterfoliage.render.particle.LeafParticleRegistry
|
||||
@@ -13,6 +16,11 @@ import mods.betterfoliage.resource.model.*
|
||||
import mods.betterfoliage.util.*
|
||||
import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel
|
||||
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext
|
||||
import net.fabricmc.fabric.impl.client.indigo.renderer.accessor.AccessBufferBuilder
|
||||
import net.fabricmc.fabric.impl.client.indigo.renderer.render.BlockRenderInfo
|
||||
import net.fabricmc.fabric.impl.client.indigo.renderer.render.TerrainMeshConsumer
|
||||
import net.fabricmc.fabric.impl.client.indigo.renderer.render.TerrainRenderContext
|
||||
import net.minecraft.block.BlockRenderLayer
|
||||
import net.minecraft.block.BlockRenderLayer.CUTOUT_MIPPED
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.client.render.model.BakedModel
|
||||
@@ -77,17 +85,19 @@ class NormalLeavesModel(val key: Key, wrapped: BakedModel) : WrappedBakedModel(w
|
||||
val leafLighting = roundLeafLighting()
|
||||
|
||||
override fun emitBlockQuads(blockView: ExtendedBlockView, state: BlockState, pos: BlockPos, randomSupplier: Supplier<Random>, context: RenderContext) {
|
||||
super.emitBlockQuads(blockView, state, pos, randomSupplier, context)
|
||||
if (!BetterFoliage.config.enabled || !BetterFoliage.config.leaves.enabled) return
|
||||
ShadersModIntegration.leaves(context, BetterFoliage.config.leaves.shaderWind) {
|
||||
super.emitBlockQuads(blockView, state, pos, randomSupplier, context)
|
||||
if (!BetterFoliage.config.enabled || !BetterFoliage.config.leaves.enabled) return
|
||||
|
||||
val ctx = BasicBlockCtx(blockView, pos)
|
||||
val stateAbove = ctx.state(UP)
|
||||
val isSnowed = stateAbove.material in SNOW_MATERIALS
|
||||
val ctx = BasicBlockCtx(blockView, pos)
|
||||
val stateAbove = ctx.state(UP)
|
||||
val isSnowed = stateAbove.material in SNOW_MATERIALS
|
||||
|
||||
val random = randomSupplier.get()
|
||||
context.withLighting(leafLighting) {
|
||||
it.accept(leafNormal[random])
|
||||
if (isSnowed) it.accept(leafSnowed[random])
|
||||
val random = randomSupplier.get()
|
||||
context.withLighting(leafLighting) {
|
||||
it.accept(leafNormal[random])
|
||||
if (isSnowed) it.accept(leafSnowed[random])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package mods.betterfoliage.render.block.vanilla
|
||||
|
||||
import mods.betterfoliage.BetterFoliage
|
||||
import mods.betterfoliage.render.ShadersModIntegration
|
||||
import mods.betterfoliage.util.Atlas
|
||||
import mods.betterfoliage.resource.discovery.BlockRenderKey
|
||||
import mods.betterfoliage.resource.discovery.ModelDiscoveryBase
|
||||
@@ -39,7 +40,9 @@ class LilypadModel(wrapped: BakedModel) : WrappedBakedModel(wrapped) {
|
||||
if (!BetterFoliage.config.enabled || !BetterFoliage.config.lilypad.enabled) return
|
||||
|
||||
val random = randomSupplier.get()
|
||||
context.meshConsumer().accept(lilypadRootModels[random])
|
||||
ShadersModIntegration.grass(context, BetterFoliage.config.lilypad.shaderWind) {
|
||||
context.meshConsumer().accept(lilypadRootModels[random])
|
||||
}
|
||||
if (random.nextInt(64) < BetterFoliage.config.lilypad.population) {
|
||||
context.meshConsumer().accept(lilypadFlowerModels[random])
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package mods.betterfoliage.render.block.vanilla
|
||||
|
||||
import mods.betterfoliage.BetterFoliage
|
||||
import mods.betterfoliage.render.ShadersModIntegration
|
||||
import mods.betterfoliage.render.lighting.withLighting
|
||||
import mods.betterfoliage.render.lighting.grassTuftLighting
|
||||
import mods.betterfoliage.util.Atlas
|
||||
@@ -45,8 +46,10 @@ class MyceliumModel(wrapped: BakedModel) : WrappedBakedModel(wrapped) {
|
||||
BetterFoliage.config.shortGrass.let { it.myceliumEnabled && random.nextInt(64) < it.population } &&
|
||||
blockView.getBlockState(pos + UP.offset).isAir
|
||||
) {
|
||||
context.withLighting(tuftLighting) {
|
||||
it.accept(myceliumTuftModels[random])
|
||||
ShadersModIntegration.grass(context, BetterFoliage.config.shortGrass.shaderWind) {
|
||||
context.withLighting(tuftLighting) {
|
||||
it.accept(myceliumTuftModels[random])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
package mods.betterfoliage.render.lighting
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectFunction
|
||||
import mods.betterfoliage.util.reflectField
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh
|
||||
import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel
|
||||
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext
|
||||
import net.fabricmc.fabric.impl.client.indigo.renderer.accessor.AccessBufferBuilder
|
||||
import net.fabricmc.fabric.impl.client.indigo.renderer.aocalc.AoCalculator
|
||||
import net.fabricmc.fabric.impl.client.indigo.renderer.render.*
|
||||
import net.minecraft.block.BlockRenderLayer
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.client.MinecraftClient
|
||||
import net.minecraft.client.render.model.BakedModel
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.ExtendedBlockView
|
||||
@@ -25,13 +27,17 @@ fun TerrainMeshConsumer.modified() = MODIFIED_CONSUMER_POOL.get() ?: let {
|
||||
ModifiedTerrainMeshConsumer(blockInfo, chunkInfo, aoCalc, transform)
|
||||
}.apply { MODIFIED_CONSUMER_POOL.set(this) }
|
||||
|
||||
val TerrainRenderContext_blockInfo = TerrainRenderContext::class.java.declaredFields.find { it.name == "blockInfo" }?.apply { isAccessible = true }
|
||||
val BlockRenderInfo_layerIndexOrDefault = BlockRenderInfo::class.java.declaredMethods.find { it.name == "layerIndexOrDefault" }?.apply { isAccessible = true }
|
||||
val AbstractQuadRenderer_bufferFunc = AbstractQuadRenderer::class.java.declaredFields.find { it.name == "bufferFunc" }?.apply { isAccessible = true }
|
||||
|
||||
/**
|
||||
* Render the given model at the given position.
|
||||
* Mutates the state of the [RenderContext]!!
|
||||
*/
|
||||
fun RenderContext.renderMasquerade(model: BakedModel, blockView: ExtendedBlockView, state: BlockState, pos: BlockPos, randomSupplier: Supplier<Random>, context: RenderContext) = when(this) {
|
||||
is TerrainRenderContext -> {
|
||||
val blockInfo = reflectField<TerrainBlockRenderInfo>("blockInfo")
|
||||
val blockInfo = TerrainRenderContext_blockInfo!!.get(this) as BlockRenderInfo
|
||||
blockInfo.prepareForBlock(state, pos, model.useAmbientOcclusion())
|
||||
(model as FabricBakedModel).emitBlockQuads(blockView, state, pos, randomSupplier, context)
|
||||
}
|
||||
@@ -51,3 +57,14 @@ fun RenderContext.withLighting(lighter: CustomLighting, func: (Consumer<Mesh>)->
|
||||
}
|
||||
else -> func(meshConsumer())
|
||||
}
|
||||
|
||||
/** Get the [BufferBuilder] responsible for a given [BlockRenderLayer] */
|
||||
fun RenderContext.getBufferBuilder(layer: BlockRenderLayer) = when(this) {
|
||||
is TerrainRenderContext -> {
|
||||
val blockInfo = TerrainRenderContext_blockInfo!!.get(this) as BlockRenderInfo
|
||||
val layerIdx = BlockRenderInfo_layerIndexOrDefault!!.invoke(blockInfo, layer) as Int
|
||||
val bufferFunc = AbstractQuadRenderer_bufferFunc!!.get(meshConsumer()) as Int2ObjectFunction<AccessBufferBuilder>
|
||||
bufferFunc[layerIdx]
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
Reference in New Issue
Block a user