register render layers properly

This commit is contained in:
Moritz Zwerger 2023-07-26 01:57:54 +02:00
parent 3f6feb89b7
commit 7408018f09
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
7 changed files with 68 additions and 11 deletions

View File

@ -89,7 +89,7 @@ class RenderLoop(
context.textures.staticTextures.animator.draw() context.textures.staticTextures.animator.draw()
context.renderer.render() context.renderer.draw()
context.system.reset() // Reset to enable depth mask, etc again context.system.reset() // Reset to enable depth mask, etc again

View File

@ -43,6 +43,7 @@ import de.bixilon.minosoft.gui.rendering.system.base.DepthFunctions
import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem
import de.bixilon.minosoft.gui.rendering.system.base.layer.OpaqueLayer import de.bixilon.minosoft.gui.rendering.system.base.layer.OpaqueLayer
import de.bixilon.minosoft.gui.rendering.system.base.layer.RenderLayer import de.bixilon.minosoft.gui.rendering.system.base.layer.RenderLayer
import de.bixilon.minosoft.gui.rendering.system.base.layer.TranslucentLayer
import de.bixilon.minosoft.gui.rendering.system.base.layer.TransparentLayer import de.bixilon.minosoft.gui.rendering.system.base.layer.TransparentLayer
import de.bixilon.minosoft.gui.rendering.system.base.settings.RenderSettings import de.bixilon.minosoft.gui.rendering.system.base.settings.RenderSettings
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.EMPTY import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.EMPTY
@ -93,7 +94,7 @@ class ChunkRenderer(
override fun registerLayers() { override fun registerLayers() {
layers.register(OpaqueLayer, shader, this::drawBlocksOpaque) { visible.opaque.isEmpty() } layers.register(OpaqueLayer, shader, this::drawBlocksOpaque) { visible.opaque.isEmpty() }
layers.register(TransparentLayer, transparentShader, this::drawBlocksTransparent) { visible.transparent.isEmpty() } layers.register(TransparentLayer, transparentShader, this::drawBlocksTransparent) { visible.transparent.isEmpty() }
layers.register(TransparentLayer, transparentShader, this::drawBlocksTranslucent) { visible.translucent.isEmpty() } layers.register(TranslucentLayer, shader, this::drawBlocksTranslucent) { visible.translucent.isEmpty() }
layers.register(TextLayer, textShader, this::drawText) { visible.text.isEmpty() } layers.register(TextLayer, textShader, this::drawText) { visible.text.isEmpty() }
layers.register(BlockEntitiesLayer, shader, this::drawBlockEntities) { visible.blockEntities.isEmpty() } layers.register(BlockEntitiesLayer, shader, this::drawBlockEntities) { visible.blockEntities.isEmpty() }
} }

View File

@ -23,13 +23,14 @@ import de.bixilon.kutil.latch.SimpleLatch
import de.bixilon.minosoft.gui.rendering.RenderContext import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.renderer.drawable.Drawable import de.bixilon.minosoft.gui.rendering.renderer.drawable.Drawable
import de.bixilon.minosoft.gui.rendering.renderer.renderer.pipeline.RendererPipeline import de.bixilon.minosoft.gui.rendering.renderer.renderer.pipeline.RendererPipeline
import de.bixilon.minosoft.gui.rendering.renderer.renderer.world.WorldRenderer
import de.bixilon.minosoft.util.logging.Log import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogLevels import de.bixilon.minosoft.util.logging.LogLevels
import de.bixilon.minosoft.util.logging.LogMessageType import de.bixilon.minosoft.util.logging.LogMessageType
class RendererManager( class RendererManager(
val context: RenderContext, val context: RenderContext,
) : Drawable { ) : Drawable, Iterable<Renderer> {
private val renderers: MutableMap<RendererBuilder<*>, Renderer> = linkedMapOf() private val renderers: MutableMap<RendererBuilder<*>, Renderer> = linkedMapOf()
private val pipeline = RendererPipeline(this) private val pipeline = RendererPipeline(this)
private val connection = context.connection private val connection = context.connection
@ -41,6 +42,7 @@ class RendererManager(
if (previous != null) { if (previous != null) {
Log.log(LogMessageType.RENDERING, LogLevels.WARN) { "Renderer $previous ($builder) got replaced by $renderer!" } Log.log(LogMessageType.RENDERING, LogLevels.WARN) { "Renderer $previous ($builder) got replaced by $renderer!" }
} }
pipeline += renderer
return renderer return renderer
} }
@ -63,6 +65,12 @@ class RendererManager(
} }
fun init(latch: AbstractLatch) { fun init(latch: AbstractLatch) {
for (renderer in renderers.values) {
if (renderer !is WorldRenderer) continue
renderer.registerLayers()
}
pipeline.world.rebuild()
runAsync(latch, Renderer::preAsyncInit) runAsync(latch, Renderer::preAsyncInit)
for (renderer in renderers.values) { for (renderer in renderers.values) {
@ -101,4 +109,8 @@ class RendererManager(
prepare() prepare()
pipeline.draw() pipeline.draw()
} }
override fun iterator(): Iterator<Renderer> {
return renderers.values.iterator()
}
} }

View File

@ -17,6 +17,7 @@ import de.bixilon.minosoft.gui.rendering.renderer.drawable.Drawable
import de.bixilon.minosoft.gui.rendering.renderer.renderer.Renderer import de.bixilon.minosoft.gui.rendering.renderer.renderer.Renderer
import de.bixilon.minosoft.gui.rendering.renderer.renderer.RendererManager import de.bixilon.minosoft.gui.rendering.renderer.renderer.RendererManager
import de.bixilon.minosoft.gui.rendering.renderer.renderer.pipeline.world.WorldRendererPipeline import de.bixilon.minosoft.gui.rendering.renderer.renderer.pipeline.world.WorldRendererPipeline
import de.bixilon.minosoft.gui.rendering.renderer.renderer.world.WorldRenderer
import de.bixilon.minosoft.gui.rendering.system.base.PolygonModes import de.bixilon.minosoft.gui.rendering.system.base.PolygonModes
import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem
import de.bixilon.minosoft.gui.rendering.system.base.phases.PostDrawable import de.bixilon.minosoft.gui.rendering.system.base.phases.PostDrawable
@ -24,9 +25,9 @@ import de.bixilon.minosoft.gui.rendering.system.base.phases.PreDrawable
import de.bixilon.minosoft.gui.rendering.system.base.phases.SkipAll import de.bixilon.minosoft.gui.rendering.system.base.phases.SkipAll
class RendererPipeline(private val renderer: RendererManager) : Drawable { class RendererPipeline(private val renderer: RendererManager) : Drawable {
private val world = WorldRendererPipeline(renderer) val world = WorldRendererPipeline(renderer)
private val rest: MutableList<Renderer> = mutableListOf() private val rest: MutableList<Drawable> = mutableListOf()
private val pre: MutableList<PreDrawable> = mutableListOf() private val pre: MutableList<PreDrawable> = mutableListOf()
private val post: MutableList<PostDrawable> = mutableListOf() private val post: MutableList<PostDrawable> = mutableListOf()
@ -43,7 +44,6 @@ class RendererPipeline(private val renderer: RendererManager) : Drawable {
private fun drawRest() { private fun drawRest() {
for (renderer in rest) { for (renderer in rest) {
if (renderer !is Drawable) continue
if (renderer.skipDraw) continue if (renderer.skipDraw) continue
if (renderer is SkipAll && renderer.skipAll) continue if (renderer is SkipAll && renderer.skipAll) continue
@ -79,4 +79,15 @@ class RendererPipeline(private val renderer: RendererManager) : Drawable {
drawPost() drawPost()
} }
operator fun plusAssign(renderer: Renderer) {
if (renderer is WorldRenderer) {
return world.rebuild()
}
if (renderer is Drawable) {
rest += renderer
// TODO: sort for framebuffer
}
if (renderer is PreDrawable) pre += renderer
if (renderer is PostDrawable) post += renderer
}
} }

View File

@ -13,6 +13,26 @@
package de.bixilon.minosoft.gui.rendering.renderer.renderer.pipeline.world package de.bixilon.minosoft.gui.rendering.renderer.renderer.pipeline.world
import de.bixilon.minosoft.gui.rendering.renderer.drawable.Drawable import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.shader.Shader
import de.bixilon.minosoft.gui.rendering.system.base.layer.RenderLayer
class PipelineElement : Comparable<PipelineElement>, Drawable class PipelineElement(
val layer: RenderLayer,
val shader: Shader?,
val renderer: () -> Unit,
val skip: (() -> Boolean)?
) : Comparable<PipelineElement> {
fun draw(context: RenderContext) {
if (skip != null && skip.invoke()) return
context.system.set(layer.settings)
shader?.use()
renderer.invoke()
}
override fun compareTo(other: PipelineElement): Int {
return layer.priority.compareTo(other.layer.priority)
}
}

View File

@ -15,13 +15,21 @@ package de.bixilon.minosoft.gui.rendering.renderer.renderer.pipeline.world
import de.bixilon.minosoft.gui.rendering.renderer.drawable.Drawable import de.bixilon.minosoft.gui.rendering.renderer.drawable.Drawable
import de.bixilon.minosoft.gui.rendering.renderer.renderer.RendererManager import de.bixilon.minosoft.gui.rendering.renderer.renderer.RendererManager
import de.bixilon.minosoft.gui.rendering.renderer.renderer.world.WorldRenderer
class WorldRendererPipeline(val renderer: RendererManager) : Drawable { class WorldRendererPipeline(val renderer: RendererManager) : Drawable {
private val framebuffer = renderer.context.framebuffer.world
private var elements: Array<PipelineElement> = emptyArray() private var elements: Array<PipelineElement> = emptyArray()
private fun build(): Array<PipelineElement> { private fun build(): Array<PipelineElement> {
TODO() val list: MutableList<PipelineElement> = mutableListOf()
for (renderer in renderer) {
if (renderer !is WorldRenderer) continue
list += renderer.layers.elements
}
return list.sorted().toTypedArray()
} }
fun rebuild() { fun rebuild() {
@ -30,8 +38,11 @@ class WorldRendererPipeline(val renderer: RendererManager) : Drawable {
override fun draw() { override fun draw() {
renderer.context.system.framebuffer = framebuffer.framebuffer
renderer.context.system.polygonMode = framebuffer.polygonMode
for (element in elements) { for (element in elements) {
element.draw() element.draw(renderer.context)
} }
} }
} }

View File

@ -13,12 +13,14 @@
package de.bixilon.minosoft.gui.rendering.renderer.renderer.world package de.bixilon.minosoft.gui.rendering.renderer.renderer.world
import de.bixilon.minosoft.gui.rendering.renderer.renderer.pipeline.world.PipelineElement
import de.bixilon.minosoft.gui.rendering.shader.Shader import de.bixilon.minosoft.gui.rendering.shader.Shader
import de.bixilon.minosoft.gui.rendering.system.base.layer.RenderLayer import de.bixilon.minosoft.gui.rendering.system.base.layer.RenderLayer
class LayerSettings { class LayerSettings {
val elements: MutableList<PipelineElement> = mutableListOf()
fun register(layer: RenderLayer, shader: Shader?, renderer: () -> Unit, skip: (() -> Boolean)? = null) { fun register(layer: RenderLayer, shader: Shader?, renderer: () -> Unit, skip: (() -> Boolean)? = null) {
TODO() elements += PipelineElement(layer, shader, renderer, skip)
} }
} }