[WIP] Roll all rendering parameters into a single context
+ split project into platform-dependent and -independent parts
This commit is contained in:
@@ -5,7 +5,7 @@ import mods.betterfoliage.client.texture.LeafParticleRegistry
|
||||
import mods.betterfoliage.client.texture.LeafRegistry
|
||||
import mods.octarinecore.PI2
|
||||
import mods.octarinecore.client.render.AbstractEntityFX
|
||||
import mods.octarinecore.client.render.HSB
|
||||
import mods.octarinecore.client.render.lighting.HSB
|
||||
import mods.octarinecore.common.Double3
|
||||
import mods.octarinecore.minmax
|
||||
import mods.octarinecore.random
|
||||
|
||||
@@ -3,11 +3,10 @@ package mods.betterfoliage.client.render
|
||||
|
||||
import mods.betterfoliage.client.config.Config
|
||||
import mods.octarinecore.client.render.*
|
||||
import mods.octarinecore.client.render.lighting.*
|
||||
import mods.octarinecore.common.Double3
|
||||
import mods.octarinecore.exchange
|
||||
import net.minecraft.util.Direction
|
||||
import net.minecraft.util.Direction.*
|
||||
import org.lwjgl.opengl.GL11
|
||||
|
||||
/** Weight of the same-side AO values on the outer edges of the 45deg chamfered column faces. */
|
||||
const val chamferAffinity = 0.9f
|
||||
|
||||
@@ -2,25 +2,17 @@ package mods.betterfoliage.client.render
|
||||
|
||||
import mods.betterfoliage.BetterFoliage
|
||||
import mods.betterfoliage.client.Client
|
||||
import mods.betterfoliage.client.config.BlockConfig
|
||||
import mods.betterfoliage.client.config.Config
|
||||
import mods.betterfoliage.client.integration.ShadersModIntegration
|
||||
import mods.octarinecore.client.render.*
|
||||
import mods.octarinecore.common.Int3
|
||||
import mods.octarinecore.common.Rotation
|
||||
import net.minecraft.block.Block
|
||||
import mods.octarinecore.client.render.CombinedContext
|
||||
import mods.octarinecore.client.render.RenderDecorator
|
||||
import net.minecraft.block.material.Material
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher
|
||||
import net.minecraft.client.renderer.BufferBuilder
|
||||
import net.minecraft.tags.BlockTags
|
||||
import net.minecraft.util.BlockRenderLayer
|
||||
import net.minecraft.util.ResourceLocation
|
||||
import net.minecraft.world.biome.Biome
|
||||
import net.minecraftforge.client.model.data.IModelData
|
||||
import org.apache.logging.log4j.Level.DEBUG
|
||||
import java.util.*
|
||||
|
||||
class RenderAlgae : AbstractBlockRenderingHandler(BetterFoliage.MOD_ID, BetterFoliage.modBus) {
|
||||
class RenderAlgae : RenderDecorator(BetterFoliage.MOD_ID, BetterFoliage.modBus) {
|
||||
|
||||
val noise = simplexNoise()
|
||||
|
||||
@@ -31,31 +23,23 @@ class RenderAlgae : AbstractBlockRenderingHandler(BetterFoliage.MOD_ID, BetterFo
|
||||
Client.log(DEBUG, "Registered ${algaeIcons.num} algae textures")
|
||||
}
|
||||
|
||||
override fun isEligible(ctx: BlockContext) =
|
||||
override fun isEligible(ctx: CombinedContext) =
|
||||
Config.enabled && Config.algae.enabled &&
|
||||
ctx.blockState(up2).material == Material.WATER &&
|
||||
ctx.blockState(up1).material == Material.WATER &&
|
||||
BlockTags.DIRT_LIKE.contains(ctx.block) &&
|
||||
ctx.state(up2).material == Material.WATER &&
|
||||
ctx.state(up1).material == Material.WATER &&
|
||||
BlockTags.DIRT_LIKE.contains(ctx.state.block) &&
|
||||
ctx.biome.category.let { it == Biome.Category.OCEAN || it == Biome.Category.BEACH || it == Biome.Category.RIVER } &&
|
||||
noise[ctx.pos] < Config.algae.population
|
||||
|
||||
override fun render(ctx: BlockContext, dispatcher: BlockRendererDispatcher, renderer: BufferBuilder, random: Random, modelData: IModelData, layer: BlockRenderLayer): Boolean {
|
||||
val baseRender = renderWorldBlockBase(ctx, dispatcher, renderer, random, modelData, layer)
|
||||
if (!layer.isCutout) return baseRender
|
||||
|
||||
modelRenderer.updateShading(Int3.zero, allFaces)
|
||||
|
||||
override fun render(ctx: CombinedContext) {
|
||||
ctx.render()
|
||||
if (!ctx.isCutout) return
|
||||
val rand = ctx.semiRandomArray(3)
|
||||
|
||||
ShadersModIntegration.grass(renderer, Config.algae.shaderWind) {
|
||||
modelRenderer.render(
|
||||
renderer,
|
||||
ShadersModIntegration.grass(ctx, Config.algae.shaderWind) {
|
||||
ctx.render(
|
||||
algaeModels[rand[2]],
|
||||
Rotation.identity,
|
||||
icon = { _, qi, _ -> algaeIcons[rand[qi and 1]]!! },
|
||||
postProcess = noPost
|
||||
icon = { _, qi, _ -> algaeIcons[rand[qi and 1]]!! }
|
||||
)
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -2,11 +2,11 @@ package mods.betterfoliage.client.render
|
||||
|
||||
import mods.betterfoliage.BetterFoliage
|
||||
import mods.betterfoliage.client.Client
|
||||
import mods.betterfoliage.client.config.BlockConfig
|
||||
import mods.betterfoliage.client.config.Config
|
||||
import mods.betterfoliage.client.render.column.ColumnTextureInfo
|
||||
import mods.betterfoliage.client.render.column.SimpleColumnInfo
|
||||
import mods.octarinecore.client.render.*
|
||||
import mods.octarinecore.client.render.lighting.*
|
||||
import mods.octarinecore.client.resource.ModelRenderRegistryConfigurable
|
||||
import mods.octarinecore.common.Int3
|
||||
import mods.octarinecore.common.Rotation
|
||||
@@ -31,7 +31,7 @@ object StandardCactusRegistry : ModelRenderRegistryConfigurable<ColumnTextureInf
|
||||
init { BetterFoliage.modBus.register(this) }
|
||||
}
|
||||
|
||||
class RenderCactus : AbstractBlockRenderingHandler(BetterFoliage.MOD_ID, BetterFoliage.modBus) {
|
||||
class RenderCactus : RenderDecorator(BetterFoliage.MOD_ID, BetterFoliage.modBus) {
|
||||
|
||||
val cactusStemRadius = 0.4375
|
||||
val cactusArmRotation = listOf(NORTH, SOUTH, EAST, WEST).map { Rotation.rot90[it.ordinal] }
|
||||
@@ -71,41 +71,30 @@ class RenderCactus : AbstractBlockRenderingHandler(BetterFoliage.MOD_ID, BetterF
|
||||
Client.log(DEBUG, "Registered ${iconArm.num} cactus arm textures")
|
||||
}
|
||||
|
||||
override fun isEligible(ctx: BlockContext): Boolean =
|
||||
override fun isEligible(ctx: CombinedContext): Boolean =
|
||||
Config.enabled && Config.cactus.enabled &&
|
||||
StandardCactusRegistry[ctx] != null
|
||||
|
||||
override fun render(ctx: BlockContext, dispatcher: BlockRendererDispatcher, renderer: BufferBuilder, random: Random, modelData: IModelData, layer: BlockRenderLayer): Boolean {
|
||||
// render the whole block on the cutout layer
|
||||
if (!layer.isCutout) return false
|
||||
override val onlyOnCutout get() = true
|
||||
|
||||
// get AO data
|
||||
modelRenderer.updateShading(Int3.zero, allFaces)
|
||||
val icons = StandardCactusRegistry[ctx] ?: return renderWorldBlockBase(ctx, dispatcher, renderer, random, modelData, null)
|
||||
override fun render(ctx: CombinedContext) {
|
||||
val icons = StandardCactusRegistry[ctx]!!
|
||||
|
||||
modelRenderer.render(
|
||||
renderer,
|
||||
ctx.render(
|
||||
modelStem.model,
|
||||
Rotation.identity,
|
||||
icon = { ctx, qi, q -> when(qi) {
|
||||
0 -> icons.bottom(ctx, qi, q); 1 -> icons.top(ctx, qi, q); else -> icons.side(ctx, qi, q)
|
||||
} },
|
||||
postProcess = noPost
|
||||
} }
|
||||
)
|
||||
modelRenderer.render(
|
||||
renderer,
|
||||
modelCross[ctx.random(0)],
|
||||
Rotation.identity,
|
||||
icon = { _, _, _ -> iconCross.icon!!},
|
||||
postProcess = noPost
|
||||
ctx.render(
|
||||
modelCross[ctx.semiRandom(0)],
|
||||
icon = { _, _, _ -> iconCross.icon!!}
|
||||
)
|
||||
modelRenderer.render(
|
||||
renderer,
|
||||
modelArm[ctx.random(1)],
|
||||
cactusArmRotation[ctx.random(2) % 4],
|
||||
icon = { _, _, _ -> iconArm[ctx.random(3)]!!},
|
||||
postProcess = noPost
|
||||
|
||||
ctx.render(
|
||||
modelArm[ctx.semiRandom(1)],
|
||||
cactusArmRotation[ctx.semiRandom(2) % 4],
|
||||
icon = { _, _, _ -> iconArm[ctx.semiRandom(3)]!!}
|
||||
)
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -1,36 +1,45 @@
|
||||
package mods.betterfoliage.client.render
|
||||
|
||||
import mods.betterfoliage.BetterFoliage
|
||||
import mods.betterfoliage.client.config.BlockConfig
|
||||
import mods.betterfoliage.client.config.Config
|
||||
import mods.betterfoliage.client.texture.GrassRegistry
|
||||
import mods.octarinecore.client.render.AbstractBlockRenderingHandler
|
||||
import mods.octarinecore.client.render.BlockContext
|
||||
import mods.octarinecore.client.render.offset
|
||||
import mods.octarinecore.client.render.CombinedContext
|
||||
import mods.octarinecore.client.render.RenderDecorator
|
||||
import mods.octarinecore.common.Int3
|
||||
import mods.octarinecore.common.forgeDirsHorizontal
|
||||
import mods.octarinecore.common.horizontalDirections
|
||||
import mods.octarinecore.common.offset
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher
|
||||
import net.minecraft.client.renderer.BufferBuilder
|
||||
import net.minecraft.tags.BlockTags
|
||||
import net.minecraft.util.BlockRenderLayer
|
||||
import net.minecraftforge.client.model.data.IModelData
|
||||
import java.util.*
|
||||
|
||||
class RenderConnectedGrass : AbstractBlockRenderingHandler(BetterFoliage.MOD_ID, BetterFoliage.modBus) {
|
||||
override fun isEligible(ctx: BlockContext) =
|
||||
class RenderConnectedGrass : RenderDecorator(BetterFoliage.MOD_ID, BetterFoliage.modBus) {
|
||||
override fun isEligible(ctx: CombinedContext) =
|
||||
Config.enabled && Config.connectedGrass.enabled &&
|
||||
BlockTags.DIRT_LIKE.contains(ctx.block) &&
|
||||
BlockTags.DIRT_LIKE.contains(ctx.state.block) &&
|
||||
GrassRegistry[ctx, up1] != null &&
|
||||
(Config.connectedGrass.snowEnabled || !ctx.blockState(up2).isSnow)
|
||||
(Config.connectedGrass.snowEnabled || !ctx.state(up2).isSnow)
|
||||
|
||||
override fun render(ctx: BlockContext, dispatcher: BlockRendererDispatcher, renderer: BufferBuilder, random: Random, modelData: IModelData, layer: BlockRenderLayer): Boolean {
|
||||
override fun render(ctx: CombinedContext) {
|
||||
// if the block sides are not visible anyway, render normally
|
||||
if (forgeDirsHorizontal.none { ctx.shouldSideBeRendered(it) }) return renderWorldBlockBase(ctx, dispatcher, renderer, random, modelData, layer)
|
||||
if (horizontalDirections.none { ctx.shouldSideBeRendered(it) }) {
|
||||
ctx.render()
|
||||
} else {
|
||||
ctx.exchange(Int3.zero, up1).exchange(up1, up2).render()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ctx.offset(Int3.zero, up1).offset(up1, up2).let { offsetCtx ->
|
||||
renderWorldBlockBase(offsetCtx, dispatcher, renderer, random, modelData, layer)
|
||||
class RenderConnectedGrassLog : RenderDecorator(BetterFoliage.MOD_ID, BetterFoliage.modBus) {
|
||||
|
||||
override fun isEligible(ctx: CombinedContext) =
|
||||
Config.enabled && Config.roundLogs.enabled && Config.roundLogs.connectGrass &&
|
||||
BlockTags.DIRT_LIKE.contains(ctx.state.block) &&
|
||||
LogRegistry[ctx, up1] != null
|
||||
|
||||
override fun render(ctx: CombinedContext) {
|
||||
val grassDir = horizontalDirections.find { GrassRegistry[ctx, it.offset] != null }
|
||||
if (grassDir == null) {
|
||||
ctx.render()
|
||||
} else {
|
||||
ctx.exchange(Int3.zero, grassDir.offset).render()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
package mods.betterfoliage.client.render
|
||||
|
||||
import mods.betterfoliage.BetterFoliage
|
||||
import mods.betterfoliage.client.config.BlockConfig
|
||||
import mods.betterfoliage.client.config.Config
|
||||
import mods.betterfoliage.client.texture.GrassRegistry
|
||||
import mods.octarinecore.client.render.AbstractBlockRenderingHandler
|
||||
import mods.octarinecore.client.render.BlockContext
|
||||
import mods.octarinecore.client.render.offset
|
||||
import mods.octarinecore.common.Int3
|
||||
import mods.octarinecore.common.offset
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher
|
||||
import net.minecraft.client.renderer.BufferBuilder
|
||||
import net.minecraft.tags.BlockTags
|
||||
import net.minecraft.util.BlockRenderLayer
|
||||
import net.minecraft.util.Direction.*
|
||||
import net.minecraftforge.client.model.data.IModelData
|
||||
import java.util.*
|
||||
|
||||
class RenderConnectedGrassLog : AbstractBlockRenderingHandler(BetterFoliage.MOD_ID, BetterFoliage.modBus) {
|
||||
|
||||
val grassCheckDirs = listOf(EAST, WEST, NORTH, SOUTH)
|
||||
|
||||
override fun isEligible(ctx: BlockContext) =
|
||||
Config.enabled && Config.roundLogs.enabled && Config.roundLogs.connectGrass &&
|
||||
BlockTags.DIRT_LIKE.contains(ctx.block) &&
|
||||
LogRegistry[ctx, up1] != null
|
||||
|
||||
override fun render(ctx: BlockContext, dispatcher: BlockRendererDispatcher, renderer: BufferBuilder, random: Random, modelData: IModelData, layer: BlockRenderLayer): Boolean {
|
||||
val grassDir = grassCheckDirs.find {
|
||||
GrassRegistry[ctx, it.offset] != null
|
||||
} ?: return renderWorldBlockBase(ctx, dispatcher, renderer, random, modelData, layer)
|
||||
|
||||
return ctx.offset(Int3.zero, grassDir.offset).let { offsetCtx ->
|
||||
renderWorldBlockBase(offsetCtx, dispatcher, renderer, random, modelData, layer)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,9 +5,11 @@ import mods.betterfoliage.client.Client
|
||||
import mods.betterfoliage.client.config.BlockConfig
|
||||
import mods.betterfoliage.client.config.Config
|
||||
import mods.octarinecore.client.render.*
|
||||
import mods.octarinecore.client.render.lighting.*
|
||||
import mods.octarinecore.common.Int3
|
||||
import mods.octarinecore.common.forgeDirOffsets
|
||||
import mods.octarinecore.common.forgeDirs
|
||||
import mods.octarinecore.common.allDirOffsets
|
||||
import mods.octarinecore.common.allDirections
|
||||
import mods.octarinecore.common.offset
|
||||
import mods.octarinecore.random
|
||||
import net.minecraft.block.material.Material
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher
|
||||
@@ -17,13 +19,11 @@ import net.minecraft.util.Direction.Axis
|
||||
import net.minecraft.util.Direction.UP
|
||||
import net.minecraft.util.ResourceLocation
|
||||
import net.minecraft.world.biome.Biome
|
||||
import net.minecraftforge.api.distmarker.Dist
|
||||
import net.minecraftforge.client.model.data.IModelData
|
||||
import net.minecraftforge.fml.common.Mod
|
||||
import org.apache.logging.log4j.Level.DEBUG
|
||||
import java.util.*
|
||||
|
||||
class RenderCoral : AbstractBlockRenderingHandler(BetterFoliage.MOD_ID, BetterFoliage.modBus) {
|
||||
class RenderCoral : RenderDecorator(BetterFoliage.MOD_ID, BetterFoliage.modBus) {
|
||||
|
||||
val noise = simplexNoise()
|
||||
|
||||
@@ -49,33 +49,27 @@ class RenderCoral : AbstractBlockRenderingHandler(BetterFoliage.MOD_ID, BetterFo
|
||||
Client.log(DEBUG, "Registered ${crustIcons.num} coral crust textures")
|
||||
}
|
||||
|
||||
override fun isEligible(ctx: BlockContext) =
|
||||
override fun isEligible(ctx: CombinedContext) =
|
||||
Config.enabled && Config.coral.enabled &&
|
||||
(ctx.blockState(up2).material == Material.WATER || Config.coral.shallowWater) &&
|
||||
ctx.blockState(up1).material == Material.WATER &&
|
||||
BlockConfig.sand.matchesClass(ctx.block) &&
|
||||
(ctx.state(up2).material == Material.WATER || Config.coral.shallowWater) &&
|
||||
ctx.state(up1).material == Material.WATER &&
|
||||
BlockConfig.sand.matchesClass(ctx.state.block) &&
|
||||
ctx.biome.category.let { it == Biome.Category.OCEAN || it == Biome.Category.BEACH } &&
|
||||
noise[ctx.pos] < Config.coral.population
|
||||
|
||||
override fun render(ctx: BlockContext, dispatcher: BlockRendererDispatcher, renderer: BufferBuilder, random: Random, modelData: IModelData, layer: BlockRenderLayer): Boolean {
|
||||
val baseRender = renderWorldBlockBase(ctx, dispatcher, renderer, random, modelData, layer)
|
||||
if (!layer.isCutout) return baseRender
|
||||
override fun render(ctx: CombinedContext) {
|
||||
val baseRender = ctx.render()
|
||||
if (!ctx.isCutout) return
|
||||
|
||||
modelRenderer.updateShading(Int3.zero, allFaces)
|
||||
|
||||
forgeDirs.forEachIndexed { idx, face ->
|
||||
if (!ctx.isNormalCube(forgeDirOffsets[idx]) && blockContext.random(idx) < Config.coral.chance) {
|
||||
var variation = blockContext.random(6)
|
||||
modelRenderer.render(
|
||||
renderer,
|
||||
allDirections.forEachIndexed { idx, face ->
|
||||
if (ctx.state(face).material == Material.WATER && ctx.semiRandom(idx) < Config.coral.chance) {
|
||||
var variation = ctx.semiRandom(6)
|
||||
ctx.render(
|
||||
coralModels[variation++],
|
||||
rotationFromUp[idx],
|
||||
icon = { _, qi, _ -> if (qi == 4) crustIcons[variation]!! else coralIcons[variation + (qi and 1)]!!},
|
||||
postProcess = noPost
|
||||
icon = { _, qi, _ -> if (qi == 4) crustIcons[variation]!! else coralIcons[variation + (qi and 1)]!!}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -6,24 +6,22 @@ import mods.betterfoliage.client.config.Config
|
||||
import mods.betterfoliage.client.integration.OptifineCustomColors
|
||||
import mods.betterfoliage.client.integration.ShadersModIntegration
|
||||
import mods.betterfoliage.client.texture.GrassRegistry
|
||||
import mods.octarinecore.client.render.*
|
||||
import mods.octarinecore.common.*
|
||||
import mods.octarinecore.client.render.CombinedContext
|
||||
import mods.octarinecore.client.render.Model
|
||||
import mods.octarinecore.client.render.RenderDecorator
|
||||
import mods.octarinecore.client.render.fullCube
|
||||
import mods.octarinecore.client.render.lighting.cornerAo
|
||||
import mods.octarinecore.client.render.lighting.cornerFlat
|
||||
import mods.octarinecore.client.render.lighting.faceOrientedAuto
|
||||
import mods.octarinecore.common.Double3
|
||||
import mods.octarinecore.common.allDirections
|
||||
import mods.octarinecore.random
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.block.BlockRenderType
|
||||
import net.minecraft.block.BlockRenderType.MODEL
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher
|
||||
import net.minecraft.client.renderer.BufferBuilder
|
||||
import net.minecraft.tags.BlockTags
|
||||
import net.minecraft.util.BlockRenderLayer
|
||||
import net.minecraft.util.Direction.Axis
|
||||
import net.minecraft.util.Direction.*
|
||||
import net.minecraft.util.ResourceLocation
|
||||
import net.minecraftforge.client.model.data.IModelData
|
||||
import org.apache.logging.log4j.Level.DEBUG
|
||||
import java.util.*
|
||||
|
||||
class RenderGrass : AbstractBlockRenderingHandler(BetterFoliage.MOD_ID, BetterFoliage.modBus) {
|
||||
class RenderGrass : RenderDecorator(BetterFoliage.MOD_ID, BetterFoliage.modBus) {
|
||||
|
||||
companion object {
|
||||
@JvmStatic fun grassTopQuads(heightMin: Double, heightMax: Double): Model.(Int)->Unit = { modelIdx ->
|
||||
@@ -50,77 +48,58 @@ class RenderGrass : AbstractBlockRenderingHandler(BetterFoliage.MOD_ID, BetterFo
|
||||
Client.log(DEBUG, "Registered ${snowedIcons.num} snowed grass textures")
|
||||
}
|
||||
|
||||
override fun isEligible(ctx: BlockContext) =
|
||||
override fun isEligible(ctx: CombinedContext) =
|
||||
Config.enabled &&
|
||||
(Config.shortGrass.grassEnabled || Config.connectedGrass.enabled) &&
|
||||
GrassRegistry[ctx] != null
|
||||
|
||||
override fun render(ctx: BlockContext, dispatcher: BlockRendererDispatcher, renderer: BufferBuilder, random: Random, modelData: IModelData, layer: BlockRenderLayer): Boolean {
|
||||
// render the whole block on the cutout layer
|
||||
if (!layer.isCutout) return false
|
||||
override val onlyOnCutout get() = true
|
||||
|
||||
val isConnected = BlockTags.DIRT_LIKE.contains(ctx.block(down1)) || GrassRegistry[ctx, down1] != null
|
||||
val isSnowed = ctx.blockState(up1).isSnow
|
||||
override fun render(ctx: CombinedContext) {
|
||||
val isConnected = BlockTags.DIRT_LIKE.contains(ctx.state(DOWN).block) || GrassRegistry[ctx, down1] != null
|
||||
val isSnowed = ctx.state(UP).isSnow
|
||||
val connectedGrass = isConnected && Config.connectedGrass.enabled && (!isSnowed || Config.connectedGrass.snowEnabled)
|
||||
|
||||
val grass = GrassRegistry[ctx]
|
||||
if (grass == null) {
|
||||
// shouldn't happen
|
||||
Client.logRenderError(ctx.blockState(Int3.zero), ctx.pos)
|
||||
return renderWorldBlockBase(ctx, dispatcher, renderer, random, modelData, null)
|
||||
}
|
||||
val grass = GrassRegistry[ctx]!!
|
||||
val blockColor = OptifineCustomColors.getBlockColor(ctx)
|
||||
|
||||
if (connectedGrass) {
|
||||
// get full AO data
|
||||
modelRenderer.updateShading(Int3.zero, allFaces)
|
||||
|
||||
// check occlusion
|
||||
val isVisible = forgeDirs.map { ctx.shouldSideBeRendered(it) }
|
||||
val isVisible = allDirections.map { ctx.shouldSideBeRendered(it) }
|
||||
|
||||
// render full grass block
|
||||
ShadersModIntegration.renderAs(ctx.blockState(Int3.zero), MODEL, renderer) {
|
||||
modelRenderer.render(
|
||||
renderer,
|
||||
fullCube,
|
||||
quadFilter = { qi, _ -> isVisible[qi] },
|
||||
icon = { _, _, _ -> grass.grassTopTexture },
|
||||
postProcess = { ctx, _, _, _, _ ->
|
||||
rotateUV(2)
|
||||
if (isSnowed) {
|
||||
if (!ctx.aoEnabled) setGrey(1.4f)
|
||||
} else if (ctx.aoEnabled && grass.overrideColor == null) multiplyColor(blockColor)
|
||||
}
|
||||
)
|
||||
}
|
||||
ctx.render(
|
||||
fullCube,
|
||||
quadFilter = { qi, _ -> isVisible[qi] },
|
||||
icon = { _, _, _ -> grass.grassTopTexture },
|
||||
postProcess = { ctx, _, _, _, _ ->
|
||||
rotateUV(2)
|
||||
if (isSnowed) {
|
||||
if (!ctx.aoEnabled) setGrey(1.4f)
|
||||
} else if (ctx.aoEnabled && grass.overrideColor == null) multiplyColor(blockColor)
|
||||
}
|
||||
)
|
||||
} else {
|
||||
renderWorldBlockBase(ctx, dispatcher, renderer, random, modelData, null)
|
||||
|
||||
// get AO data only for block top
|
||||
modelRenderer.updateShading(Int3.zero, topOnly)
|
||||
ctx.render()
|
||||
}
|
||||
|
||||
if (!Config.shortGrass.grassEnabled) return true
|
||||
if (isSnowed && !Config.shortGrass.snowEnabled) return true
|
||||
if (ctx.isNormalCube(up1)) return true
|
||||
if (Config.shortGrass.population < 64 && noise[ctx.pos] >= Config.shortGrass.population) return true
|
||||
if (!Config.shortGrass.grassEnabled) return
|
||||
if (isSnowed && !Config.shortGrass.snowEnabled) return
|
||||
if (ctx.offset(UP).isNormalCube) return
|
||||
if (Config.shortGrass.population < 64 && noise[ctx.pos] >= Config.shortGrass.population) return
|
||||
|
||||
// render grass quads
|
||||
val iconset = if (isSnowed) snowedIcons else normalIcons
|
||||
val iconGen = if (isSnowed) snowedGenIcon else normalGenIcon
|
||||
val rand = ctx.semiRandomArray(2)
|
||||
|
||||
ShadersModIntegration.grass(renderer, Config.shortGrass.shaderWind) {
|
||||
modelRenderer.render(
|
||||
renderer,
|
||||
ShadersModIntegration.grass(ctx, Config.shortGrass.shaderWind) {
|
||||
ctx.render(
|
||||
grassModels[rand[0]],
|
||||
Rotation.identity,
|
||||
ctx.blockCenter + (if (isSnowed) snowOffset else Double3.zero),
|
||||
translation = ctx.blockCenter + (if (isSnowed) snowOffset else Double3.zero),
|
||||
icon = { _, qi, _ -> if (Config.shortGrass.useGenerated) iconGen.icon!! else iconset[rand[qi and 1]]!! },
|
||||
postProcess = { _, _, _, _, _ -> if (isSnowed) setGrey(1.0f) else multiplyColor(grass.overrideColor ?: blockColor) }
|
||||
)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -1,30 +1,27 @@
|
||||
package mods.betterfoliage.client.render
|
||||
|
||||
import mods.betterfoliage.BetterFoliage
|
||||
import mods.betterfoliage.client.Client
|
||||
import mods.betterfoliage.client.config.Config
|
||||
import mods.betterfoliage.client.integration.OptifineCustomColors
|
||||
import mods.betterfoliage.client.integration.ShadersModIntegration
|
||||
import mods.betterfoliage.client.texture.LeafRegistry
|
||||
import mods.octarinecore.PI2
|
||||
import mods.octarinecore.client.render.*
|
||||
import mods.octarinecore.client.render.CombinedContext
|
||||
import mods.octarinecore.client.render.RenderDecorator
|
||||
import mods.octarinecore.client.render.lighting.FlatOffset
|
||||
import mods.octarinecore.client.render.lighting.cornerAoMaxGreen
|
||||
import mods.octarinecore.client.render.lighting.edgeOrientedAuto
|
||||
import mods.octarinecore.common.Double3
|
||||
import mods.octarinecore.common.Int3
|
||||
import mods.octarinecore.common.Rotation
|
||||
import mods.octarinecore.common.allDirections
|
||||
import mods.octarinecore.common.vec
|
||||
import mods.octarinecore.random
|
||||
import net.minecraft.block.material.Material
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher
|
||||
import net.minecraft.client.renderer.BufferBuilder
|
||||
import net.minecraft.util.BlockRenderLayer
|
||||
import net.minecraft.util.Direction.*
|
||||
import net.minecraft.util.Direction.UP
|
||||
import net.minecraft.util.ResourceLocation
|
||||
import net.minecraftforge.client.model.data.IModelData
|
||||
import java.lang.Math.cos
|
||||
import java.lang.Math.sin
|
||||
import java.util.*
|
||||
|
||||
class RenderLeaves : AbstractBlockRenderingHandler(BetterFoliage.MOD_ID, BetterFoliage.modBus) {
|
||||
class RenderLeaves : RenderDecorator(BetterFoliage.MOD_ID, BetterFoliage.modBus) {
|
||||
|
||||
val leavesModel = model {
|
||||
verticalRectangle(x1 = -0.5, z1 = 0.5, x2 = 0.5, z2 = -0.5, yBottom = -0.5 * 1.41, yTop = 0.5 * 1.41)
|
||||
@@ -41,34 +38,28 @@ class RenderLeaves : AbstractBlockRenderingHandler(BetterFoliage.MOD_ID, BetterF
|
||||
UP.vec * random(-1.0, 1.0) * Config.leaves.vOffset
|
||||
}
|
||||
|
||||
override fun isEligible(ctx: BlockContext) =
|
||||
override fun isEligible(ctx: CombinedContext) =
|
||||
Config.enabled &&
|
||||
Config.leaves.enabled &&
|
||||
LeafRegistry[ctx] != null &&
|
||||
!(Config.leaves.hideInternal && ctx.isSurroundedByNormal)
|
||||
!(Config.leaves.hideInternal && allDirections.all { ctx.offset(it).isNormalCube } )
|
||||
|
||||
override fun render(ctx: BlockContext, dispatcher: BlockRendererDispatcher, renderer: BufferBuilder, random: Random, modelData: IModelData, layer: BlockRenderLayer): Boolean {
|
||||
val isSnowed = ctx.blockState(up1).isSnow
|
||||
val leafInfo = LeafRegistry[ctx]
|
||||
if (leafInfo == null) {
|
||||
// shouldn't happen
|
||||
Client.logRenderError(ctx.blockState(Int3.zero), ctx.pos)
|
||||
return renderWorldBlockBase(ctx, dispatcher, renderer, random, modelData, layer)
|
||||
}
|
||||
override val onlyOnCutout get() = true
|
||||
|
||||
override fun render(ctx: CombinedContext) {
|
||||
val isSnowed = ctx.state(UP).isSnow
|
||||
val leafInfo = LeafRegistry[ctx]!!
|
||||
val blockColor = OptifineCustomColors.getBlockColor(ctx)
|
||||
|
||||
renderWorldBlockBase(ctx, dispatcher, renderer, random, modelData, layer)
|
||||
if (!layer.isCutout) return true
|
||||
ctx.render(force = true)
|
||||
|
||||
modelRenderer.updateShading(Int3.zero, allFaces)
|
||||
ShadersModIntegration.leaves(renderer) {
|
||||
ShadersModIntegration.leaves(ctx) {
|
||||
val rand = ctx.semiRandomArray(2)
|
||||
(if (Config.leaves.dense) denseLeavesRot else normalLeavesRot).forEach { rotation ->
|
||||
modelRenderer.render(
|
||||
renderer,
|
||||
ctx.render(
|
||||
leavesModel.model,
|
||||
rotation,
|
||||
ctx.blockCenter + perturbs[rand[0]],
|
||||
translation = ctx.blockCenter + perturbs[rand[0]],
|
||||
icon = { _, _, _ -> leafInfo.roundLeafTexture },
|
||||
postProcess = { _, _, _, _, _ ->
|
||||
rotateUV(rand[1])
|
||||
@@ -76,16 +67,12 @@ class RenderLeaves : AbstractBlockRenderingHandler(BetterFoliage.MOD_ID, BetterF
|
||||
}
|
||||
)
|
||||
}
|
||||
if (isSnowed && Config.leaves.snowEnabled) modelRenderer.render(
|
||||
renderer,
|
||||
if (isSnowed && Config.leaves.snowEnabled) ctx.render(
|
||||
leavesModel.model,
|
||||
Rotation.identity,
|
||||
ctx.blockCenter + perturbs[rand[0]],
|
||||
translation = ctx.blockCenter + perturbs[rand[0]],
|
||||
icon = { _, _, _ -> snowedIcon[rand[1]]!! },
|
||||
postProcess = whitewash
|
||||
)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -5,20 +5,16 @@ import mods.betterfoliage.client.Client
|
||||
import mods.betterfoliage.client.config.BlockConfig
|
||||
import mods.betterfoliage.client.config.Config
|
||||
import mods.betterfoliage.client.integration.ShadersModIntegration
|
||||
import mods.octarinecore.client.render.*
|
||||
import mods.octarinecore.client.render.CombinedContext
|
||||
import mods.octarinecore.client.render.RenderDecorator
|
||||
import mods.octarinecore.client.render.lighting.FlatOffsetNoColor
|
||||
import mods.octarinecore.common.Int3
|
||||
import mods.octarinecore.common.Rotation
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher
|
||||
import net.minecraft.client.renderer.BufferBuilder
|
||||
import net.minecraft.util.BlockRenderLayer
|
||||
import net.minecraft.util.Direction.DOWN
|
||||
import net.minecraft.util.Direction.UP
|
||||
import net.minecraft.util.ResourceLocation
|
||||
import net.minecraftforge.client.model.data.IModelData
|
||||
import org.apache.logging.log4j.Level.DEBUG
|
||||
import java.util.*
|
||||
|
||||
class RenderLilypad : AbstractBlockRenderingHandler(BetterFoliage.MOD_ID, BetterFoliage.modBus) {
|
||||
class RenderLilypad : RenderDecorator(BetterFoliage.MOD_ID, BetterFoliage.modBus) {
|
||||
|
||||
val rootModel = model {
|
||||
verticalRectangle(x1 = -0.5, z1 = 0.5, x2 = 0.5, z2 = -0.5, yBottom = -1.5, yTop = -0.5)
|
||||
@@ -40,41 +36,28 @@ class RenderLilypad : AbstractBlockRenderingHandler(BetterFoliage.MOD_ID, Better
|
||||
Client.log(DEBUG, "Registered ${flowerIcon.num} lilypad flower textures")
|
||||
}
|
||||
|
||||
override fun isEligible(ctx: BlockContext): Boolean =
|
||||
override fun isEligible(ctx: CombinedContext): Boolean =
|
||||
Config.enabled && Config.lilypad.enabled &&
|
||||
BlockConfig.lilypad.matchesClass(ctx.block)
|
||||
BlockConfig.lilypad.matchesClass(ctx.state.block)
|
||||
|
||||
override fun render(ctx: BlockContext, dispatcher: BlockRendererDispatcher, renderer: BufferBuilder, random: Random, modelData: IModelData, layer: BlockRenderLayer): Boolean {
|
||||
// render the whole block on the cutout layer
|
||||
if (!layer.isCutout) return false
|
||||
|
||||
renderWorldBlockBase(ctx, dispatcher, renderer, random, modelData, null)
|
||||
modelRenderer.updateShading(Int3.zero, allFaces)
|
||||
override fun render(ctx: CombinedContext) {
|
||||
ctx.render()
|
||||
|
||||
val rand = ctx.semiRandomArray(5)
|
||||
|
||||
ShadersModIntegration.grass(renderer) {
|
||||
modelRenderer.render(
|
||||
renderer,
|
||||
ShadersModIntegration.grass(ctx) {
|
||||
ctx.render(
|
||||
rootModel.model,
|
||||
Rotation.identity,
|
||||
ctx.blockCenter.add(perturbs[rand[2]]),
|
||||
translation = ctx.blockCenter.add(perturbs[rand[2]]),
|
||||
forceFlat = true,
|
||||
icon = { ctx, qi, q -> rootIcon[rand[qi and 1]]!! },
|
||||
postProcess = noPost
|
||||
icon = { ctx, qi, q -> rootIcon[rand[qi and 1]]!! }
|
||||
)
|
||||
}
|
||||
|
||||
if (rand[3] < Config.lilypad.flowerChance) modelRenderer.render(
|
||||
renderer,
|
||||
if (rand[3] < Config.lilypad.flowerChance) ctx.render(
|
||||
flowerModel.model,
|
||||
Rotation.identity,
|
||||
ctx.blockCenter.add(perturbs[rand[4]]),
|
||||
translation = ctx.blockCenter.add(perturbs[rand[4]]),
|
||||
forceFlat = true,
|
||||
icon = { _, _, _ -> flowerIcon[rand[0]]!! },
|
||||
postProcess = noPost
|
||||
icon = { _, _, _ -> flowerIcon[rand[0]]!! }
|
||||
)
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -8,8 +8,8 @@ import mods.betterfoliage.client.render.column.AbstractRenderColumn
|
||||
import mods.betterfoliage.client.render.column.ColumnRenderLayer
|
||||
import mods.betterfoliage.client.render.column.ColumnTextureInfo
|
||||
import mods.betterfoliage.client.render.column.SimpleColumnInfo
|
||||
import mods.betterfoliage.client.texture.GrassRegistry
|
||||
import mods.octarinecore.client.render.BlockContext
|
||||
import mods.octarinecore.client.render.BlockCtx
|
||||
import mods.octarinecore.client.render.CombinedContext
|
||||
import mods.octarinecore.client.resource.ModelRenderRegistry
|
||||
import mods.octarinecore.client.resource.ModelRenderRegistryConfigurable
|
||||
import mods.octarinecore.client.resource.ModelRenderRegistryRoot
|
||||
@@ -19,12 +19,13 @@ import mods.octarinecore.tryDefault
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.block.LogBlock
|
||||
import net.minecraft.util.Direction.Axis
|
||||
import net.minecraft.world.IEnviromentBlockReader
|
||||
|
||||
class RenderLog : AbstractRenderColumn(BetterFoliage.MOD_ID, BetterFoliage.modBus) {
|
||||
|
||||
override val addToCutout: Boolean get() = false
|
||||
override val renderOnCutout: Boolean get() = false
|
||||
|
||||
override fun isEligible(ctx: BlockContext) =
|
||||
override fun isEligible(ctx: CombinedContext) =
|
||||
Config.enabled && Config.roundLogs.enabled &&
|
||||
LogRegistry[ctx] != null
|
||||
|
||||
@@ -40,7 +41,6 @@ class RenderLog : AbstractRenderColumn(BetterFoliage.MOD_ID, BetterFoliage.modBu
|
||||
class RoundLogOverlayLayer : ColumnRenderLayer() {
|
||||
override val registry: ModelRenderRegistry<ColumnTextureInfo> get() = LogRegistry
|
||||
override val blockPredicate = { state: BlockState -> BlockConfig.logBlocks.matchesClass(state.block) }
|
||||
override val surroundPredicate = { state: BlockState -> !BlockConfig.logBlocks.matchesClass(state.block) }
|
||||
|
||||
override val connectSolids: Boolean get() = Config.roundLogs.connectSolids
|
||||
override val lenientConnect: Boolean get() = Config.roundLogs.lenientConnect
|
||||
|
||||
@@ -4,21 +4,15 @@ import mods.betterfoliage.BetterFoliage
|
||||
import mods.betterfoliage.client.Client
|
||||
import mods.betterfoliage.client.config.BlockConfig
|
||||
import mods.betterfoliage.client.config.Config
|
||||
import mods.octarinecore.client.render.AbstractBlockRenderingHandler
|
||||
import mods.octarinecore.client.render.BlockContext
|
||||
import mods.octarinecore.client.render.modelRenderer
|
||||
import mods.octarinecore.client.render.CombinedContext
|
||||
import mods.octarinecore.client.render.RenderDecorator
|
||||
import mods.octarinecore.client.render.noPost
|
||||
import mods.octarinecore.common.Double3
|
||||
import mods.octarinecore.common.Rotation
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher
|
||||
import net.minecraft.client.renderer.BufferBuilder
|
||||
import net.minecraft.util.BlockRenderLayer
|
||||
import net.minecraft.util.Direction.UP
|
||||
import net.minecraft.util.ResourceLocation
|
||||
import net.minecraftforge.client.model.data.IModelData
|
||||
import org.apache.logging.log4j.Level.DEBUG
|
||||
import java.util.*
|
||||
|
||||
class RenderMycelium : AbstractBlockRenderingHandler(BetterFoliage.MOD_ID, BetterFoliage.modBus) {
|
||||
class RenderMycelium : RenderDecorator(BetterFoliage.MOD_ID, BetterFoliage.modBus) {
|
||||
|
||||
val myceliumIcon = iconSet { idx -> ResourceLocation(BetterFoliage.MOD_ID, "blocks/better_mycel_$idx") }
|
||||
val myceliumModel = modelSet(64) { idx -> RenderGrass.grassTopQuads(Config.shortGrass.heightMin, Config.shortGrass.heightMax)(idx) }
|
||||
@@ -27,32 +21,25 @@ class RenderMycelium : AbstractBlockRenderingHandler(BetterFoliage.MOD_ID, Bette
|
||||
Client.log(DEBUG, "Registered ${myceliumIcon.num} mycelium textures")
|
||||
}
|
||||
|
||||
override fun isEligible(ctx: BlockContext): Boolean {
|
||||
override fun isEligible(ctx: CombinedContext): Boolean {
|
||||
if (!Config.enabled || !Config.shortGrass.myceliumEnabled) return false
|
||||
return BlockConfig.mycelium.matchesClass(ctx.block)
|
||||
return BlockConfig.mycelium.matchesClass(ctx.state.block)
|
||||
}
|
||||
|
||||
override fun render(ctx: BlockContext, dispatcher: BlockRendererDispatcher, renderer: BufferBuilder, random: Random, modelData: IModelData, layer: BlockRenderLayer): Boolean {
|
||||
// render the whole block on the cutout layer
|
||||
if (!layer.isCutout) return false
|
||||
|
||||
val isSnowed = ctx.blockState(up1).isSnow
|
||||
|
||||
renderWorldBlockBase(ctx, dispatcher, renderer, random, modelData, null)
|
||||
|
||||
if (isSnowed && !Config.shortGrass.snowEnabled) return true
|
||||
if (ctx.isNormalCube(up1)) return true
|
||||
override fun render(ctx: CombinedContext) {
|
||||
ctx.render()
|
||||
if (!ctx.isCutout) return
|
||||
|
||||
val isSnowed = ctx.state(UP).isSnow
|
||||
if (isSnowed && !Config.shortGrass.snowEnabled) return
|
||||
if (ctx.offset(UP).isNormalCube) return
|
||||
val rand = ctx.semiRandomArray(2)
|
||||
modelRenderer.render(
|
||||
renderer,
|
||||
|
||||
ctx.render(
|
||||
myceliumModel[rand[0]],
|
||||
Rotation.identity,
|
||||
ctx.blockCenter + (if (isSnowed) snowOffset else Double3.zero),
|
||||
translation = ctx.blockCenter + (if (isSnowed) snowOffset else Double3.zero),
|
||||
icon = { _, qi, _ -> myceliumIcon[rand[qi and 1]]!! },
|
||||
postProcess = if (isSnowed) whitewash else noPost
|
||||
)
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import mods.betterfoliage.client.Client
|
||||
import mods.betterfoliage.client.config.BlockConfig
|
||||
import mods.betterfoliage.client.config.Config
|
||||
import mods.octarinecore.client.render.*
|
||||
import mods.octarinecore.client.render.lighting.*
|
||||
import mods.octarinecore.common.Int3
|
||||
import mods.octarinecore.common.Rotation
|
||||
import mods.octarinecore.random
|
||||
@@ -18,7 +19,7 @@ import net.minecraftforge.client.model.data.IModelData
|
||||
import org.apache.logging.log4j.Level.DEBUG
|
||||
import java.util.*
|
||||
|
||||
class RenderNetherrack : AbstractBlockRenderingHandler(BetterFoliage.MOD_ID, BetterFoliage.modBus) {
|
||||
class RenderNetherrack : RenderDecorator(BetterFoliage.MOD_ID, BetterFoliage.modBus) {
|
||||
|
||||
val netherrackIcon = iconSet { idx -> ResourceLocation(BetterFoliage.MOD_ID, "blocks/better_netherrack_$idx") }
|
||||
val netherrackModel = modelSet(64) { modelIdx ->
|
||||
@@ -34,28 +35,20 @@ class RenderNetherrack : AbstractBlockRenderingHandler(BetterFoliage.MOD_ID, Bet
|
||||
Client.log(DEBUG, "Registered ${netherrackIcon.num} netherrack textures")
|
||||
}
|
||||
|
||||
override fun isEligible(ctx: BlockContext): Boolean {
|
||||
override fun isEligible(ctx: CombinedContext): Boolean {
|
||||
if (!Config.enabled || !Config.netherrack.enabled) return false
|
||||
return BlockConfig.netherrack.matchesClass(ctx.block)
|
||||
return BlockConfig.netherrack.matchesClass(ctx.state.block)
|
||||
}
|
||||
|
||||
override fun render(ctx: BlockContext, dispatcher: BlockRendererDispatcher, renderer: BufferBuilder, random: Random, modelData: IModelData, layer: BlockRenderLayer): Boolean {
|
||||
val baseRender = renderWorldBlockBase(ctx, dispatcher, renderer, random, modelData, layer)
|
||||
if (!layer.isCutout) return baseRender
|
||||
|
||||
if (ctx.isNormalCube(down1)) return baseRender
|
||||
|
||||
modelRenderer.updateShading(Int3.zero, allFaces)
|
||||
override fun render(ctx: CombinedContext) {
|
||||
ctx.render()
|
||||
if (!ctx.isCutout) return
|
||||
if (ctx.offset(DOWN).isNormalCube) return
|
||||
|
||||
val rand = ctx.semiRandomArray(2)
|
||||
modelRenderer.render(
|
||||
renderer,
|
||||
ctx.render(
|
||||
netherrackModel[rand[0]],
|
||||
Rotation.identity,
|
||||
icon = { _, qi, _ -> netherrackIcon[rand[qi and 1]]!! },
|
||||
postProcess = noPost
|
||||
icon = { _, qi, _ -> netherrackIcon[rand[qi and 1]]!! }
|
||||
)
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -2,26 +2,19 @@ package mods.betterfoliage.client.render
|
||||
|
||||
import mods.betterfoliage.BetterFoliage
|
||||
import mods.betterfoliage.client.Client
|
||||
import mods.betterfoliage.client.config.BlockConfig
|
||||
import mods.betterfoliage.client.config.Config
|
||||
import mods.betterfoliage.client.integration.ShadersModIntegration
|
||||
import mods.octarinecore.client.render.*
|
||||
import mods.octarinecore.common.Int3
|
||||
import mods.octarinecore.common.Rotation
|
||||
import mods.octarinecore.client.render.CombinedContext
|
||||
import mods.octarinecore.client.render.RenderDecorator
|
||||
import mods.octarinecore.client.render.lighting.FlatOffsetNoColor
|
||||
import mods.octarinecore.random
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.block.material.Material
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher
|
||||
import net.minecraft.client.renderer.BufferBuilder
|
||||
import net.minecraft.tags.BlockTags
|
||||
import net.minecraft.util.BlockRenderLayer
|
||||
import net.minecraft.util.Direction.UP
|
||||
import net.minecraft.util.ResourceLocation
|
||||
import net.minecraftforge.client.model.data.IModelData
|
||||
import org.apache.logging.log4j.Level.DEBUG
|
||||
import java.util.*
|
||||
|
||||
class RenderReeds : AbstractBlockRenderingHandler(BetterFoliage.MOD_ID, BetterFoliage.modBus) {
|
||||
class RenderReeds : RenderDecorator(BetterFoliage.MOD_ID, BetterFoliage.modBus) {
|
||||
|
||||
val noise = simplexNoise()
|
||||
val reedIcons = iconSet { idx -> Client.genReeds.registerResource(ResourceLocation(BetterFoliage.MOD_ID, "blocks/better_reed_$idx")) }
|
||||
@@ -47,31 +40,27 @@ class RenderReeds : AbstractBlockRenderingHandler(BetterFoliage.MOD_ID, BetterFo
|
||||
Client.log(DEBUG, "Registered ${reedIcons.num} reed textures")
|
||||
}
|
||||
|
||||
override fun isEligible(ctx: BlockContext) =
|
||||
override fun isEligible(ctx: CombinedContext) =
|
||||
Config.enabled && Config.reed.enabled &&
|
||||
ctx.blockState(up2).material == Material.AIR &&
|
||||
ctx.blockState(up1).material == Material.WATER &&
|
||||
BlockTags.DIRT_LIKE.contains(ctx.block) &&
|
||||
ctx.state(up2).material == Material.AIR &&
|
||||
ctx.state(UP).material == Material.WATER &&
|
||||
BlockTags.DIRT_LIKE.contains(ctx.state.block) &&
|
||||
ctx.biome.let { it.downfall > Config.reed.minBiomeRainfall && it.defaultTemperature >= Config.reed.minBiomeTemp } &&
|
||||
noise[ctx.pos] < Config.reed.population
|
||||
|
||||
override fun render(ctx: BlockContext, dispatcher: BlockRendererDispatcher, renderer: BufferBuilder, random: Random, modelData: IModelData, layer: BlockRenderLayer): Boolean {
|
||||
val baseRender = renderWorldBlockBase(ctx, dispatcher, renderer, random, modelData, layer)
|
||||
if (!layer.isCutout) return baseRender
|
||||
override val onlyOnCutout get() = false
|
||||
|
||||
modelRenderer.updateShading(Int3.zero, allFaces)
|
||||
override fun render(ctx: CombinedContext) {
|
||||
ctx.render()
|
||||
if (!ctx.isCutout) return
|
||||
|
||||
val iconVar = ctx.random(1)
|
||||
ShadersModIntegration.grass(renderer, Config.reed.shaderWind) {
|
||||
modelRenderer.render(
|
||||
renderer,
|
||||
reedModels[ctx.random(0)],
|
||||
Rotation.identity,
|
||||
val iconVar = ctx.semiRandom(1)
|
||||
ShadersModIntegration.grass(ctx, Config.reed.shaderWind) {
|
||||
ctx.render(
|
||||
reedModels[ctx.semiRandom(0)],
|
||||
forceFlat = true,
|
||||
icon = { _, _, _ -> reedIcons[iconVar]!! },
|
||||
postProcess = noPost
|
||||
icon = { _, _, _ -> reedIcons[iconVar]!! }
|
||||
)
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ package mods.betterfoliage.client.render
|
||||
|
||||
import mods.octarinecore.PI2
|
||||
import mods.octarinecore.client.render.Model
|
||||
import mods.octarinecore.client.render.PostProcessLambda
|
||||
import mods.octarinecore.client.render.lighting.PostProcessLambda
|
||||
import mods.octarinecore.client.render.Quad
|
||||
import mods.octarinecore.common.Double3
|
||||
import mods.octarinecore.common.Int3
|
||||
|
||||
@@ -7,22 +7,19 @@ import mods.betterfoliage.client.render.*
|
||||
import mods.betterfoliage.client.render.column.ColumnLayerData.SpecialRender.BlockType.*
|
||||
import mods.betterfoliage.client.render.column.ColumnLayerData.SpecialRender.QuadrantType
|
||||
import mods.betterfoliage.client.render.column.ColumnLayerData.SpecialRender.QuadrantType.*
|
||||
import mods.octarinecore.client.render.*
|
||||
import mods.octarinecore.common.Int3
|
||||
import mods.octarinecore.client.render.CombinedContext
|
||||
import mods.octarinecore.client.render.Model
|
||||
import mods.octarinecore.client.render.RenderDecorator
|
||||
import mods.octarinecore.client.render.noPost
|
||||
import mods.octarinecore.common.Rotation
|
||||
import mods.octarinecore.common.face
|
||||
import mods.octarinecore.common.rot
|
||||
import net.minecraft.block.BlockRenderType.MODEL
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher
|
||||
import net.minecraft.client.renderer.BufferBuilder
|
||||
import net.minecraft.util.BlockRenderLayer
|
||||
import net.minecraft.util.Direction.*
|
||||
import net.minecraftforge.client.model.data.IModelData
|
||||
import net.minecraftforge.eventbus.api.IEventBus
|
||||
import java.util.*
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
abstract class AbstractRenderColumn(modId: String, modBus: IEventBus) : AbstractBlockRenderingHandler(modId, modBus) {
|
||||
abstract class AbstractRenderColumn(modId: String, modBus: IEventBus) : RenderDecorator(modId, modBus) {
|
||||
|
||||
/** The rotations necessary to bring the models in position for the 4 quadrants */
|
||||
val quadrantRotations = Array(4) { Rotation.rot90[UP.ordinal] * it }
|
||||
@@ -93,28 +90,25 @@ abstract class AbstractRenderColumn(modId: String, modBus: IEventBus) : Abstract
|
||||
q1 == q2 || ((q1 == SQUARE || q1 == INVISIBLE) && (q2 == SQUARE || q2 == INVISIBLE))
|
||||
|
||||
@Suppress("NON_EXHAUSTIVE_WHEN")
|
||||
override fun render(ctx: BlockContext, dispatcher: BlockRendererDispatcher, renderer: BufferBuilder, random: Random, modelData: IModelData, layer: BlockRenderLayer): Boolean {
|
||||
override fun render(ctx: CombinedContext) {
|
||||
|
||||
val roundLog = ChunkOverlayManager.get(overlayLayer, ctx.reader!!, ctx.pos)
|
||||
val roundLog = ChunkOverlayManager.get(overlayLayer, ctx)
|
||||
when(roundLog) {
|
||||
ColumnLayerData.SkipRender -> return true
|
||||
ColumnLayerData.NormalRender -> return renderWorldBlockBase(ctx, dispatcher, renderer, random, modelData, null)
|
||||
ColumnLayerData.SkipRender -> return
|
||||
ColumnLayerData.NormalRender -> return ctx.render()
|
||||
ColumnLayerData.ResolveError, null -> {
|
||||
Client.logRenderError(ctx.blockState(Int3.zero), ctx.pos)
|
||||
return renderWorldBlockBase(ctx, dispatcher, renderer, random, modelData, null)
|
||||
Client.logRenderError(ctx.state, ctx.pos)
|
||||
return ctx.render()
|
||||
}
|
||||
}
|
||||
|
||||
// if log axis is not defined and "Default to vertical" config option is not set, render normally
|
||||
if ((roundLog as ColumnLayerData.SpecialRender).column.axis == null && !overlayLayer.defaultToY) {
|
||||
return renderWorldBlockBase(ctx, dispatcher, renderer, random, modelData, null)
|
||||
return ctx.render()
|
||||
}
|
||||
|
||||
// get AO data
|
||||
modelRenderer.updateShading(Int3.zero, allFaces)
|
||||
|
||||
val baseRotation = rotationFromUp[((roundLog.column.axis ?: Axis.Y) to AxisDirection.POSITIVE).face.ordinal]
|
||||
renderAs(ctx.blockState(Int3.zero), MODEL, renderer) {
|
||||
renderAs(ctx, MODEL) {
|
||||
quadrantRotations.forEachIndexed { idx, quadrantRotation ->
|
||||
// set rotation for the current quadrant
|
||||
val rotation = baseRotation + quadrantRotation
|
||||
@@ -136,8 +130,7 @@ abstract class AbstractRenderColumn(modId: String, modBus: IEventBus) : Abstract
|
||||
else -> null
|
||||
}
|
||||
|
||||
if (sideModel != null) modelRenderer.render(
|
||||
renderer,
|
||||
if (sideModel != null) ctx.render(
|
||||
sideModel,
|
||||
rotation,
|
||||
icon = roundLog.column.side,
|
||||
@@ -190,8 +183,7 @@ abstract class AbstractRenderColumn(modId: String, modBus: IEventBus) : Abstract
|
||||
}
|
||||
}
|
||||
|
||||
if (upModel != null) modelRenderer.render(
|
||||
renderer,
|
||||
if (upModel != null) ctx.render(
|
||||
upModel,
|
||||
rotation,
|
||||
icon = upIcon,
|
||||
@@ -201,8 +193,7 @@ abstract class AbstractRenderColumn(modId: String, modBus: IEventBus) : Abstract
|
||||
}
|
||||
}
|
||||
)
|
||||
if (downModel != null) modelRenderer.render(
|
||||
renderer,
|
||||
if (downModel != null) ctx.render(
|
||||
downModel,
|
||||
rotation,
|
||||
icon = downIcon,
|
||||
@@ -214,6 +205,5 @@ abstract class AbstractRenderColumn(modId: String, modBus: IEventBus) : Abstract
|
||||
)
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,12 +8,9 @@ import mods.betterfoliage.client.render.column.ColumnLayerData.SpecialRender.Blo
|
||||
import mods.betterfoliage.client.render.column.ColumnLayerData.SpecialRender.QuadrantType
|
||||
import mods.betterfoliage.client.render.column.ColumnLayerData.SpecialRender.QuadrantType.*
|
||||
import mods.betterfoliage.client.render.rotationFromUp
|
||||
import mods.octarinecore.client.render.BlockContext
|
||||
import mods.octarinecore.client.render.BlockCtx
|
||||
import mods.octarinecore.client.resource.ModelRenderRegistry
|
||||
import mods.octarinecore.common.Int3
|
||||
import mods.octarinecore.common.Rotation
|
||||
import mods.octarinecore.common.face
|
||||
import mods.octarinecore.common.plus
|
||||
import mods.octarinecore.common.*
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.util.Direction.Axis
|
||||
import net.minecraft.util.Direction.AxisDirection
|
||||
@@ -64,21 +61,18 @@ abstract class ColumnRenderLayer : ChunkOverlayLayer<ColumnLayerData> {
|
||||
|
||||
abstract val registry: ModelRenderRegistry<ColumnTextureInfo>
|
||||
abstract val blockPredicate: (BlockState)->Boolean
|
||||
abstract val surroundPredicate: (BlockState) -> Boolean
|
||||
abstract val connectSolids: Boolean
|
||||
abstract val lenientConnect: Boolean
|
||||
abstract val defaultToY: Boolean
|
||||
|
||||
val allNeighborOffsets = (-1..1).flatMap { offsetX -> (-1..1).flatMap { offsetY -> (-1..1).map { offsetZ -> Int3(offsetX, offsetY, offsetZ) }}}
|
||||
|
||||
override fun onBlockUpdate(reader: IEnviromentBlockReader, pos: BlockPos) {
|
||||
allNeighborOffsets.forEach { offset -> ChunkOverlayManager.clear(reader.dimType, this, pos + offset) }
|
||||
override fun onBlockUpdate(world: IEnviromentBlockReader, pos: BlockPos) {
|
||||
allNeighborOffsets.forEach { offset -> ChunkOverlayManager.clear(world.dimType, this, pos + offset) }
|
||||
}
|
||||
|
||||
override fun calculate(reader: IEnviromentBlockReader, pos: BlockPos) = calculate(BlockContext(reader, pos))
|
||||
|
||||
fun calculate(ctx: BlockContext): ColumnLayerData {
|
||||
if (ctx.isSurroundedBy(surroundPredicate) && ctx.isSurroundedByNormal) return ColumnLayerData.SkipRender
|
||||
override fun calculate(ctx: BlockCtx): ColumnLayerData {
|
||||
if (allDirections.all { ctx.offset(it).isNormalCube }) return ColumnLayerData.SkipRender
|
||||
val columnTextures = registry[ctx] ?: return ColumnLayerData.ResolveError
|
||||
|
||||
// if log axis is not defined and "Default to vertical" config option is not set, render normally
|
||||
@@ -104,7 +98,7 @@ abstract class ColumnRenderLayer : ChunkOverlayLayer<ColumnLayerData> {
|
||||
}
|
||||
|
||||
/** Fill the array of [QuadrantType]s based on the blocks to the sides of this one. */
|
||||
fun Array<QuadrantType>.checkNeighbors(ctx: BlockContext, rotation: Rotation, logAxis: Axis, yOff: Int): Array<QuadrantType> {
|
||||
fun Array<QuadrantType>.checkNeighbors(ctx: BlockCtx, rotation: Rotation, logAxis: Axis, yOff: Int): Array<QuadrantType> {
|
||||
val blkS = ctx.blockType(rotation, logAxis, Int3(0, yOff, 1))
|
||||
val blkE = ctx.blockType(rotation, logAxis, Int3(1, yOff, 0))
|
||||
val blkN = ctx.blockType(rotation, logAxis, Int3(0, yOff, -1))
|
||||
@@ -171,13 +165,13 @@ abstract class ColumnRenderLayer : ChunkOverlayLayer<ColumnLayerData> {
|
||||
/**
|
||||
* Get the type of the block at the given offset in a rotated reference frame.
|
||||
*/
|
||||
fun BlockContext.blockType(rotation: Rotation, axis: Axis, offset: Int3): ColumnLayerData.SpecialRender.BlockType {
|
||||
fun BlockCtx.blockType(rotation: Rotation, axis: Axis, offset: Int3): ColumnLayerData.SpecialRender.BlockType {
|
||||
val offsetRot = offset.rotate(rotation)
|
||||
val state = blockState(offsetRot)
|
||||
val state = state(offsetRot)
|
||||
return if (!blockPredicate(state)) {
|
||||
if (isNormalCube(offsetRot)) SOLID else NONSOLID
|
||||
if (offset(offsetRot).isNormalCube) SOLID else NONSOLID
|
||||
} else {
|
||||
(registry[state, reader!!, pos + offsetRot]?.axis ?: if (Config.roundLogs.defaultY) Axis.Y else null)?.let {
|
||||
(registry[state, world, pos + offsetRot]?.axis ?: if (Config.roundLogs.defaultY) Axis.Y else null)?.let {
|
||||
if (it == axis) PARALLEL else PERPENDICULAR
|
||||
} ?: SOLID
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package mods.betterfoliage.client.render.column
|
||||
|
||||
import mods.octarinecore.client.render.QuadIconResolver
|
||||
import mods.octarinecore.client.render.blockContext
|
||||
import mods.octarinecore.client.render.lighting.QuadIconResolver
|
||||
import mods.octarinecore.client.resource.ModelRenderKey
|
||||
import mods.octarinecore.client.resource.get
|
||||
import mods.octarinecore.client.resource.missingSprite
|
||||
@@ -31,8 +30,8 @@ open class SimpleColumnInfo(
|
||||
override val top: QuadIconResolver = { _, _, _ -> topTexture }
|
||||
override val bottom: QuadIconResolver = { _, _, _ -> bottomTexture }
|
||||
override val side: QuadIconResolver = { ctx, idx, _ ->
|
||||
val worldFace = (if ((idx and 1) == 0) SOUTH else EAST).rotate(ctx.rotation)
|
||||
val sideIdx = if (sideTextures.size > 1) (blockContext.random(1) + dirToIdx[worldFace.ordinal]) % sideTextures.size else 0
|
||||
val worldFace = (if ((idx and 1) == 0) SOUTH else EAST).rotate(ctx.modelRotation)
|
||||
val sideIdx = if (sideTextures.size > 1) (ctx.semiRandom(1) + dirToIdx[worldFace.ordinal]) % sideTextures.size else 0
|
||||
sideTextures[sideIdx]
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user