From c470f77eb3f0f23b9ed6ce2909269c5bfbaed519 Mon Sep 17 00:00:00 2001 From: Bixilon Date: Mon, 1 Nov 2021 22:29:49 +0100 Subject: [PATCH] render phases --- .../minosoft/gui/rendering/RenderWindow.kt | 15 ++-- .../minosoft/gui/rendering/Renderer.kt | 10 +-- .../gui/rendering/block/WorldRenderer.kt | 49 +++++++---- .../block/chunk/ChunkBorderRenderer.kt | 17 ++-- .../block/outline/BlockOutlineRenderer.kt | 9 +- .../rendering/entity/EntityHitBoxRenderer.kt | 13 ++- .../minosoft/gui/rendering/hud/HUDRenderer.kt | 25 ++++-- .../rendering/particle/ParticleRenderer.kt | 87 ++++++++++++------- .../gui/rendering/particle/types/Particle.kt | 4 +- .../types/norender/NoRenderParticle.kt | 2 +- .../types/render/texture/TextureParticle.kt | 14 ++- .../advanced/AdvancedTextureParticle.kt | 14 ++- .../minosoft/gui/rendering/sky/SkyRenderer.kt | 13 +-- .../gui/rendering/system/base/RenderModes.kt | 20 ----- .../gui/rendering/system/base/RenderSystem.kt | 10 --- .../system/base/phases/CustomDrawable.kt | 8 ++ .../system/base/phases/OpaqueDrawable.kt | 12 +++ .../system/base/phases/OtherDrawable.kt | 12 +++ .../system/base/phases/RenderPhases.kt | 44 ++++++++++ .../system/base/phases/TranslucentDrawable.kt | 14 +++ .../system/base/phases/TransparentDrawable.kt | 12 +++ .../rendering/system/base/shader/Shader.kt | 2 + .../rendering/system/opengl/OpenGLShader.kt | 2 +- .../java/de/bixilon/minosoft/util/Pair.kt | 1 + .../includes/postprocessing/fragment.glsl | 2 +- .../rendering/shader/particle/particle.fsh | 7 ++ .../rendering/shader/sky/sun/sky_sun.fsh | 2 +- .../minosoft/rendering/shader/world/world.fsh | 8 +- 28 files changed, 292 insertions(+), 136 deletions(-) delete mode 100644 src/main/java/de/bixilon/minosoft/gui/rendering/system/base/RenderModes.kt create mode 100644 src/main/java/de/bixilon/minosoft/gui/rendering/system/base/phases/CustomDrawable.kt create mode 100644 src/main/java/de/bixilon/minosoft/gui/rendering/system/base/phases/OpaqueDrawable.kt create mode 100644 src/main/java/de/bixilon/minosoft/gui/rendering/system/base/phases/OtherDrawable.kt create mode 100644 src/main/java/de/bixilon/minosoft/gui/rendering/system/base/phases/RenderPhases.kt create mode 100644 src/main/java/de/bixilon/minosoft/gui/rendering/system/base/phases/TranslucentDrawable.kt create mode 100644 src/main/java/de/bixilon/minosoft/gui/rendering/system/base/phases/TransparentDrawable.kt diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/RenderWindow.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/RenderWindow.kt index 3eda237a0..375c398a5 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/RenderWindow.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/RenderWindow.kt @@ -31,6 +31,7 @@ import de.bixilon.minosoft.gui.rendering.sky.SkyRenderer import de.bixilon.minosoft.gui.rendering.system.base.IntegratedBufferTypes 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.phases.RenderPhases import de.bixilon.minosoft.gui.rendering.system.opengl.OpenGLRenderSystem import de.bixilon.minosoft.gui.rendering.system.window.BaseWindow import de.bixilon.minosoft.gui.rendering.system.window.GLFWWindow @@ -254,13 +255,17 @@ class RenderWindow( for (renderer in rendererMap.values) { - renderer.update() + renderer.prepareDraw() } + for (renderer in rendererMap.values) { - renderer.draw() - } - for (renderer in rendererMap.values) { - renderer.postDraw() + for (phase in RenderPhases.VALUES) { + if (!phase.type.java.isAssignableFrom(renderer::class.java)) { + continue + } + phase.invokeSetup(renderer) + phase.invokeDraw(renderer) + } } renderStats.endDraw() diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/Renderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/Renderer.kt index 501dba3cb..6bc20f52f 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/Renderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/Renderer.kt @@ -13,15 +13,15 @@ package de.bixilon.minosoft.gui.rendering +import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem + interface Renderer { + val renderWindow: RenderWindow + val renderSystem: RenderSystem fun init() {} fun postInit() {} - fun update() {} - - fun draw() {} - - fun postDraw() {} + fun prepareDraw() {} } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/block/WorldRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/block/WorldRenderer.kt index 48463138c..301c806e8 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/block/WorldRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/block/WorldRenderer.kt @@ -33,10 +33,12 @@ import de.bixilon.minosoft.gui.rendering.block.renderable.BlockLikeRenderContext import de.bixilon.minosoft.gui.rendering.input.camera.Frustum import de.bixilon.minosoft.gui.rendering.modding.events.FrustumChangeEvent import de.bixilon.minosoft.gui.rendering.modding.events.RenderingStateChangeEvent -import de.bixilon.minosoft.gui.rendering.system.base.RenderModes +import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem +import de.bixilon.minosoft.gui.rendering.system.base.phases.OpaqueDrawable +import de.bixilon.minosoft.gui.rendering.system.base.phases.TranslucentDrawable +import de.bixilon.minosoft.gui.rendering.system.base.phases.TransparentDrawable import de.bixilon.minosoft.gui.rendering.system.base.shader.Shader import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureManager -import de.bixilon.minosoft.gui.rendering.system.opengl.OpenGLShader import de.bixilon.minosoft.gui.rendering.util.VecUtil.chunkPosition import de.bixilon.minosoft.gui.rendering.util.VecUtil.getWorldOffset import de.bixilon.minosoft.gui.rendering.util.VecUtil.of @@ -58,13 +60,14 @@ import glm_.vec3.Vec3i class WorldRenderer( private val connection: PlayConnection, - val renderWindow: RenderWindow, -) : Renderer { + override val renderWindow: RenderWindow, +) : Renderer, OpaqueDrawable, TransparentDrawable, TranslucentDrawable { + override val renderSystem: RenderSystem = renderWindow.renderSystem private val world: World = connection.world private val waterBlock = connection.registries.blockRegistry[ResourceLocation("minecraft:water")].nullCast() - private val chunkShader: Shader = renderWindow.renderSystem.createShader(ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "world")) - private val transparentShader: Shader = renderWindow.renderSystem.createShader(ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "world")) + private val chunkShader: Shader = renderSystem.createShader(ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "world")) + private val transparentShader: Shader = renderSystem.createShader(ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "world")) private val lightMap = LightMap(connection) val allChunkSections: SynchronizedMap> = synchronizedMapOf() @@ -186,15 +189,16 @@ class WorldRenderer( } override fun postInit() { - chunkShader.load() - (transparentShader as OpenGLShader).defines["TRANSPARENT"] = "" // ToDo - transparentShader.load() lightMap.init() - - renderWindow.textureManager.staticTextures.use(chunkShader) - renderWindow.textureManager.staticTextures.use(transparentShader) + chunkShader.load() renderWindow.textureManager.staticTextures.animator.use(chunkShader) lightMap.use(chunkShader) + + transparentShader.defines[Shader.TRANSPARENT_DEFINE] = "" + transparentShader.load() + renderWindow.textureManager.staticTextures.use(chunkShader) + renderWindow.textureManager.staticTextures.use(transparentShader) + renderWindow.textureManager.staticTextures.animator.use(transparentShader) lightMap.use(transparentShader) for (blockState in allBlocks!!) { @@ -205,15 +209,17 @@ class WorldRenderer( allBlocks = null } - override fun update() { + override fun prepareDraw() { lastVisibleChunks = visibleChunks.toSynchronizedMap() lightMap.update() } - override fun draw() { - renderWindow.renderSystem.reset() + override fun setupOpaque() { + super.setupOpaque() chunkShader.use() + } + override fun drawOpaque() { for (map in lastVisibleChunks.values) { for (mesh in map.values) { mesh.opaqueMesh.draw() @@ -221,20 +227,25 @@ class WorldRenderer( } } - override fun postDraw() { - renderWindow.renderSystem.reset() + override fun setupTransparent() { + super.setupTransparent() transparentShader.use() + } - + override fun drawTransparent() { for (map in lastVisibleChunks.values) { for (mesh in map.values) { mesh.transparentMesh?.draw() } } + } + override fun setupTranslucent() { + super.setupTranslucent() chunkShader.use() - renderWindow.renderSystem.renderMode(RenderModes.TRANSLUCENT) + } + override fun drawTranslucent() { for (map in lastVisibleChunks.values) { for (mesh in map.values) { mesh.translucentMesh?.draw() diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/block/chunk/ChunkBorderRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/block/chunk/ChunkBorderRenderer.kt index 8dc9fc2ac..3bafb714f 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/block/chunk/ChunkBorderRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/block/chunk/ChunkBorderRenderer.kt @@ -19,6 +19,8 @@ import de.bixilon.minosoft.gui.rendering.RenderConstants import de.bixilon.minosoft.gui.rendering.RenderWindow import de.bixilon.minosoft.gui.rendering.Renderer import de.bixilon.minosoft.gui.rendering.RendererBuilder +import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem +import de.bixilon.minosoft.gui.rendering.system.base.phases.OpaqueDrawable import de.bixilon.minosoft.gui.rendering.util.mesh.LineMesh import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition @@ -27,13 +29,14 @@ import glm_.vec3.Vec3 class ChunkBorderRenderer( val connection: PlayConnection, - val renderWindow: RenderWindow, -) : Renderer { + override val renderWindow: RenderWindow, +) : Renderer, OpaqueDrawable { + override val renderSystem: RenderSystem = renderWindow.renderSystem private var lastChunkPosition: Vec2i? = null private var lastMesh: LineMesh? = null - private fun prepare() { + override fun prepareDraw() { val chunkPosition = renderWindow.connection.player.positionInfo.chunkPosition if (chunkPosition == lastChunkPosition && lastMesh != null) { return @@ -109,11 +112,13 @@ class ChunkBorderRenderer( this.lastChunkPosition = chunkPosition } - override fun draw() { - prepare() - val mesh = lastMesh ?: return + override fun setupOpaque() { renderWindow.renderSystem.reset(faceCulling = false) renderWindow.shaderManager.genericColorShader.use() + } + + override fun drawOpaque() { + val mesh = lastMesh ?: return mesh.draw() } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/block/outline/BlockOutlineRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/block/outline/BlockOutlineRenderer.kt index 9745e1048..a38f281b2 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/block/outline/BlockOutlineRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/block/outline/BlockOutlineRenderer.kt @@ -23,6 +23,7 @@ import de.bixilon.minosoft.gui.rendering.Renderer import de.bixilon.minosoft.gui.rendering.RendererBuilder import de.bixilon.minosoft.gui.rendering.input.camera.hit.BlockRaycastHit import de.bixilon.minosoft.gui.rendering.system.base.DepthFunctions +import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem import de.bixilon.minosoft.gui.rendering.util.VecUtil.getWorldOffset import de.bixilon.minosoft.gui.rendering.util.VecUtil.toVec3d import de.bixilon.minosoft.gui.rendering.util.mesh.LineMesh @@ -32,13 +33,15 @@ import glm_.vec3.Vec3i class BlockOutlineRenderer( val connection: PlayConnection, - val renderWindow: RenderWindow, + override val renderWindow: RenderWindow, ) : Renderer { + override val renderSystem: RenderSystem = renderWindow.renderSystem private var currentOutlinePosition: Vec3i? = null private var currentOutlineBlockState: BlockState? = null private var currentMesh: LineMesh? = null + private fun drawMesh() { val currentMesh = currentMesh ?: return renderWindow.renderSystem.reset(faceCulling = false) @@ -47,6 +50,7 @@ class BlockOutlineRenderer( } renderWindow.shaderManager.genericColorShader.use() currentMesh.draw() + draw() } private fun unload() { @@ -57,7 +61,8 @@ class BlockOutlineRenderer( this.currentOutlineBlockState = null } - override fun draw() { + @Deprecated("TODO") + private fun draw() { val raycastHit = renderWindow.inputHandler.camera.target.nullCast() var currentMesh = currentMesh diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/entity/EntityHitBoxRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/entity/EntityHitBoxRenderer.kt index 73d6b1a20..59039a9be 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/entity/EntityHitBoxRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/entity/EntityHitBoxRenderer.kt @@ -22,6 +22,8 @@ import de.bixilon.minosoft.gui.rendering.Renderer import de.bixilon.minosoft.gui.rendering.RendererBuilder import de.bixilon.minosoft.gui.rendering.modding.events.FrustumChangeEvent 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.phases.OpaqueDrawable import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh import de.bixilon.minosoft.modding.event.events.EntityDestroyEvent import de.bixilon.minosoft.modding.event.events.EntitySpawnEvent @@ -33,8 +35,9 @@ import de.bixilon.minosoft.util.collections.SynchronizedMap class EntityHitBoxRenderer( val connection: PlayConnection, - val renderWindow: RenderWindow, -) : Renderer { + override val renderWindow: RenderWindow, +) : Renderer, OpaqueDrawable { + override val renderSystem: RenderSystem = renderWindow.renderSystem private val meshes: SynchronizedMap = synchronizedMapOf() @@ -102,13 +105,15 @@ class EntityHitBoxRenderer( } } - override fun draw() { - renderWindow.renderSystem.reset(faceCulling = false) + override fun setupOpaque() { + renderWindow.renderSystem.reset(faceCulling = false) // ToDo? if (Minosoft.config.config.game.entities.hitBox.disableZBuffer) { renderWindow.renderSystem.depth = DepthFunctions.ALWAYS } renderWindow.shaderManager.genericColorShader.use() + } + override fun drawOpaque() { fun draw(mesh: EntityHitBoxMesh?) { mesh ?: return diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/HUDRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/HUDRenderer.kt index 95cbd2004..4c98e7ba6 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/HUDRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/HUDRenderer.kt @@ -28,6 +28,8 @@ import de.bixilon.minosoft.gui.rendering.hud.nodes.chat.ChatBoxHUDElement import de.bixilon.minosoft.gui.rendering.hud.nodes.debug.HUDSystemDebugNode import de.bixilon.minosoft.gui.rendering.hud.nodes.debug.HUDWorldDebugNode import de.bixilon.minosoft.gui.rendering.modding.events.ResizeWindowEvent +import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem +import de.bixilon.minosoft.gui.rendering.system.base.phases.OtherDrawable import de.bixilon.minosoft.modding.event.invoker.CallbackEventInvoker import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition @@ -37,10 +39,14 @@ import glm_.glm import glm_.mat4x4.Mat4 import glm_.vec2.Vec2i -class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow) : Renderer { +class HUDRenderer( + val connection: PlayConnection, + override val renderWindow: RenderWindow, +) : Renderer, OtherDrawable { + override val renderSystem: RenderSystem = renderWindow.renderSystem private val hudElements: MutableMap> = mutableMapOf() private val enabledHUDElement: MutableMap> = mutableMapOf() - private val hudShader = renderWindow.renderSystem.createShader(ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "hud")) + private val hudShader = renderSystem.createShader(ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "hud")) lateinit var hudAtlasElements: Map var orthographicMatrix: Mat4 = Mat4() private set @@ -146,7 +152,18 @@ class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow } } - override fun postDraw() { + override fun setupOther() { + if (!RenderConstants.RENDER_HUD) { + return + } + if (!hudEnabled) { + return + } + super.setupOther() + hudShader.use() + } + + override fun drawOther() { if (!RenderConstants.RENDER_HUD) { return } @@ -154,7 +171,6 @@ class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow if (!hudEnabled) { return } - renderWindow.renderSystem.reset() var needsUpdate = false val tempMesh = HUDMesh(renderWindow) @@ -183,7 +199,6 @@ class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow tempMesh.load() currentHUDMesh = tempMesh } - hudShader.use() currentHUDMesh.draw() } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleRenderer.kt index 63233af79..70ae8f8b9 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleRenderer.kt @@ -20,6 +20,9 @@ import de.bixilon.minosoft.gui.rendering.Renderer import de.bixilon.minosoft.gui.rendering.RendererBuilder import de.bixilon.minosoft.gui.rendering.modding.events.CameraMatrixChangeEvent import de.bixilon.minosoft.gui.rendering.particle.types.Particle +import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem +import de.bixilon.minosoft.gui.rendering.system.base.phases.TranslucentDrawable +import de.bixilon.minosoft.gui.rendering.system.base.phases.TransparentDrawable import de.bixilon.minosoft.gui.rendering.system.base.shader.Shader import de.bixilon.minosoft.modding.event.invoker.CallbackEventInvoker import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection @@ -32,24 +35,38 @@ import glm_.vec3.Vec3 class ParticleRenderer( private val connection: PlayConnection, - val renderWindow: RenderWindow, -) : Renderer { - private val particleShader: Shader = renderWindow.renderSystem.createShader(ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "particle")) - private var particleMesh = ParticleMesh(renderWindow) - private var transparentParticleMesh = ParticleMesh(renderWindow) + override val renderWindow: RenderWindow, +) : Renderer, TransparentDrawable, TranslucentDrawable { + override val renderSystem: RenderSystem = renderWindow.renderSystem + private val transparentShader: Shader = renderSystem.createShader(ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "particle")) + private val translucentShader: Shader = renderSystem.createShader(ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "particle")) + + // There is no opaque mesh because it is simply not needed (every particle has transparency) + private var transparentMesh = ParticleMesh(renderWindow) + private var translucentMesh = ParticleMesh(renderWindow) private var particles: MutableSet = synchronizedSetOf() override fun init() { connection.registerEvent(CallbackEventInvoker.of { renderWindow.queue += { - particleShader.use().setMat4("uViewProjectionMatrix", Mat4(it.viewProjectionMatrix)) - particleShader.use().setVec3("uCameraRight", Vec3(it.viewMatrix[0][0], it.viewMatrix[1][0], it.viewMatrix[2][0])) - particleShader.use().setVec3("uCameraUp", Vec3(it.viewMatrix[0][1], it.viewMatrix[1][1], it.viewMatrix[2][1])) + + fun applyToShader(shader: Shader) { + shader.apply { + use() + setMat4("uViewProjectionMatrix", Mat4(it.viewProjectionMatrix)) + setVec3("uCameraRight", Vec3(it.viewMatrix[0][0], it.viewMatrix[1][0], it.viewMatrix[2][0])) + setVec3("uCameraUp", Vec3(it.viewMatrix[0][1], it.viewMatrix[1][1], it.viewMatrix[2][1])) + } + } + + applyToShader(transparentShader) + applyToShader(translucentShader) } }) - particleMesh.load() - transparentParticleMesh.load() + transparentMesh.load() + translucentMesh.load() + connection.registries.particleTypeRegistry.forEachItem { for (resourceLocation in it.textures) { renderWindow.textureManager.staticTextures.createTexture(resourceLocation) @@ -60,9 +77,15 @@ class ParticleRenderer( } override fun postInit() { - particleShader.load() - renderWindow.textureManager.staticTextures.use(particleShader) - renderWindow.textureManager.staticTextures.animator.use(particleShader) + transparentShader.defines[Shader.TRANSPARENT_DEFINE] = "" + transparentShader.load() + renderWindow.textureManager.staticTextures.use(transparentShader) + renderWindow.textureManager.staticTextures.animator.use(transparentShader) + + translucentShader.load() + renderWindow.textureManager.staticTextures.use(translucentShader) + renderWindow.textureManager.staticTextures.animator.use(translucentShader) + connection.world.particleRenderer = this } @@ -76,11 +99,11 @@ class ParticleRenderer( add(particle) } - override fun update() { - particleMesh.unload() - transparentParticleMesh.unload() - particleMesh = ParticleMesh(renderWindow) - transparentParticleMesh = ParticleMesh(renderWindow) + override fun prepareDraw() { + transparentMesh.unload() + translucentMesh.unload() + transparentMesh = ParticleMesh(renderWindow) + translucentMesh = ParticleMesh(renderWindow) for (particle in particles.toSynchronizedSet()) { @@ -89,23 +112,29 @@ class ParticleRenderer( this.particles -= particle continue } - particle.addVertex(transparentParticleMesh, particleMesh) + particle.addVertex(transparentMesh, translucentMesh) } - particleMesh.load() - transparentParticleMesh.load() + transparentMesh.load() + translucentMesh.load() } - override fun draw() { - renderWindow.renderSystem.reset() - particleShader.use() - particleMesh.draw() + override fun setupTransparent() { + super.setupTransparent() + transparentShader.use() } - override fun postDraw() { - renderWindow.renderSystem.reset(depthMask = false) - particleShader.use() - transparentParticleMesh.draw() + override fun drawTransparent() { + transparentMesh.draw() + } + + override fun setupTranslucent() { + super.setupTranslucent() + translucentShader.use() + } + + override fun drawTranslucent() { + translucentMesh.draw() } companion object : RendererBuilder { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/Particle.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/Particle.kt index 27eeb4884..7f415502d 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/Particle.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/Particle.kt @@ -181,10 +181,10 @@ abstract class Particle( } } - abstract fun addVertex(transparentMesh: ParticleMesh, particleMesh: ParticleMesh) + abstract fun addVertex(transparentMesh: ParticleMesh, translucentMesh: ParticleMesh) companion object { - private const val MAGIC_VELOCITY_CONSTANT = 0.4000000059604645 + private const val MAGIC_VELOCITY_CONSTANT = 0.4 private const val MAGIC_VELOCITY_CONSTANTf = MAGIC_VELOCITY_CONSTANT.toFloat() private const val Y_VELOCITY_TO_CHECK = 9.999999747378752E-6f } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/norender/NoRenderParticle.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/norender/NoRenderParticle.kt index 2be0dee67..15a243830 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/norender/NoRenderParticle.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/norender/NoRenderParticle.kt @@ -21,5 +21,5 @@ import glm_.vec3.Vec3d abstract class NoRenderParticle(connection: PlayConnection, position: Vec3d, velocity: Vec3d, data: ParticleData?) : Particle(connection, position, velocity, data) { - override fun addVertex(transparentMesh: ParticleMesh, particleMesh: ParticleMesh) {} + override fun addVertex(transparentMesh: ParticleMesh, translucentMesh: ParticleMesh) {} } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/TextureParticle.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/TextureParticle.kt index a6c5b2d1f..af150b752 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/TextureParticle.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/TextureParticle.kt @@ -25,13 +25,11 @@ abstract class TextureParticle(connection: PlayConnection, position: Vec3d, velo abstract val texture: AbstractTexture? - override fun addVertex(transparentMesh: ParticleMesh, particleMesh: ParticleMesh) { - texture?.let { - if (it.transparency == TextureTransparencies.TRANSLUCENT || color.alpha != 255) { - transparentMesh - } else { - particleMesh - }.addVertex(cameraPosition, scale, it, color) - } + override fun addVertex(transparentMesh: ParticleMesh, translucentMesh: ParticleMesh) { + val texture = texture ?: return + when { + texture.transparency == TextureTransparencies.TRANSLUCENT || color.alpha != 255 -> translucentMesh + else -> transparentMesh + }.addVertex(cameraPosition, scale, texture, color) } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/advanced/AdvancedTextureParticle.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/advanced/AdvancedTextureParticle.kt index ed024d0a1..d9f45b93d 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/advanced/AdvancedTextureParticle.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/advanced/AdvancedTextureParticle.kt @@ -25,13 +25,11 @@ abstract class AdvancedTextureParticle(connection: PlayConnection, position: Vec var minUV: Vec2 = Vec2(0.0f, 0.0f) var maxUV: Vec2 = Vec2(1.0f, 1.0f) - override fun addVertex(transparentMesh: ParticleMesh, particleMesh: ParticleMesh) { - texture?.let { - if (it.transparency == TextureTransparencies.TRANSLUCENT || color.alpha != 255) { - transparentMesh - } else { - particleMesh - }.addVertex(cameraPosition, scale, it, color, minUV, maxUV) - } + override fun addVertex(transparentMesh: ParticleMesh, translucentMesh: ParticleMesh) { + val texture = texture ?: return + when { + texture.transparency == TextureTransparencies.TRANSLUCENT || color.alpha != 255 -> translucentMesh + else -> transparentMesh + }.addVertex(cameraPosition, scale, texture, color, minUV, maxUV) } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/sky/SkyRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/sky/SkyRenderer.kt index a3259cf5b..0fcfb3f7d 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/sky/SkyRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/sky/SkyRenderer.kt @@ -24,6 +24,8 @@ import de.bixilon.minosoft.gui.rendering.RendererBuilder import de.bixilon.minosoft.gui.rendering.modding.events.CameraMatrixChangeEvent import de.bixilon.minosoft.gui.rendering.system.base.BlendingFunctions 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.phases.CustomDrawable import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture import de.bixilon.minosoft.gui.rendering.util.mesh.SimpleTextureMesh import de.bixilon.minosoft.modding.event.events.TimeChangeEvent @@ -38,10 +40,11 @@ import glm_.vec3.Vec3d class SkyRenderer( private val connection: PlayConnection, - val renderWindow: RenderWindow, -) : Renderer { - private val skyboxShader = renderWindow.renderSystem.createShader(ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "sky/skybox")) - private val skySunShader = renderWindow.renderSystem.createShader(ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "sky/sun")) + override val renderWindow: RenderWindow, +) : Renderer, CustomDrawable { + override val renderSystem: RenderSystem = renderWindow.renderSystem + private val skyboxShader = renderSystem.createShader(ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "sky/skybox")) + private val skySunShader = renderSystem.createShader(ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "sky/sun")) private val skyboxMesh = SkyboxMesh(renderWindow) private var skySunMesh = SimpleTextureMesh(renderWindow) private lateinit var sunTexture: AbstractTexture @@ -138,7 +141,7 @@ class SkyRenderer( skyboxMesh.draw() } - override fun draw() { + override fun drawCustom() { renderWindow.renderSystem.reset(depth = DepthFunctions.LESS_OR_EQUAL) drawSkybox() drawSun() diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/RenderModes.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/RenderModes.kt deleted file mode 100644 index 5b328c60f..000000000 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/RenderModes.kt +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Minosoft - * Copyright (C) 2021 Moritz Zwerger - * - * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with this program. If not, see . - * - * This software is not affiliated with Mojang AB, the original developer of Minecraft. - */ - -package de.bixilon.minosoft.gui.rendering.system.base - -enum class RenderModes { - DEFAULT, - TRANSLUCENT, - ; -} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/RenderSystem.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/RenderSystem.kt index 1fcd8cdc0..0cbecd78c 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/RenderSystem.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/RenderSystem.kt @@ -89,14 +89,4 @@ interface RenderSystem { fun createTextureManager(): TextureManager fun clear(vararg buffers: IntegratedBufferTypes) - - - fun renderMode(mode: RenderModes) { - when (mode) { - RenderModes.TRANSLUCENT -> { - depthMask = false - setBlendFunc(BlendingFunctions.SOURCE_ALPHA, BlendingFunctions.ONE_MINUS_SOURCE_ALPHA, BlendingFunctions.ONE, BlendingFunctions.ONE_MINUS_SOURCE_ALPHA) - } - } - } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/phases/CustomDrawable.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/phases/CustomDrawable.kt new file mode 100644 index 000000000..14fa1100d --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/phases/CustomDrawable.kt @@ -0,0 +1,8 @@ +package de.bixilon.minosoft.gui.rendering.system.base.phases + +import de.bixilon.minosoft.gui.rendering.Renderer + +interface CustomDrawable : Renderer { + + fun drawCustom() +} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/phases/OpaqueDrawable.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/phases/OpaqueDrawable.kt new file mode 100644 index 000000000..516575d18 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/phases/OpaqueDrawable.kt @@ -0,0 +1,12 @@ +package de.bixilon.minosoft.gui.rendering.system.base.phases + +import de.bixilon.minosoft.gui.rendering.Renderer + +interface OpaqueDrawable : Renderer { + + fun setupOpaque() { + renderSystem.reset() + } + + fun drawOpaque() +} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/phases/OtherDrawable.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/phases/OtherDrawable.kt new file mode 100644 index 000000000..8e274f64b --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/phases/OtherDrawable.kt @@ -0,0 +1,12 @@ +package de.bixilon.minosoft.gui.rendering.system.base.phases + +import de.bixilon.minosoft.gui.rendering.Renderer + +interface OtherDrawable : Renderer { + + fun setupOther() { + renderSystem.reset() + } + + fun drawOther() +} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/phases/RenderPhases.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/phases/RenderPhases.kt new file mode 100644 index 000000000..4ebb99b77 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/phases/RenderPhases.kt @@ -0,0 +1,44 @@ +/* + * Minosoft + * Copyright (C) 2021 Moritz Zwerger + * + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.gui.rendering.system.base.phases + +import de.bixilon.minosoft.gui.rendering.Renderer +import de.bixilon.minosoft.util.KUtil.unsafeCast +import kotlin.reflect.KClass + +class RenderPhases( + val type: KClass, + val setup: (T) -> Unit, + val draw: (T) -> Unit, +) { + + fun invokeSetup(renderer: Renderer) { + setup.invoke(renderer.unsafeCast()) + } + + fun invokeDraw(renderer: Renderer) { + draw.invoke(renderer.unsafeCast()) + } + + companion object { + val OTHER = RenderPhases(OtherDrawable::class, { it.setupOther() }, { it.drawOther() }) + val CUSTOM = RenderPhases(CustomDrawable::class, { }, { it.drawCustom() }) + val OPAQUE = RenderPhases(OpaqueDrawable::class, { it.setupOpaque() }, { it.drawOpaque() }) + val TRANSPARENT = RenderPhases(TransparentDrawable::class, { it.setupTransparent() }, { it.drawTransparent() }) + val TRANSLUCENT = RenderPhases(TranslucentDrawable::class, { it.setupTranslucent() }, { it.drawTranslucent() }) + + + val VALUES = arrayOf(OTHER, CUSTOM, OPAQUE, TRANSPARENT, TRANSLUCENT) + } +} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/phases/TranslucentDrawable.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/phases/TranslucentDrawable.kt new file mode 100644 index 000000000..d87dcf7cf --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/phases/TranslucentDrawable.kt @@ -0,0 +1,14 @@ +package de.bixilon.minosoft.gui.rendering.system.base.phases + +import de.bixilon.minosoft.gui.rendering.Renderer +import de.bixilon.minosoft.gui.rendering.system.base.BlendingFunctions + +interface TranslucentDrawable : Renderer { + + fun setupTranslucent() { + renderSystem.reset(depthMask = false) // ToDo: This is just a translucent workaround + renderSystem.setBlendFunc(BlendingFunctions.SOURCE_ALPHA, BlendingFunctions.ONE_MINUS_SOURCE_ALPHA, BlendingFunctions.ONE, BlendingFunctions.ONE_MINUS_SOURCE_ALPHA) + } + + fun drawTranslucent() +} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/phases/TransparentDrawable.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/phases/TransparentDrawable.kt new file mode 100644 index 000000000..e78983f1b --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/phases/TransparentDrawable.kt @@ -0,0 +1,12 @@ +package de.bixilon.minosoft.gui.rendering.system.base.phases + +import de.bixilon.minosoft.gui.rendering.Renderer + +interface TransparentDrawable : Renderer { + + fun setupTransparent() { + renderSystem.reset() + } + + fun drawTransparent() +} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/shader/Shader.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/shader/Shader.kt index e37cece2b..afed581b2 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/shader/Shader.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/shader/Shader.kt @@ -30,6 +30,7 @@ interface Shader { val renderWindow: RenderWindow val resourceLocation: ResourceLocation val uniforms: List + val defines: MutableMap val log: String @@ -74,6 +75,7 @@ interface Shader { } companion object { + const val TRANSPARENT_DEFINE = "TRANSPARENT" val DEFAULT_DEFINES: Map Any?> = mapOf( "ANIMATED_TEXTURE_COUNT" to { max(it.textureManager.staticTextures.animator.size, 1) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/OpenGLShader.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/OpenGLShader.kt index e36d82870..adbaa7a78 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/OpenGLShader.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/OpenGLShader.kt @@ -40,7 +40,7 @@ class OpenGLShader( ) : Shader { override var loaded: Boolean = false private set - val defines: MutableMap = mutableMapOf() + override val defines: MutableMap = mutableMapOf() private var shader = -1 override var uniforms: MutableList = mutableListOf() private set diff --git a/src/main/java/de/bixilon/minosoft/util/Pair.kt b/src/main/java/de/bixilon/minosoft/util/Pair.kt index 60a85a970..8ddeeac6e 100644 --- a/src/main/java/de/bixilon/minosoft/util/Pair.kt +++ b/src/main/java/de/bixilon/minosoft/util/Pair.kt @@ -12,6 +12,7 @@ */ package de.bixilon.minosoft.util +@Deprecated("Java only") data class Pair( val key: K, val value: V, diff --git a/src/main/resources/assets/minosoft/rendering/shader/includes/postprocessing/fragment.glsl b/src/main/resources/assets/minosoft/rendering/shader/includes/postprocessing/fragment.glsl index c99daeaaa..af16f3d5e 100644 --- a/src/main/resources/assets/minosoft/rendering/shader/includes/postprocessing/fragment.glsl +++ b/src/main/resources/assets/minosoft/rendering/shader/includes/postprocessing/fragment.glsl @@ -41,7 +41,7 @@ void main() { float fogFactor = getFogFactor(distance(uCameraPosition, finVertexPosition)); if (fogFactor != 1.0f) { - outColor = vec4(mix(uFogColor.rgb, outColor.rgb, fogFactor), outColor.a); + foutColor = vec4(mix(uFogColor.rgb, foutColor.rgb, fogFactor), foutColor.a); }; #endif } diff --git a/src/main/resources/assets/minosoft/rendering/shader/particle/particle.fsh b/src/main/resources/assets/minosoft/rendering/shader/particle/particle.fsh index 012cc3909..9001ce2af 100644 --- a/src/main/resources/assets/minosoft/rendering/shader/particle/particle.fsh +++ b/src/main/resources/assets/minosoft/rendering/shader/particle/particle.fsh @@ -43,4 +43,11 @@ void main() { } foutColor = mix(texelColor1, texelColor2, finInterpolation) * finTintColor; + + + #ifndef TRANSPARENT + if (foutColor.a < 0.5){ + discard; + } + #endif } diff --git a/src/main/resources/assets/minosoft/rendering/shader/sky/sun/sky_sun.fsh b/src/main/resources/assets/minosoft/rendering/shader/sky/sun/sky_sun.fsh index ebda5c585..ba6a0267a 100644 --- a/src/main/resources/assets/minosoft/rendering/shader/sky/sun/sky_sun.fsh +++ b/src/main/resources/assets/minosoft/rendering/shader/sky/sun/sky_sun.fsh @@ -28,6 +28,6 @@ void main() { if (finTintColor.a == 1.0f && texelColor.a == 0) { discard; } - // outColor = vec4(0.0f, 1.0f, 1.0f, 1.0f); + // foutColor = vec4(0.0f, 1.0f, 1.0f, 1.0f); foutColor = texelColor * finTintColor; } diff --git a/src/main/resources/assets/minosoft/rendering/shader/world/world.fsh b/src/main/resources/assets/minosoft/rendering/shader/world/world.fsh index d61445ef5..d7baba2be 100644 --- a/src/main/resources/assets/minosoft/rendering/shader/world/world.fsh +++ b/src/main/resources/assets/minosoft/rendering/shader/world/world.fsh @@ -13,7 +13,7 @@ #version 330 core -out vec4 outColor; +out vec4 foutColor; flat in uint finTextureIndex1; in vec3 finTextureCoordinates1; @@ -34,7 +34,7 @@ void work() { } if (finInterpolation == 0.0f) { - outColor = firstTexelColor * finTintColor; + foutColor = firstTexelColor * finTintColor; return; } @@ -44,10 +44,10 @@ void work() { discard; } - outColor = mix(firstTexelColor, secondTexelColor, finInterpolation) * finTintColor; + foutColor = mix(firstTexelColor, secondTexelColor, finInterpolation) * finTintColor; #ifndef TRANSPARENT - if (outColor.a < 0.5){ + if (foutColor.a < 0.5){ discard; } #endif