[WIP] Lilypad working
+ shader integration
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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(){
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)) }
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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) }
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user