diff --git a/src/main/java/de/bixilon/minosoft/data/accounts/Account.kt b/src/main/java/de/bixilon/minosoft/data/accounts/Account.kt
index 18ae96829..6611fd6e6 100644
--- a/src/main/java/de/bixilon/minosoft/data/accounts/Account.kt
+++ b/src/main/java/de/bixilon/minosoft/data/accounts/Account.kt
@@ -27,6 +27,7 @@ import de.bixilon.minosoft.data.accounts.types.offline.OfflineAccount
import de.bixilon.minosoft.data.player.properties.PlayerProperties
import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
+import java.util.*
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonSubTypes(
@@ -42,6 +43,7 @@ abstract class Account(
abstract val properties: PlayerProperties?
@get:JsonIgnore @set:JsonIgnore open var state: AccountStates by watched(AccountStates.UNCHECKED)
@get:JsonIgnore open var error: Throwable? by watched(null)
+ abstract val uuid: UUID
@Transient
@JsonIgnore
diff --git a/src/main/java/de/bixilon/minosoft/data/accounts/types/microsoft/MicrosoftAccount.kt b/src/main/java/de/bixilon/minosoft/data/accounts/types/microsoft/MicrosoftAccount.kt
index 6048346fd..80487b79a 100644
--- a/src/main/java/de/bixilon/minosoft/data/accounts/types/microsoft/MicrosoftAccount.kt
+++ b/src/main/java/de/bixilon/minosoft/data/accounts/types/microsoft/MicrosoftAccount.kt
@@ -32,7 +32,7 @@ import java.net.ConnectException
import java.util.*
class MicrosoftAccount(
- val uuid: UUID,
+ override val uuid: UUID,
username: String,
@field:JsonProperty private var msa: MicrosoftTokens,
@field:JsonProperty private var minecraft: MinecraftTokens,
diff --git a/src/main/java/de/bixilon/minosoft/data/accounts/types/mojang/MojangAccount.kt b/src/main/java/de/bixilon/minosoft/data/accounts/types/mojang/MojangAccount.kt
index a3284ee26..a0a228908 100644
--- a/src/main/java/de/bixilon/minosoft/data/accounts/types/mojang/MojangAccount.kt
+++ b/src/main/java/de/bixilon/minosoft/data/accounts/types/mojang/MojangAccount.kt
@@ -38,7 +38,7 @@ import java.util.*
class MojangAccount(
override val id: String,
username: String,
- val uuid: UUID,
+ override val uuid: UUID,
val email: String,
@field:JsonProperty private var accessToken: String,
override val properties: PlayerProperties?,
diff --git a/src/main/java/de/bixilon/minosoft/data/accounts/types/offline/OfflineAccount.kt b/src/main/java/de/bixilon/minosoft/data/accounts/types/offline/OfflineAccount.kt
index 2708cc138..441832299 100644
--- a/src/main/java/de/bixilon/minosoft/data/accounts/types/offline/OfflineAccount.kt
+++ b/src/main/java/de/bixilon/minosoft/data/accounts/types/offline/OfflineAccount.kt
@@ -21,9 +21,11 @@ import de.bixilon.minosoft.data.player.properties.PlayerProperties
import de.bixilon.minosoft.data.registries.CompanionResourceLocation
import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.util.KUtil.toResourceLocation
+import java.util.*
class OfflineAccount(username: String) : Account(username) {
override val id: String = username
+ override val uuid: UUID = UUID("OfflinePlayer:$username".hashCode().toLong(), 0L) // ToDo
override val type: ResourceLocation = RESOURCE_LOCATION
override var state: AccountStates
get() = AccountStates.WORKING
diff --git a/src/main/java/de/bixilon/minosoft/data/player/properties/PlayerProperties.kt b/src/main/java/de/bixilon/minosoft/data/player/properties/PlayerProperties.kt
index d0ec672c1..d93ac0b13 100644
--- a/src/main/java/de/bixilon/minosoft/data/player/properties/PlayerProperties.kt
+++ b/src/main/java/de/bixilon/minosoft/data/player/properties/PlayerProperties.kt
@@ -22,7 +22,7 @@ import de.bixilon.minosoft.data.player.properties.textures.PlayerTextures
import java.net.URL
import java.util.*
-class PlayerProperties(
+data class PlayerProperties(
@JsonInclude(JsonInclude.Include.NON_EMPTY)
val textures: PlayerTextures? = null,
) {
diff --git a/src/main/java/de/bixilon/minosoft/data/player/properties/textures/PlayerTexture.kt b/src/main/java/de/bixilon/minosoft/data/player/properties/textures/PlayerTexture.kt
index c5c79a81a..3b2c72dec 100644
--- a/src/main/java/de/bixilon/minosoft/data/player/properties/textures/PlayerTexture.kt
+++ b/src/main/java/de/bixilon/minosoft/data/player/properties/textures/PlayerTexture.kt
@@ -17,6 +17,9 @@ import com.fasterxml.jackson.annotation.JsonIgnore
import de.bixilon.kutil.url.URLUtil.checkWeb
import de.bixilon.minosoft.assets.util.FileAssetsUtil
import de.bixilon.minosoft.assets.util.FileUtil
+import de.bixilon.minosoft.util.logging.Log
+import de.bixilon.minosoft.util.logging.LogLevels
+import de.bixilon.minosoft.util.logging.LogMessageType
import java.net.URL
import java.util.*
@@ -33,7 +36,9 @@ open class PlayerTexture(
check(urlMatches(url, ALLOWED_DOMAINS) && !urlMatches(url, BLOCKED_DOMAINS)) { "URL hostname is not allowed!" }
}
+ @Synchronized
fun read(): ByteArray {
+ this.data?.let { return it }
val sha256 = when (url.host) {
"textures.minecraft.net" -> url.file.split("/").last()
else -> TODO("Can not get texture identifier!")
@@ -50,6 +55,7 @@ open class PlayerTexture(
throw IllegalStateException("Texture is too big!")
}
val data = FileAssetsUtil.saveAndGet(input)
+ Log.log(LogMessageType.ASSETS, LogLevels.VERBOSE) { "Downloaded skin ($url)" }
return data.second
}
diff --git a/src/main/java/de/bixilon/minosoft/data/player/properties/textures/PlayerTextures.kt b/src/main/java/de/bixilon/minosoft/data/player/properties/textures/PlayerTextures.kt
index dab6a17dc..d2c02e43d 100644
--- a/src/main/java/de/bixilon/minosoft/data/player/properties/textures/PlayerTextures.kt
+++ b/src/main/java/de/bixilon/minosoft/data/player/properties/textures/PlayerTextures.kt
@@ -22,7 +22,7 @@ import de.bixilon.minosoft.util.YggdrasilUtil
import de.bixilon.minosoft.util.json.Jackson
import java.util.*
-class PlayerTextures(
+data class PlayerTextures(
@JsonInclude(JsonInclude.Include.NON_EMPTY) val name: String?,
@JsonInclude(JsonInclude.Include.NON_EMPTY) val uuid: UUID?,
@JsonInclude(JsonInclude.Include.NON_EMPTY) val date: Date?,
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 78949c601..d983aca20 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/RenderWindow.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/RenderWindow.kt
@@ -211,6 +211,9 @@ class RenderWindow(
connection.fireEvent(ResizeWindowEvent(previousSize = Vec2i(0, 0), size = window.size))
+ textureManager.dynamicTextures.activate()
+ textureManager.staticTextures.activate()
+
Log.log(LogMessageType.RENDERING_LOADING) { "Rendering is fully prepared in ${stopwatch.totalTime()}" }
initialized = true
latch.dec()
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/primitive/DynamicImageElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/primitive/DynamicImageElement.kt
index 6799dd2df..943898c63 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/primitive/DynamicImageElement.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/primitive/DynamicImageElement.kt
@@ -22,7 +22,9 @@ import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIMesh
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
+import de.bixilon.minosoft.gui.rendering.system.base.texture.ShaderIdentifiable
import de.bixilon.minosoft.gui.rendering.system.base.texture.dynamic.DynamicTexture
+import de.bixilon.minosoft.gui.rendering.system.base.texture.dynamic.DynamicTextureState
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.EMPTY
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.EMPTY
@@ -33,12 +35,15 @@ open class DynamicImageElement(
uvEnd: Vec2 = Vec2(1.0f, 1.0f),
size: Vec2i = Vec2i.EMPTY,
tint: RGBColor = ChatColors.WHITE,
+ parent: Element? = null,
) : Element(guiRenderer, GUIMesh.GUIMeshStruct.FLOATS_PER_VERTEX * 6) {
- var texture: DynamicTexture? = texture
+ var texture: DynamicTexture? = null
set(value) {
field?.usages?.decrementAndGet()
+ field?.onStateChange = null
value?.usages?.incrementAndGet()
+ value?.onStateChange = { forceApply() }
field = value
cacheUpToDate = false
}
@@ -74,11 +79,20 @@ open class DynamicImageElement(
init {
this.size = size
- texture?.usages?.incrementAndGet()
+ this.texture = texture
+ this.parent = parent
+ }
+
+ private fun getAvailableTexture(): ShaderIdentifiable {
+ val texture = texture ?: return renderWindow.textureManager.whiteTexture.texture
+ if (texture.state != DynamicTextureState.LOADED) {
+ return renderWindow.textureManager.whiteTexture.texture
+ }
+ return texture
}
override fun forceRender(offset: Vec2i, consumer: GUIVertexConsumer, options: GUIVertexOptions?) {
- consumer.addQuad(offset, offset + size, texture ?: return, uvStart, uvEnd, tint, options)
+ consumer.addQuad(offset, offset + size, getAvailableTexture(), uvStart, uvEnd, tint, options)
}
override fun forceSilentApply() = Unit
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/tab/TabListEntryElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/tab/TabListEntryElement.kt
index 4b7b2307e..5e3cd0bd6 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/tab/TabListEntryElement.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/tab/TabListEntryElement.kt
@@ -49,7 +49,7 @@ class TabListEntryElement(
private val background: ColorElement
- private val skinElement = DynamicImageElement(guiRenderer, renderWindow.textureManager.getSkin(uuid, item.properties.textures), uvStart = Vec2(0.125), uvEnd = Vec2(0.25), size = Vec2i(8, 8))
+ private val skinElement = DynamicImageElement(guiRenderer, renderWindow.textureManager.getSkin(uuid, item.properties), uvStart = Vec2(0.125), uvEnd = Vec2(0.25), size = Vec2i(8, 8), parent = this)
// private val skinElement = ImageElement(guiRenderer, guiRenderer.renderWindow.textureManager.steveTexture, uvStart = Vec2(0.125), uvEnd = Vec2(0.25), size = Vec2i(512, 512))
private val nameElement = TextElement(guiRenderer, "", background = false, parent = this)
@@ -86,7 +86,7 @@ class TabListEntryElement(
override fun forceRender(offset: Vec2i, consumer: GUIVertexConsumer, options: GUIVertexOptions?) {
background.render(offset, consumer, options)
skinElement.render(offset + Vec2i(PADDING, PADDING), consumer, options)
- nameElement.render(offset + Vec2i(skinElement.size.x + PADDING, PADDING), consumer, options)
+ nameElement.render(offset + Vec2i(skinElement.size.x + PADDING * 3, PADDING), consumer, options)
pingElement.render(offset + Vec2i(HorizontalAlignments.RIGHT.getOffset(maxSize.x, pingElement.size.x + PADDING), PADDING), consumer, options)
}
@@ -104,7 +104,7 @@ class TabListEntryElement(
nameElement.text = displayName
- this.prefSize = Vec2i((PADDING * 3) + skinElement.prefSize.x + nameElement.prefSize.x + INNER_MARGIN + pingElement.prefSize.x, HEIGHT)
+ this.prefSize = Vec2i((PADDING * 6) + skinElement.prefSize.x + nameElement.prefSize.x + INNER_MARGIN + pingElement.prefSize.x, HEIGHT)
background.size = size
cacheUpToDate = false
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/TextureArray.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/TextureArray.kt
index 44fd3f561..1ee547d83 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/TextureArray.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/TextureArray.kt
@@ -19,5 +19,6 @@ import de.bixilon.minosoft.gui.rendering.system.base.shader.Shader
interface TextureArray {
fun load(latch: CountUpAndDownLatch)
+ fun activate()
fun use(shader: Shader, name: String = "uTextures")
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/TextureManager.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/TextureManager.kt
index a62ebb428..ab3ce4155 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/TextureManager.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/TextureManager.kt
@@ -15,9 +15,9 @@ package de.bixilon.minosoft.gui.rendering.system.base.texture
import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kotlinglm.vec2.Vec2i
-import de.bixilon.kutil.uuid.UUIDUtil.toUUID
+import de.bixilon.minosoft.config.profile.profiles.account.AccountProfileManager
+import de.bixilon.minosoft.data.player.properties.PlayerProperties
import de.bixilon.minosoft.data.player.properties.textures.PlayerTexture.Companion.isSteve
-import de.bixilon.minosoft.data.player.properties.textures.PlayerTextures
import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.gui.rendering.RenderConstants
import de.bixilon.minosoft.gui.rendering.gui.atlas.TextureLikeTexture
@@ -56,14 +56,25 @@ abstract class TextureManager {
fun loadDefaultSkins(connection: PlayConnection) {
// ToDo: For testing purposes only, they will be moved to static textures
- steveTexture = dynamicTextures.pushBuffer("3780a46b-a725-4b22-8366-01056c698386".toUUID()) { connection.assetsManager["minecraft:entity/steve".toResourceLocation().texture()].readTexture().second }
- alexTexture = dynamicTextures.pushBuffer("3780a46b-a725-4b22-8366-01056c698386".toUUID()) { connection.assetsManager["minecraft:entity/alex".toResourceLocation().texture()].readTexture().second }
- skin = getSkin(connection.player.uuid ?: UUID.randomUUID(), connection.account.properties?.textures)
+ steveTexture = dynamicTextures.pushBuffer(UUID(0L, 0L)) { connection.assetsManager["minecraft:entity/steve".toResourceLocation().texture()].readTexture().second }.apply { usages.incrementAndGet() }
+ alexTexture = dynamicTextures.pushBuffer(UUID(1L, 0L)) { connection.assetsManager["minecraft:entity/alex".toResourceLocation().texture()].readTexture().second }.apply { usages.incrementAndGet() }
+ skin = getSkin(connection.account.uuid, connection.account.properties).apply { usages.incrementAndGet() }
}
- fun getSkin(uuid: UUID, properties: PlayerTextures?): DynamicTexture {
- properties?.skin?.let { return dynamicTextures.pushRawArray(uuid) { it.read() } }
+ fun getSkin(uuid: UUID, properties: PlayerProperties?): DynamicTexture {
+ var properties = properties
+ if (properties == null) {
+ for (account in AccountProfileManager.selected.entries.values) {
+ if (account.uuid == uuid) {
+ properties = account.properties
+ }
+ }
+ if (properties == null) {
+ properties = PlayerProperties.fetch(uuid) // ToDo: async
+ }
+ }
+ properties.textures?.skin?.let { return dynamicTextures.pushRawArray(uuid) { it.read() } }
if (uuid.isSteve()) {
return steveTexture
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/dynamic/DynamicTexture.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/dynamic/DynamicTexture.kt
index 44b673b12..8e6d426f1 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/dynamic/DynamicTexture.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/dynamic/DynamicTexture.kt
@@ -20,4 +20,8 @@ import java.util.concurrent.atomic.AtomicInteger
interface DynamicTexture : ShaderIdentifiable {
val uuid: UUID
val usages: AtomicInteger
+
+ val state: DynamicTextureState
+
+ var onStateChange: (() -> Unit)?
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/dynamic/DynamicTextureState.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/dynamic/DynamicTextureState.kt
new file mode 100644
index 000000000..b49962f37
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/dynamic/DynamicTextureState.kt
@@ -0,0 +1,22 @@
+/*
+ * Minosoft
+ * Copyright (C) 2020-2022 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.texture.dynamic
+
+enum class DynamicTextureState {
+ WAITING,
+ LOADING,
+ LOADED,
+ UNLOADED,
+ ;
+}
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 2e3d043c4..87c3110e3 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
@@ -191,16 +191,26 @@ class OpenGLTextureArray(
state = TextureArrayStates.LOADED
}
-
- override fun use(shader: Shader, name: String) {
- shader.use()
-
+ override fun activate() {
for ((index, textureId) in textureIds.withIndex()) {
if (textureId == -1) {
continue
}
glActiveTexture(GL_TEXTURE0 + index)
glBindTexture(GL_TEXTURE_2D_ARRAY, textureId)
+ }
+ }
+
+ override fun use(shader: Shader, name: String) {
+ shader.use()
+ activate()
+
+ for ((index, textureId) in textureIds.withIndex()) {
+ if (textureId == -1) {
+ continue
+ }
+
+ glBindTexture(GL_TEXTURE_2D_ARRAY, textureId)
shader.setTexture("$name[$index]", index)
}
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/texture/dynamic/OpenGLDynamicTexture.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/texture/dynamic/OpenGLDynamicTexture.kt
index c503ce0a5..9ea325e47 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/texture/dynamic/OpenGLDynamicTexture.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/texture/dynamic/OpenGLDynamicTexture.kt
@@ -14,6 +14,7 @@
package de.bixilon.minosoft.gui.rendering.system.opengl.texture.dynamic
import de.bixilon.minosoft.gui.rendering.system.base.texture.dynamic.DynamicTexture
+import de.bixilon.minosoft.gui.rendering.system.base.texture.dynamic.DynamicTextureState
import java.util.*
import java.util.concurrent.atomic.AtomicInteger
@@ -21,13 +22,23 @@ class OpenGLDynamicTexture(
override val uuid: UUID,
shaderId: Int,
) : DynamicTexture {
+ override var onStateChange: (() -> Unit)? = null
override val usages = AtomicInteger()
+ override var state: DynamicTextureState = DynamicTextureState.WAITING
+ set(value) {
+ field = value
+ onStateChange?.invoke()
+ }
- override val shaderId: Int = shaderId
+ override var shaderId: Int = shaderId
get() {
- if (usages.get() == 0) {
+ if (usages.get() == 0 || state == DynamicTextureState.UNLOADED) {
throw IllegalStateException("Texture was eventually garbage collected")
}
return field
}
+
+ override fun toString(): String {
+ return uuid.toString()
+ }
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/texture/dynamic/OpenGLDynamicTextureArray.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/texture/dynamic/OpenGLDynamicTextureArray.kt
index fe4762276..196688f5d 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/texture/dynamic/OpenGLDynamicTextureArray.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/texture/dynamic/OpenGLDynamicTextureArray.kt
@@ -14,11 +14,13 @@
package de.bixilon.minosoft.gui.rendering.system.opengl.texture.dynamic
import de.bixilon.kotlinglm.vec2.Vec2i
+import de.bixilon.kutil.concurrent.pool.DefaultThreadPool
import de.bixilon.kutil.latch.CountUpAndDownLatch
import de.bixilon.minosoft.gui.rendering.RenderWindow
import de.bixilon.minosoft.gui.rendering.system.base.shader.Shader
import de.bixilon.minosoft.gui.rendering.system.base.texture.dynamic.DynamicTexture
import de.bixilon.minosoft.gui.rendering.system.base.texture.dynamic.DynamicTextureArray
+import de.bixilon.minosoft.gui.rendering.system.base.texture.dynamic.DynamicTextureState
import de.bixilon.minosoft.gui.rendering.system.opengl.texture.OpenGLTextureUtil
import org.lwjgl.opengl.GL11.*
import org.lwjgl.opengl.GL12.glTexImage3D
@@ -54,6 +56,18 @@ class OpenGLDynamicTextureArray(
return pushBuffer(identifier) { ByteBuffer.wrap(data()) }
}
+ private fun load(texture: OpenGLDynamicTexture, index: Int, mipmaps: Array) {
+ glBindTexture(GL_TEXTURE_2D_ARRAY, textureId)
+
+ for ((level, mipmap) in mipmaps.withIndex()) {
+ glTexSubImage3D(GL_TEXTURE_2D_ARRAY, level, 0, 0, index, resolution shr level, resolution shr level, 1, GL_RGBA, GL_UNSIGNED_BYTE, mipmap)
+ }
+
+ texture.state = DynamicTextureState.LOADED
+ renderWindow.textureManager.staticTextures.activate()
+ }
+
+ @Synchronized
override fun pushBuffer(identifier: UUID, data: () -> ByteBuffer): OpenGLDynamicTexture {
check(textureId >= 0) { "Dynamic texture array not yet initialized!" }
cleanup()
@@ -62,20 +76,19 @@ class OpenGLDynamicTextureArray(
return texture
}
}
- val bytes = data()
-
- check(bytes.limit() == resolution * resolution * 4) { "Texture must have a size of ${resolution}x${resolution}" }
-
- val mipmaps = OpenGLTextureUtil.generateMipMaps(bytes, Vec2i(resolution, resolution))
val index = getNextIndex()
+ val texture = OpenGLDynamicTexture(identifier, createShaderIdentifier(index = index))
+ textures[index] = texture
+ texture.state = DynamicTextureState.LOADING
+ DefaultThreadPool += {
+ val bytes = data()
- glBindTexture(GL_TEXTURE_2D_ARRAY, textureId)
+ check(bytes.limit() == resolution * resolution * 4) { "Texture must have a size of ${resolution}x${resolution}" }
- for ((level, mipmap) in mipmaps.withIndex()) {
- glTexSubImage3D(GL_TEXTURE_2D_ARRAY, level, 0, 0, index, resolution shr level, resolution shr level, 1, GL_RGBA, GL_UNSIGNED_BYTE, mipmap)
+ val mipmaps = OpenGLTextureUtil.generateMipMaps(bytes, Vec2i(resolution, resolution))
+ renderWindow.queue += { load(texture, index, mipmaps) }
}
-
- return OpenGLDynamicTexture(identifier, createShaderIdentifier(index = index))
+ return texture
}
private fun createShaderIdentifier(array: Int = this.index, index: Int): Int {
@@ -96,11 +109,16 @@ class OpenGLDynamicTextureArray(
this.textureId = textureId
}
+ override fun activate() {
+ glActiveTexture(GL_TEXTURE0 + index)
+ glBindTexture(GL_TEXTURE_2D_ARRAY, textureId)
+ }
+
override fun use(shader: Shader, name: String) {
shader.use()
- glActiveTexture(GL_TEXTURE0 + index)
- glBindTexture(GL_TEXTURE_2D_ARRAY, textureId)
+ activate()
+
shader.setTexture("$name[$index]", index)
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/world/WorldRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/world/WorldRenderer.kt
index a83a1e3a6..2fdf6e760 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/world/WorldRenderer.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/world/WorldRenderer.kt
@@ -648,6 +648,7 @@ class WorldRenderer(
}
override fun prepareDraw() {
+ renderWindow.textureManager.staticTextures.use(shader)
if (clearVisibleNextFrame) {
visible.clear()
clearVisibleNextFrame = false
diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/tab/TabListS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/tab/TabListS2CP.kt
index 2502f36b5..0f52dfb80 100644
--- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/tab/TabListS2CP.kt
+++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/tab/TabListS2CP.kt
@@ -102,7 +102,11 @@ class TabListS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
// item not yet created
return@run null
}
- val item = TabListItem(name = data.name)
+ val item = if (entity === connection.player) {
+ connection.player.tabListItem
+ } else {
+ TabListItem(name = data.name)
+ }
connection.tabList.tabListItemsByUUID[uuid] = item
connection.tabList.tabListItemsByName[data.name] = item