mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-18 11:54:59 -04:00
load dynamic textures
This commit is contained in:
parent
888db361d9
commit
e2df230da4
@ -18,6 +18,7 @@ import de.bixilon.kutil.url.URLUtil.checkWeb
|
||||
import de.bixilon.minosoft.assets.util.FileAssetsUtil
|
||||
import de.bixilon.minosoft.assets.util.FileUtil
|
||||
import java.net.URL
|
||||
import java.util.*
|
||||
|
||||
open class PlayerTexture(
|
||||
val url: URL,
|
||||
@ -65,5 +66,9 @@ open class PlayerTexture(
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun UUID.isSteve(): Boolean {
|
||||
return hashCode() % 2 == 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2021 Moritz Zwerger
|
||||
* 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.
|
||||
*
|
||||
|
@ -150,7 +150,8 @@ class RenderWindow(
|
||||
val initLatch = CountUpAndDownLatch(1, latch)
|
||||
Log.log(LogMessageType.RENDERING_LOADING, LogLevels.VERBOSE) { "Generating font and gathering textures (${stopwatch.labTime()})..." }
|
||||
textureManager.dynamicTextures.load(initLatch)
|
||||
textureManager.loadDefaultTextures(connection.assetsManager)
|
||||
textureManager.loadDefaultSkins(connection)
|
||||
textureManager.loadDefaultTextures()
|
||||
font = FontLoader.load(this, initLatch)
|
||||
|
||||
|
||||
|
@ -34,8 +34,11 @@ open class DynamicImageElement(
|
||||
size: Vec2i = Vec2i.EMPTY,
|
||||
tint: RGBColor = ChatColors.WHITE,
|
||||
) : Element(guiRenderer, GUIMesh.GUIMeshStruct.FLOATS_PER_VERTEX * 6) {
|
||||
|
||||
var texture: DynamicTexture? = texture
|
||||
set(value) {
|
||||
field?.usages?.decrementAndGet()
|
||||
value?.usages?.incrementAndGet()
|
||||
field = value
|
||||
cacheUpToDate = false
|
||||
}
|
||||
@ -71,6 +74,7 @@ open class DynamicImageElement(
|
||||
|
||||
init {
|
||||
this.size = size
|
||||
texture?.usages?.incrementAndGet()
|
||||
}
|
||||
|
||||
override fun forceRender(offset: Vec2i, consumer: GUIVertexConsumer, options: GUIVertexOptions?) {
|
||||
|
@ -202,7 +202,7 @@ class TabListElement(guiRenderer: GUIRenderer) : Element(guiRenderer), LayoutedE
|
||||
|
||||
fun update(uuid: UUID) {
|
||||
val item = guiRenderer.renderWindow.connection.tabList.tabListItemsByUUID[uuid] ?: return
|
||||
val entry = entries.getOrPut(uuid) { TabListEntryElement(guiRenderer, this, item, 0) }
|
||||
val entry = entries.getOrPut(uuid) { TabListEntryElement(guiRenderer, this, uuid, item, 0) }
|
||||
lock.lock()
|
||||
entry.silentApply()
|
||||
lock.unlock()
|
||||
|
@ -33,10 +33,12 @@ import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.EMPTY
|
||||
import de.bixilon.minosoft.util.KUtil.nullCompare
|
||||
import java.lang.Integer.max
|
||||
import java.util.*
|
||||
|
||||
class TabListEntryElement(
|
||||
guiRenderer: GUIRenderer,
|
||||
val tabList: TabListElement,
|
||||
uuid: UUID,
|
||||
val item: TabListItem,
|
||||
width: Int,
|
||||
) : Element(guiRenderer), Pollable, Comparable<TabListEntryElement> {
|
||||
@ -47,7 +49,7 @@ class TabListEntryElement(
|
||||
|
||||
private val background: ColorElement
|
||||
|
||||
private val skinElement = DynamicImageElement(guiRenderer, guiRenderer.renderWindow.textureManager.alexTexture, uvStart = Vec2(0.125), uvEnd = Vec2(0.25), size = Vec2i(512, 512))
|
||||
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 = 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)
|
||||
@ -82,9 +84,8 @@ class TabListEntryElement(
|
||||
}
|
||||
|
||||
override fun forceRender(offset: Vec2i, consumer: GUIVertexConsumer, options: GUIVertexOptions?) {
|
||||
skinElement
|
||||
background.render(offset, consumer, options)
|
||||
skinElement.render(offset, consumer, options)
|
||||
skinElement.render(offset + Vec2i(PADDING, PADDING), consumer, options)
|
||||
nameElement.render(offset + Vec2i(skinElement.size.x + PADDING, PADDING), consumer, options)
|
||||
pingElement.render(offset + Vec2i(HorizontalAlignments.RIGHT.getOffset(maxSize.x, pingElement.size.x + PADDING), PADDING), consumer, options)
|
||||
}
|
||||
|
@ -16,7 +16,8 @@ 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.assets.AssetsManager
|
||||
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
|
||||
@ -25,7 +26,9 @@ import de.bixilon.minosoft.gui.rendering.system.base.texture.dynamic.DynamicText
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
|
||||
import de.bixilon.minosoft.gui.rendering.system.opengl.texture.OpenGLTextureUtil.readTexture
|
||||
import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.texture
|
||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
||||
import java.util.*
|
||||
|
||||
abstract class TextureManager {
|
||||
abstract val staticTextures: StaticTextureArray
|
||||
@ -39,21 +42,31 @@ abstract class TextureManager {
|
||||
private set
|
||||
lateinit var alexTexture: DynamicTexture
|
||||
private set
|
||||
lateinit var skin: DynamicTexture
|
||||
private set
|
||||
|
||||
fun loadDefaultTextures(assetsManager: AssetsManager) {
|
||||
fun loadDefaultTextures() {
|
||||
if (this::debugTexture.isInitialized) {
|
||||
throw IllegalStateException("Already initialized!")
|
||||
}
|
||||
debugTexture = staticTextures.createTexture(RenderConstants.DEBUG_TEXTURE_RESOURCE_LOCATION)
|
||||
// steveTexture = staticTextures.createTexture("minecraft:entity/steve".toResourceLocation().texture())
|
||||
whiteTexture = TextureLikeTexture(texture = staticTextures.createTexture(ResourceLocation("minosoft:textures/white.png")), uvStart = Vec2(0.0f, 0.0f), uvEnd = Vec2(0.001f, 0.001f), size = Vec2i(16, 16))
|
||||
|
||||
loadDefaultSkins(assetsManager)
|
||||
}
|
||||
|
||||
private fun loadDefaultSkins(assetsManager: AssetsManager) {
|
||||
fun loadDefaultSkins(connection: PlayConnection) {
|
||||
// ToDo: For testing purposes only, they will be moved to static textures
|
||||
steveTexture = dynamicTextures.push("3780a46b-a725-4b22-8366-01056c698386".toUUID()) { assetsManager["minecraft:entity/steve".toResourceLocation().texture()].readTexture().second }
|
||||
alexTexture = dynamicTextures.push("3780a46b-a725-4b22-8366-01056c698386".toUUID()) { assetsManager["minecraft:entity/alex".toResourceLocation().texture()].readTexture().second }
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
fun getSkin(uuid: UUID, properties: PlayerTextures?): DynamicTexture {
|
||||
properties?.skin?.let { return dynamicTextures.pushRawArray(uuid) { it.read() } }
|
||||
if (uuid.isSteve()) {
|
||||
return steveTexture
|
||||
}
|
||||
return alexTexture
|
||||
}
|
||||
}
|
||||
|
@ -14,13 +14,18 @@
|
||||
package de.bixilon.minosoft.gui.rendering.system.base.texture.dynamic
|
||||
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureArray
|
||||
import de.bixilon.minosoft.gui.rendering.system.opengl.texture.OpenGLTextureUtil.readTexture
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.nio.ByteBuffer
|
||||
import java.util.*
|
||||
|
||||
interface DynamicTextureArray : TextureArray {
|
||||
val size: Int
|
||||
|
||||
fun push(identifier: UUID, data: () -> ByteBuffer): DynamicTexture
|
||||
fun remove(texture: DynamicTexture)
|
||||
fun remove(uuid: UUID)
|
||||
fun pushBuffer(identifier: UUID, data: () -> ByteBuffer): DynamicTexture
|
||||
fun pushArray(identifier: UUID, data: () -> ByteArray): DynamicTexture
|
||||
|
||||
fun pushRawArray(identifier: UUID, data: () -> ByteArray): DynamicTexture {
|
||||
return pushBuffer(identifier) { ByteArrayInputStream(data()).readTexture().second }
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,15 @@ import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
class OpenGLDynamicTexture(
|
||||
override val uuid: UUID,
|
||||
override val shaderId: Int,
|
||||
shaderId: Int,
|
||||
) : DynamicTexture {
|
||||
override val usages = AtomicInteger()
|
||||
|
||||
override val shaderId: Int = shaderId
|
||||
get() {
|
||||
if (usages.get() == 0) {
|
||||
throw IllegalStateException("Texture was eventually garbage collected")
|
||||
}
|
||||
return field
|
||||
}
|
||||
}
|
||||
|
@ -32,33 +32,42 @@ import java.util.*
|
||||
class OpenGLDynamicTextureArray(
|
||||
val renderWindow: RenderWindow,
|
||||
val index: Int = 7,
|
||||
initialSize: Int = 32,
|
||||
val resolution: Int,
|
||||
) : DynamicTextureArray {
|
||||
private val textures: Array<OpenGLDynamicTexture?> = arrayOfNulls(2)
|
||||
private val textures: Array<OpenGLDynamicTexture?> = arrayOfNulls(initialSize)
|
||||
private var textureId = -1
|
||||
|
||||
@Deprecated("temp")
|
||||
private var lastTextureId = 0
|
||||
|
||||
override val size: Int
|
||||
get() = 2
|
||||
get() {
|
||||
var size = 0
|
||||
for (texture in textures) {
|
||||
if (texture == null) {
|
||||
continue
|
||||
}
|
||||
size++
|
||||
}
|
||||
return size
|
||||
}
|
||||
|
||||
override fun remove(uuid: UUID) {
|
||||
TODO("Not yet implemented")
|
||||
override fun pushArray(identifier: UUID, data: () -> ByteArray): DynamicTexture {
|
||||
return pushBuffer(identifier) { ByteBuffer.wrap(data()) }
|
||||
}
|
||||
|
||||
override fun remove(texture: DynamicTexture) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun push(identifier: UUID, data: () -> ByteBuffer): OpenGLDynamicTexture {
|
||||
override fun pushBuffer(identifier: UUID, data: () -> ByteBuffer): OpenGLDynamicTexture {
|
||||
check(textureId >= 0) { "Dynamic texture array not yet initialized!" }
|
||||
cleanup()
|
||||
for (texture in textures) {
|
||||
if (texture?.uuid == identifier) {
|
||||
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 = lastTextureId++
|
||||
val index = getNextIndex()
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, textureId)
|
||||
|
||||
@ -94,4 +103,31 @@ class OpenGLDynamicTextureArray(
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, textureId)
|
||||
shader.setTexture("$name[$index]", index)
|
||||
}
|
||||
|
||||
private fun getNextIndex(): Int {
|
||||
for ((index, texture) in textures.withIndex()) {
|
||||
if (texture == null) {
|
||||
return index
|
||||
}
|
||||
}
|
||||
val nextIndex = textures.size
|
||||
grow()
|
||||
return nextIndex
|
||||
}
|
||||
|
||||
private fun grow() {
|
||||
TODO()
|
||||
}
|
||||
|
||||
private fun cleanup() {
|
||||
for ((index, texture) in textures.withIndex()) {
|
||||
if (texture == null) {
|
||||
continue
|
||||
}
|
||||
if (texture.usages.get() > 0) {
|
||||
continue
|
||||
}
|
||||
textures[index] = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -186,7 +186,7 @@ class NettyClient(
|
||||
if (RunConfiguration.DISABLE_EROS || connection !is StatusConnection) {
|
||||
Log.log(LogMessageType.NETWORK_PACKETS_IN, LogLevels.WARN) { cause }
|
||||
}
|
||||
if (cause !is NetworkException || cause is CriticalNetworkException) {
|
||||
if (cause !is NetworkException || cause is CriticalNetworkException || state == ProtocolStates.LOGIN) {
|
||||
connection.error = cause
|
||||
if (reportErrors && !ErosCrashReport.alreadyCrashed) {
|
||||
cause.report()
|
||||
|
Loading…
x
Reference in New Issue
Block a user