mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-17 11:24:56 -04:00
maven: remove apache primitives, improve hud rendering performance A LOT
This commit is contained in:
parent
77af672985
commit
8ffce5f563
5
pom.xml
5
pom.xml
@ -346,10 +346,5 @@
|
|||||||
<artifactId>moshi-kotlin</artifactId>
|
<artifactId>moshi-kotlin</artifactId>
|
||||||
<version>1.11.0</version>
|
<version>1.11.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>commons-primitives</groupId>
|
|
||||||
<artifactId>commons-primitives</artifactId>
|
|
||||||
<version>1.0</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
@ -215,10 +215,11 @@ open class TextComponent : ChatComponent {
|
|||||||
// add all chars
|
// add all chars
|
||||||
for (char in charArray) {
|
for (char in charArray) {
|
||||||
if (char == '\n') {
|
if (char == '\n') {
|
||||||
val yOffset = offset.y
|
offset.x = 0
|
||||||
offset *= 0
|
offset.y = 0
|
||||||
offset += Vec2(0, yOffset + Font.CHAR_HEIGHT + RenderConstants.TEXT_LINE_PADDING)
|
val yOffset = offset.y + Font.CHAR_HEIGHT + RenderConstants.TEXT_LINE_PADDING
|
||||||
retMaxSize += Vec2(0, yOffset + Font.CHAR_HEIGHT + RenderConstants.TEXT_LINE_PADDING)
|
offset.y += yOffset
|
||||||
|
retMaxSize.y += yOffset
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
val fontChar = font.getChar(char)
|
val fontChar = font.getChar(char)
|
||||||
@ -228,7 +229,7 @@ open class TextComponent : ChatComponent {
|
|||||||
textElement.addChild(ImageElement(charStart, fontChar, charStart + Vec2(scaledWidth, Font.CHAR_HEIGHT), z, color))
|
textElement.addChild(ImageElement(charStart, fontChar, charStart + Vec2(scaledWidth, Font.CHAR_HEIGHT), z, color))
|
||||||
|
|
||||||
// ad spacer between chars
|
// ad spacer between chars
|
||||||
offset += Vec2i(scaledWidth + Font.SPACE_BETWEEN_CHARS, 0f)
|
offset.x += scaledWidth + Font.SPACE_BETWEEN_CHARS
|
||||||
if (offset.x > retMaxSize.x) {
|
if (offset.x > retMaxSize.x) {
|
||||||
retMaxSize.x += scaledWidth + Font.SPACE_BETWEEN_CHARS
|
retMaxSize.x += scaledWidth + Font.SPACE_BETWEEN_CHARS
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,7 @@ object RenderConstants {
|
|||||||
const val CHUNK_SECTIONS_PER_MESH = 1
|
const val CHUNK_SECTIONS_PER_MESH = 1
|
||||||
|
|
||||||
const val FRUSTUM_CULLING_ENABLED = true
|
const val FRUSTUM_CULLING_ENABLED = true
|
||||||
|
const val SHOW_FPS_IN_WINDOW_TITLE = true
|
||||||
|
|
||||||
const val MAXIMUM_CALLS_PER_FRAME = 10
|
const val MAXIMUM_CALLS_PER_FRAME = 10
|
||||||
}
|
}
|
||||||
|
@ -383,7 +383,9 @@ class RenderWindow(
|
|||||||
}
|
}
|
||||||
renderStats.endFrame()
|
renderStats.endFrame()
|
||||||
|
|
||||||
glfwSetWindowTitle(windowId, "FPS: ${renderStats.fpsLastSecond}")
|
if (RenderConstants.SHOW_FPS_IN_WINDOW_TITLE) {
|
||||||
|
glfwSetWindowTitle(windowId, "Minosoft | FPS: ${renderStats.fpsLastSecond}")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,20 +24,12 @@ import org.lwjgl.opengl.GL11.GL_FLOAT
|
|||||||
import org.lwjgl.opengl.GL20.glEnableVertexAttribArray
|
import org.lwjgl.opengl.GL20.glEnableVertexAttribArray
|
||||||
import org.lwjgl.opengl.GL20.glVertexAttribPointer
|
import org.lwjgl.opengl.GL20.glVertexAttribPointer
|
||||||
|
|
||||||
class SectionArrayMesh : Mesh() {
|
class SectionArrayMesh : Mesh(initialCacheSize = 100000) {
|
||||||
var lowestBlockHeight = 0
|
var lowestBlockHeight = 0
|
||||||
var highestBlockHeight = 0
|
var highestBlockHeight = 0
|
||||||
|
|
||||||
fun addVertex(position: Vec3, textureCoordinates: Vec2, texture: Texture, tintColor: RGBColor?, lightLevel: Int = 14) {
|
fun addVertex(position: Vec3, textureCoordinates: Vec2, texture: Texture, tintColor: RGBColor?, lightLevel: Int = 14) {
|
||||||
val data = data!!
|
val data = data!!
|
||||||
data.add(position.x)
|
|
||||||
data.add(position.y)
|
|
||||||
data.add(position.z)
|
|
||||||
data.add(textureCoordinates.x * texture.uvEnd.x)
|
|
||||||
data.add(textureCoordinates.y * texture.uvEnd.y)
|
|
||||||
data.add(Float.fromBits((texture.arrayId shl 24) or texture.arrayLayer))
|
|
||||||
|
|
||||||
data.add(Float.fromBits(texture.properties.animation?.animationId ?: -1))
|
|
||||||
|
|
||||||
val color = tintColor ?: ChatColors.WHITE
|
val color = tintColor ?: ChatColors.WHITE
|
||||||
|
|
||||||
@ -45,8 +37,17 @@ class SectionArrayMesh : Mesh() {
|
|||||||
|
|
||||||
val lightColor = RGBColor(color.red / lightFactor, color.green / lightFactor, color.blue / lightFactor)
|
val lightColor = RGBColor(color.red / lightFactor, color.green / lightFactor, color.blue / lightFactor)
|
||||||
|
|
||||||
|
data.addAll(floatArrayOf(
|
||||||
data.add(Float.fromBits(lightColor.color ushr 8))
|
position.x,
|
||||||
|
position.y,
|
||||||
|
position.z,
|
||||||
|
textureCoordinates.x * texture.uvEnd.x,
|
||||||
|
textureCoordinates.y * texture.uvEnd.y,
|
||||||
|
Float.fromBits((texture.arrayId shl 24) or texture.arrayLayer),
|
||||||
|
Float.fromBits(texture.properties.animation?.animationId ?: -1),
|
||||||
|
Float.fromBits(lightColor.color ushr 8),
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun load() {
|
override fun load() {
|
||||||
|
@ -15,33 +15,37 @@ package de.bixilon.minosoft.gui.rendering.hud
|
|||||||
|
|
||||||
import de.bixilon.minosoft.data.text.RGBColor
|
import de.bixilon.minosoft.data.text.RGBColor
|
||||||
import de.bixilon.minosoft.gui.rendering.textures.Texture
|
import de.bixilon.minosoft.gui.rendering.textures.Texture
|
||||||
|
import de.bixilon.minosoft.util.collections.ArrayFloatList
|
||||||
import glm_.vec2.Vec2
|
import glm_.vec2.Vec2
|
||||||
import glm_.vec3.Vec3
|
import glm_.vec3.Vec3
|
||||||
import org.apache.commons.collections.primitives.ArrayFloatList
|
|
||||||
|
|
||||||
class HUDCacheMesh {
|
class HUDCacheMesh(
|
||||||
private val data = ArrayFloatList()
|
initialCacheSize: Int = 1000,
|
||||||
|
) {
|
||||||
|
private val data = ArrayFloatList(initialCacheSize)
|
||||||
|
|
||||||
val cache: ArrayFloatList
|
val cache: ArrayFloatList
|
||||||
get() = data
|
get() = data
|
||||||
|
|
||||||
fun addVertex(position: Vec3, textureCoordinates: Vec2, texture: Texture?, tintColor: RGBColor? = null) {
|
fun addVertex(position: Vec3, textureCoordinates: Vec2, texture: Texture?, tintColor: RGBColor? = null) {
|
||||||
data.add(position.x)
|
data.addAll(floatArrayOf(
|
||||||
data.add(position.y)
|
position.x,
|
||||||
data.add(position.z)
|
position.y,
|
||||||
data.add(textureCoordinates.x)
|
position.z,
|
||||||
data.add(textureCoordinates.y)
|
textureCoordinates.x,
|
||||||
data.add(Float.fromBits((texture?.arrayLayer ?: 0) or ((texture?.arrayId ?: 0) shl 24)))
|
textureCoordinates.y,
|
||||||
|
Float.fromBits((texture?.arrayLayer ?: 0) or ((texture?.arrayId ?: 0) shl 24)),
|
||||||
|
if (tintColor == null) {
|
||||||
|
0f
|
||||||
|
} else {
|
||||||
|
Float.fromBits(tintColor.color)
|
||||||
|
},
|
||||||
|
))
|
||||||
|
|
||||||
if (tintColor == null) {
|
|
||||||
data.add(0f)
|
|
||||||
} else {
|
|
||||||
data.add(Float.fromBits(tintColor.color))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val size: Int
|
val size: Int
|
||||||
get() = data.size()
|
get() = data.size
|
||||||
|
|
||||||
fun isEmpty(): Boolean {
|
fun isEmpty(): Boolean {
|
||||||
return data.isEmpty
|
return data.isEmpty
|
||||||
|
@ -19,6 +19,7 @@ import glm_.vec2.Vec2i
|
|||||||
|
|
||||||
abstract class Element(
|
abstract class Element(
|
||||||
private var _start: Vec2i,
|
private var _start: Vec2i,
|
||||||
|
initialCacheSize: Int = 1000,
|
||||||
) {
|
) {
|
||||||
var start: Vec2i
|
var start: Vec2i
|
||||||
get() {
|
get() {
|
||||||
@ -30,7 +31,7 @@ abstract class Element(
|
|||||||
clearCache()
|
clearCache()
|
||||||
}
|
}
|
||||||
|
|
||||||
val cache = HUDCacheMesh()
|
val cache = HUDCacheMesh(initialCacheSize)
|
||||||
open var parent: Element? = null
|
open var parent: Element? = null
|
||||||
var size: Vec2i = Vec2i()
|
var size: Vec2i = Vec2i()
|
||||||
|
|
||||||
|
@ -18,7 +18,8 @@ import glm_.vec2.Vec2i
|
|||||||
abstract class EndElement(
|
abstract class EndElement(
|
||||||
start: Vec2i,
|
start: Vec2i,
|
||||||
private var _end: Vec2i,
|
private var _end: Vec2i,
|
||||||
) : Element(start) {
|
initialCacheSize: Int = 10000,
|
||||||
|
) : Element(start, initialCacheSize = initialCacheSize) {
|
||||||
var end: Vec2i
|
var end: Vec2i
|
||||||
get() {
|
get() {
|
||||||
return _end
|
return _end
|
||||||
|
@ -36,7 +36,7 @@ class HealthBar(
|
|||||||
private val singleHeartSize = blackHeartContainerAtlasElement.binding.size
|
private val singleHeartSize = blackHeartContainerAtlasElement.binding.size
|
||||||
private val width = singleHeartSize.x * MAX_HEARTS_IN_ROW
|
private val width = singleHeartSize.x * MAX_HEARTS_IN_ROW
|
||||||
|
|
||||||
private val alternativeText = TextElement(font = font, start = Vec2i(), background = false)
|
private val alternativeText = TextElement(font = font, start = Vec2i(0, 0), background = false)
|
||||||
private var _value = 0.0f
|
private var _value = 0.0f
|
||||||
var value: Float
|
var value: Float
|
||||||
get() = _value
|
get() = _value
|
||||||
|
@ -28,7 +28,8 @@ class ImageElement(
|
|||||||
end: Vec2i = textureLike?.size ?: Vec2i(0, 0),
|
end: Vec2i = textureLike?.size ?: Vec2i(0, 0),
|
||||||
val z: Int = 0,
|
val z: Int = 0,
|
||||||
val tintColor: RGBColor? = null,
|
val tintColor: RGBColor? = null,
|
||||||
) : EndElement(start, end) {
|
) : EndElement(start, end, initialCacheSize = 42) {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
recalculateSize()
|
recalculateSize()
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ class TextElement(
|
|||||||
size = if (text.message.isBlank()) {
|
size = if (text.message.isBlank()) {
|
||||||
Vec2i(0, Font.CHAR_HEIGHT)
|
Vec2i(0, Font.CHAR_HEIGHT)
|
||||||
} else {
|
} else {
|
||||||
val textSize = Vec2i()
|
val textSize = Vec2i(0, 0)
|
||||||
text.prepareRender(Vec2i(0, 1), Vec2i(), font, this, this.z + z + 1, textSize)
|
text.prepareRender(Vec2i(0, 1), Vec2i(), font, this, this.z + z + 1, textSize)
|
||||||
|
|
||||||
if (background) {
|
if (background) {
|
||||||
|
@ -13,13 +13,15 @@
|
|||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.util
|
package de.bixilon.minosoft.gui.rendering.util
|
||||||
|
|
||||||
import org.apache.commons.collections.primitives.ArrayFloatList
|
import de.bixilon.minosoft.util.collections.ArrayFloatList
|
||||||
import org.lwjgl.opengl.GL11.GL_TRIANGLES
|
import org.lwjgl.opengl.GL11.GL_TRIANGLES
|
||||||
import org.lwjgl.opengl.GL11.glDrawArrays
|
import org.lwjgl.opengl.GL11.glDrawArrays
|
||||||
import org.lwjgl.opengl.GL30.*
|
import org.lwjgl.opengl.GL30.*
|
||||||
|
|
||||||
abstract class Mesh {
|
abstract class Mesh(
|
||||||
protected var data: ArrayFloatList? = ArrayFloatList()
|
initialCacheSize: Int = 10000,
|
||||||
|
) {
|
||||||
|
protected var data: ArrayFloatList? = ArrayFloatList(initialCacheSize)
|
||||||
private var vao: Int = -1
|
private var vao: Int = -1
|
||||||
private var vbo: Int = -1
|
private var vbo: Int = -1
|
||||||
var trianglesCount: Int = -1
|
var trianglesCount: Int = -1
|
||||||
@ -34,7 +36,7 @@ abstract class Mesh {
|
|||||||
protected fun initializeBuffers(floatsPerVertex: Int) {
|
protected fun initializeBuffers(floatsPerVertex: Int) {
|
||||||
check(state == MeshStates.PREPARING) { "Mesh already loaded: $state" }
|
check(state == MeshStates.PREPARING) { "Mesh already loaded: $state" }
|
||||||
|
|
||||||
trianglesCount = data!!.size() / floatsPerVertex
|
trianglesCount = data!!.size / floatsPerVertex
|
||||||
vao = glGenVertexArrays()
|
vao = glGenVertexArrays()
|
||||||
vbo = glGenBuffers()
|
vbo = glGenBuffers()
|
||||||
glBindVertexArray(vao)
|
glBindVertexArray(vao)
|
||||||
|
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* 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.util.collections
|
||||||
|
|
||||||
|
class ArrayFloatList(
|
||||||
|
private val initialSize: Int = 1000,
|
||||||
|
) {
|
||||||
|
private var data: FloatArray = FloatArray(initialSize)
|
||||||
|
val limit: Int
|
||||||
|
get() = data.size
|
||||||
|
var size = 0
|
||||||
|
private set
|
||||||
|
val isEmpty: Boolean
|
||||||
|
get() = size == 0
|
||||||
|
|
||||||
|
private var output: FloatArray = FloatArray(0)
|
||||||
|
private var outputUpToDate = false
|
||||||
|
|
||||||
|
fun clear() {
|
||||||
|
size = 0
|
||||||
|
data = FloatArray(initialSize)
|
||||||
|
outputUpToDate = false
|
||||||
|
output = FloatArray(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ensureSize(needed: Int) {
|
||||||
|
if (limit - size >= needed) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var newSize = data.size
|
||||||
|
while (newSize - size < needed) {
|
||||||
|
newSize += initialSize
|
||||||
|
}
|
||||||
|
val oldData = data
|
||||||
|
data = FloatArray(newSize)
|
||||||
|
System.arraycopy(oldData, 0, data, 0, oldData.size)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun add(float: Float) {
|
||||||
|
ensureSize(1)
|
||||||
|
data[size++] = float
|
||||||
|
outputUpToDate = false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addAll(floats: FloatArray) {
|
||||||
|
ensureSize(floats.size)
|
||||||
|
System.arraycopy(floats, 0, data, size, floats.size)
|
||||||
|
size += floats.size
|
||||||
|
outputUpToDate = false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addAll(floats: ArrayFloatList) {
|
||||||
|
ensureSize(floats.size)
|
||||||
|
System.arraycopy(floats.data, 0, data, size, floats.size)
|
||||||
|
size += floats.size
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkOutputArray() {
|
||||||
|
if (outputUpToDate) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
output = FloatArray(size)
|
||||||
|
System.arraycopy(data, 0, output, 0, size)
|
||||||
|
outputUpToDate = true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun toArray(): FloatArray {
|
||||||
|
checkOutputArray()
|
||||||
|
return output
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user