From 2fdad3dbce130ceb39ddfbf73ca6d436ac777997 Mon Sep 17 00:00:00 2001 From: Bixilon Date: Tue, 11 May 2021 18:07:27 +0200 Subject: [PATCH] wip improve shaders, replace all rendering callbacks with events --- .../minosoft/gui/input/camera/Camera.kt | 37 ++++------- .../minosoft/gui/rendering/RenderWindow.kt | 31 +++------- .../minosoft/gui/rendering/Renderer.kt | 6 +- .../minosoft/gui/rendering/Rendering.kt | 9 +++ .../gui/rendering/chunk/SectionArrayMesh.kt | 2 - .../gui/rendering/chunk/WorldRenderer.kt | 29 ++++----- .../minosoft/gui/rendering/hud/HUDMesh.kt | 2 +- .../minosoft/gui/rendering/hud/HUDRenderer.kt | 31 ++++------ .../hud/nodes/chat/ChatBoxHUDElement.kt | 18 +++--- .../hud/nodes/debug/HUDSystemDebugNode.kt | 14 ++--- .../modding/events/FrustumChangeEvent.kt} | 13 ++-- .../events/RenderEvent.kt} | 12 ++-- .../events/RenderingStateChangeEvent.kt | 2 +- .../events/ScreenResizeEvent.kt} | 14 +++-- .../minosoft/gui/rendering/shader/Shader.kt | 62 ++++++++++++------- .../minosoft/gui/rendering/sky/SkyMesh.kt | 2 - .../minosoft/gui/rendering/sky/SkyRenderer.kt | 19 +++--- .../minosoft/gui/rendering/util/Mesh.kt | 14 +++-- .../{chunk_fragment.glsl => chunk/chunk.fsh} | 0 .../{chunk_vertex.glsl => chunk/chunk.vsh} | 0 .../shader/{hud_fragment.glsl => hud/hud.fsh} | 0 .../shader/{hud_vertex.glsl => hud/hud.vsh} | 0 .../color/sky_color.fsh} | 0 .../color/sky_color.vsh} | 0 24 files changed, 159 insertions(+), 158 deletions(-) rename src/main/java/de/bixilon/minosoft/gui/{input/camera/FrustumChangeCallback.kt => rendering/modding/events/FrustumChangeEvent.kt} (68%) rename src/main/java/de/bixilon/minosoft/gui/rendering/{util/abstractions/ScreenResizeCallback.kt => modding/events/RenderEvent.kt} (72%) rename src/main/java/de/bixilon/minosoft/gui/{ => rendering}/modding/events/RenderingStateChangeEvent.kt (95%) rename src/main/java/de/bixilon/minosoft/gui/rendering/{shader/ShaderHolder.kt => modding/events/ScreenResizeEvent.kt} (67%) rename src/main/resources/assets/minosoft/rendering/shader/{chunk_fragment.glsl => chunk/chunk.fsh} (100%) rename src/main/resources/assets/minosoft/rendering/shader/{chunk_vertex.glsl => chunk/chunk.vsh} (100%) rename src/main/resources/assets/minosoft/rendering/shader/{hud_fragment.glsl => hud/hud.fsh} (100%) rename src/main/resources/assets/minosoft/rendering/shader/{hud_vertex.glsl => hud/hud.vsh} (100%) rename src/main/resources/assets/minosoft/rendering/shader/{sky_fragment.glsl => sky/color/sky_color.fsh} (100%) rename src/main/resources/assets/minosoft/rendering/shader/{sky_vertex.glsl => sky/color/sky_color.vsh} (100%) diff --git a/src/main/java/de/bixilon/minosoft/gui/input/camera/Camera.kt b/src/main/java/de/bixilon/minosoft/gui/input/camera/Camera.kt index 7e07c37a0..7e940dba8 100644 --- a/src/main/java/de/bixilon/minosoft/gui/input/camera/Camera.kt +++ b/src/main/java/de/bixilon/minosoft/gui/input/camera/Camera.kt @@ -20,13 +20,14 @@ import de.bixilon.minosoft.data.entities.entities.player.PlayerEntity import de.bixilon.minosoft.data.mappings.biomes.Biome import de.bixilon.minosoft.gui.rendering.RenderConstants import de.bixilon.minosoft.gui.rendering.RenderWindow -import de.bixilon.minosoft.gui.rendering.shader.Shader +import de.bixilon.minosoft.gui.rendering.modding.events.FrustumChangeEvent +import de.bixilon.minosoft.gui.rendering.modding.events.ScreenResizeEvent import de.bixilon.minosoft.gui.rendering.util.VecUtil import de.bixilon.minosoft.gui.rendering.util.VecUtil.blockPosition import de.bixilon.minosoft.gui.rendering.util.VecUtil.chunkPosition import de.bixilon.minosoft.gui.rendering.util.VecUtil.inChunkSectionPosition import de.bixilon.minosoft.gui.rendering.util.VecUtil.sectionHeight -import de.bixilon.minosoft.gui.rendering.util.abstractions.ScreenResizeCallback +import de.bixilon.minosoft.modding.event.CallbackEventInvoker import de.bixilon.minosoft.protocol.network.connection.PlayConnection import de.bixilon.minosoft.protocol.packets.c2s.play.PositionAndRotationC2SP import de.bixilon.minosoft.protocol.packets.c2s.play.PositionC2SP @@ -46,7 +47,7 @@ class Camera( val connection: PlayConnection, var fov: Float, val renderWindow: RenderWindow, -) : ScreenResizeCallback { +) { private var mouseSensitivity = Minosoft.getConfig().config.game.camera.moseSensitivity private val walkingSpeed get() = connection.player.baseAbilities.walkingSpeed * ProtocolDefinition.TICKS_PER_SECOND * 2 private val flyingSpeed get() = connection.player.baseAbilities.flyingSpeed * ProtocolDefinition.TICKS_PER_SECOND * 2 @@ -80,9 +81,6 @@ class Camera( val frustum: Frustum = Frustum(this) - private val shaders: MutableSet = mutableSetOf() - private val frustumChangeCallbacks: MutableSet = mutableSetOf() - var viewMatrix = calculateViewMatrix() private set @@ -135,10 +133,9 @@ class Camera( KeyBindingsNames.MOVE_JUMP, ) + connection.registerEvent(CallbackEventInvoker.of { recalculateViewProjectionMatrix() }) frustum.recalculate() - for (frustumChangeCallback in frustumChangeCallbacks) { - frustumChangeCallback.onFrustumChange() - } + connection.fireEvent(FrustumChangeEvent(renderWindow, frustum)) } fun handleInput(deltaTime: Double) { @@ -211,25 +208,15 @@ class Camera( } } - fun addShaders(vararg shaders: Shader) { - this.shaders.addAll(shaders) - } - - fun addFrustumChangeCallback(vararg shaders: FrustumChangeCallback) { - this.frustumChangeCallbacks.addAll(shaders) - } - - override fun onScreenResize(screenDimensions: Vec2i) { - recalculateViewProjectionMatrix() - } - private fun recalculateViewProjectionMatrix() { viewMatrix = calculateViewMatrix() projectionMatrix = calculateProjectionMatrix(renderWindow.screenDimensionsF) viewProjectionMatrix = projectionMatrix * viewMatrix lastMatrixChange = System.currentTimeMillis() - for (shader in shaders) { - shader.use().setMat4("viewProjectionMatrix", viewProjectionMatrix) + for (shader in renderWindow.shaders) { + if (shader.uniforms.contains("viewProjectionMatrix")) { + shader.use().setMat4("viewProjectionMatrix", viewProjectionMatrix) + } } positionChangeCallback() } @@ -244,9 +231,7 @@ class Camera( renderWindow.setSkyColor(connection.world.getBiome(blockPosition)?.skyColor ?: RenderConstants.DEFAULT_SKY_COLOR) frustum.recalculate() - for (frustumChangeCallback in frustumChangeCallbacks) { - frustumChangeCallback.onFrustumChange() - } + connection.fireEvent(FrustumChangeEvent(renderWindow, frustum)) connection.world.dimension?.hasSkyLight?.let { if (it) { 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 70f4418f2..913599160 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/RenderWindow.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/RenderWindow.kt @@ -18,20 +18,19 @@ import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames import de.bixilon.minosoft.data.mappings.ResourceLocation import de.bixilon.minosoft.data.text.RGBColor import de.bixilon.minosoft.data.text.RGBColor.Companion.asColor -import de.bixilon.minosoft.gui.input.camera.FrustumChangeCallback import de.bixilon.minosoft.gui.input.key.RenderWindowInputHandler -import de.bixilon.minosoft.gui.modding.events.RenderingStateChangeEvent import de.bixilon.minosoft.gui.rendering.chunk.WorldRenderer import de.bixilon.minosoft.gui.rendering.font.Font import de.bixilon.minosoft.gui.rendering.hud.HUDRenderer import de.bixilon.minosoft.gui.rendering.hud.atlas.TextureLike import de.bixilon.minosoft.gui.rendering.hud.atlas.TextureLikeTexture -import de.bixilon.minosoft.gui.rendering.shader.ShaderHolder +import de.bixilon.minosoft.gui.rendering.modding.events.RenderingStateChangeEvent +import de.bixilon.minosoft.gui.rendering.modding.events.ScreenResizeEvent +import de.bixilon.minosoft.gui.rendering.shader.Shader import de.bixilon.minosoft.gui.rendering.sky.SkyRenderer import de.bixilon.minosoft.gui.rendering.textures.Texture import de.bixilon.minosoft.gui.rendering.textures.TextureArray import de.bixilon.minosoft.gui.rendering.util.ScreenshotTaker -import de.bixilon.minosoft.gui.rendering.util.abstractions.ScreenResizeCallback import de.bixilon.minosoft.modding.event.CallbackEventInvoker import de.bixilon.minosoft.modding.event.events.ConnectionStateChangeEvent import de.bixilon.minosoft.modding.event.events.PacketReceiveEvent @@ -41,7 +40,6 @@ import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition import de.bixilon.minosoft.util.CountUpAndDownLatch import de.bixilon.minosoft.util.KUtil.synchronizedListOf import de.bixilon.minosoft.util.KUtil.synchronizedMapOf -import de.bixilon.minosoft.util.KUtil.synchronizedSetOf import de.bixilon.minosoft.util.Stopwatch import de.bixilon.minosoft.util.logging.Log import de.bixilon.minosoft.util.logging.LogMessageType @@ -84,11 +82,12 @@ class RenderWindow( val renderQueue: MutableList = synchronizedListOf() + + val shaders: MutableList = mutableListOf() + lateinit var WHITE_TEXTURE: TextureLike - val screenResizeCallbacks: MutableSet = synchronizedSetOf(inputHandler.camera) - var tickCount = 0L var lastTickTimer = System.currentTimeMillis() @@ -221,9 +220,6 @@ class RenderWindow( Log.log(LogMessageType.RENDERING_LOADING) { "Post loading renderer (${stopwatch.labTime()})..." } for (renderer in rendererMap.values) { renderer.postInit() - if (renderer is ShaderHolder) { - inputHandler.camera.addShaders(renderer.shader) - } } @@ -231,11 +227,10 @@ class RenderWindow( glfwSetWindowSizeCallback(windowId, object : GLFWWindowSizeCallback() { override fun invoke(window: Long, width: Int, height: Int) { glViewport(0, 0, width, height) + val previousSize = screenDimensions screenDimensions = Vec2i(width, height) screenDimensionsF = Vec2(screenDimensions) - for (callback in screenResizeCallbacks) { - callback.onScreenResize(screenDimensions) - } + connection.fireEvent(ScreenResizeEvent(previousScreenDimensions = previousSize, screenDimensions = screenDimensions)) } }) @@ -266,9 +261,7 @@ class RenderWindow( registerGlobalKeyCombinations() - for (callback in screenResizeCallbacks) { - callback.onScreenResize(screenDimensions) - } + connection.fireEvent(ScreenResizeEvent(previousScreenDimensions = Vec2i(0, 0), screenDimensions = screenDimensions)) Log.log(LogMessageType.RENDERING_LOADING) { "Rendering is fully prepared in ${stopwatch.totalTime()}" } @@ -392,12 +385,6 @@ class RenderWindow( fun registerRenderer(renderBuilder: RenderBuilder) { val renderer = renderBuilder.build(connection, this) rendererMap[renderBuilder.RESOURCE_LOCATION] = renderer - if (renderer is ScreenResizeCallback) { - screenResizeCallbacks.add(renderer) - } - if (renderer is FrustumChangeCallback) { - inputHandler.camera.addFrustumChangeCallback(renderer) - } } @Deprecated(message = "Will be replaced with SkyRenderer") 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 1f8e8fb70..7a6c3c203 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/Renderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/Renderer.kt @@ -14,7 +14,7 @@ package de.bixilon.minosoft.gui.rendering interface Renderer { - fun init() - fun postInit() - fun draw() + fun init() {} + fun postInit() {} + fun draw() {} } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/Rendering.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/Rendering.kt index 32c59fde1..37d103e40 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/Rendering.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/Rendering.kt @@ -29,10 +29,12 @@ class Rendering(private val connection: PlayConnection) { Thread({ try { Log.log(LogMessageType.RENDERING_GENERAL, LogLevels.INFO) { "Hello LWJGL ${Version.getVersion()}!" } + CONTEXT_MAP[Thread.currentThread()] = renderWindow renderWindow.init(latch) renderWindow.startRenderLoop() renderWindow.exit() } catch (exception: Throwable) { + CONTEXT_MAP.remove(Thread.currentThread()) exception.printStackTrace() try { renderWindow.exit() @@ -45,4 +47,11 @@ class Rendering(private val connection: PlayConnection) { } }, "Rendering").start() } + + companion object { + private val CONTEXT_MAP: MutableMap = mutableMapOf() + + val currentContext: RenderWindow? + get() = CONTEXT_MAP[Thread.currentThread()] + } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/SectionArrayMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/SectionArrayMesh.kt index dc9ddaafc..a4c6ea467 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/SectionArrayMesh.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/SectionArrayMesh.kt @@ -27,8 +27,6 @@ import org.lwjgl.opengl.GL20.glVertexAttribPointer class SectionArrayMesh : Mesh(initialCacheSize = 100000) { fun addVertex(position: Vec3, textureCoordinates: Vec2, texture: Texture, tintColor: RGBColor?, lightLevel: Int = 14) { - val data = data!! - val color = tintColor ?: ChatColors.WHITE val lightFactor = (lightLevel + 1) / MAX_LIGHT_LEVEL_FLOAT diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/WorldRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/WorldRenderer.kt index 6c6fa63e6..7a27046a3 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/WorldRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/WorldRenderer.kt @@ -25,11 +25,11 @@ import de.bixilon.minosoft.data.world.Chunk import de.bixilon.minosoft.data.world.ChunkSection import de.bixilon.minosoft.data.world.ChunkSection.Companion.indexPosition import de.bixilon.minosoft.data.world.World -import de.bixilon.minosoft.gui.input.camera.FrustumChangeCallback -import de.bixilon.minosoft.gui.modding.events.RenderingStateChangeEvent +import de.bixilon.minosoft.gui.input.camera.Frustum import de.bixilon.minosoft.gui.rendering.* +import de.bixilon.minosoft.gui.rendering.modding.events.FrustumChangeEvent +import de.bixilon.minosoft.gui.rendering.modding.events.RenderingStateChangeEvent import de.bixilon.minosoft.gui.rendering.shader.Shader -import de.bixilon.minosoft.gui.rendering.shader.ShaderHolder import de.bixilon.minosoft.gui.rendering.textures.Texture import de.bixilon.minosoft.gui.rendering.util.VecUtil.chunkPosition import de.bixilon.minosoft.gui.rendering.util.VecUtil.of @@ -52,11 +52,11 @@ import org.lwjgl.opengl.GL11.glDepthMask class WorldRenderer( private val connection: PlayConnection, val renderWindow: RenderWindow, -) : Renderer, ShaderHolder, FrustumChangeCallback { +) : Renderer { private val world: World = connection.world private val waterBlock = connection.mapping.blockRegistry.get(ResourceLocation("minecraft:water"))?.nullCast() - override lateinit var shader: Shader + lateinit var chunkShader: Shader val allChunkSections: MutableMap> = synchronizedMapOf() val visibleChunks: MutableMap> = synchronizedMapOf() val queuedChunks: MutableSet = synchronizedSetOf() @@ -160,19 +160,20 @@ class WorldRenderer( clearChunkCache() } }) + + connection.registerEvent(CallbackEventInvoker.of { onFrustumChange(it.frustum) }) } override fun postInit() { check(renderWindow.textures.animator.animatedTextures.size < 4096) { "Can not have more than 4096 animated textures!" } // uniform buffer limit: 16kb. 4 ints per texture - shader = Shader( - vertexPath = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "rendering/shader/chunk_vertex.glsl"), - fragmentPath = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "rendering/shader/chunk_fragment.glsl"), + chunkShader = Shader( + resourceLocation = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "chunk"), defines = mapOf("ANIMATED_TEXTURE_COUNT" to MMath.clamp(renderWindow.textures.animator.animatedTextures.size, 1, Int.MAX_VALUE)), ) - shader.load() + chunkShader.load() - renderWindow.textures.use(shader, "textureArray") - renderWindow.textures.animator.use(shader, "AnimatedDataBuffer") + renderWindow.textures.use(chunkShader, "textureArray") + renderWindow.textures.animator.use(chunkShader, "AnimatedDataBuffer") for (blockState in allBlocks!!) { for (model in blockState.renderers) { @@ -183,7 +184,7 @@ class WorldRenderer( } override fun draw() { - shader.use() + chunkShader.use() val visibleChunks = visibleChunks.toSynchronizedMap() for ((_, map) in visibleChunks) { @@ -398,13 +399,13 @@ class WorldRenderer( prepareWorld(connection.world) } - override fun onFrustumChange() { + private fun onFrustumChange(frustum: Frustum) { visibleChunks.clear() for ((chunkLocation, rawIndexMap) in allChunkSections.toSynchronizedMap()) { val visibleIndexMap: MutableMap = synchronizedMapOf() val indexMap = rawIndexMap.toMap() for ((index, mesh) in indexMap) { - if (renderWindow.inputHandler.camera.frustum.containsChunk(chunkLocation, mesh.lowestBlockHeight, mesh.highestBlockHeight)) { + if (frustum.containsChunk(chunkLocation, mesh.lowestBlockHeight, mesh.highestBlockHeight)) { visibleIndexMap[index] = mesh } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/HUDMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/HUDMesh.kt index bb4953a05..fc39c0c51 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/HUDMesh.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/HUDMesh.kt @@ -35,7 +35,7 @@ class HUDMesh : Mesh() { } fun addCacheMesh(cacheMesh: HUDCacheMesh) { - data!!.addAll(cacheMesh.cache) + data.addAll(cacheMesh.cache) } 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 e742eb856..3201986fc 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 @@ -26,8 +26,9 @@ import de.bixilon.minosoft.gui.rendering.hud.nodes.HUDElement 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.ScreenResizeEvent import de.bixilon.minosoft.gui.rendering.shader.Shader -import de.bixilon.minosoft.gui.rendering.util.abstractions.ScreenResizeCallback +import de.bixilon.minosoft.modding.event.CallbackEventInvoker import de.bixilon.minosoft.protocol.network.connection.PlayConnection import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition import de.bixilon.minosoft.util.MMath @@ -36,12 +37,11 @@ import glm_.glm import glm_.mat4x4.Mat4 import glm_.vec2.Vec2i -class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow) : Renderer, ScreenResizeCallback { +class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow) : Renderer { private val hudElements: MutableMap> = mutableMapOf() private val enabledHUDElement: MutableMap> = mutableMapOf() private val hudShader = Shader( - vertexPath = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "rendering/shader/hud_vertex.glsl"), - fragmentPath = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "rendering/shader/hud_fragment.glsl"), + resourceLocation = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "hud"), ) lateinit var hudAtlasElements: Map var orthographicMatrix: Mat4 = Mat4() @@ -74,6 +74,13 @@ class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow renderWindow.inputHandler.registerKeyCallback(KeyBindingsNames.CLOSE) { } + + connection.registerEvent(CallbackEventInvoker.of { + orthographicMatrix = glm.ortho(-it.screenDimensions.x / 2.0f, it.screenDimensions.x / 2.0f, -it.screenDimensions.y / 2.0f, it.screenDimensions.y / 2.0f) + for ((_, hudElement) in hudElements.values) { + hudElement.layout.clearChildrenCache() + } + }) } private fun registerDefaultElements() { @@ -95,9 +102,6 @@ class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow } val hudElement = builder.build(this) hudElement.properties = properties - if (hudElement is ScreenResizeCallback) { - renderWindow.screenResizeCallbacks.add(hudElement) - } val pair = Pair(properties, hudElement) hudElements[builder.RESOURCE_LOCATION] = pair @@ -124,12 +128,6 @@ class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow fun removeElement(resourceLocation: ResourceLocation) { val element = hudElements[resourceLocation] ?: return - element.second.let { - if (it is ScreenResizeCallback) { - renderWindow.screenResizeCallbacks.remove(it) - } - } - element.first.toggleKeyBinding?.let { renderWindow.inputHandler.unregisterKeyBinding(it) } @@ -150,13 +148,6 @@ class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow } } - override fun onScreenResize(screenDimensions: Vec2i) { - orthographicMatrix = glm.ortho(-screenDimensions.x / 2.0f, screenDimensions.x / 2.0f, -screenDimensions.y / 2.0f, screenDimensions.y / 2.0f) - for ((_, hudElement) in hudElements.values) { - hudElement.layout.clearChildrenCache() - } - } - override fun draw() { if (!RenderConstants.RENDER_HUD) { return diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/nodes/chat/ChatBoxHUDElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/nodes/chat/ChatBoxHUDElement.kt index 00d60a959..d80776b70 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/nodes/chat/ChatBoxHUDElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/nodes/chat/ChatBoxHUDElement.kt @@ -23,11 +23,12 @@ import de.bixilon.minosoft.gui.rendering.hud.elements.input.TextField import de.bixilon.minosoft.gui.rendering.hud.elements.input.TextFieldProperties import de.bixilon.minosoft.gui.rendering.hud.nodes.HUDElement import de.bixilon.minosoft.gui.rendering.hud.nodes.layout.AbsoluteLayout -import de.bixilon.minosoft.gui.rendering.util.abstractions.ScreenResizeCallback +import de.bixilon.minosoft.gui.rendering.modding.events.ScreenResizeEvent +import de.bixilon.minosoft.modding.event.CallbackEventInvoker import glm_.vec2.Vec2 import glm_.vec2.Vec2i -class ChatBoxHUDElement(hudRenderer: HUDRenderer) : HUDElement(hudRenderer), ScreenResizeCallback { +class ChatBoxHUDElement(hudRenderer: HUDRenderer) : HUDElement(hudRenderer) { override val layout = AbsoluteLayout(hudRenderer.renderWindow) private lateinit var inputField: TextField @@ -48,13 +49,12 @@ class ChatBoxHUDElement(hudRenderer: HUDRenderer) : HUDElement(hudRenderer), Scr hudRenderer.renderWindow.inputHandler.registerKeyCallback(KeyBindingsNames.OPEN_CHAT) { openChat() } - } - - override fun onScreenResize(screenDimensions: Vec2i) { - layout.sizing.minSize.x = screenDimensions.x - layout.sizing.maxSize.x = screenDimensions.x - inputField.textElement.setProperties.hardWrap = (inputField.textElement.sizing.minSize.x / scale).toInt() - layout.apply() + hudRenderer.connection.registerEvent(CallbackEventInvoker.of { + layout.sizing.minSize.x = it.screenDimensions.x + layout.sizing.maxSize.x = it.screenDimensions.x + inputField.textElement.setProperties.hardWrap = (inputField.textElement.sizing.minSize.x / scale).toInt() + layout.apply() + }) } fun openChat() { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/nodes/debug/HUDSystemDebugNode.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/nodes/debug/HUDSystemDebugNode.kt index 2b5e59157..75bd726fa 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/nodes/debug/HUDSystemDebugNode.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/nodes/debug/HUDSystemDebugNode.kt @@ -19,18 +19,18 @@ import de.bixilon.minosoft.gui.rendering.hud.HUDElementProperties import de.bixilon.minosoft.gui.rendering.hud.HUDRenderBuilder import de.bixilon.minosoft.gui.rendering.hud.HUDRenderer import de.bixilon.minosoft.gui.rendering.hud.nodes.properties.NodeAlignment -import de.bixilon.minosoft.gui.rendering.util.abstractions.ScreenResizeCallback +import de.bixilon.minosoft.gui.rendering.modding.events.ScreenResizeEvent +import de.bixilon.minosoft.modding.event.CallbackEventInvoker import de.bixilon.minosoft.modding.loading.ModLoader import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition import de.bixilon.minosoft.util.GitInfo import de.bixilon.minosoft.util.SystemInformation import de.bixilon.minosoft.util.UnitFormatter import glm_.vec2.Vec2 -import glm_.vec2.Vec2i import org.lwjgl.opengl.GL11.* -class HUDSystemDebugNode(hudRenderer: HUDRenderer) : DebugScreenNode(hudRenderer), ScreenResizeCallback { +class HUDSystemDebugNode(hudRenderer: HUDRenderer) : DebugScreenNode(hudRenderer) { init { layout.sizing.forceAlign = NodeAlignment.RIGHT @@ -67,13 +67,13 @@ class HUDSystemDebugNode(hudRenderer: HUDRenderer) : DebugScreenNode(hudRenderer text("Mods: ${ModLoader.MOD_MAP.size} active, ${hudRenderer.connection.eventListenerSize} listeners") } - override fun onScreenResize(screenDimensions: Vec2i) { - displayText.sText = "Display: ${getScreenDimensions()}" - } - override fun init() { gpuText.sText = "GPU: " + (glGetString(GL_RENDERER) ?: "unknown") gpuVersionText.sText = "Version: " + (glGetString(GL_VERSION) ?: "unknown") + + hudRenderer.connection.registerEvent(CallbackEventInvoker.of { + displayText.sText = "Display: ${getScreenDimensions()}" + }) } override fun draw() { diff --git a/src/main/java/de/bixilon/minosoft/gui/input/camera/FrustumChangeCallback.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/FrustumChangeEvent.kt similarity index 68% rename from src/main/java/de/bixilon/minosoft/gui/input/camera/FrustumChangeCallback.kt rename to src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/FrustumChangeEvent.kt index 5e39c22b6..85ac917f4 100644 --- a/src/main/java/de/bixilon/minosoft/gui/input/camera/FrustumChangeCallback.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/FrustumChangeEvent.kt @@ -11,8 +11,13 @@ * This software is not affiliated with Mojang AB, the original developer of Minecraft. */ -package de.bixilon.minosoft.gui.input.camera +package de.bixilon.minosoft.gui.rendering.modding.events -interface FrustumChangeCallback { - fun onFrustumChange() -} +import de.bixilon.minosoft.gui.input.camera.Frustum +import de.bixilon.minosoft.gui.rendering.RenderWindow +import de.bixilon.minosoft.gui.rendering.Rendering + +class FrustumChangeEvent( + renderWindow: RenderWindow = Rendering.currentContext!!, + val frustum: Frustum, +) : RenderEvent(renderWindow) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/util/abstractions/ScreenResizeCallback.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/RenderEvent.kt similarity index 72% rename from src/main/java/de/bixilon/minosoft/gui/rendering/util/abstractions/ScreenResizeCallback.kt rename to src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/RenderEvent.kt index bd4b6fca0..7e41ebc92 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/util/abstractions/ScreenResizeCallback.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/RenderEvent.kt @@ -11,11 +11,11 @@ * This software is not affiliated with Mojang AB, the original developer of Minecraft. */ -package de.bixilon.minosoft.gui.rendering.util.abstractions +package de.bixilon.minosoft.gui.rendering.modding.events -import glm_.vec2.Vec2i +import de.bixilon.minosoft.gui.rendering.RenderWindow +import de.bixilon.minosoft.modding.event.events.PlayConnectionEvent -interface ScreenResizeCallback { - - fun onScreenResize(screenDimensions: Vec2i) {} -} +abstract class RenderEvent( + val renderWindow: RenderWindow, +) : PlayConnectionEvent(renderWindow.connection) diff --git a/src/main/java/de/bixilon/minosoft/gui/modding/events/RenderingStateChangeEvent.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/RenderingStateChangeEvent.kt similarity index 95% rename from src/main/java/de/bixilon/minosoft/gui/modding/events/RenderingStateChangeEvent.kt rename to src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/RenderingStateChangeEvent.kt index 6fbd8775f..c84397b0f 100644 --- a/src/main/java/de/bixilon/minosoft/gui/modding/events/RenderingStateChangeEvent.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/RenderingStateChangeEvent.kt @@ -11,7 +11,7 @@ * This software is not affiliated with Mojang AB, the original developer of Minecraft. */ -package de.bixilon.minosoft.gui.modding.events +package de.bixilon.minosoft.gui.rendering.modding.events import de.bixilon.minosoft.gui.rendering.RenderingStates import de.bixilon.minosoft.modding.event.events.PlayConnectionEvent diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/shader/ShaderHolder.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/ScreenResizeEvent.kt similarity index 67% rename from src/main/java/de/bixilon/minosoft/gui/rendering/shader/ShaderHolder.kt rename to src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/ScreenResizeEvent.kt index 60ccabafd..497e3d944 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/shader/ShaderHolder.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/modding/events/ScreenResizeEvent.kt @@ -11,8 +11,14 @@ * This software is not affiliated with Mojang AB, the original developer of Minecraft. */ -package de.bixilon.minosoft.gui.rendering.shader +package de.bixilon.minosoft.gui.rendering.modding.events -interface ShaderHolder { - val shader: Shader -} +import de.bixilon.minosoft.gui.rendering.RenderWindow +import de.bixilon.minosoft.gui.rendering.Rendering +import glm_.vec2.Vec2i + +class ScreenResizeEvent( + renderWindow: RenderWindow = Rendering.currentContext!!, + val previousScreenDimensions: Vec2i, + val screenDimensions: Vec2i, +) : RenderEvent(renderWindow) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/shader/Shader.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/shader/Shader.kt index d58b6d8c8..8e2e3dbc1 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/shader/Shader.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/shader/Shader.kt @@ -15,7 +15,9 @@ package de.bixilon.minosoft.gui.rendering.shader import de.bixilon.minosoft.Minosoft import de.bixilon.minosoft.data.assets.AssetsManager +import de.bixilon.minosoft.data.commands.CommandStringReader import de.bixilon.minosoft.data.mappings.ResourceLocation +import de.bixilon.minosoft.gui.rendering.Rendering import de.bixilon.minosoft.gui.rendering.exceptions.ShaderLoadingException import de.bixilon.minosoft.gui.rendering.util.OpenGLUtil import glm_.mat4x4.Mat4 @@ -30,19 +32,23 @@ import org.lwjgl.opengl.ARBVertexShader.GL_VERTEX_SHADER_ARB import org.lwjgl.opengl.GL11.GL_FALSE import org.lwjgl.opengl.GL43.* import org.lwjgl.system.MemoryUtil +import java.io.FileNotFoundException class Shader( - private val vertexPath: ResourceLocation, - private val geometryPath: ResourceLocation? = null, - private val fragmentPath: ResourceLocation, + private val resourceLocation: ResourceLocation, private val defines: Map = mapOf(), ) { + lateinit var uniforms: List + private set private var programId = 0 fun load(assetsManager: AssetsManager = Minosoft.MINOSOFT_ASSETS_MANAGER): Int { - val vertexShader = createShader(assetsManager, vertexPath, GL_VERTEX_SHADER_ARB, defines) - val geometryShader = geometryPath?.let { createShader(assetsManager, it, GL_GEOMETRY_SHADER_ARB, defines) } - val fragmentShader = createShader(assetsManager, fragmentPath, GL_FRAGMENT_SHADER_ARB, defines) + val uniforms: MutableList = mutableListOf() + val pathPrefix = resourceLocation.namespace + ":rendering/shader/" + resourceLocation.path + "/" + resourceLocation.path.replace("/", "_") + val vertexShader = createShader(assetsManager, ResourceLocation("$pathPrefix.vsh"), GL_VERTEX_SHADER_ARB, defines, uniforms)!! + val geometryShader = createShader(assetsManager, ResourceLocation("$pathPrefix.gsh"), GL_GEOMETRY_SHADER_ARB, defines, uniforms) + val fragmentShader = createShader(assetsManager, ResourceLocation("$pathPrefix.fsh"), GL_FRAGMENT_SHADER_ARB, defines, uniforms)!! + this.uniforms = uniforms.toList() programId = glCreateProgramObjectARB() if (programId.toLong() == MemoryUtil.NULL) { @@ -71,13 +77,15 @@ class Shader( } glDeleteShader(fragmentShader) + val context = Rendering.currentContext!! + context.shaders.add(this) return programId } fun use(): Shader { - if (usedShader !== this) { + if (currentShaderInUse !== this) { glUseProgram(programId) - usedShader = this + currentShaderInUse = this } return this } @@ -142,30 +150,42 @@ class Shader( companion object { - private var usedShader: Shader? = null + private var currentShaderInUse: Shader? = null - - private fun createShader(assetsManager: AssetsManager = Minosoft.MINOSOFT_ASSETS_MANAGER, resourceLocation: ResourceLocation, shaderType: Int, defines: Map): Int { + private fun createShader(assetsManager: AssetsManager = Minosoft.MINOSOFT_ASSETS_MANAGER, resourceLocation: ResourceLocation, shaderType: Int, defines: Map, uniforms: MutableList): Int? { val shaderId = glCreateShaderObjectARB(shaderType) if (shaderId.toLong() == MemoryUtil.NULL) { throw ShaderLoadingException() } val total = StringBuilder() - val lines = assetsManager.readStringAsset(resourceLocation).lines() + val lines = try { + assetsManager.readStringAsset(resourceLocation).lines() + } catch (exception: FileNotFoundException) { + return null + } for (line in lines) { total.append(line) total.append('\n') - if (line.startsWith("#version")) { - - // add all defines - total.append('\n') - for ((define, value) in defines) { - total.append("#define ") - total.append(define) - total.append(' ') - total.append(value) + val reader = CommandStringReader(line) + when { + line.startsWith("#version") -> { + // add all defines total.append('\n') + for ((define, value) in defines) { + total.append("#define ") + total.append(define) + total.append(' ') + total.append(value) + total.append('\n') + } + } + line.startsWith("uniform ") -> { // ToDo: Packed in layout + reader.readUnquotedString() // "uniform" + reader.skipWhitespaces() + reader.readUnquotedString() // datatype + reader.skipWhitespaces() + uniforms.add(reader.readString()) // uniform name } } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/sky/SkyMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/sky/SkyMesh.kt index 7a92b0c71..109d56653 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/sky/SkyMesh.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/sky/SkyMesh.kt @@ -22,8 +22,6 @@ import org.lwjgl.opengl.GL20.glVertexAttribPointer class SkyMesh : Mesh(initialCacheSize = 6 * 2 * 3 * FLOATS_PER_VERTEX) { fun addVertex(position: Vec3) { - val data = data!! - data.addAll(floatArrayOf( position.x, position.y, 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 5d8cb40fb..b3d435d01 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 @@ -18,7 +18,6 @@ import de.bixilon.minosoft.gui.rendering.RenderBuilder import de.bixilon.minosoft.gui.rendering.RenderWindow import de.bixilon.minosoft.gui.rendering.Renderer import de.bixilon.minosoft.gui.rendering.shader.Shader -import de.bixilon.minosoft.gui.rendering.shader.ShaderHolder import de.bixilon.minosoft.protocol.network.connection.PlayConnection import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition import org.lwjgl.opengl.GL11.* @@ -26,39 +25,35 @@ import org.lwjgl.opengl.GL11.* class SkyRenderer( private val connection: PlayConnection, val renderWindow: RenderWindow, -) : Renderer, ShaderHolder { +) : Renderer { private var lastMatrixUpdate = System.currentTimeMillis() - override val shader = Shader( - vertexPath = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "rendering/shader/sky_vertex.glsl"), - fragmentPath = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "rendering/shader/sky_fragment.glsl"), + private val skyColorShader = Shader( + resourceLocation = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "sky/color"), ) private val mesh = SkyMesh() init { - mesh.data!!.addAll(VERTICES) + mesh.data.addAll(VERTICES) } override fun init() { - shader.load() + skyColorShader.load() mesh.load() } - override fun postInit() { - } - private fun setShaderMatrix() { if (lastMatrixUpdate == renderWindow.inputHandler.camera.lastMatrixChange) { return } - shader.use().setMat4("skyViewProjectionMatrix", renderWindow.inputHandler.camera.projectionMatrix * renderWindow.inputHandler.camera.viewMatrix.toMat3().toMat4()) + skyColorShader.use().setMat4("skyViewProjectionMatrix", renderWindow.inputHandler.camera.projectionMatrix * renderWindow.inputHandler.camera.viewMatrix.toMat3().toMat4()) lastMatrixUpdate = renderWindow.inputHandler.camera.lastMatrixChange } override fun draw() { glDepthFunc(GL_LEQUAL) - shader.use() + skyColorShader.use() setShaderMatrix() mesh.draw() glDepthFunc(GL_LESS) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/util/Mesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/util/Mesh.kt index ca6a4248c..739565969 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/util/Mesh.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/util/Mesh.kt @@ -21,7 +21,13 @@ import org.lwjgl.opengl.GL30.* abstract class Mesh( initialCacheSize: Int = 10000, ) { - var data: ArrayFloatList? = ArrayFloatList(initialCacheSize) + private var _data: ArrayFloatList? = ArrayFloatList(initialCacheSize) + var data: ArrayFloatList + get() = _data!! + set(value) { + _data = value + } + private var vao: Int = -1 private var vbo: Int = -1 var trianglesCount: Int = -1 @@ -36,16 +42,16 @@ abstract class Mesh( protected fun initializeBuffers(floatsPerVertex: Int) { check(state == MeshStates.PREPARING) { "Mesh already loaded: $state" } - trianglesCount = data!!.size / floatsPerVertex + trianglesCount = data.size / floatsPerVertex vao = glGenVertexArrays() vbo = glGenBuffers() glBindVertexArray(vao) glBindBuffer(GL_ARRAY_BUFFER, vbo) - glBufferData(GL_ARRAY_BUFFER, data!!.toArray(), GL_STATIC_DRAW) + glBufferData(GL_ARRAY_BUFFER, data.toArray(), GL_STATIC_DRAW) state = MeshStates.LOADED - data = null + _data = null } protected fun unbind() { diff --git a/src/main/resources/assets/minosoft/rendering/shader/chunk_fragment.glsl b/src/main/resources/assets/minosoft/rendering/shader/chunk/chunk.fsh similarity index 100% rename from src/main/resources/assets/minosoft/rendering/shader/chunk_fragment.glsl rename to src/main/resources/assets/minosoft/rendering/shader/chunk/chunk.fsh diff --git a/src/main/resources/assets/minosoft/rendering/shader/chunk_vertex.glsl b/src/main/resources/assets/minosoft/rendering/shader/chunk/chunk.vsh similarity index 100% rename from src/main/resources/assets/minosoft/rendering/shader/chunk_vertex.glsl rename to src/main/resources/assets/minosoft/rendering/shader/chunk/chunk.vsh diff --git a/src/main/resources/assets/minosoft/rendering/shader/hud_fragment.glsl b/src/main/resources/assets/minosoft/rendering/shader/hud/hud.fsh similarity index 100% rename from src/main/resources/assets/minosoft/rendering/shader/hud_fragment.glsl rename to src/main/resources/assets/minosoft/rendering/shader/hud/hud.fsh diff --git a/src/main/resources/assets/minosoft/rendering/shader/hud_vertex.glsl b/src/main/resources/assets/minosoft/rendering/shader/hud/hud.vsh similarity index 100% rename from src/main/resources/assets/minosoft/rendering/shader/hud_vertex.glsl rename to src/main/resources/assets/minosoft/rendering/shader/hud/hud.vsh diff --git a/src/main/resources/assets/minosoft/rendering/shader/sky_fragment.glsl b/src/main/resources/assets/minosoft/rendering/shader/sky/color/sky_color.fsh similarity index 100% rename from src/main/resources/assets/minosoft/rendering/shader/sky_fragment.glsl rename to src/main/resources/assets/minosoft/rendering/shader/sky/color/sky_color.fsh diff --git a/src/main/resources/assets/minosoft/rendering/shader/sky_vertex.glsl b/src/main/resources/assets/minosoft/rendering/shader/sky/color/sky_color.vsh similarity index 100% rename from src/main/resources/assets/minosoft/rendering/shader/sky_vertex.glsl rename to src/main/resources/assets/minosoft/rendering/shader/sky/color/sky_color.vsh