diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/Element.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/Element.kt index 03c5ee4a3..3832c619d 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/Element.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/Element.kt @@ -14,6 +14,7 @@ package de.bixilon.minosoft.gui.rendering.gui.elements import de.bixilon.minosoft.gui.rendering.gui.hud.HUDRenderer +import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIMeshCache import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer import de.bixilon.minosoft.gui.rendering.util.vec.Vec2Util.EMPTY import de.bixilon.minosoft.gui.rendering.util.vec.Vec2Util.MAX @@ -29,7 +30,8 @@ abstract class Element(val hudRenderer: HUDRenderer) { field = value onParentChange() } - open var prepared: Boolean = false + protected var cache = GUIMeshCache(hudRenderer.matrix) + open var cacheUpToDate: Boolean = false /** * If maxSize was infinity, what size would the element have? diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/layout/grid/GridCell.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/layout/grid/GridCell.kt index bbfcb3fe1..20f48dc44 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/layout/grid/GridCell.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/layout/grid/GridCell.kt @@ -26,7 +26,7 @@ class GridCell( private val child: Element, override var parent: Element?, ) : Element(hudRenderer) { - override var prepared: Boolean by child::prepared + override var cacheUpToDate: Boolean by child::cacheUpToDate override var size: Vec2i by child::size override var margin: Vec4i by child::margin override var prefSize: Vec2i by child::prefSize diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/text/TextElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/text/TextElement.kt index 6d393fb19..64e26a5ca 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/text/TextElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/text/TextElement.kt @@ -24,6 +24,7 @@ import de.bixilon.minosoft.gui.rendering.gui.elements.ElementAlignments import de.bixilon.minosoft.gui.rendering.gui.elements.ElementAlignments.Companion.getOffset import de.bixilon.minosoft.gui.rendering.gui.elements.InfiniteSizeElement import de.bixilon.minosoft.gui.rendering.gui.hud.HUDRenderer +import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIMeshCache import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer import de.bixilon.minosoft.gui.rendering.util.vec.Vec2Util.EMPTY import de.bixilon.minosoft.gui.rendering.util.vec.Vec4Util.offset @@ -36,6 +37,9 @@ open class TextElement( var background: Boolean = true, var backgroundColor: RGBColor = RenderConstants.TEXT_BACKGROUND_COLOR, ) : LabeledElement(hudRenderer) { + private var previousOffset = Vec2i.EMPTY + private var previousMatrix = hudRenderer.matrix + private var preparedSize = Vec2i.EMPTY private var renderInfo = TextRenderInfo() @@ -43,7 +47,7 @@ open class TextElement( set(value) { textComponent = ChatComponent.of(value) field = value - prepared = false + cacheUpToDate = false } private var emptyMessage: Boolean = true @@ -75,6 +79,7 @@ open class TextElement( this.renderInfo = renderInfo } + this.cacheUpToDate = false this.size = size preparedSize = size } @@ -103,18 +108,32 @@ open class TextElement( if (emptyMessage) { return 0 } + if (previousOffset != offset || previousMatrix != hudRenderer.matrix) { + cacheUpToDate = false + } + if (cacheUpToDate) { + consumer.addCache(cache) + return LAYERS + } + val cache = GUIMeshCache(hudRenderer.matrix) val initialOffset = offset + margin.offset - ChatComponentRenderer.render(initialOffset, Vec2i(initialOffset), Vec2i.EMPTY, z + 1, this, fontAlignment, renderWindow, consumer, renderInfo, textComponent) + ChatComponentRenderer.render(initialOffset, Vec2i(initialOffset), Vec2i.EMPTY, z + 1, this, fontAlignment, renderWindow, cache, renderInfo, textComponent) renderInfo.currentLineNumber = 0 if (background) { for ((line, info) in renderInfo.lines.withIndex()) { val start = initialOffset + Vec2i(fontAlignment.getOffset(size.x, info.width), line * Font.TOTAL_CHAR_HEIGHT) - consumer.addQuad(start, start + Vec2i(info.width + Font.CHAR_MARGIN, Font.TOTAL_CHAR_HEIGHT), z, renderWindow.WHITE_TEXTURE, backgroundColor) + cache.addQuad(start, start + Vec2i(info.width + Font.CHAR_MARGIN, Font.TOTAL_CHAR_HEIGHT), z, renderWindow.WHITE_TEXTURE, backgroundColor) } } + consumer.addCache(cache) + this.cache = cache + this.previousOffset = offset + this.previousMatrix = hudRenderer.matrix + this.cacheUpToDate = true + return LAYERS } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/mesh/GUIMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/mesh/GUIMesh.kt index 85c45de2b..e05860d89 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/mesh/GUIMesh.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/mesh/GUIMesh.kt @@ -43,6 +43,10 @@ class GUIMesh( )) } + override fun addCache(cache: GUIMeshCache) { + data.addAll(cache.data) + } + data class HUDMeshStruct( val position: Vec3, val uv: Vec2, @@ -53,7 +57,7 @@ class GUIMesh( } companion object { - private const val BASE_Z = -0.99f - private const val Z_MULTIPLIER = -0.00001f + const val BASE_Z = -0.99f + const val Z_MULTIPLIER = -0.00001f } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/mesh/GUIMeshCache.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/mesh/GUIMeshCache.kt new file mode 100644 index 000000000..09c9c8bf3 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/mesh/GUIMeshCache.kt @@ -0,0 +1,47 @@ +/* + * 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.gui.mesh + +import de.bixilon.minosoft.data.text.RGBColor +import de.bixilon.minosoft.gui.rendering.RenderConstants +import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture +import de.bixilon.minosoft.util.collections.ArrayFloatList +import glm_.mat4x4.Mat4 +import glm_.vec2.Vec2 +import glm_.vec2.Vec2t +import glm_.vec4.Vec4 + +class GUIMeshCache( + val matrix: Mat4, + initialCahceSize: Int = 1000, +) : GUIVertexConsumer { + val data: ArrayFloatList = ArrayFloatList(initialCahceSize) + + override fun addVertex(position: Vec2t<*>, z: Int, texture: AbstractTexture, uv: Vec2, tint: RGBColor) { + val outPosition = matrix * Vec4(position.x.toFloat(), position.y.toFloat(), 1.0f, 1.0f) + data.addAll(floatArrayOf( + outPosition.x, + outPosition.y, + GUIMesh.BASE_Z + GUIMesh.Z_MULTIPLIER * z, + uv.x, + uv.y, + Float.fromBits(texture.renderData?.layer ?: RenderConstants.DEBUG_TEXTURE_ID), + Float.fromBits(tint.rgba), + )) + } + + override fun addCache(cache: GUIMeshCache) { + data.addAll(cache.data) + } +} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/mesh/GUIVertexConsumer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/mesh/GUIVertexConsumer.kt index 141fd6d90..07a59c08d 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/mesh/GUIVertexConsumer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/mesh/GUIVertexConsumer.kt @@ -46,4 +46,6 @@ interface GUIVertexConsumer { fun addQuad(start: Vec2t<*>, end: Vec2t<*>, z: Int, texture: TextureLike, tint: RGBColor) { addQuad(start, end, z, texture.texture, texture.uvStart, texture.uvEnd, tint) } + + fun addCache(cache: GUIMeshCache) } 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 843c3568e..66dfcfdc9 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 @@ -152,6 +152,8 @@ class OpenGLTextureArray( for ((mipMapLevel, data) in mipMaps.withIndex()) { glTexSubImage3D(GL_TEXTURE_2D_ARRAY, mipMapLevel, 0, 0, renderData.index, data.first.x, data.first.y, mipMapLevel + 1, GL_RGBA, GL_UNSIGNED_BYTE, data.second) } + + texture.data = null } return textureId