diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/font/types/bitmap/BitmapFontTypeTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/font/types/bitmap/BitmapFontTypeTest.kt index 67b56fc91..e96ff6fa0 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/font/types/bitmap/BitmapFontTypeTest.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/font/types/bitmap/BitmapFontTypeTest.kt @@ -16,6 +16,7 @@ package de.bixilon.minosoft.gui.rendering.font.types.bitmap import de.bixilon.kotlinglm.vec2.Vec2 import de.bixilon.kotlinglm.vec2.Vec2i import de.bixilon.minosoft.gui.rendering.font.types.empty.EmptyCodeRenderer +import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureFormats import de.bixilon.minosoft.gui.rendering.system.base.texture.data.TextureData import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture import de.bixilon.minosoft.gui.rendering.system.dummy.texture.DummyTexture @@ -35,7 +36,7 @@ class BitmapFontTypeTest { val rows = (start.size / 16) + if (start.size % 16 == 0) 0 else 1 val size = Vec2i(width * 16, rows * height) - val buffer = ByteBuffer.allocate(size.x * size.y * 4) + val buffer = ByteBuffer.allocate(size.x * size.y) for (row in 0 until rows) { for (height in 0 until height) { @@ -44,10 +45,6 @@ class BitmapFontTypeTest { val end = end.getOrNull((row * 16) + char) ?: width for (pixel in 0 until width) { - buffer.put(0xFF.toByte()) - buffer.put(0xFF.toByte()) - buffer.put(0xFF.toByte()) - if (pixel in start..end) { buffer.put(0xFF.toByte()) } else { @@ -61,7 +58,7 @@ class BitmapFontTypeTest { val texture = DummyTexture() texture.size = size - texture.data = TextureData(size, buffer) + texture.data = TextureData(size, TextureFormats.RGBA2, buffer) return texture } diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/font/types/unicode/unihex/UnihexFontTypeTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/font/types/unicode/unihex/UnihexFontTypeTest.kt index 8470049c3..7a4e21db3 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/font/types/unicode/unihex/UnihexFontTypeTest.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/font/types/unicode/unihex/UnihexFontTypeTest.kt @@ -78,9 +78,7 @@ class UnihexFontTypeTest { } private fun ByteArray.assertPixel(index: Int, set: Boolean = true) { - val offset = index * 4 - - val value = this[offset + 0].toInt() or this[offset + 1].toInt() or this[offset + 2].toInt() or this[offset + 3].toInt() + val value = this[index + 0].toInt() if (set) { assertTrue(value != 0, "Did expect pixel at $index") diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/gui/elements/input/button/ButtonElementTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/gui/elements/input/button/ButtonElementTest.kt index 36074c35f..eb12d6318 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/gui/elements/input/button/ButtonElementTest.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/gui/elements/input/button/ButtonElementTest.kt @@ -17,11 +17,18 @@ import de.bixilon.kotlinglm.vec2.Vec2 import de.bixilon.minosoft.gui.rendering.gui.test.GuiRenderTestUtil import de.bixilon.minosoft.gui.rendering.gui.test.GuiTestConsumer import org.testng.Assert.assertEquals +import org.testng.Assert.assertFalse import org.testng.annotations.Test @Test(groups = ["gui"]) class ButtonElementTest { + fun `initial clean`() { + val button = ButtonElement(GuiRenderTestUtil.create(), "bc") { } + assertFalse(button.update) + } + + fun `basic verification`() { var invoked = 0 val button = ButtonElement(GuiRenderTestUtil.create(), "bc") { invoked++ } diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/gui/elements/text/TextElementTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/gui/elements/text/TextElementTest.kt index 802d579d7..4cad0f696 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/gui/elements/text/TextElementTest.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/gui/elements/text/TextElementTest.kt @@ -23,6 +23,7 @@ import de.bixilon.minosoft.gui.rendering.gui.test.GuiRenderTestUtil.assetSize import de.bixilon.minosoft.gui.rendering.gui.test.GuiTestConsumer import de.bixilon.minosoft.gui.rendering.util.vec.vec4.Vec4Util.marginOf import org.testng.Assert.assertEquals +import org.testng.Assert.assertFalse import org.testng.annotations.Test @Test(groups = ["font", "gui"]) @@ -33,6 +34,11 @@ class TextElementTest { element.assetSize(Vec2(0, 0)) } + fun `initial clean`() { + val element = TextElement(GuiRenderTestUtil.create(), "") + assertFalse(element.update) + } + fun `size of single char`() { val element = TextElement(GuiRenderTestUtil.create(), "b", background = null, properties = TextRenderProperties(shadow = false)) element.assetSize(Vec2(0.5f, 11.0f)) diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/system/dummy/texture/DummyStaticTextureArray.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/system/dummy/texture/DummyStaticTextureArray.kt index 1e39aafbd..1be45e548 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/system/dummy/texture/DummyStaticTextureArray.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/system/dummy/texture/DummyStaticTextureArray.kt @@ -18,6 +18,7 @@ import de.bixilon.kutil.latch.AbstractLatch import de.bixilon.minosoft.data.registries.identified.ResourceLocation import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem import de.bixilon.minosoft.gui.rendering.system.base.shader.NativeShader +import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureFormats import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureStates import de.bixilon.minosoft.gui.rendering.system.base.texture.array.StaticTextureArray import de.bixilon.minosoft.gui.rendering.system.base.texture.array.TextureArrayStates @@ -35,7 +36,7 @@ class DummyStaticTextureArray(renderSystem: RenderSystem) : StaticTextureArray { TODO("Not yet implemented") } - override fun createTexture(resourceLocation: ResourceLocation, mipmaps: Boolean, properties: Boolean, default: (mipmaps: Boolean) -> Texture): Texture { + override fun createTexture(resourceLocation: ResourceLocation, mipmaps: Boolean, format: TextureFormats, properties: Boolean, default: (mipmaps: Boolean) -> Texture): Texture { return textures.getOrPut(resourceLocation) { DummyTexture() } } diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/system/dummy/texture/DummyTexture.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/system/dummy/texture/DummyTexture.kt index 993f2007c..f226ebdfb 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/system/dummy/texture/DummyTexture.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/system/dummy/texture/DummyTexture.kt @@ -16,6 +16,7 @@ package de.bixilon.minosoft.gui.rendering.system.dummy.texture import de.bixilon.kotlinglm.vec2.Vec2 import de.bixilon.kotlinglm.vec2.Vec2i import de.bixilon.minosoft.gui.rendering.RenderContext +import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureFormats import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureStates import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureTransparencies import de.bixilon.minosoft.gui.rendering.system.base.texture.array.TextureArrayProperties @@ -36,6 +37,6 @@ class DummyTexture : Texture { override var mipmaps: Boolean = false override fun load(context: RenderContext) { - data = TextureData(size, TextureGenerator.allocate(size)) + data = TextureData(size, TextureFormats.RGBA8, TextureGenerator.allocate(size, TextureFormats.RGBA8)) } } diff --git a/src/main/java/de/bixilon/minosoft/data/text/formatting/color/ColorUtil.kt b/src/main/java/de/bixilon/minosoft/data/text/formatting/color/ColorUtil.kt index 111fba22d..7dedbfab5 100644 --- a/src/main/java/de/bixilon/minosoft/data/text/formatting/color/ColorUtil.kt +++ b/src/main/java/de/bixilon/minosoft/data/text/formatting/color/ColorUtil.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020-2022 Moritz Zwerger + * Copyright (C) 2020-2023 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. * @@ -33,4 +33,14 @@ object ColorUtil { val color = (this * RGBColor.COLOR_FLOAT_DIVIDER).toInt() return color shl 16 or color shl 8 or color } + + + fun rgba8ToRgba2(rgba8: Int): Byte { + val red = (rgba8 shr 24 + 6) and 0x03 + val green = (rgba8 shr 16 + 6) and 0x03 + val blue = (rgba8 shr 8 + 6) and 0x03 + val alpha = (rgba8 shr 0 + 6) and 0x03 + + return ((red shl 6) or (green shl 4) or (blue shl 2) or alpha).toByte() + } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/font/types/bitmap/BitmapFontType.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/font/types/bitmap/BitmapFontType.kt index 2b7adb2db..6c6c8b6a2 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/font/types/bitmap/BitmapFontType.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/font/types/bitmap/BitmapFontType.kt @@ -27,6 +27,7 @@ import de.bixilon.minosoft.gui.rendering.font.renderer.properties.FontProperties import de.bixilon.minosoft.gui.rendering.font.types.PostInitFontType import de.bixilon.minosoft.gui.rendering.font.types.empty.EmptyCodeRenderer import de.bixilon.minosoft.gui.rendering.font.types.factory.FontTypeFactory +import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureFormats import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.texture import de.bixilon.minosoft.util.KUtil.toResourceLocation @@ -73,7 +74,7 @@ class BitmapFontType( private fun load(file: ResourceLocation, height: Int, ascent: Int, chars: List, context: RenderContext): BitmapFontType? { if (chars.isEmpty() || height <= 0) return null - val texture = context.textures.staticTextures.createTexture(file, mipmaps = false, properties = false) + val texture = context.textures.staticTextures.createTexture(file, mipmaps = false, format = TextureFormats.RGBA2, properties = false) texture.load(context) // force load it, we need to calculate the width of every char return load(texture, height, ascent, chars.codePoints()) @@ -82,7 +83,7 @@ class BitmapFontType( private fun ByteBuffer.scanLine(y: Int, width: Int, start: IntArray, end: IntArray) { for (index in 0 until (width * ROW)) { val pixelIndex = ((ROW * width * y) + index) - val alpha = this[pixelIndex * 4 + 3].toInt() // index * rgba + a + val alpha = this[pixelIndex].toInt() and 0x03 // index * rgba + a if (alpha == 0) { // transparent continue diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/font/types/unicode/legacy/LegacyUnicodeFontType.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/font/types/unicode/legacy/LegacyUnicodeFontType.kt index 2597bf71b..1dc7670e5 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/font/types/unicode/legacy/LegacyUnicodeFontType.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/font/types/unicode/legacy/LegacyUnicodeFontType.kt @@ -26,6 +26,7 @@ import de.bixilon.minosoft.gui.rendering.font.renderer.properties.FontProperties import de.bixilon.minosoft.gui.rendering.font.types.PostInitFontType import de.bixilon.minosoft.gui.rendering.font.types.factory.FontTypeFactory import de.bixilon.minosoft.gui.rendering.font.types.unicode.UnicodeCodeRenderer +import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureFormats import de.bixilon.minosoft.gui.rendering.system.base.texture.array.StaticTextureArray import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.texture @@ -84,7 +85,7 @@ class LegacyUnicodeFontType( sizes.skip(PAGE_SIZE.toLong()) return } - val texture = textures.createTexture(textureFile, mipmaps = false, properties = false) + val texture = textures.createTexture(textureFile, mipmaps = false, format = TextureFormats.RGBA2, properties = false) loadPage(pageId, texture, chars, sizes) } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/font/types/unicode/unihex/UnifontTexture.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/font/types/unicode/unihex/UnifontTexture.kt index 4f5702018..9067d62f5 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/font/types/unicode/unihex/UnifontTexture.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/font/types/unicode/unihex/UnifontTexture.kt @@ -20,6 +20,7 @@ import de.bixilon.minosoft.gui.rendering.RenderContext import de.bixilon.minosoft.gui.rendering.font.renderer.code.CodePointRenderer import de.bixilon.minosoft.gui.rendering.font.renderer.properties.FontProperties import de.bixilon.minosoft.gui.rendering.font.types.unicode.UnicodeCodeRenderer +import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureFormats import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureStates import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureTransparencies import de.bixilon.minosoft.gui.rendering.system.base.texture.array.TextureArrayProperties @@ -39,7 +40,7 @@ class UnifontTexture( override lateinit var array: TextureArrayProperties override lateinit var renderData: TextureRenderData - override var data: TextureData = TextureData(size) + override var data: TextureData = TextureData(size, TextureFormats.RGBA2) override var properties = ImageProperties.DEFAULT override val state: TextureStates = TextureStates.LOADED @@ -60,9 +61,9 @@ class UnifontTexture( } private fun TextureData.set(row: Int, offset: Int, x: Int, y: Int) { - val index = ((row * UnifontRasterizer.HEIGHT + y) * resolution + offset + x) * 4 + val index = (row * UnifontRasterizer.HEIGHT + y) * resolution + offset + x - buffer.putInt(index, 0xFFFFFFFF.toInt()) + buffer.put(index, 0xFF.toByte()) } private fun rasterize(row: Int, offset: Int, start: Int, end: Int, dataWidth: Int, data: ByteArray): CodePointRenderer { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/input/button/ButtonElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/input/button/ButtonElement.kt index 4eab04419..a4739c206 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/input/button/ButtonElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/input/button/ButtonElement.kt @@ -60,7 +60,7 @@ open class ButtonElement( init { padding = Vec4(4.0f) - updateSize() + tryUpdate() } protected fun updateSize() { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/HUDManager.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/HUDManager.kt index 3d924a397..384eec5e3 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/HUDManager.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/HUDManager.kt @@ -17,12 +17,12 @@ import de.bixilon.kutil.cast.CastUtil.unsafeCast import de.bixilon.kutil.collections.CollectionUtil.lockMapOf import de.bixilon.kutil.collections.CollectionUtil.toSynchronizedMap import de.bixilon.kutil.collections.map.LockMap -import de.bixilon.kutil.concurrent.pool.DefaultThreadPool import de.bixilon.kutil.latch.SimpleLatch import de.bixilon.minosoft.config.key.KeyActions import de.bixilon.minosoft.config.key.KeyBinding import de.bixilon.minosoft.config.key.KeyCodes import de.bixilon.minosoft.data.registries.identified.ResourceLocation +import de.bixilon.minosoft.gui.rendering.RenderUtil.runAsync import de.bixilon.minosoft.gui.rendering.gui.GUIElementDrawer import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer import de.bixilon.minosoft.gui.rendering.gui.gui.LayoutedGUIElement @@ -69,7 +69,7 @@ class HUDManager( for (builder in DEFAULT_ELEMENTS) { latch.inc() - DefaultThreadPool += { registerElement(builder); latch.dec() } + context.runAsync { registerElement(builder); latch.dec() } } latch.dec() latch.await() diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/sky/clouds/CloudMatrix.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/sky/clouds/CloudMatrix.kt index c40931a44..5e9ae9496 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/sky/clouds/CloudMatrix.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/sky/clouds/CloudMatrix.kt @@ -16,6 +16,7 @@ package de.bixilon.minosoft.gui.rendering.sky.clouds import de.bixilon.minosoft.assets.AssetsManager import de.bixilon.minosoft.config.DebugOptions import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft +import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureFormats import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.readTexture import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.texture import java.util.* @@ -25,7 +26,7 @@ class CloudMatrix { fun load(assetsManager: AssetsManager) { - val data = assetsManager[CLOUD_MATRIX].readTexture() + val data = assetsManager[CLOUD_MATRIX].readTexture(TextureFormats.RGBA2) // TODO: luminance if (data.size.x != CLOUD_MATRIX_SIZE || data.size.y != CLOUD_MATRIX_SIZE) { throw IllegalStateException("Cloud matrix has invalid size: ${data.size}") @@ -35,7 +36,7 @@ class CloudMatrix { if (DebugOptions.CLOUD_RASTER) { matrix[i] = if ((i / CLOUD_MATRIX_SIZE) % 2 == 0) (i + 1) % 2 == 0 else (i % 2) == 0 } else { - matrix[i] = data.buffer.getInt(i * 4) ushr 24 == 0xFF + matrix[i] = data.buffer.getInt(i) != 0x00 } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/TextureFormats.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/TextureFormats.kt new file mode 100644 index 000000000..c0b985e1a --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/TextureFormats.kt @@ -0,0 +1,20 @@ +/* + * Minosoft + * Copyright (C) 2020-2023 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 + +enum class TextureFormats(val bytes: Int) { + RGBA8(4), + RGBA2(1), + ; +} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/array/StaticTextureArray.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/array/StaticTextureArray.kt index e76dca9db..d601ef3f8 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/array/StaticTextureArray.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/array/StaticTextureArray.kt @@ -15,6 +15,7 @@ package de.bixilon.minosoft.gui.rendering.system.base.texture.array import de.bixilon.kutil.latch.AbstractLatch import de.bixilon.minosoft.data.registries.identified.ResourceLocation +import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureFormats import de.bixilon.minosoft.gui.rendering.system.base.texture.sprite.SpriteAnimator import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.file.PNGTexture @@ -26,7 +27,7 @@ interface StaticTextureArray : TextureArray { fun get(resourceLocation: ResourceLocation): Texture? fun pushTexture(texture: Texture) - fun createTexture(resourceLocation: ResourceLocation, mipmaps: Boolean = true, properties: Boolean = true, default: (mipmaps: Boolean) -> Texture = { PNGTexture(resourceLocation, mipmaps = it) }): Texture + fun createTexture(resourceLocation: ResourceLocation, mipmaps: Boolean = true, format: TextureFormats = TextureFormats.RGBA8, properties: Boolean = true, default: (mipmaps: Boolean) -> Texture = { PNGTexture(resourceLocation, format = format, mipmaps = it) }): Texture fun preLoad(latch: AbstractLatch) } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/data/MipmapTextureData.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/data/MipmapTextureData.kt index 54f09dde4..55ca0ede4 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/data/MipmapTextureData.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/data/MipmapTextureData.kt @@ -14,14 +14,16 @@ package de.bixilon.minosoft.gui.rendering.system.base.texture.data import de.bixilon.kotlinglm.vec2.Vec2i +import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureFormats import de.bixilon.minosoft.gui.rendering.system.opengl.texture.OpenGLTextureUtil import java.nio.ByteBuffer open class MipmapTextureData( size: Vec2i, + format: TextureFormats, buffer: ByteBuffer, -) : TextureData(size, buffer) { - val mipmaps: Array = OpenGLTextureUtil.generateMipMaps(buffer, size) +) : TextureData(size, format, buffer) { + val mipmaps: Array = OpenGLTextureUtil.generateMipMaps(buffer, format, size) override fun collect(): Array = mipmaps } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/data/TextureData.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/data/TextureData.kt index 467c6d032..24c4d611f 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/data/TextureData.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/data/TextureData.kt @@ -14,15 +14,17 @@ package de.bixilon.minosoft.gui.rendering.system.base.texture.data import de.bixilon.kotlinglm.vec2.Vec2i +import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureFormats import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.memory.TextureGenerator import org.objenesis.ObjenesisStd import java.nio.ByteBuffer open class TextureData( val size: Vec2i, - val buffer: ByteBuffer = TextureGenerator.allocate(size), + val format: TextureFormats, + val buffer: ByteBuffer = TextureGenerator.allocate(size, format), ) { - constructor(size: Vec2i, array: ByteArray) : this(size, ByteBuffer.wrap(array)) + constructor(size: Vec2i, format: TextureFormats, array: ByteArray) : this(size, format, ByteBuffer.wrap(array)) open fun collect(): Array = arrayOf(buffer) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/dynamic/DynamicTextureArray.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/dynamic/DynamicTextureArray.kt index 6d2be9145..ebda39d1d 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/dynamic/DynamicTextureArray.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/dynamic/DynamicTextureArray.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020-2022 Moritz Zwerger + * Copyright (C) 2020-2023 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. * @@ -13,6 +13,7 @@ package de.bixilon.minosoft.gui.rendering.system.base.texture.dynamic +import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureFormats import de.bixilon.minosoft.gui.rendering.system.base.texture.array.TextureArray import de.bixilon.minosoft.gui.rendering.system.base.texture.data.TextureData import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.readTexture @@ -25,6 +26,6 @@ interface DynamicTextureArray : TextureArray { fun pushBuffer(identifier: UUID, force: Boolean = false, data: () -> TextureData): DynamicTexture fun pushRawArray(identifier: UUID, force: Boolean = false, data: () -> ByteArray): DynamicTexture { - return pushBuffer(identifier, force) { ByteArrayInputStream(data()).readTexture() } + return pushBuffer(identifier, force) { ByteArrayInputStream(data()).readTexture(TextureFormats.RGBA8) } } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/skin/vanilla/DefaultSkinProvider.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/skin/vanilla/DefaultSkinProvider.kt index 1382fca8a..89127f976 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/skin/vanilla/DefaultSkinProvider.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/skin/vanilla/DefaultSkinProvider.kt @@ -18,6 +18,7 @@ import de.bixilon.minosoft.assets.AssetsManager import de.bixilon.minosoft.data.entities.entities.player.PlayerEntity import de.bixilon.minosoft.data.entities.entities.player.properties.textures.metadata.SkinModel import de.bixilon.minosoft.data.registries.identified.ResourceLocation +import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureFormats 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.skin.PlayerSkin @@ -65,7 +66,7 @@ class DefaultSkinProvider( } private fun load(path: ResourceLocation): DynamicTexture? { - val data = assets.getOrNull(path)?.readTexture() ?: return null + val data = assets.getOrNull(path)?.readTexture(TextureFormats.RGBA8) ?: return null val texture = array.pushBuffer(UUID(0L, defaultId++.toLong()), true) { data } texture.usages.incrementAndGet() return texture diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/sprite/SpriteTexture.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/sprite/SpriteTexture.kt index a5a2a1c9f..efb71fea7 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/sprite/SpriteTexture.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/sprite/SpriteTexture.kt @@ -59,11 +59,11 @@ class SpriteTexture(private val original: Texture) : Texture { val bytesPerTexture = size.x * size.y * PNGDecoder.Format.RGBA.numComponents for (i in 0 until animationProperties.frameCount) { - val buffer = TextureGenerator.allocate(size) + val buffer = TextureGenerator.allocate(size, data.format) buffer.copyFrom(original, bytesPerTexture * i, 0, bytesPerTexture) buffer.flip() - val splitTexture = MemoryTexture(size, mipmaps = true, buffer = buffer) + val splitTexture = MemoryTexture(size, mipmaps = true, format = data.format, buffer = buffer) splitTextures += splitTexture } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/texture/Texture.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/texture/Texture.kt index 53d0ea862..e88720be3 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/texture/Texture.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/texture/Texture.kt @@ -16,6 +16,7 @@ package de.bixilon.minosoft.gui.rendering.system.base.texture.texture import de.bixilon.kotlinglm.vec2.Vec2 import de.bixilon.kotlinglm.vec2.Vec2i import de.bixilon.minosoft.gui.rendering.RenderContext +import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureFormats import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureStates import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureTransparencies import de.bixilon.minosoft.gui.rendering.system.base.texture.array.TextureArrayProperties @@ -52,7 +53,7 @@ interface Texture : ShaderTexture { return renderData.transformUV(end) } - fun createData(mipmaps: Boolean = this.mipmaps, size: Vec2i, buffer: ByteBuffer): TextureData { - return if (mipmaps) MipmapTextureData(size, buffer) else TextureData(size, buffer) + fun createData(mipmaps: Boolean = this.mipmaps, size: Vec2i, format: TextureFormats, buffer: ByteBuffer): TextureData { + return if (mipmaps) MipmapTextureData(size, format, buffer) else TextureData(size, format, buffer) } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/texture/file/PNGTexture.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/texture/file/PNGTexture.kt index 935f15e6c..d40da1ab7 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/texture/file/PNGTexture.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/texture/file/PNGTexture.kt @@ -17,6 +17,7 @@ import de.bixilon.kotlinglm.vec2.Vec2i import de.bixilon.minosoft.assets.AssetsManager import de.bixilon.minosoft.data.registries.identified.ResourceLocation import de.bixilon.minosoft.gui.rendering.RenderConstants +import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureFormats import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureStates import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureTransparencies import de.bixilon.minosoft.gui.rendering.system.base.texture.array.TextureArrayProperties @@ -34,6 +35,7 @@ import java.io.FileNotFoundException class PNGTexture( override val resourceLocation: ResourceLocation, override var mipmaps: Boolean = true, + val format: TextureFormats = TextureFormats.RGBA8, ) : FileTexture { override lateinit var renderData: TextureRenderData @@ -57,17 +59,17 @@ class PNGTexture( } var data = try { - assetsManager[resourceLocation].readTexture() + assetsManager[resourceLocation].readTexture(format) } catch (error: Throwable) { state = TextureStates.ERRORED Log.log(LogMessageType.RENDERING, LogLevels.WARN) { "Can not load texture $resourceLocation: $error" } if (error !is FileNotFoundException) { Log.log(LogMessageType.RENDERING, LogLevels.VERBOSE) { error } } - assetsManager[RenderConstants.DEBUG_TEXTURE_RESOURCE_LOCATION].readTexture() + assetsManager[RenderConstants.DEBUG_TEXTURE_RESOURCE_LOCATION].readTexture(format) } data.buffer.rewind() - if (mipmaps) data = MipmapTextureData(data.size, data.buffer) + if (mipmaps) data = MipmapTextureData(data.size, format, data.buffer) this.size = data.size transparency = TextureTransparencies.OPAQUE diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/texture/memory/MemoryTexture.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/texture/memory/MemoryTexture.kt index 0c291f6e0..896ab1378 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/texture/memory/MemoryTexture.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/texture/memory/MemoryTexture.kt @@ -15,6 +15,7 @@ package de.bixilon.minosoft.gui.rendering.system.base.texture.texture.memory import de.bixilon.kotlinglm.vec2.Vec2i import de.bixilon.minosoft.gui.rendering.RenderContext +import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureFormats import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureStates import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureTransparencies import de.bixilon.minosoft.gui.rendering.system.base.texture.array.TextureArrayProperties @@ -28,16 +29,17 @@ class MemoryTexture( override val size: Vec2i, override var properties: ImageProperties = ImageProperties(), override var mipmaps: Boolean = true, + format: TextureFormats, buffer: ByteBuffer, ) : Texture { override lateinit var array: TextureArrayProperties override lateinit var renderData: TextureRenderData override var transparency: TextureTransparencies = TextureTransparencies.OPAQUE private set - override var data: TextureData = createData(mipmaps, size, buffer) + override var data: TextureData = createData(mipmaps, size, format, buffer) init { - if (buffer.limit() != TextureGenerator.getBufferSize(size)) throw IllegalArgumentException("Invalid buffer size: ${buffer.limit()}") + if (buffer.limit() != TextureGenerator.getBufferSize(size, format)) throw IllegalArgumentException("Invalid buffer size: ${buffer.limit()}") } override val state: TextureStates = TextureStates.LOADED diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/texture/memory/TextureGenerator.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/texture/memory/TextureGenerator.kt index c19f142d1..86eda91ee 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/texture/memory/TextureGenerator.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/texture/memory/TextureGenerator.kt @@ -14,12 +14,14 @@ package de.bixilon.minosoft.gui.rendering.system.base.texture.texture.memory import de.bixilon.kotlinglm.vec2.Vec2i -import de.matthiasmann.twl.utils.PNGDecoder +import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureFormats import org.lwjgl.BufferUtils object TextureGenerator { - fun getBufferSize(size: Vec2i) = size.x * size.y * PNGDecoder.Format.RGBA.numComponents + fun getBufferSize(size: Vec2i, bytes: Int) = size.x * size.y * bytes + fun getBufferSize(size: Vec2i, format: TextureFormats) = getBufferSize(size, format.bytes) - fun allocate(size: Vec2i) = BufferUtils.createByteBuffer(getBufferSize(size)) + fun allocate(size: Vec2i, bytes: Int) = BufferUtils.createByteBuffer(getBufferSize(size, bytes)) + fun allocate(size: Vec2i, format: TextureFormats) = allocate(size, format.bytes) } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/buffer/frame/texture/OpenGLTexture.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/buffer/frame/texture/OpenGLTexture.kt index c04614882..03a3fb9c1 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/buffer/frame/texture/OpenGLTexture.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/buffer/frame/texture/OpenGLTexture.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020-2022 Moritz Zwerger + * Copyright (C) 2020-2023 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. * @@ -24,7 +24,7 @@ abstract class OpenGLTexture { abstract fun init() fun bind(target: Int) { - check(target in 0 until 12) + check(target in 0 until 16) glActiveTexture(GL_TEXTURE0 + target) glBindTexture(GL_TEXTURE_2D, id) } 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 e938a9316..7b2cc7ff0 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 @@ -24,6 +24,7 @@ import de.bixilon.minosoft.assets.util.InputStreamUtil.readAsString import de.bixilon.minosoft.data.registries.identified.ResourceLocation import de.bixilon.minosoft.gui.rendering.RenderContext import de.bixilon.minosoft.gui.rendering.system.base.shader.NativeShader +import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureFormats import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureStates import de.bixilon.minosoft.gui.rendering.system.base.texture.array.StaticTextureArray import de.bixilon.minosoft.gui.rendering.system.base.texture.array.TextureArrayProperties @@ -32,6 +33,7 @@ import de.bixilon.minosoft.gui.rendering.system.base.texture.data.TextureData import de.bixilon.minosoft.gui.rendering.system.base.texture.sprite.SpriteAnimator import de.bixilon.minosoft.gui.rendering.system.base.texture.sprite.SpriteTexture import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture +import de.bixilon.minosoft.gui.rendering.system.opengl.texture.OpenGLTextureUtil.gl import de.bixilon.minosoft.gui.rendering.textures.TextureAnimation import de.bixilon.minosoft.gui.rendering.textures.properties.ImageProperties import de.bixilon.minosoft.util.KUtil.toResourceLocation @@ -73,7 +75,7 @@ class OpenGLTextureArray( } @Synchronized - override fun createTexture(resourceLocation: ResourceLocation, mipmaps: Boolean, properties: Boolean, default: (mipmaps: Boolean) -> Texture): Texture { + override fun createTexture(resourceLocation: ResourceLocation, mipmaps: Boolean, format: TextureFormats, properties: Boolean, default: (mipmaps: Boolean) -> Texture): Texture { namedTextures[resourceLocation]?.let { return it } // load .mcmeta @@ -189,7 +191,7 @@ class OpenGLTextureArray( for ((level, data) in texture.data.collect().withIndex()) { val size = texture.size shr level - glTexSubImage3D(GL_TEXTURE_2D_ARRAY, level, 0, 0, renderData.index, size.x, size.y, 1, GL_RGBA, GL_UNSIGNED_BYTE, data) + glTexSubImage3D(GL_TEXTURE_2D_ARRAY, level, 0, 0, renderData.index, size.x, size.y, 1, texture.data.format.gl, GL_UNSIGNED_BYTE, data) } texture.data = TextureData.NULL diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/texture/OpenGLTextureUtil.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/texture/OpenGLTextureUtil.kt index 80f3da0f8..54f42149f 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/texture/OpenGLTextureUtil.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/texture/OpenGLTextureUtil.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020-2022 Moritz Zwerger + * Copyright (C) 2020-2023 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. * @@ -14,6 +14,7 @@ package de.bixilon.minosoft.gui.rendering.system.opengl.texture import de.bixilon.kotlinglm.vec2.Vec2i +import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureFormats import example.jonathan2520.SRGBAverager import org.lwjgl.BufferUtils import org.lwjgl.opengl.GL11.* @@ -38,7 +39,8 @@ object OpenGLTextureUtil { return textureId } - fun generateMipMaps(data: ByteBuffer, size: Vec2i): Array { + fun generateMipMaps(data: ByteBuffer, format: TextureFormats, size: Vec2i): Array { + if (format != TextureFormats.RGBA8) TODO("Mipmap only supports rgba8 atm.") val images: MutableList = mutableListOf() images += data @@ -93,4 +95,11 @@ object OpenGLTextureUtil { buffer.position(0) return buffer } + + + val TextureFormats.gl: Int + get() = when (this) { + TextureFormats.RGBA8 -> GL_RGBA8 + TextureFormats.RGBA2 -> GL_RGBA2 + } } 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 641d57153..ae2cb8bd2 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 @@ -96,7 +96,7 @@ class OpenGLDynamicTextureArray( Log.log(LogMessageType.ASSETS, LogLevels.WARN) { "Dynamic texture $texture, has not a size of ${resolution}x${resolution}!" } } - val mipmaps = OpenGLTextureUtil.generateMipMaps(data.buffer, data.size) + val mipmaps = OpenGLTextureUtil.generateMipMaps(data.buffer, data.format, data.size) texture.data = mipmaps texture.size = data.size if (force) { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/textures/TextureUtil.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/textures/TextureUtil.kt index d38413b8b..c3c2eb369 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/textures/TextureUtil.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/textures/TextureUtil.kt @@ -15,12 +15,15 @@ package de.bixilon.minosoft.gui.rendering.textures import de.bixilon.kotlinglm.vec2.Vec2i import de.bixilon.minosoft.data.registries.identified.ResourceLocation +import de.bixilon.minosoft.data.text.formatting.color.ColorUtil +import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureFormats import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureTransparencies import de.bixilon.minosoft.gui.rendering.system.base.texture.array.StaticTextureArray import de.bixilon.minosoft.gui.rendering.system.base.texture.data.TextureData import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture import de.bixilon.minosoft.gui.rendering.world.mesh.SingleWorldMesh import de.bixilon.minosoft.gui.rendering.world.mesh.WorldMesh +import de.bixilon.minosoft.util.KUtil.getRGBA import de.bixilon.minosoft.util.KUtil.toResourceLocation import de.matthiasmann.twl.utils.PNGDecoder import org.lwjgl.BufferUtils @@ -29,6 +32,7 @@ import java.awt.image.BufferedImage import java.io.ByteArrayOutputStream import java.io.DataOutputStream import java.io.InputStream +import java.nio.ByteBuffer import javax.imageio.ImageIO object TextureUtil { @@ -91,7 +95,7 @@ object TextureUtil { * Only happens to some weird textures (seen in PureBDCraft) * Ignores the alpha channel */ - private fun InputStream.readTexture2(): TextureData { + private fun InputStream.readTexture2(format: TextureFormats): TextureData { val image: BufferedImage = ImageIO.read(this) val rgb = image.getRGB(0, 0, image.width, image.height, null, 0, image.width) @@ -99,25 +103,46 @@ object TextureUtil { val dataOutput = DataOutputStream(byteOutput) for (color in rgb) { - dataOutput.writeInt((color shl 8) or 0xFF) + val rgba = (color shl 8) or 0xFF + when (format) { + TextureFormats.RGBA8 -> dataOutput.writeInt(rgba) + TextureFormats.RGBA2 -> dataOutput.writeByte(ColorUtil.rgba8ToRgba2(rgba).toInt()) + } } val buffer = MemoryUtil.memAlloc(byteOutput.size()) buffer.put(byteOutput.toByteArray()) - return TextureData(Vec2i(image.width, image.height), buffer) + return TextureData(Vec2i(image.width, image.height), format, buffer) } - fun InputStream.readTexture(): TextureData { - return try { + fun InputStream.readTexture(format: TextureFormats): TextureData { + try { val decoder = PNGDecoder(this) val data = BufferUtils.createByteBuffer(decoder.width * decoder.height * PNGDecoder.Format.RGBA.numComponents) decoder.decode(data, decoder.width * PNGDecoder.Format.RGBA.numComponents, PNGDecoder.Format.RGBA) - TextureData(Vec2i(decoder.width, decoder.height), data) - } catch (exception: Throwable) { - this.reset() - readTexture2() + + val converted = when (format) { + TextureFormats.RGBA8 -> data + TextureFormats.RGBA2 -> data.copyRgba8ToRgba2() + } + return TextureData(Vec2i(decoder.width, decoder.height), format, converted) + } catch (_: Throwable) { } + this.reset() + return readTexture2(format) + } + + + private fun ByteBuffer.copyRgba8ToRgba2(): ByteBuffer { + val next = BufferUtils.createByteBuffer(this.limit() / 4) + + for (index in 0..next.limit()) { + val rgba = this.getRGBA(index) + next.put(index, ColorUtil.rgba8ToRgba2(rgba)) + } + + return next } } diff --git a/src/main/java/de/bixilon/minosoft/util/KUtil.kt b/src/main/java/de/bixilon/minosoft/util/KUtil.kt index 6cc83579f..e5ec48481 100644 --- a/src/main/java/de/bixilon/minosoft/util/KUtil.kt +++ b/src/main/java/de/bixilon/minosoft/util/KUtil.kt @@ -60,6 +60,7 @@ import de.bixilon.minosoft.util.url.ResourceURLHandler import io.netty.channel.SimpleChannelInboundHandler import javafx.application.Platform import org.kamranzafar.jtar.TarHeader +import java.nio.ByteBuffer import java.security.SecureRandom import java.util.* import javax.net.ssl.SSLContext @@ -352,4 +353,16 @@ object KUtil { inline fun > ValuesEnum.set(): EnumSet { return EnumSetUtil.create(T::class.java, VALUES) } + + fun ByteBuffer.getRGB(index: Int): Int { + val red: Int = this[index].toInt() and 0xFF + val green: Int = this[index + 1].toInt() and 0xFF + val blue: Int = this[index + 2].toInt() and 0xFF + + return 0xFF shl 24 or (red shl 16) or (green shl 8) or blue + } + + fun ByteBuffer.getRGBA(index: Int): Int { + return (getRGB(index) shl 8) or (this[index + 3].toInt() and 0x0FF) + } }