render phases

This commit is contained in:
Bixilon 2021-11-01 22:29:49 +01:00
parent c4d242228a
commit c470f77eb3
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
28 changed files with 292 additions and 136 deletions

View File

@ -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.IntegratedBufferTypes
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.RenderPhases
import de.bixilon.minosoft.gui.rendering.system.opengl.OpenGLRenderSystem 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.BaseWindow
import de.bixilon.minosoft.gui.rendering.system.window.GLFWWindow import de.bixilon.minosoft.gui.rendering.system.window.GLFWWindow
@ -254,13 +255,17 @@ class RenderWindow(
for (renderer in rendererMap.values) { for (renderer in rendererMap.values) {
renderer.update() renderer.prepareDraw()
} }
for (renderer in rendererMap.values) { for (renderer in rendererMap.values) {
renderer.draw() for (phase in RenderPhases.VALUES) {
} if (!phase.type.java.isAssignableFrom(renderer::class.java)) {
for (renderer in rendererMap.values) { continue
renderer.postDraw() }
phase.invokeSetup(renderer)
phase.invokeDraw(renderer)
}
} }
renderStats.endDraw() renderStats.endDraw()

View File

@ -13,15 +13,15 @@
package de.bixilon.minosoft.gui.rendering package de.bixilon.minosoft.gui.rendering
import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem
interface Renderer { interface Renderer {
val renderWindow: RenderWindow
val renderSystem: RenderSystem
fun init() {} fun init() {}
fun postInit() {} fun postInit() {}
fun update() {} fun prepareDraw() {}
fun draw() {}
fun postDraw() {}
} }

View File

@ -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.input.camera.Frustum
import de.bixilon.minosoft.gui.rendering.modding.events.FrustumChangeEvent import de.bixilon.minosoft.gui.rendering.modding.events.FrustumChangeEvent
import de.bixilon.minosoft.gui.rendering.modding.events.RenderingStateChangeEvent 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.shader.Shader
import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureManager 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.chunkPosition
import de.bixilon.minosoft.gui.rendering.util.VecUtil.getWorldOffset import de.bixilon.minosoft.gui.rendering.util.VecUtil.getWorldOffset
import de.bixilon.minosoft.gui.rendering.util.VecUtil.of import de.bixilon.minosoft.gui.rendering.util.VecUtil.of
@ -58,13 +60,14 @@ import glm_.vec3.Vec3i
class WorldRenderer( class WorldRenderer(
private val connection: PlayConnection, private val connection: PlayConnection,
val renderWindow: RenderWindow, override val renderWindow: RenderWindow,
) : Renderer { ) : Renderer, OpaqueDrawable, TransparentDrawable, TranslucentDrawable {
override val renderSystem: RenderSystem = renderWindow.renderSystem
private val world: World = connection.world private val world: World = connection.world
private val waterBlock = connection.registries.blockRegistry[ResourceLocation("minecraft:water")].nullCast<FluidBlock>() private val waterBlock = connection.registries.blockRegistry[ResourceLocation("minecraft:water")].nullCast<FluidBlock>()
private val chunkShader: Shader = renderWindow.renderSystem.createShader(ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "world")) private val chunkShader: Shader = renderSystem.createShader(ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "world"))
private val transparentShader: Shader = renderWindow.renderSystem.createShader(ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "world")) private val transparentShader: Shader = renderSystem.createShader(ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "world"))
private val lightMap = LightMap(connection) private val lightMap = LightMap(connection)
val allChunkSections: SynchronizedMap<Vec2i, SynchronizedMap<Int, ChunkSectionMeshCollection>> = synchronizedMapOf() val allChunkSections: SynchronizedMap<Vec2i, SynchronizedMap<Int, ChunkSectionMeshCollection>> = synchronizedMapOf()
@ -186,15 +189,16 @@ class WorldRenderer(
} }
override fun postInit() { override fun postInit() {
chunkShader.load()
(transparentShader as OpenGLShader).defines["TRANSPARENT"] = "" // ToDo
transparentShader.load()
lightMap.init() lightMap.init()
chunkShader.load()
renderWindow.textureManager.staticTextures.use(chunkShader)
renderWindow.textureManager.staticTextures.use(transparentShader)
renderWindow.textureManager.staticTextures.animator.use(chunkShader) renderWindow.textureManager.staticTextures.animator.use(chunkShader)
lightMap.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) lightMap.use(transparentShader)
for (blockState in allBlocks!!) { for (blockState in allBlocks!!) {
@ -205,15 +209,17 @@ class WorldRenderer(
allBlocks = null allBlocks = null
} }
override fun update() { override fun prepareDraw() {
lastVisibleChunks = visibleChunks.toSynchronizedMap() lastVisibleChunks = visibleChunks.toSynchronizedMap()
lightMap.update() lightMap.update()
} }
override fun draw() { override fun setupOpaque() {
renderWindow.renderSystem.reset() super.setupOpaque()
chunkShader.use() chunkShader.use()
}
override fun drawOpaque() {
for (map in lastVisibleChunks.values) { for (map in lastVisibleChunks.values) {
for (mesh in map.values) { for (mesh in map.values) {
mesh.opaqueMesh.draw() mesh.opaqueMesh.draw()
@ -221,20 +227,25 @@ class WorldRenderer(
} }
} }
override fun postDraw() { override fun setupTransparent() {
renderWindow.renderSystem.reset() super.setupTransparent()
transparentShader.use() transparentShader.use()
}
override fun drawTransparent() {
for (map in lastVisibleChunks.values) { for (map in lastVisibleChunks.values) {
for (mesh in map.values) { for (mesh in map.values) {
mesh.transparentMesh?.draw() mesh.transparentMesh?.draw()
} }
} }
}
override fun setupTranslucent() {
super.setupTranslucent()
chunkShader.use() chunkShader.use()
renderWindow.renderSystem.renderMode(RenderModes.TRANSLUCENT) }
override fun drawTranslucent() {
for (map in lastVisibleChunks.values) { for (map in lastVisibleChunks.values) {
for (mesh in map.values) { for (mesh in map.values) {
mesh.translucentMesh?.draw() mesh.translucentMesh?.draw()

View File

@ -19,6 +19,8 @@ import de.bixilon.minosoft.gui.rendering.RenderConstants
import de.bixilon.minosoft.gui.rendering.RenderWindow import de.bixilon.minosoft.gui.rendering.RenderWindow
import de.bixilon.minosoft.gui.rendering.Renderer import de.bixilon.minosoft.gui.rendering.Renderer
import de.bixilon.minosoft.gui.rendering.RendererBuilder 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.gui.rendering.util.mesh.LineMesh
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
@ -27,13 +29,14 @@ import glm_.vec3.Vec3
class ChunkBorderRenderer( class ChunkBorderRenderer(
val connection: PlayConnection, val connection: PlayConnection,
val renderWindow: RenderWindow, override val renderWindow: RenderWindow,
) : Renderer { ) : Renderer, OpaqueDrawable {
override val renderSystem: RenderSystem = renderWindow.renderSystem
private var lastChunkPosition: Vec2i? = null private var lastChunkPosition: Vec2i? = null
private var lastMesh: LineMesh? = null private var lastMesh: LineMesh? = null
private fun prepare() { override fun prepareDraw() {
val chunkPosition = renderWindow.connection.player.positionInfo.chunkPosition val chunkPosition = renderWindow.connection.player.positionInfo.chunkPosition
if (chunkPosition == lastChunkPosition && lastMesh != null) { if (chunkPosition == lastChunkPosition && lastMesh != null) {
return return
@ -109,11 +112,13 @@ class ChunkBorderRenderer(
this.lastChunkPosition = chunkPosition this.lastChunkPosition = chunkPosition
} }
override fun draw() { override fun setupOpaque() {
prepare()
val mesh = lastMesh ?: return
renderWindow.renderSystem.reset(faceCulling = false) renderWindow.renderSystem.reset(faceCulling = false)
renderWindow.shaderManager.genericColorShader.use() renderWindow.shaderManager.genericColorShader.use()
}
override fun drawOpaque() {
val mesh = lastMesh ?: return
mesh.draw() mesh.draw()
} }

View File

@ -23,6 +23,7 @@ import de.bixilon.minosoft.gui.rendering.Renderer
import de.bixilon.minosoft.gui.rendering.RendererBuilder import de.bixilon.minosoft.gui.rendering.RendererBuilder
import de.bixilon.minosoft.gui.rendering.input.camera.hit.BlockRaycastHit 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.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.getWorldOffset
import de.bixilon.minosoft.gui.rendering.util.VecUtil.toVec3d import de.bixilon.minosoft.gui.rendering.util.VecUtil.toVec3d
import de.bixilon.minosoft.gui.rendering.util.mesh.LineMesh import de.bixilon.minosoft.gui.rendering.util.mesh.LineMesh
@ -32,13 +33,15 @@ import glm_.vec3.Vec3i
class BlockOutlineRenderer( class BlockOutlineRenderer(
val connection: PlayConnection, val connection: PlayConnection,
val renderWindow: RenderWindow, override val renderWindow: RenderWindow,
) : Renderer { ) : Renderer {
override val renderSystem: RenderSystem = renderWindow.renderSystem
private var currentOutlinePosition: Vec3i? = null private var currentOutlinePosition: Vec3i? = null
private var currentOutlineBlockState: BlockState? = null private var currentOutlineBlockState: BlockState? = null
private var currentMesh: LineMesh? = null private var currentMesh: LineMesh? = null
private fun drawMesh() { private fun drawMesh() {
val currentMesh = currentMesh ?: return val currentMesh = currentMesh ?: return
renderWindow.renderSystem.reset(faceCulling = false) renderWindow.renderSystem.reset(faceCulling = false)
@ -47,6 +50,7 @@ class BlockOutlineRenderer(
} }
renderWindow.shaderManager.genericColorShader.use() renderWindow.shaderManager.genericColorShader.use()
currentMesh.draw() currentMesh.draw()
draw()
} }
private fun unload() { private fun unload() {
@ -57,7 +61,8 @@ class BlockOutlineRenderer(
this.currentOutlineBlockState = null this.currentOutlineBlockState = null
} }
override fun draw() { @Deprecated("TODO")
private fun draw() {
val raycastHit = renderWindow.inputHandler.camera.target.nullCast<BlockRaycastHit>() val raycastHit = renderWindow.inputHandler.camera.target.nullCast<BlockRaycastHit>()
var currentMesh = currentMesh var currentMesh = currentMesh

View File

@ -22,6 +22,8 @@ import de.bixilon.minosoft.gui.rendering.Renderer
import de.bixilon.minosoft.gui.rendering.RendererBuilder import de.bixilon.minosoft.gui.rendering.RendererBuilder
import de.bixilon.minosoft.gui.rendering.modding.events.FrustumChangeEvent 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.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.gui.rendering.util.mesh.Mesh
import de.bixilon.minosoft.modding.event.events.EntityDestroyEvent import de.bixilon.minosoft.modding.event.events.EntityDestroyEvent
import de.bixilon.minosoft.modding.event.events.EntitySpawnEvent import de.bixilon.minosoft.modding.event.events.EntitySpawnEvent
@ -33,8 +35,9 @@ import de.bixilon.minosoft.util.collections.SynchronizedMap
class EntityHitBoxRenderer( class EntityHitBoxRenderer(
val connection: PlayConnection, val connection: PlayConnection,
val renderWindow: RenderWindow, override val renderWindow: RenderWindow,
) : Renderer { ) : Renderer, OpaqueDrawable {
override val renderSystem: RenderSystem = renderWindow.renderSystem
private val meshes: SynchronizedMap<Entity, EntityHitBoxMesh> = synchronizedMapOf() private val meshes: SynchronizedMap<Entity, EntityHitBoxMesh> = synchronizedMapOf()
@ -102,13 +105,15 @@ class EntityHitBoxRenderer(
} }
} }
override fun draw() { override fun setupOpaque() {
renderWindow.renderSystem.reset(faceCulling = false) renderWindow.renderSystem.reset(faceCulling = false) // ToDo?
if (Minosoft.config.config.game.entities.hitBox.disableZBuffer) { if (Minosoft.config.config.game.entities.hitBox.disableZBuffer) {
renderWindow.renderSystem.depth = DepthFunctions.ALWAYS renderWindow.renderSystem.depth = DepthFunctions.ALWAYS
} }
renderWindow.shaderManager.genericColorShader.use() renderWindow.shaderManager.genericColorShader.use()
}
override fun drawOpaque() {
fun draw(mesh: EntityHitBoxMesh?) { fun draw(mesh: EntityHitBoxMesh?) {
mesh ?: return mesh ?: return

View File

@ -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.HUDSystemDebugNode
import de.bixilon.minosoft.gui.rendering.hud.nodes.debug.HUDWorldDebugNode 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.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.modding.event.invoker.CallbackEventInvoker
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
@ -37,10 +39,14 @@ import glm_.glm
import glm_.mat4x4.Mat4 import glm_.mat4x4.Mat4
import glm_.vec2.Vec2i 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<ResourceLocation, Pair<HUDElementProperties, HUDElement>> = mutableMapOf() private val hudElements: MutableMap<ResourceLocation, Pair<HUDElementProperties, HUDElement>> = mutableMapOf()
private val enabledHUDElement: MutableMap<ResourceLocation, Pair<HUDElementProperties, HUDElement>> = mutableMapOf() private val enabledHUDElement: MutableMap<ResourceLocation, Pair<HUDElementProperties, HUDElement>> = 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<ResourceLocation, HUDAtlasElement> lateinit var hudAtlasElements: Map<ResourceLocation, HUDAtlasElement>
var orthographicMatrix: Mat4 = Mat4() var orthographicMatrix: Mat4 = Mat4()
private set 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) { if (!RenderConstants.RENDER_HUD) {
return return
} }
@ -154,7 +171,6 @@ class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow
if (!hudEnabled) { if (!hudEnabled) {
return return
} }
renderWindow.renderSystem.reset()
var needsUpdate = false var needsUpdate = false
val tempMesh = HUDMesh(renderWindow) val tempMesh = HUDMesh(renderWindow)
@ -183,7 +199,6 @@ class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow
tempMesh.load() tempMesh.load()
currentHUDMesh = tempMesh currentHUDMesh = tempMesh
} }
hudShader.use()
currentHUDMesh.draw() currentHUDMesh.draw()
} }

View File

@ -20,6 +20,9 @@ import de.bixilon.minosoft.gui.rendering.Renderer
import de.bixilon.minosoft.gui.rendering.RendererBuilder import de.bixilon.minosoft.gui.rendering.RendererBuilder
import de.bixilon.minosoft.gui.rendering.modding.events.CameraMatrixChangeEvent import de.bixilon.minosoft.gui.rendering.modding.events.CameraMatrixChangeEvent
import de.bixilon.minosoft.gui.rendering.particle.types.Particle 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.gui.rendering.system.base.shader.Shader
import de.bixilon.minosoft.modding.event.invoker.CallbackEventInvoker import de.bixilon.minosoft.modding.event.invoker.CallbackEventInvoker
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
@ -32,24 +35,38 @@ import glm_.vec3.Vec3
class ParticleRenderer( class ParticleRenderer(
private val connection: PlayConnection, private val connection: PlayConnection,
val renderWindow: RenderWindow, override val renderWindow: RenderWindow,
) : Renderer { ) : Renderer, TransparentDrawable, TranslucentDrawable {
private val particleShader: Shader = renderWindow.renderSystem.createShader(ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "particle")) override val renderSystem: RenderSystem = renderWindow.renderSystem
private var particleMesh = ParticleMesh(renderWindow) private val transparentShader: Shader = renderSystem.createShader(ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "particle"))
private var transparentParticleMesh = ParticleMesh(renderWindow) 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<Particle> = synchronizedSetOf() private var particles: MutableSet<Particle> = synchronizedSetOf()
override fun init() { override fun init() {
connection.registerEvent(CallbackEventInvoker.of<CameraMatrixChangeEvent> { connection.registerEvent(CallbackEventInvoker.of<CameraMatrixChangeEvent> {
renderWindow.queue += { 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])) fun applyToShader(shader: Shader) {
particleShader.use().setVec3("uCameraUp", Vec3(it.viewMatrix[0][1], it.viewMatrix[1][1], it.viewMatrix[2][1])) 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() transparentMesh.load()
transparentParticleMesh.load() translucentMesh.load()
connection.registries.particleTypeRegistry.forEachItem { connection.registries.particleTypeRegistry.forEachItem {
for (resourceLocation in it.textures) { for (resourceLocation in it.textures) {
renderWindow.textureManager.staticTextures.createTexture(resourceLocation) renderWindow.textureManager.staticTextures.createTexture(resourceLocation)
@ -60,9 +77,15 @@ class ParticleRenderer(
} }
override fun postInit() { override fun postInit() {
particleShader.load() transparentShader.defines[Shader.TRANSPARENT_DEFINE] = ""
renderWindow.textureManager.staticTextures.use(particleShader) transparentShader.load()
renderWindow.textureManager.staticTextures.animator.use(particleShader) 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 connection.world.particleRenderer = this
} }
@ -76,11 +99,11 @@ class ParticleRenderer(
add(particle) add(particle)
} }
override fun update() { override fun prepareDraw() {
particleMesh.unload() transparentMesh.unload()
transparentParticleMesh.unload() translucentMesh.unload()
particleMesh = ParticleMesh(renderWindow) transparentMesh = ParticleMesh(renderWindow)
transparentParticleMesh = ParticleMesh(renderWindow) translucentMesh = ParticleMesh(renderWindow)
for (particle in particles.toSynchronizedSet()) { for (particle in particles.toSynchronizedSet()) {
@ -89,23 +112,29 @@ class ParticleRenderer(
this.particles -= particle this.particles -= particle
continue continue
} }
particle.addVertex(transparentParticleMesh, particleMesh) particle.addVertex(transparentMesh, translucentMesh)
} }
particleMesh.load() transparentMesh.load()
transparentParticleMesh.load() translucentMesh.load()
} }
override fun draw() { override fun setupTransparent() {
renderWindow.renderSystem.reset() super.setupTransparent()
particleShader.use() transparentShader.use()
particleMesh.draw()
} }
override fun postDraw() { override fun drawTransparent() {
renderWindow.renderSystem.reset(depthMask = false) transparentMesh.draw()
particleShader.use() }
transparentParticleMesh.draw()
override fun setupTranslucent() {
super.setupTranslucent()
translucentShader.use()
}
override fun drawTranslucent() {
translucentMesh.draw()
} }
companion object : RendererBuilder<ParticleRenderer> { companion object : RendererBuilder<ParticleRenderer> {

View File

@ -181,10 +181,10 @@ abstract class Particle(
} }
} }
abstract fun addVertex(transparentMesh: ParticleMesh, particleMesh: ParticleMesh) abstract fun addVertex(transparentMesh: ParticleMesh, translucentMesh: ParticleMesh)
companion object { 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 MAGIC_VELOCITY_CONSTANTf = MAGIC_VELOCITY_CONSTANT.toFloat()
private const val Y_VELOCITY_TO_CHECK = 9.999999747378752E-6f private const val Y_VELOCITY_TO_CHECK = 9.999999747378752E-6f
} }

View File

@ -21,5 +21,5 @@ import glm_.vec3.Vec3d
abstract class NoRenderParticle(connection: PlayConnection, position: Vec3d, velocity: Vec3d, data: ParticleData?) : Particle(connection, position, velocity, data) { 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) {}
} }

View File

@ -25,13 +25,11 @@ abstract class TextureParticle(connection: PlayConnection, position: Vec3d, velo
abstract val texture: AbstractTexture? abstract val texture: AbstractTexture?
override fun addVertex(transparentMesh: ParticleMesh, particleMesh: ParticleMesh) { override fun addVertex(transparentMesh: ParticleMesh, translucentMesh: ParticleMesh) {
texture?.let { val texture = texture ?: return
if (it.transparency == TextureTransparencies.TRANSLUCENT || color.alpha != 255) { when {
transparentMesh texture.transparency == TextureTransparencies.TRANSLUCENT || color.alpha != 255 -> translucentMesh
} else { else -> transparentMesh
particleMesh }.addVertex(cameraPosition, scale, texture, color)
}.addVertex(cameraPosition, scale, it, color)
}
} }
} }

View File

@ -25,13 +25,11 @@ abstract class AdvancedTextureParticle(connection: PlayConnection, position: Vec
var minUV: Vec2 = Vec2(0.0f, 0.0f) var minUV: Vec2 = Vec2(0.0f, 0.0f)
var maxUV: Vec2 = Vec2(1.0f, 1.0f) var maxUV: Vec2 = Vec2(1.0f, 1.0f)
override fun addVertex(transparentMesh: ParticleMesh, particleMesh: ParticleMesh) { override fun addVertex(transparentMesh: ParticleMesh, translucentMesh: ParticleMesh) {
texture?.let { val texture = texture ?: return
if (it.transparency == TextureTransparencies.TRANSLUCENT || color.alpha != 255) { when {
transparentMesh texture.transparency == TextureTransparencies.TRANSLUCENT || color.alpha != 255 -> translucentMesh
} else { else -> transparentMesh
particleMesh }.addVertex(cameraPosition, scale, texture, color, minUV, maxUV)
}.addVertex(cameraPosition, scale, it, color, minUV, maxUV)
}
} }
} }

View File

@ -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.modding.events.CameraMatrixChangeEvent
import de.bixilon.minosoft.gui.rendering.system.base.BlendingFunctions 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.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.system.base.texture.texture.AbstractTexture
import de.bixilon.minosoft.gui.rendering.util.mesh.SimpleTextureMesh import de.bixilon.minosoft.gui.rendering.util.mesh.SimpleTextureMesh
import de.bixilon.minosoft.modding.event.events.TimeChangeEvent import de.bixilon.minosoft.modding.event.events.TimeChangeEvent
@ -38,10 +40,11 @@ import glm_.vec3.Vec3d
class SkyRenderer( class SkyRenderer(
private val connection: PlayConnection, private val connection: PlayConnection,
val renderWindow: RenderWindow, override val renderWindow: RenderWindow,
) : Renderer { ) : Renderer, CustomDrawable {
private val skyboxShader = renderWindow.renderSystem.createShader(ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "sky/skybox")) override val renderSystem: RenderSystem = renderWindow.renderSystem
private val skySunShader = renderWindow.renderSystem.createShader(ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "sky/sun")) 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 val skyboxMesh = SkyboxMesh(renderWindow)
private var skySunMesh = SimpleTextureMesh(renderWindow) private var skySunMesh = SimpleTextureMesh(renderWindow)
private lateinit var sunTexture: AbstractTexture private lateinit var sunTexture: AbstractTexture
@ -138,7 +141,7 @@ class SkyRenderer(
skyboxMesh.draw() skyboxMesh.draw()
} }
override fun draw() { override fun drawCustom() {
renderWindow.renderSystem.reset(depth = DepthFunctions.LESS_OR_EQUAL) renderWindow.renderSystem.reset(depth = DepthFunctions.LESS_OR_EQUAL)
drawSkybox() drawSkybox()
drawSun() drawSun()

View File

@ -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 <https://www.gnu.org/licenses/>.
*
* 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,
;
}

View File

@ -89,14 +89,4 @@ interface RenderSystem {
fun createTextureManager(): TextureManager fun createTextureManager(): TextureManager
fun clear(vararg buffers: IntegratedBufferTypes) 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)
}
}
}
} }

View File

@ -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()
}

View File

@ -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()
}

View File

@ -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()
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*
* 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<T : Renderer>(
val type: KClass<T>,
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)
}
}

View File

@ -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()
}

View File

@ -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()
}

View File

@ -30,6 +30,7 @@ interface Shader {
val renderWindow: RenderWindow val renderWindow: RenderWindow
val resourceLocation: ResourceLocation val resourceLocation: ResourceLocation
val uniforms: List<String> val uniforms: List<String>
val defines: MutableMap<String, Any>
val log: String val log: String
@ -74,6 +75,7 @@ interface Shader {
} }
companion object { companion object {
const val TRANSPARENT_DEFINE = "TRANSPARENT"
val DEFAULT_DEFINES: Map<String, (renderWindow: RenderWindow) -> Any?> = mapOf( val DEFAULT_DEFINES: Map<String, (renderWindow: RenderWindow) -> Any?> = mapOf(
"ANIMATED_TEXTURE_COUNT" to { "ANIMATED_TEXTURE_COUNT" to {
max(it.textureManager.staticTextures.animator.size, 1) max(it.textureManager.staticTextures.animator.size, 1)

View File

@ -40,7 +40,7 @@ class OpenGLShader(
) : Shader { ) : Shader {
override var loaded: Boolean = false override var loaded: Boolean = false
private set private set
val defines: MutableMap<String, Any> = mutableMapOf() override val defines: MutableMap<String, Any> = mutableMapOf()
private var shader = -1 private var shader = -1
override var uniforms: MutableList<String> = mutableListOf() override var uniforms: MutableList<String> = mutableListOf()
private set private set

View File

@ -12,6 +12,7 @@
*/ */
package de.bixilon.minosoft.util package de.bixilon.minosoft.util
@Deprecated("Java only")
data class Pair<K, V>( data class Pair<K, V>(
val key: K, val key: K,
val value: V, val value: V,

View File

@ -41,7 +41,7 @@ void main() {
float fogFactor = getFogFactor(distance(uCameraPosition, finVertexPosition)); float fogFactor = getFogFactor(distance(uCameraPosition, finVertexPosition));
if (fogFactor != 1.0f) { 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 #endif
} }

View File

@ -43,4 +43,11 @@ void main() {
} }
foutColor = mix(texelColor1, texelColor2, finInterpolation) * finTintColor; foutColor = mix(texelColor1, texelColor2, finInterpolation) * finTintColor;
#ifndef TRANSPARENT
if (foutColor.a < 0.5){
discard;
}
#endif
} }

View File

@ -28,6 +28,6 @@ void main() {
if (finTintColor.a == 1.0f && texelColor.a == 0) { if (finTintColor.a == 1.0f && texelColor.a == 0) {
discard; discard;
} }
// outColor = vec4(0.0f, 1.0f, 1.0f, 1.0f); // foutColor = vec4(0.0f, 1.0f, 1.0f, 1.0f);
foutColor = texelColor * finTintColor; foutColor = texelColor * finTintColor;
} }

View File

@ -13,7 +13,7 @@
#version 330 core #version 330 core
out vec4 outColor; out vec4 foutColor;
flat in uint finTextureIndex1; flat in uint finTextureIndex1;
in vec3 finTextureCoordinates1; in vec3 finTextureCoordinates1;
@ -34,7 +34,7 @@ void work() {
} }
if (finInterpolation == 0.0f) { if (finInterpolation == 0.0f) {
outColor = firstTexelColor * finTintColor; foutColor = firstTexelColor * finTintColor;
return; return;
} }
@ -44,10 +44,10 @@ void work() {
discard; discard;
} }
outColor = mix(firstTexelColor, secondTexelColor, finInterpolation) * finTintColor; foutColor = mix(firstTexelColor, secondTexelColor, finInterpolation) * finTintColor;
#ifndef TRANSPARENT #ifndef TRANSPARENT
if (outColor.a < 0.5){ if (foutColor.a < 0.5){
discard; discard;
} }
#endif #endif