restructure hud renderer

This commit is contained in:
Bixilon 2021-10-24 19:58:02 +02:00
parent f1ca745c50
commit 1dc2323073
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
14 changed files with 181 additions and 72 deletions

View File

@ -0,0 +1,21 @@
/*
* 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
interface Drawable {
/**
* Functions gets called every frame
*/
fun draw()
}

View File

@ -0,0 +1,45 @@
/*
* 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.gui.hud
import de.bixilon.minosoft.gui.rendering.RenderWindow
interface HUDElement {
val hudRenderer: HUDRenderer
val renderWindow: RenderWindow
var enabled: Boolean
/**
* Initializes the element (e.g. getting atlas elements, creating shaders, creating textures, etc)
*/
fun init() {}
/**
* Phase after everything is initialized. May be used to load shaders, ...
* Can not be used to load static textures
*/
fun postInit() {}
/**
* Functions that gets called every tick
*/
fun tick() {}
/**
* Functions that sets new texts, changes data in the element
* May be used to poll data (see Pollable)
*/
fun apply() {}
}

View File

@ -18,17 +18,25 @@ import de.bixilon.minosoft.config.key.KeyAction
import de.bixilon.minosoft.config.key.KeyBinding
import de.bixilon.minosoft.config.key.KeyCodes
import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.gui.rendering.Drawable
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.gui.elements.Pollable
import de.bixilon.minosoft.gui.rendering.gui.hud.atlas.HUDAtlasManager
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.*
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.HUDBuilder
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.LayoutedHUDElement
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.chat.ChatHUDElement
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.chat.InternalMessagesHUDElement
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.hotbar.HotbarHUDElement
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.other.BreakProgressHUDElement
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.other.CrosshairHUDElement
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.other.DebugHUDElement
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.other.WorldInfoHUDElement
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.tab.TabListHUDElement
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIMesh
import de.bixilon.minosoft.gui.rendering.modding.events.ResizeWindowEvent
import de.bixilon.minosoft.gui.rendering.system.base.IntegratedBufferTypes
import de.bixilon.minosoft.gui.rendering.util.vec.Vec2Util.EMPTY
import de.bixilon.minosoft.modding.event.invoker.CallbackEventInvoker
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
@ -53,7 +61,7 @@ class HUDRenderer(
var matrixChange = true
private set
private val hudElements: MutableMap<ResourceLocation, HUDElement<*>> = synchronizedMapOf()
private val hudElements: MutableMap<ResourceLocation, HUDElement> = synchronizedMapOf()
private var lastTickTime = 0L
@ -95,7 +103,9 @@ class HUDRenderer(
matrixChange = true
for (element in hudElements.toSynchronizedMap().values) {
element.layout?.silentApply()
if (element is LayoutedHUDElement<*>) {
element.layout.silentApply()
}
element.apply()
}
})
@ -142,28 +152,37 @@ class HUDRenderer(
continue
}
element.tick()
if (element is Pollable) {
if (element.poll()) {
element.apply()
}
}
}
lastTickTime = time
}
// ToDo: size > maxSize
renderWindow.renderSystem.reset()
renderWindow.renderSystem.clear(IntegratedBufferTypes.DEPTH_BUFFER)
var z = 0
for (element in hudElements) {
if (!element.enabled) {
continue
}
element.draw()
z += element.layout?.render(element.layoutOffset ?: Vec2i.EMPTY, z, mesh, null) ?: 0
if (element is Drawable) {
element.draw()
}
if (element is LayoutedHUDElement<*>) {
z += element.layout.render(element.layoutOffset, z, mesh, null)
}
}
renderWindow.renderSystem.reset()
renderWindow.renderSystem.clear(IntegratedBufferTypes.DEPTH_BUFFER)
mesh.load()
shader.use()
mesh.draw()
@ -172,7 +191,7 @@ class HUDRenderer(
}
}
operator fun <T : HUDElement<*>> get(hudBuilder: HUDBuilder<*>): T? {
operator fun <T : LayoutedHUDElement<*>> get(hudBuilder: HUDBuilder<*>): T? {
return hudElements[hudBuilder.RESOURCE_LOCATION].unsafeCast()
}

View File

@ -0,0 +1,30 @@
/*
* 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.gui.hud.elements
import de.bixilon.minosoft.gui.rendering.Drawable
import de.bixilon.minosoft.gui.rendering.RenderWindow
import de.bixilon.minosoft.gui.rendering.gui.hud.HUDElement
import de.bixilon.minosoft.gui.rendering.gui.hud.HUDRenderer
abstract class CustomHUDElement(final override val hudRenderer: HUDRenderer) : HUDElement, Drawable {
override val renderWindow: RenderWindow = hudRenderer.renderWindow
override var enabled = true
/**
* Function to draw the custom content.
* May create buffers, changes shaders, resets the render system, etc
*/
override fun draw() {}
}

View File

@ -16,9 +16,10 @@ package de.bixilon.minosoft.gui.rendering.gui.hud.elements
import de.bixilon.minosoft.config.key.KeyBinding
import de.bixilon.minosoft.data.registries.CompanionResourceLocation
import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.gui.rendering.gui.hud.HUDElement
import de.bixilon.minosoft.gui.rendering.gui.hud.HUDRenderer
interface HUDBuilder<T : HUDElement<*>> : CompanionResourceLocation {
interface HUDBuilder<T : HUDElement> : CompanionResourceLocation {
val ENABLE_KEY_BINDING_NAME: ResourceLocation?
get() = null
val ENABLE_KEY_BINDING: KeyBinding?

View File

@ -15,28 +15,18 @@ package de.bixilon.minosoft.gui.rendering.gui.hud.elements
import de.bixilon.minosoft.gui.rendering.RenderWindow
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.hud.HUDElement
import de.bixilon.minosoft.gui.rendering.gui.hud.HUDRenderer
import glm_.vec2.Vec2i
abstract class HUDElement<T : Element>(val hudRenderer: HUDRenderer) {
val renderWindow: RenderWindow = hudRenderer.renderWindow
var enabled = true
abstract class LayoutedHUDElement<T : Element>(final override val hudRenderer: HUDRenderer) : HUDElement {
override val renderWindow: RenderWindow = hudRenderer.renderWindow
override var enabled = true
open val layout: T?
get() = null
abstract val layout: T
abstract val layoutOffset: Vec2i
open val layoutOffset: Vec2i?
get() = null
open fun init() {}
open fun postInit() {}
open fun draw() {}
open fun tick() {
layout?.tick()
override fun tick() {
layout.tick()
}
open fun apply() {}
}

View File

@ -11,19 +11,21 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.gui.rendering.gui.hud.elements
package de.bixilon.minosoft.gui.rendering.gui.hud.elements.chat
import de.bixilon.minosoft.Minosoft
import de.bixilon.minosoft.data.ChatTextPositions
import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.gui.rendering.gui.elements.text.TextFlowElement
import de.bixilon.minosoft.gui.rendering.gui.hud.HUDRenderer
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.HUDBuilder
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.LayoutedHUDElement
import de.bixilon.minosoft.modding.event.events.ChatMessageReceiveEvent
import de.bixilon.minosoft.modding.event.invoker.CallbackEventInvoker
import de.bixilon.minosoft.util.KUtil.toResourceLocation
import glm_.vec2.Vec2i
class ChatHUDElement(hudRenderer: HUDRenderer) : HUDElement<TextFlowElement>(hudRenderer) {
class ChatHUDElement(hudRenderer: HUDRenderer) : LayoutedHUDElement<TextFlowElement>(hudRenderer) {
private val connection = renderWindow.connection
override val layout = TextFlowElement(hudRenderer, 20000)

View File

@ -11,18 +11,20 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.gui.rendering.gui.hud.elements
package de.bixilon.minosoft.gui.rendering.gui.hud.elements.chat
import de.bixilon.minosoft.Minosoft
import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.gui.rendering.gui.elements.text.TextFlowElement
import de.bixilon.minosoft.gui.rendering.gui.hud.HUDRenderer
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.HUDBuilder
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.LayoutedHUDElement
import de.bixilon.minosoft.modding.event.events.InternalMessageReceiveEvent
import de.bixilon.minosoft.modding.event.invoker.CallbackEventInvoker
import de.bixilon.minosoft.util.KUtil.toResourceLocation
import glm_.vec2.Vec2i
class InternalMessagesHUDElement(hudRenderer: HUDRenderer) : HUDElement<TextFlowElement>(hudRenderer) {
class InternalMessagesHUDElement(hudRenderer: HUDRenderer) : LayoutedHUDElement<TextFlowElement>(hudRenderer) {
private val connection = renderWindow.connection
override val layout = TextFlowElement(hudRenderer, 15000)

View File

@ -18,7 +18,7 @@ import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.data.registries.other.game.event.handlers.gamemode.GamemodeChangeEvent
import de.bixilon.minosoft.gui.rendering.gui.hud.HUDRenderer
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.HUDBuilder
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.HUDElement
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.LayoutedHUDElement
import de.bixilon.minosoft.modding.event.events.ChatMessageReceiveEvent
import de.bixilon.minosoft.modding.event.events.ExperienceChangeEvent
import de.bixilon.minosoft.modding.event.events.SelectHotbarSlotEvent
@ -27,7 +27,7 @@ import de.bixilon.minosoft.modding.event.invoker.CallbackEventInvoker
import de.bixilon.minosoft.util.KUtil.toResourceLocation
import glm_.vec2.Vec2i
class HotbarHUDElement(hudRenderer: HUDRenderer) : HUDElement<HotbarElement>(hudRenderer) {
class HotbarHUDElement(hudRenderer: HUDRenderer) : LayoutedHUDElement<HotbarElement>(hudRenderer) {
private val connection = renderWindow.connection
override lateinit var layout: HotbarElement

View File

@ -11,44 +11,47 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.gui.rendering.gui.hud.elements
package de.bixilon.minosoft.gui.rendering.gui.hud.elements.other
import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.data.text.ChatColors
import de.bixilon.minosoft.data.text.TextComponent
import de.bixilon.minosoft.gui.rendering.Drawable
import de.bixilon.minosoft.gui.rendering.gui.elements.text.TextElement
import de.bixilon.minosoft.gui.rendering.gui.hud.HUDRenderer
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.HUDBuilder
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.LayoutedHUDElement
import de.bixilon.minosoft.util.KUtil.toResourceLocation
import glm_.vec2.Vec2i
class BreakProgressHUDElement(hudRenderer: HUDRenderer) : HUDElement<TextElement>(hudRenderer) {
class BreakProgressHUDElement(hudRenderer: HUDRenderer) : LayoutedHUDElement<TextElement>(hudRenderer), Drawable {
override val layout: TextElement = TextElement(hudRenderer, "")
private val leftClickHandler = hudRenderer.renderWindow.inputHandler.leftClickHandler
override val layoutOffset: Vec2i
get() = Vec2i((hudRenderer.scaledSize.x / 2) + CrosshairHUDElement.CROSSHAIR_SIZE / 2 + 5, (hudRenderer.scaledSize.y - layout.size.y) / 2)
private var lastPercent = -1
private var percent = -1
override fun draw() {
val breakProgress = leftClickHandler.breakProgress
if (breakProgress <= 0 || breakProgress >= 1.0) {
layout.text = ""
lastPercent = -1
this.percent = -1
return
}
val percent = (leftClickHandler.breakProgress * 100).toInt()
if (percent == lastPercent) {
if (percent == this.percent) {
return
}
val text = TextComponent("$percent%")
text.color = when {
percent <= 30 -> ChatColors.RED
percent <= 70 -> ChatColors.YELLOW
else -> ChatColors.GREEN
layout.text = TextComponent("$percent%").apply {
color = when {
percent <= 30 -> ChatColors.RED
percent <= 70 -> ChatColors.YELLOW
else -> ChatColors.GREEN
}
}
layout.text = text
lastPercent = percent
this.percent = percent
}
companion object : HUDBuilder<BreakProgressHUDElement> {

View File

@ -11,21 +11,22 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.gui.rendering.gui.hud.elements
package de.bixilon.minosoft.gui.rendering.gui.hud.elements.other
import de.bixilon.minosoft.Minosoft
import de.bixilon.minosoft.data.abilities.Gamemodes
import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.hud.HUDRenderer
import de.bixilon.minosoft.gui.rendering.gui.hud.atlas.HUDAtlasElement
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.CustomHUDElement
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.HUDBuilder
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIMesh
import de.bixilon.minosoft.gui.rendering.input.camera.hit.BlockRaycastHit
import de.bixilon.minosoft.gui.rendering.input.camera.hit.EntityRaycastHit
import de.bixilon.minosoft.gui.rendering.system.base.BlendingFunctions
import de.bixilon.minosoft.util.KUtil.toResourceLocation
class CrosshairHUDElement(hudRenderer: HUDRenderer) : HUDElement<Element>(hudRenderer) {
class CrosshairHUDElement(hudRenderer: HUDRenderer) : CustomHUDElement(hudRenderer) {
private lateinit var crosshairAtlasElement: HUDAtlasElement
private var mesh: GUIMesh? = null
private var previousDebugEnabled: Boolean? = true

View File

@ -11,7 +11,7 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.gui.rendering.gui.hud.elements
package de.bixilon.minosoft.gui.rendering.gui.hud.elements.other
import de.bixilon.minosoft.Minosoft
import de.bixilon.minosoft.config.key.KeyAction
@ -35,8 +35,11 @@ import de.bixilon.minosoft.gui.rendering.gui.elements.spacer.LineSpacerElement
import de.bixilon.minosoft.gui.rendering.gui.elements.text.AutoTextElement
import de.bixilon.minosoft.gui.rendering.gui.elements.text.TextElement
import de.bixilon.minosoft.gui.rendering.gui.hud.HUDRenderer
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.HUDBuilder
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.LayoutedHUDElement
import de.bixilon.minosoft.gui.rendering.modding.events.ResizeWindowEvent
import de.bixilon.minosoft.gui.rendering.particle.ParticleRenderer
import de.bixilon.minosoft.gui.rendering.util.vec.Vec2Util.EMPTY
import de.bixilon.minosoft.modding.event.events.DifficultyChangeEvent
import de.bixilon.minosoft.modding.event.events.GameEventChangeEvent
import de.bixilon.minosoft.modding.event.events.TimeChangeEvent
@ -54,8 +57,9 @@ import glm_.vec2.Vec2i
import glm_.vec4.Vec4i
import kotlin.math.abs
class DebugHUDElement(hudRenderer: HUDRenderer) : HUDElement<GridLayout>(hudRenderer) {
class DebugHUDElement(hudRenderer: HUDRenderer) : LayoutedHUDElement<GridLayout>(hudRenderer) {
private val connection = renderWindow.connection
override val layoutOffset: Vec2i = Vec2i.EMPTY
override val layout = GridLayout(hudRenderer, Vec2i(3, 1)).apply {
columnConstraints[0].apply {
grow = GridGrow.NEVER

View File

@ -11,23 +11,22 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.gui.rendering.gui.hud.elements
package de.bixilon.minosoft.gui.rendering.gui.hud.elements.other
import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.gui.rendering.gui.elements.Pollable
import de.bixilon.minosoft.gui.rendering.gui.elements.text.TextElement
import de.bixilon.minosoft.gui.rendering.gui.hud.HUDRenderer
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.HUDBuilder
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.LayoutedHUDElement
import de.bixilon.minosoft.util.KUtil.toResourceLocation
import de.bixilon.minosoft.util.MMath.round10
import glm_.vec2.Vec2i
class WorldInfoHUDElement(hudRenderer: HUDRenderer) : HUDElement<TextElement>(hudRenderer), Pollable {
override val layout: TextElement = TextElement(hudRenderer, "", scale = 3.0f)
class WorldInfoHUDElement(hudRenderer: HUDRenderer) : LayoutedHUDElement<TextElement>(hudRenderer), Pollable {
override val layout: TextElement = TextElement(hudRenderer, "")
override val layoutOffset: Vec2i = Vec2i(2, 2)
private var fps = -1.0
private var hide: Boolean = false
override fun tick() {
@ -41,10 +40,13 @@ class WorldInfoHUDElement(hudRenderer: HUDRenderer) : HUDElement<TextElement>(hu
}
override fun poll(): Boolean {
val debugHUDElement: DebugHUDElement? = hudRenderer[DebugHUDElement]
val hide = debugHUDElement?.enabled == true
val fps = hudRenderer.renderWindow.renderStats.smoothAvgFPS.round10
if (this.fps == fps) {
if (this.hide == hide && this.fps == fps) {
return false
}
this.hide = hide
this.fps = fps
return true
}
@ -57,17 +59,6 @@ class WorldInfoHUDElement(hudRenderer: HUDRenderer) : HUDElement<TextElement>(hu
}
}
override fun draw() {
val debugHUDElement: DebugHUDElement? = hudRenderer[DebugHUDElement]
val debugEnabled = debugHUDElement?.enabled == true
if (this.hide != debugEnabled) {
this.hide = debugEnabled
poll()
apply()
}
}
companion object : HUDBuilder<WorldInfoHUDElement> {
override val RESOURCE_LOCATION: ResourceLocation = "minosoft:world_info".toResourceLocation()

View File

@ -19,14 +19,14 @@ import de.bixilon.minosoft.config.key.KeyCodes
import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.gui.rendering.gui.hud.HUDRenderer
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.HUDBuilder
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.HUDElement
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.LayoutedHUDElement
import de.bixilon.minosoft.modding.event.events.TabListEntryChangeEvent
import de.bixilon.minosoft.modding.event.events.TabListInfoChangeEvent
import de.bixilon.minosoft.modding.event.invoker.CallbackEventInvoker
import de.bixilon.minosoft.util.KUtil.toResourceLocation
import glm_.vec2.Vec2i
class TabListHUDElement(hudRenderer: HUDRenderer) : HUDElement<TabListElement>(hudRenderer) {
class TabListHUDElement(hudRenderer: HUDRenderer) : LayoutedHUDElement<TabListElement>(hudRenderer) {
private val connection = renderWindow.connection
override val layout = TabListElement(hudRenderer)