[WIP] Lilypad working

+ shader integration
This commit is contained in:
octarine-noise
2021-05-11 16:18:58 +02:00
parent 835bf45f13
commit a917d5b3db
12 changed files with 126 additions and 31 deletions

View File

@@ -11,6 +11,8 @@ import mods.betterfoliage.render.block.vanilla.StandardGrassDiscovery
import mods.betterfoliage.render.block.vanilla.StandardGrassModel
import mods.betterfoliage.render.block.vanilla.StandardLeafDiscovery
import mods.betterfoliage.render.block.vanilla.StandardLeafModel
import mods.betterfoliage.render.block.vanilla.StandardLilypadDiscovery
import mods.betterfoliage.render.block.vanilla.StandardLilypadModel
import mods.betterfoliage.render.block.vanilla.StandardMyceliumDiscovery
import mods.betterfoliage.render.block.vanilla.StandardMyceliumModel
import mods.betterfoliage.render.block.vanilla.StandardSandDiscovery
@@ -46,7 +48,8 @@ object Client {
StandardGrassDiscovery,
StandardDirtDiscovery,
StandardMyceliumDiscovery,
StandardSandDiscovery
StandardSandDiscovery,
StandardLilypadDiscovery
).forEach {
BakeWrapperManager.discoverers.add(it)
}
@@ -64,7 +67,8 @@ object Client {
StandardGrassModel.Companion,
StandardDirtModel.Companion,
StandardMyceliumModel.Companion,
StandardSandModel.Companion
StandardSandModel.Companion,
StandardLilypadModel.Companion
)
// init mod integrations

View File

@@ -76,6 +76,7 @@ object Config : DelegatingConfig(BetterFoliageMod.MOD_ID, BetterFoliageMod.MOD_I
override val enabled by featureEnable()
val hOffset by double(max=0.25, default=0.1).lang("hOffset")
override val population by int(max=64, default=16, min=0)
val shaderWind by boolean(true).lang("shaderWind")
}
object reed : PopulationConfigCategory(){

View File

@@ -1,6 +1,9 @@
package mods.betterfoliage.integration
import mods.betterfoliage.config.BlockConfig
import mods.betterfoliage.render.pipeline.RenderCtxBase
import mods.betterfoliage.render.pipeline.RenderCtxForge
import mods.betterfoliage.render.pipeline.RenderCtxVanilla
import mods.betterfoliage.util.HasLogger
import mods.betterfoliage.util.allAvailable
import mods.betterfoliage.util.get
@@ -51,10 +54,15 @@ object ShadersModIntegration : HasLogger() {
}
/** Quads rendered inside this block will behave as tallgrass blocks in shader programs. */
inline fun grass(buffer: BufferBuilder, enabled: Boolean = true, func: ()->Unit) =
renderAs(buffer, defaultGrass, MODEL, enabled, func)
inline fun grass(ctx: RenderCtxBase, enabled: Boolean = true, func: ()->Unit) =
((ctx as? RenderCtxVanilla)?.buffer as? BufferBuilder)?.let { bufferBuilder ->
renderAs(bufferBuilder, defaultGrass, MODEL, enabled, func)
}
/** Quads rendered inside this block will behave as leaf blocks in shader programs. */
inline fun leaves(buffer: BufferBuilder, enabled: Boolean = true, func: ()->Unit) =
renderAs(buffer, defaultLeaves, MODEL, enabled, func)
inline fun leaves(ctx: RenderCtxBase, enabled: Boolean = true, func: ()->Unit) =
((ctx as? RenderCtxVanilla)?.buffer as? BufferBuilder)?.let { bufferBuilder ->
renderAs(bufferBuilder, defaultLeaves, MODEL, enabled, func)
}
}

View File

@@ -36,7 +36,7 @@ open class HalfBakedSimpleModelWrapper(baseModel: SimpleBakedModel): IBakedModel
val baseQuads = baseModel.unbakeQuads()
override fun render(ctx: RenderCtxBase, noDecorations: Boolean) {
ctx.render(baseQuads)
ctx.renderQuads(baseQuads)
}
}

View File

@@ -50,13 +50,13 @@ fun tuftQuadSingle(size: Double, height: Double, flipU: Boolean) =
)
.mirrorUV(flipU, false)
fun tuftModelSet(shapes: Array<TuftShapeKey>, overrideColor: Color?, spriteGetter: (Int) -> TextureAtlasSprite) =
fun tuftModelSet(shapes: Array<TuftShapeKey>, tintIndex: Int, spriteGetter: (Int) -> TextureAtlasSprite) =
shapes.mapIndexed { idx, shape ->
listOf(
tuftQuadSingle(shape.size, shape.height, shape.flipU1),
tuftQuadSingle(shape.size, shape.height, shape.flipU2).rotate(rot(UP))
).map { it.move(shape.offset) }
.map { it.colorAndIndex(overrideColor) }
.map { it.colorIndex(tintIndex) }
.map { it.sprite(spriteGetter(idx)) }
}

View File

@@ -3,7 +3,6 @@ package mods.betterfoliage.render.block.vanilla
import mods.betterfoliage.BetterFoliageMod
import mods.betterfoliage.Client
import mods.betterfoliage.config.Config
import mods.betterfoliage.model.Color
import mods.betterfoliage.model.HalfBakedSpecialWrapper
import mods.betterfoliage.model.HalfBakedWrapperKey
import mods.betterfoliage.model.SpecialRenderModel
@@ -89,10 +88,10 @@ class StandardDirtModel(
if (Config.algae.enabled(ctx.random) && isDeepWater) {
(ctx as? RenderCtxVanilla)?.vertexLighter = vanillaTuftLighting
ctx.render(algaeModels[ctx.random])
ctx.renderQuads(algaeModels[ctx.random])
} else if (Config.reed.enabled(ctx.random) && isShallowWater && !isSaltWater) {
(ctx as? RenderCtxVanilla)?.vertexLighter = vanillaTuftLighting
ctx.render(reedModels[ctx.random])
ctx.renderQuads(reedModels[ctx.random])
}
}
@@ -109,11 +108,11 @@ class StandardDirtModel(
)
val algaeModels by LazyInvalidatable(BakeWrapperManager) {
val shapes = Config.algae.let { tuftShapeSet(it.size, it.heightMin, it.heightMax, it.hOffset) }
tuftModelSet(shapes, Color.white) { algaeSprites[randomI()] }.buildTufts()
tuftModelSet(shapes, -1) { algaeSprites[randomI()] }.buildTufts()
}
val reedModels by LazyInvalidatable(BakeWrapperManager) {
val shapes = Config.reed.let { tuftShapeSet(2.0, it.heightMin, it.heightMax, it.hOffset) }
tuftModelSet(shapes, Color.white) { reedSprites[randomI()] }.buildTufts()
tuftModelSet(shapes, -1) { reedSprites[randomI()] }.buildTufts()
}
}
}

View File

@@ -6,6 +6,7 @@ import mods.betterfoliage.config.BlockConfig
import mods.betterfoliage.config.Config
import mods.betterfoliage.config.ConfigurableBlockMatcher
import mods.betterfoliage.config.ModelTextureList
import mods.betterfoliage.integration.ShadersModIntegration
import mods.betterfoliage.model.Color
import mods.betterfoliage.model.HalfBakedSpecialWrapper
import mods.betterfoliage.model.HalfBakedWrapperKey
@@ -17,7 +18,6 @@ import mods.betterfoliage.model.tuftModelSet
import mods.betterfoliage.model.tuftShapeSet
import mods.betterfoliage.render.lighting.LightingPreferredFace
import mods.betterfoliage.render.pipeline.RenderCtxBase
import mods.betterfoliage.render.pipeline.RenderCtxVanilla
import mods.betterfoliage.resource.discovery.BakeWrapperManager
import mods.betterfoliage.resource.discovery.ConfigurableModelDiscovery
import mods.betterfoliage.resource.discovery.ModelBakingKey
@@ -88,14 +88,16 @@ class StandardGrassModel(
Client.blockTypes.run { stateBelow in grass || stateBelow in dirt }
if (connected) {
ctx.render(if (isSnowed) snowFullBlockMeshes[ctx.random] else fullBlock[ctx.random])
ctx.renderQuads(if (isSnowed) snowFullBlockMeshes[ctx.random] else fullBlock[ctx.random])
} else {
super.render(ctx, noDecorations)
}
if (Config.shortGrass.enabled(ctx.random) && !ctx.isNeighborSolid(UP)) {
(ctx as? RenderCtxVanilla)?.let { it.vertexLighter = tuftLighting }
ctx.render(if (isSnowed) tuftSnowed[ctx.random] else tuftNormal[ctx.random])
ctx.vertexLighter = tuftLighting
ShadersModIntegration.grass(ctx, Config.shortGrass.shaderWind) {
ctx.renderQuads(if (isSnowed) tuftSnowed[ctx.random] else tuftNormal[ctx.random])
}
}
}
@@ -107,10 +109,10 @@ class StandardGrassModel(
Config.shortGrass.let { tuftShapeSet(it.size, it.heightMin, it.heightMax, it.hOffset) }
}
val grassTuftMeshesNormal = LazyMapInvalidatable(BakeWrapperManager) { key: StandardGrassKey ->
tuftModelSet(grassTuftShapes, key.overrideColor) { idx -> grassTuftSprites[randomI()] }.buildTufts()
tuftModelSet(grassTuftShapes, key.tintIndex) { idx -> grassTuftSprites[randomI()] }.buildTufts()
}
val grassTuftMeshesSnowed = LazyMapInvalidatable(BakeWrapperManager) { key: StandardGrassKey ->
tuftModelSet(grassTuftShapes, Color.white) { idx -> grassTuftSprites[randomI()] }.buildTufts()
tuftModelSet(grassTuftShapes, -1) { idx -> grassTuftSprites[randomI()] }.buildTufts()
}
val grassFullBlockMeshes = LazyMapInvalidatable(BakeWrapperManager) { key: StandardGrassKey ->
Array(64) { fullCubeTextured(key.grassLocation, key.tintIndex) }

View File

@@ -98,8 +98,8 @@ class StandardLeafModel(
if (!Config.enabled || !Config.leaves.enabled || noDecorations) return
(ctx as? RenderCtxVanilla)?.let { it.vertexLighter = RoundLeafLighting }
ctx.render(leafNormal[ctx.random.nextInt(64)])
if (ctx.state(UP).isSnow) ctx.render(leafSnowed[ctx.random.nextInt(64)])
ctx.renderQuads(leafNormal[ctx.random.nextInt(64)])
if (ctx.state(UP).isSnow) ctx.renderQuads(leafSnowed[ctx.random.nextInt(64)])
}
companion object {

View File

@@ -0,0 +1,83 @@
package mods.betterfoliage.render.block.vanilla
import mods.betterfoliage.BetterFoliageMod
import mods.betterfoliage.config.Config
import mods.betterfoliage.integration.ShadersModIntegration
import mods.betterfoliage.model.HalfBakedSpecialWrapper
import mods.betterfoliage.model.HalfBakedWrapperKey
import mods.betterfoliage.model.SpecialRenderModel
import mods.betterfoliage.model.SpriteSetDelegate
import mods.betterfoliage.model.buildTufts
import mods.betterfoliage.model.transform
import mods.betterfoliage.model.tuftModelSet
import mods.betterfoliage.model.tuftShapeSet
import mods.betterfoliage.render.pipeline.RenderCtxBase
import mods.betterfoliage.resource.discovery.AbstractModelDiscovery
import mods.betterfoliage.resource.discovery.BakeWrapperManager
import mods.betterfoliage.resource.discovery.ModelBakingKey
import mods.betterfoliage.util.Atlas
import mods.betterfoliage.util.LazyInvalidatable
import mods.betterfoliage.util.get
import net.minecraft.block.BlockState
import net.minecraft.block.Blocks
import net.minecraft.client.renderer.model.BlockModel
import net.minecraft.client.renderer.model.ModelBakery
import net.minecraft.util.Direction.DOWN
import net.minecraft.util.ResourceLocation
object StandardLilypadDiscovery : AbstractModelDiscovery() {
val LILYPAD_BLOCKS = listOf(Blocks.LILY_PAD)
override fun processModel(
bakery: ModelBakery,
state: BlockState,
location: ResourceLocation,
sprites: MutableSet<ResourceLocation>,
replacements: MutableMap<ResourceLocation, ModelBakingKey>
): Boolean {
val model = bakery.getUnbakedModel(location)
if (model is BlockModel && state.block in LILYPAD_BLOCKS) {
replacements[location] = StandardLilypadKey
}
return super.processModel(bakery, state, location, sprites, replacements)
}
}
object StandardLilypadKey : HalfBakedWrapperKey() {
override fun replace(wrapped: SpecialRenderModel) = StandardLilypadModel(wrapped)
}
class StandardLilypadModel(
wrapped: SpecialRenderModel
) : HalfBakedSpecialWrapper(wrapped) {
override fun render(ctx: RenderCtxBase, noDecorations: Boolean) {
ctx.checkSides = false
super.render(ctx, noDecorations)
if (!Config.enabled || !Config.lilypad.enabled) return
ShadersModIntegration.grass(ctx, Config.lilypad.shaderWind) {
ctx.renderQuads(lilypadRootModels[ctx.random])
}
if (Config.lilypad.enabled(ctx.random)) ctx.renderQuads(lilypadFlowerModels[ctx.random])
}
companion object {
val lilypadRootSprites by SpriteSetDelegate(Atlas.BLOCKS) { idx ->
ResourceLocation(BetterFoliageMod.MOD_ID, "blocks/better_lilypad_roots_$idx")
}
val lilypadFlowerSprites by SpriteSetDelegate(Atlas.BLOCKS) { idx ->
ResourceLocation(BetterFoliageMod.MOD_ID, "blocks/better_lilypad_flower_$idx")
}
val lilypadRootModels by LazyInvalidatable(BakeWrapperManager) {
val shapes = tuftShapeSet(1.0, 1.0, 1.0, Config.lilypad.hOffset)
tuftModelSet(shapes, -1) { lilypadRootSprites[it] }
.transform { move(2.0 to DOWN) }
.buildTufts()
}
val lilypadFlowerModels by LazyInvalidatable(BakeWrapperManager) {
val shapes = tuftShapeSet(0.5, 0.5, 0.5, Config.lilypad.hOffset)
tuftModelSet(shapes, -1) { lilypadFlowerSprites[it] }
.transform { move(1.0 to DOWN) }
.buildTufts()
}
}
}

View File

@@ -2,7 +2,6 @@ package mods.betterfoliage.render.block.vanilla
import mods.betterfoliage.BetterFoliageMod
import mods.betterfoliage.config.Config
import mods.betterfoliage.model.Color
import mods.betterfoliage.model.HalfBakedSpecialWrapper
import mods.betterfoliage.model.HalfBakedWrapperKey
import mods.betterfoliage.model.SpecialRenderModel
@@ -67,7 +66,7 @@ class StandardMyceliumModel(
ctx.state(Direction.UP).isAir(ctx.world, ctx.pos)
) {
ctx.vertexLighter = tuftLighting
ctx.render(myceliumTuftModels[ctx.random])
ctx.renderQuads(myceliumTuftModels[ctx.random])
}
}
@@ -77,7 +76,7 @@ class StandardMyceliumModel(
}
val myceliumTuftModels by LazyInvalidatable(BakeWrapperManager) {
val shapes = Config.shortGrass.let { tuftShapeSet(it.size, it.heightMin, it.heightMax, it.hOffset) }
tuftModelSet(shapes, Color.white) { idx -> myceliumTuftSprites[randomI()] }.buildTufts()
tuftModelSet(shapes, -1) { idx -> myceliumTuftSprites[randomI()] }.buildTufts()
}
}
}

View File

@@ -3,7 +3,6 @@ package mods.betterfoliage.render.block.vanilla
import mods.betterfoliage.BetterFoliageMod
import mods.betterfoliage.Client
import mods.betterfoliage.config.Config
import mods.betterfoliage.model.Color
import mods.betterfoliage.model.HalfBakedSpecialWrapper
import mods.betterfoliage.model.HalfBakedWrapperKey
import mods.betterfoliage.model.Quad
@@ -79,8 +78,8 @@ class StandardSandModel(
val isDeepWater = isWater && ctx.offset(face).state(UP).material == Material.WATER
if (isDeepWater) {
ctx.vertexLighter = coralLighting[face]
ctx.render(coralCrustModels[face][ctx.random])
ctx.render(coralTuftModels[face][ctx.random])
ctx.renderQuads(coralCrustModels[face][ctx.random])
ctx.renderQuads(coralTuftModels[face][ctx.random])
}
}
}
@@ -95,7 +94,7 @@ class StandardSandModel(
val coralTuftModels by LazyInvalidatable(BakeWrapperManager) {
val shapes = Config.coral.let { tuftShapeSet(it.size, 1.0, 1.0, it.hOffset) }
allDirections.mapArray { face ->
tuftModelSet(shapes, Color.white) { coralTuftSprites[randomI()] }
tuftModelSet(shapes, -1) { coralTuftSprites[randomI()] }
.transform { rotate(Rotation.fromUp[face]) }
.buildTufts()
}

View File

@@ -28,7 +28,7 @@ abstract class RenderCtxBase(
world: ILightReader,
pos: BlockPos,
val matrixStack: MatrixStack,
val checkSides: Boolean,
var checkSides: Boolean,
val random: Random,
val modelData: IModelData
) : BlockCtx by BasicBlockCtx(world, pos) {
@@ -45,7 +45,7 @@ abstract class RenderCtxBase(
inline fun Direction?.shouldRender() = this == null || !checkSides || Block.shouldSideBeRendered(state, world, pos, this)
fun render(quads: Iterable<HalfBakedQuad>) {
fun renderQuads(quads: Iterable<HalfBakedQuad>) {
quads.forEach { quad ->
if (quad.raw.face.shouldRender()) {
renderQuad(quad)