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 52f183bc2..48463138c 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,8 +33,10 @@ 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.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 @@ -62,6 +64,7 @@ class WorldRenderer( 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 lightMap = LightMap(connection) val allChunkSections: SynchronizedMap> = synchronizedMapOf() @@ -118,8 +121,12 @@ class WorldRenderer( } } - if (meshCollection.transparentSectionArrayMesh!!.data.isEmpty) { - meshCollection.transparentSectionArrayMesh = null + if (meshCollection.translucentMesh!!.data.isEmpty) { + meshCollection.translucentMesh = null + } + + if (meshCollection.transparentMesh!!.data.isEmpty) { + meshCollection.transparentMesh = null } return meshCollection } @@ -180,11 +187,15 @@ 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) renderWindow.textureManager.staticTextures.animator.use(chunkShader) lightMap.use(chunkShader) + lightMap.use(transparentShader) for (blockState in allBlocks!!) { for (model in blockState.renderers) { @@ -205,18 +216,28 @@ class WorldRenderer( for (map in lastVisibleChunks.values) { for (mesh in map.values) { - mesh.opaqueSectionArrayMesh.draw() + mesh.opaqueMesh.draw() } } } override fun postDraw() { - renderWindow.renderSystem.reset(depthMask = false) - chunkShader.use() + renderWindow.renderSystem.reset() + transparentShader.use() + for (map in lastVisibleChunks.values) { for (mesh in map.values) { - mesh.transparentSectionArrayMesh?.draw() + mesh.transparentMesh?.draw() + } + } + + chunkShader.use() + renderWindow.renderSystem.renderMode(RenderModes.TRANSLUCENT) + + for (map in lastVisibleChunks.values) { + for (mesh in map.values) { + mesh.translucentMesh?.draw() } } } @@ -329,23 +350,33 @@ class WorldRenderer( val sectionMap = allChunkSections.getOrPut(chunkPosition) { synchronizedMapOf() } sectionMap[index]?.let { - it.opaqueSectionArrayMesh.unload() + it.opaqueMesh.unload() meshes-- - triangles -= it.opaqueSectionArrayMesh.vertices + triangles -= it.opaqueMesh.vertices - it.transparentSectionArrayMesh?.let { + it.translucentMesh?.let { + it.unload() + meshes-- + triangles -= it.vertices + } + it.transparentMesh?.let { it.unload() meshes-- triangles -= it.vertices } } - meshCollection.opaqueSectionArrayMesh.let { + meshCollection.opaqueMesh.let { it.load() meshes++ triangles += it.vertices } - meshCollection.transparentSectionArrayMesh?.let { + meshCollection.translucentMesh?.let { + it.load() + meshes++ + triangles += it.vertices + } + meshCollection.transparentMesh?.let { it.load() meshes++ triangles += it.vertices @@ -410,12 +441,17 @@ class WorldRenderer( private fun unloadMeshes(meshes: Collection) { renderWindow.assertOnRenderThread() for (meshCollection in meshes) { - meshCollection.opaqueSectionArrayMesh.let { + meshCollection.opaqueMesh.let { it.unload() this.meshes-- triangles -= it.vertices } - meshCollection.transparentSectionArrayMesh?.let { + meshCollection.translucentMesh?.let { + it.unload() + this.meshes-- + triangles -= it.vertices + } + meshCollection.transparentMesh?.let { it.unload() this.meshes-- triangles -= it.vertices diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/block/mesh/ChunkSectionMeshCollection.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/block/mesh/ChunkSectionMeshCollection.kt index a02481b94..69e5ab11c 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/block/mesh/ChunkSectionMeshCollection.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/block/mesh/ChunkSectionMeshCollection.kt @@ -17,8 +17,9 @@ import de.bixilon.minosoft.gui.rendering.RenderWindow class ChunkSectionMeshCollection( renderWindow: RenderWindow, - val opaqueSectionArrayMesh: ChunkSectionArrayMesh = ChunkSectionArrayMesh(renderWindow), - var transparentSectionArrayMesh: ChunkSectionArrayMesh? = ChunkSectionArrayMesh(renderWindow), + val opaqueMesh: ChunkSectionArrayMesh = ChunkSectionArrayMesh(renderWindow), + var translucentMesh: ChunkSectionArrayMesh? = ChunkSectionArrayMesh(renderWindow), + var transparentMesh: ChunkSectionArrayMesh? = ChunkSectionArrayMesh(renderWindow), ) { var lowestBlockHeight = 0 var highestBlockHeight = 0 diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/block/renderable/block/ElementRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/block/renderable/block/ElementRenderer.kt index a243d4392..dce59a574 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/block/renderable/block/ElementRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/block/renderable/block/ElementRenderer.kt @@ -168,11 +168,11 @@ class ElementRenderer( val DRAW_OFFSET = Vec3(+0.5f, +0.5f, +0.5f) - fun getMesh(meshCollection: ChunkSectionMeshCollection, textureTransparencies: TextureTransparencies): ChunkSectionArrayMesh { - return if (textureTransparencies == TextureTransparencies.TRANSLUCENT) { - meshCollection.transparentSectionArrayMesh!! - } else { - meshCollection.opaqueSectionArrayMesh + fun getMesh(meshCollection: ChunkSectionMeshCollection, transparency: TextureTransparencies): ChunkSectionArrayMesh { + return when (transparency) { + TextureTransparencies.OPAQUE -> meshCollection.opaqueMesh + TextureTransparencies.TRANSPARENT -> meshCollection.transparentMesh!! + TextureTransparencies.TRANSLUCENT -> meshCollection.translucentMesh!! } } } 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 new file mode 100644 index 000000000..5b328c60f --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/RenderModes.kt @@ -0,0 +1,20 @@ +/* + * 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 0cbecd78c..1fcd8cdc0 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,4 +89,14 @@ 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/texture/SpriteAnimator.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/SpriteAnimator.kt index c4835ace3..999b41109 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/SpriteAnimator.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/SpriteAnimator.kt @@ -23,5 +23,5 @@ interface SpriteAnimator { fun draw() - fun use(shader: Shader, bufferName: String = "uAnimationBuffer") + fun use(shader: Shader, bufferName: String = "uSpriteBuffer") } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/texture/OpenGLTextureArray.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/texture/OpenGLTextureArray.kt index b52d757eb..4ab5e274a 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/texture/OpenGLTextureArray.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/texture/OpenGLTextureArray.kt @@ -189,7 +189,7 @@ class OpenGLTextureArray( companion object { - val TEXTURE_RESOLUTION_ID_MAP = arrayOf(16, 32, 64, 128, 256, 512, 1024) // A 12x12 texture will be saved in texture id 0 (in 0 are only 16x16 textures). Animated textures get split + val TEXTURE_RESOLUTION_ID_MAP = intArrayOf(16, 32, 64, 128, 256, 512, 1024) // A 12x12 texture will be saved in texture id 0 (in 0 are only 16x16 textures). Animated textures get split const val TEXTURE_MAX_RESOLUTION = 1024 const val MAX_MIPMAP_LEVELS = 5 } 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 ee405e536..d61445ef5 100644 --- a/src/main/resources/assets/minosoft/rendering/shader/world/world.fsh +++ b/src/main/resources/assets/minosoft/rendering/shader/world/world.fsh @@ -45,6 +45,12 @@ void work() { } outColor = mix(firstTexelColor, secondTexelColor, finInterpolation) * finTintColor; + + #ifndef TRANSPARENT + if (outColor.a < 0.5){ + discard; + } + #endif } -#include "minosoft:postprocessing/fragment" + #include "minosoft:postprocessing/fragment"