mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-17 11:24:56 -04:00
wip dynamic textures
This commit is contained in:
parent
b7f7ba21ec
commit
75b1bebd6b
@ -38,9 +38,7 @@ import de.bixilon.minosoft.gui.rendering.stats.ExperimentalRenderStats
|
||||
import de.bixilon.minosoft.gui.rendering.stats.RenderStats
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.IntegratedBufferTypes
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem
|
||||
import de.bixilon.minosoft.gui.rendering.system.opengl.OpenGLRenderSystem
|
||||
import de.bixilon.minosoft.gui.rendering.system.window.BaseWindow
|
||||
import de.bixilon.minosoft.gui.rendering.system.window.GLFWWindow
|
||||
import de.bixilon.minosoft.gui.rendering.tint.TintManager
|
||||
import de.bixilon.minosoft.gui.rendering.util.ScreenshotTaker
|
||||
import de.bixilon.minosoft.gui.rendering.world.LightMap
|
||||
@ -60,8 +58,8 @@ class RenderWindow(
|
||||
private val profile = connection.profiles.rendering
|
||||
val preferQuads = profile.advanced.preferQuads
|
||||
|
||||
val window: BaseWindow = GLFWWindow(this, connection)
|
||||
val renderSystem: RenderSystem = OpenGLRenderSystem(this)
|
||||
val window = BaseWindow.createWindow(this)
|
||||
val renderSystem = RenderSystem.createRenderSystem(this)
|
||||
val camera = Camera(this)
|
||||
|
||||
val inputHandler = RenderWindowInputHandler(this)
|
||||
@ -151,7 +149,7 @@ class RenderWindow(
|
||||
// Init stage
|
||||
val initLatch = CountUpAndDownLatch(1, latch)
|
||||
Log.log(LogMessageType.RENDERING_LOADING, LogLevels.VERBOSE) { "Generating font and gathering textures (${stopwatch.labTime()})..." }
|
||||
textureManager.loadDefaultTextures()
|
||||
textureManager.loadDefaultTextures(connection.assetsManager)
|
||||
font = FontLoader.load(this, initLatch)
|
||||
|
||||
|
||||
|
@ -21,6 +21,7 @@ import de.bixilon.minosoft.gui.rendering.font.renderer.ChatComponentRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIMeshCache
|
||||
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.texture.AbstractTexture
|
||||
import de.bixilon.minosoft.gui.rendering.world.mesh.SingleWorldMesh
|
||||
|
||||
@ -28,9 +29,9 @@ import de.bixilon.minosoft.gui.rendering.world.mesh.SingleWorldMesh
|
||||
class WorldGUIConsumer(val mesh: SingleWorldMesh, val transform: Mat4, val light: Int) : GUIVertexConsumer {
|
||||
override val order: Array<Pair<Int, Int>> get() = mesh.order
|
||||
|
||||
override fun addVertex(position: Vec2t<*>, texture: AbstractTexture, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?) {
|
||||
override fun addVertex(position: Vec2t<*>, texture: ShaderIdentifiable, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?) {
|
||||
val transformed = transform.fastTimes(position.x.toFloat() / ChatComponentRenderer.TEXT_BLOCK_RESOLUTION, -position.y.toFloat() / ChatComponentRenderer.TEXT_BLOCK_RESOLUTION)
|
||||
mesh.addVertex(transformed, uv, texture, tint.rgb, light)
|
||||
mesh.addVertex(transformed, uv, texture as AbstractTexture, tint.rgb, light)
|
||||
}
|
||||
|
||||
override fun addCache(cache: GUIMeshCache) {
|
||||
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.gui.elements.primitive
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec2.Vec2i
|
||||
import de.bixilon.minosoft.data.text.ChatColors
|
||||
import de.bixilon.minosoft.data.text.RGBColor
|
||||
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
|
||||
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.dynamic.DynamicTexture
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.EMPTY
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.EMPTY
|
||||
|
||||
open class DynamicImageElement(
|
||||
guiRenderer: GUIRenderer,
|
||||
texture: DynamicTexture?,
|
||||
uvStart: Vec2 = Vec2.EMPTY,
|
||||
uvEnd: Vec2 = Vec2(1.0f, 1.0f),
|
||||
size: Vec2i = Vec2i.EMPTY,
|
||||
tint: RGBColor = ChatColors.WHITE,
|
||||
) : Element(guiRenderer, GUIMesh.GUIMeshStruct.FLOATS_PER_VERTEX * 6) {
|
||||
var texture: DynamicTexture? = texture
|
||||
set(value) {
|
||||
field = value
|
||||
cacheUpToDate = false
|
||||
}
|
||||
var uvStart: Vec2 = uvStart
|
||||
set(value) {
|
||||
field = value
|
||||
cacheUpToDate = false
|
||||
}
|
||||
var uvEnd: Vec2 = uvEnd
|
||||
set(value) {
|
||||
field = value
|
||||
cacheUpToDate = false
|
||||
}
|
||||
|
||||
override var size: Vec2i
|
||||
get() = super.size
|
||||
set(value) {
|
||||
super.size = value
|
||||
cacheUpToDate = false
|
||||
}
|
||||
|
||||
override var prefSize: Vec2i
|
||||
get() = size
|
||||
set(value) {
|
||||
size = value
|
||||
}
|
||||
|
||||
var tint: RGBColor = tint
|
||||
set(value) {
|
||||
field = value
|
||||
cacheUpToDate = false
|
||||
}
|
||||
|
||||
init {
|
||||
this.size = size
|
||||
}
|
||||
|
||||
override fun forceRender(offset: Vec2i, consumer: GUIVertexConsumer, options: GUIVertexOptions?) {
|
||||
consumer.addQuad(offset, offset + size, texture ?: return, uvStart, uvEnd, tint, options)
|
||||
}
|
||||
|
||||
override fun forceSilentApply() = Unit
|
||||
override fun silentApply(): Boolean = false
|
||||
}
|
@ -13,6 +13,7 @@
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.gui.hud.elements.tab
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec2.Vec2i
|
||||
import de.bixilon.minosoft.data.abilities.Gamemodes
|
||||
import de.bixilon.minosoft.data.player.tab.TabListItem
|
||||
@ -25,6 +26,7 @@ import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments.Compa
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.Pollable
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.primitive.AtlasImageElement
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.primitive.ColorElement
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.primitive.DynamicImageElement
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.text.TextElement
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
|
||||
@ -38,6 +40,7 @@ class TabListEntryElement(
|
||||
val item: TabListItem,
|
||||
width: Int,
|
||||
) : Element(guiRenderer), Pollable, Comparable<TabListEntryElement> {
|
||||
|
||||
init {
|
||||
_parent = tabList
|
||||
}
|
||||
@ -45,6 +48,7 @@ class TabListEntryElement(
|
||||
// ToDo: Skin
|
||||
private val background: ColorElement
|
||||
|
||||
private val skinElement = DynamicImageElement(guiRenderer, guiRenderer.renderWindow.textureManager.alexTexture, uvStart = Vec2(0.125), uvEnd = Vec2(0.25), size = Vec2i(8, 8))
|
||||
private val nameElement = TextElement(guiRenderer, "", background = false, parent = this)
|
||||
private lateinit var pingElement: AtlasImageElement
|
||||
|
||||
@ -77,8 +81,10 @@ class TabListEntryElement(
|
||||
}
|
||||
|
||||
override fun forceRender(offset: Vec2i, consumer: GUIVertexConsumer, options: GUIVertexOptions?) {
|
||||
skinElement
|
||||
background.render(offset, consumer, options)
|
||||
nameElement.render(offset, consumer, options)
|
||||
skinElement.render(offset, 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)
|
||||
}
|
||||
|
||||
@ -96,7 +102,7 @@ class TabListEntryElement(
|
||||
|
||||
nameElement.text = displayName
|
||||
|
||||
this.prefSize = Vec2i((PADDING * 2) + nameElement.prefSize.x + INNER_MARGIN + pingElement.prefSize.x, HEIGHT)
|
||||
this.prefSize = Vec2i((PADDING * 3) + skinElement.prefSize.x + nameElement.prefSize.x + INNER_MARGIN + pingElement.prefSize.x, HEIGHT)
|
||||
background.size = size
|
||||
cacheUpToDate = false
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec2.Vec2t
|
||||
import de.bixilon.minosoft.data.text.RGBColor
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.ShaderIdentifiable
|
||||
import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh
|
||||
import de.bixilon.minosoft.gui.rendering.util.mesh.MeshStruct
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.orthoTimes
|
||||
@ -31,7 +31,7 @@ class GUIMesh(
|
||||
data: DirectArrayFloatList,
|
||||
) : Mesh(renderWindow, GUIMeshStruct, initialCacheSize = 40000, clearOnLoad = false, data = data), GUIVertexConsumer {
|
||||
|
||||
override fun addVertex(position: Vec2t<*>, texture: AbstractTexture, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?) {
|
||||
override fun addVertex(position: Vec2t<*>, texture: ShaderIdentifiable, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?) {
|
||||
addVertex(data, matrix, position, texture, uv, tint, options)
|
||||
}
|
||||
|
||||
@ -50,7 +50,7 @@ class GUIMesh(
|
||||
|
||||
companion object {
|
||||
|
||||
fun addVertex(data: AbstractFloatList, matrix: Mat4, position: Vec2t<*>, texture: AbstractTexture, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?) {
|
||||
fun addVertex(data: AbstractFloatList, matrix: Mat4, position: Vec2t<*>, texture: ShaderIdentifiable, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?) {
|
||||
val outPosition = matrix orthoTimes position
|
||||
var color = tint.rgba
|
||||
|
||||
@ -69,7 +69,7 @@ class GUIMesh(
|
||||
data.add(outPosition.y)
|
||||
data.add(uv.x)
|
||||
data.add(uv.y)
|
||||
data.add(Float.fromBits(texture.renderData.shaderTextureId))
|
||||
data.add(Float.fromBits(texture.shaderId))
|
||||
data.add(Float.fromBits(color))
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec2.Vec2i
|
||||
import de.bixilon.kotlinglm.vec2.Vec2t
|
||||
import de.bixilon.minosoft.data.text.RGBColor
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.ShaderIdentifiable
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.EMPTY
|
||||
import de.bixilon.minosoft.util.collections.floats.AbstractFloatList
|
||||
import de.bixilon.minosoft.util.collections.floats.HeapArrayFloatList
|
||||
@ -41,7 +41,7 @@ class GUIMeshCache(
|
||||
}
|
||||
}
|
||||
|
||||
override fun addVertex(position: Vec2t<*>, texture: AbstractTexture, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?) {
|
||||
override fun addVertex(position: Vec2t<*>, texture: ShaderIdentifiable, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?) {
|
||||
GUIMesh.addVertex(data, matrix, position, texture, uv, tint, options)
|
||||
revision++
|
||||
}
|
||||
|
@ -17,14 +17,14 @@ import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec2.Vec2t
|
||||
import de.bixilon.minosoft.data.text.RGBColor
|
||||
import de.bixilon.minosoft.gui.rendering.gui.atlas.TextureLike
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.ShaderIdentifiable
|
||||
|
||||
interface GUIVertexConsumer {
|
||||
val order: Array<Pair<Int, Int>>
|
||||
|
||||
fun addVertex(position: Vec2t<*>, texture: AbstractTexture, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?)
|
||||
fun addVertex(position: Vec2t<*>, texture: ShaderIdentifiable, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?)
|
||||
|
||||
fun addQuad(start: Vec2t<*>, end: Vec2t<*>, texture: AbstractTexture, uvStart: Vec2 = Vec2(0.0f, 0.0f), uvEnd: Vec2 = Vec2(1.0f, 1.0f), tint: RGBColor, options: GUIVertexOptions?) {
|
||||
fun addQuad(start: Vec2t<*>, end: Vec2t<*>, texture: ShaderIdentifiable, uvStart: Vec2 = Vec2(0.0f, 0.0f), uvEnd: Vec2 = Vec2(1.0f, 1.0f), tint: RGBColor, options: GUIVertexOptions?) {
|
||||
val positions = arrayOf(
|
||||
start,
|
||||
Vec2(end.x, start.y),
|
||||
|
@ -17,6 +17,7 @@ import de.bixilon.kotlinglm.vec2.Vec2i
|
||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||
import de.bixilon.minosoft.data.text.Colors
|
||||
import de.bixilon.minosoft.data.text.RGBColor
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.buffer.frame.Framebuffer
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.buffer.uniform.FloatUniformBuffer
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.buffer.uniform.IntUniformBuffer
|
||||
@ -24,6 +25,7 @@ import de.bixilon.minosoft.gui.rendering.system.base.buffer.vertex.FloatVertexBu
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.buffer.vertex.PrimitiveTypes
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.shader.Shader
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureManager
|
||||
import de.bixilon.minosoft.gui.rendering.system.opengl.OpenGLRenderSystem
|
||||
import de.bixilon.minosoft.gui.rendering.util.mesh.MeshStruct
|
||||
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
||||
import java.nio.ByteBuffer
|
||||
@ -118,4 +120,12 @@ interface RenderSystem {
|
||||
|
||||
|
||||
fun polygonOffset(factor: Float, unit: Float)
|
||||
|
||||
|
||||
companion object {
|
||||
|
||||
fun createRenderSystem(renderWindow: RenderWindow): RenderSystem {
|
||||
return OpenGLRenderSystem(renderWindow)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.system.base.texture
|
||||
|
||||
interface ShaderIdentifiable {
|
||||
val shaderId: Int
|
||||
}
|
@ -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.
|
||||
*
|
||||
@ -13,13 +13,21 @@
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.system.base.texture
|
||||
|
||||
import de.bixilon.kutil.latch.CountUpAndDownLatch
|
||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.PNGTexture
|
||||
|
||||
interface StaticTextureArray : TextureArray {
|
||||
val textures: MutableMap<ResourceLocation, AbstractTexture>
|
||||
val animator: SpriteAnimator
|
||||
val state: TextureArrayStates
|
||||
|
||||
override fun get(resourceLocation: ResourceLocation): AbstractTexture? {
|
||||
fun get(resourceLocation: ResourceLocation): AbstractTexture? {
|
||||
return textures[resourceLocation]
|
||||
}
|
||||
|
||||
fun createTexture(resourceLocation: ResourceLocation, mipmaps: Boolean = true, default: () -> AbstractTexture = { PNGTexture(resourceLocation, generateMipMaps = mipmaps) }): AbstractTexture
|
||||
|
||||
fun preLoad(latch: CountUpAndDownLatch)
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
@ -14,21 +14,10 @@
|
||||
package de.bixilon.minosoft.gui.rendering.system.base.texture
|
||||
|
||||
import de.bixilon.kutil.latch.CountUpAndDownLatch
|
||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.shader.Shader
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.PNGTexture
|
||||
|
||||
interface TextureArray {
|
||||
val animator: SpriteAnimator
|
||||
val state: TextureArrayStates
|
||||
|
||||
operator fun get(resourceLocation: ResourceLocation): AbstractTexture?
|
||||
fun createTexture(resourceLocation: ResourceLocation, mipmaps: Boolean = true, default: () -> AbstractTexture = { PNGTexture(resourceLocation, generateMipMaps = mipmaps) }): AbstractTexture
|
||||
|
||||
fun preLoad(latch: CountUpAndDownLatch)
|
||||
|
||||
fun load(latch: CountUpAndDownLatch)
|
||||
|
||||
fun use(shader: Shader, arrayName: String = "uTextures")
|
||||
fun use(shader: Shader, name: String = "uTextures")
|
||||
}
|
||||
|
@ -15,24 +15,44 @@ 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.registries.ResourceLocation
|
||||
import de.bixilon.minosoft.gui.rendering.RenderConstants
|
||||
import de.bixilon.minosoft.gui.rendering.gui.atlas.TextureLikeTexture
|
||||
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.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.util.KUtil.toResourceLocation
|
||||
|
||||
abstract class TextureManager {
|
||||
abstract var staticTextures: StaticTextureArray
|
||||
abstract val staticTextures: StaticTextureArray
|
||||
abstract val dynamicTextures: DynamicTextureArray
|
||||
|
||||
lateinit var debugTexture: AbstractTexture
|
||||
private set
|
||||
lateinit var whiteTexture: TextureLikeTexture
|
||||
private set
|
||||
lateinit var steveTexture: DynamicTexture
|
||||
private set
|
||||
lateinit var alexTexture: DynamicTexture
|
||||
private set
|
||||
|
||||
fun loadDefaultTextures() {
|
||||
fun loadDefaultTextures(assetsManager: AssetsManager) {
|
||||
if (this::debugTexture.isInitialized) {
|
||||
throw IllegalStateException("Already initialized!")
|
||||
}
|
||||
debugTexture = staticTextures.createTexture(RenderConstants.DEBUG_TEXTURE_RESOURCE_LOCATION)
|
||||
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) {
|
||||
// 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 }
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.system.base.texture.dynamic
|
||||
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.ShaderIdentifiable
|
||||
import java.util.*
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
interface DynamicTexture : ShaderIdentifiable {
|
||||
val uuid: UUID
|
||||
val usages: AtomicInteger
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.system.base.texture.dynamic
|
||||
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureArray
|
||||
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)
|
||||
}
|
@ -17,15 +17,14 @@ import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec2.Vec2i
|
||||
import de.bixilon.minosoft.assets.AssetsManager
|
||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.ShaderIdentifiable
|
||||
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.opengl.texture.OpenGLTextureArray
|
||||
import de.bixilon.minosoft.gui.rendering.system.opengl.texture.OpenGLTextureUtil
|
||||
import de.bixilon.minosoft.gui.rendering.textures.properties.ImageProperties
|
||||
import example.jonathan2520.SRGBAverager
|
||||
import org.lwjgl.BufferUtils
|
||||
import java.nio.ByteBuffer
|
||||
|
||||
interface AbstractTexture {
|
||||
interface AbstractTexture : ShaderIdentifiable {
|
||||
val resourceLocation: ResourceLocation
|
||||
|
||||
var textureArrayUV: Vec2
|
||||
@ -45,61 +44,15 @@ interface AbstractTexture {
|
||||
|
||||
fun load(assetsManager: AssetsManager)
|
||||
|
||||
override val shaderId: Int
|
||||
get() = renderData.shaderTextureId
|
||||
|
||||
|
||||
fun generateMipMaps(data: ByteBuffer = this.data!!): Array<ByteBuffer> {
|
||||
val images: MutableList<ByteBuffer> = mutableListOf()
|
||||
|
||||
images += data
|
||||
if (!generateMipMaps) {
|
||||
return images.toTypedArray()
|
||||
return arrayOf(data)
|
||||
}
|
||||
|
||||
var currentData = data
|
||||
for (i in 1 until OpenGLTextureArray.MAX_MIPMAP_LEVELS) {
|
||||
val mipMapSize = Vec2i(size.x shr i, size.y shr i)
|
||||
if (mipMapSize.x <= 0 || mipMapSize.y <= 0) {
|
||||
break
|
||||
}
|
||||
currentData = generateMipmap(currentData, Vec2i(size.x shr (i - 1), size.y shr (i - 1)))
|
||||
images += currentData
|
||||
}
|
||||
|
||||
return images.toTypedArray()
|
||||
}
|
||||
|
||||
private fun generateMipmap(origin: ByteBuffer, oldSize: Vec2i): ByteBuffer {
|
||||
// No Vec2i: performance reasons
|
||||
val oldSizeX = oldSize.x
|
||||
val newSizeX = oldSizeX shr 1
|
||||
|
||||
val buffer = BufferUtils.createByteBuffer(origin.capacity() shr 1)
|
||||
buffer.limit(buffer.capacity())
|
||||
|
||||
fun getRGB(x: Int, y: Int): Int {
|
||||
return origin.getInt((y * oldSizeX + x) * 4)
|
||||
}
|
||||
|
||||
fun setRGB(x: Int, y: Int, color: Int) {
|
||||
buffer.putInt((y * newSizeX + x) * 4, color)
|
||||
}
|
||||
|
||||
for (y in 0 until (oldSize.y shr 1)) {
|
||||
for (x in 0 until newSizeX) {
|
||||
val xOffset = x * 2
|
||||
val yOffset = y * 2
|
||||
|
||||
val output = SRGBAverager.average(
|
||||
getRGB(xOffset + 0, yOffset + 0),
|
||||
getRGB(xOffset + 1, yOffset + 0),
|
||||
getRGB(xOffset + 0, yOffset + 1),
|
||||
getRGB(xOffset + 1, yOffset + 1),
|
||||
)
|
||||
|
||||
setRGB(x, y, output)
|
||||
}
|
||||
}
|
||||
|
||||
buffer.rewind()
|
||||
return buffer
|
||||
return OpenGLTextureUtil.generateMipMaps(data, size)
|
||||
}
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ class MemoryTexture(
|
||||
|
||||
init {
|
||||
val data = BufferUtils.createByteBuffer(size.x * size.y * PNGDecoder.Format.RGBA.numComponents)
|
||||
this.data = data
|
||||
|
||||
generator?.let {
|
||||
var index = 0
|
||||
|
@ -19,14 +19,9 @@ import de.bixilon.minosoft.assets.AssetsManager
|
||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||
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.opengl.texture.OpenGLTextureUtil.readTexture
|
||||
import de.bixilon.minosoft.gui.rendering.textures.properties.ImageProperties
|
||||
import de.matthiasmann.twl.utils.PNGDecoder
|
||||
import org.lwjgl.BufferUtils
|
||||
import java.awt.image.BufferedImage
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.DataOutputStream
|
||||
import java.nio.ByteBuffer
|
||||
import javax.imageio.ImageIO
|
||||
|
||||
|
||||
class PNGTexture(
|
||||
@ -57,26 +52,9 @@ class PNGTexture(
|
||||
return
|
||||
}
|
||||
|
||||
val decoder = PNGDecoder(assetsManager[resourceLocation])
|
||||
val data = BufferUtils.createByteBuffer(decoder.width * decoder.height * PNGDecoder.Format.RGBA.numComponents)
|
||||
try {
|
||||
decoder.decode(data, decoder.width * PNGDecoder.Format.RGBA.numComponents, PNGDecoder.Format.RGBA)
|
||||
} catch (exception: Throwable) {
|
||||
// ToDo: This somehow crashes with some resource packs
|
||||
// exception.printStackTrace()
|
||||
val image: BufferedImage = ImageIO.read(assetsManager[resourceLocation])
|
||||
val rgb = image.getRGB(0, 0, image.width, image.height, null, 0, image.width)
|
||||
val (size, data) = assetsManager[resourceLocation].readTexture()
|
||||
|
||||
val byteOutput = ByteArrayOutputStream()
|
||||
val dataOutput = DataOutputStream(byteOutput)
|
||||
for (color in rgb) {
|
||||
dataOutput.writeInt(color shl 8)
|
||||
}
|
||||
|
||||
data.put(byteOutput.toByteArray())
|
||||
}
|
||||
|
||||
size = Vec2i(decoder.width, decoder.height)
|
||||
this.size = size
|
||||
transparency = TextureTransparencies.OPAQUE
|
||||
for (i in 0 until data.limit() / 4) {
|
||||
val alpha = data[i * 4 + 3].toInt() and 0xFF
|
||||
|
@ -151,16 +151,9 @@ class OpenGLTextureArray(
|
||||
|
||||
@Synchronized
|
||||
private fun loadSingleArray(resolution: Int, textures: List<AbstractTexture>): Int {
|
||||
val textureId = glGenTextures()
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, textureId)
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT)
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT)
|
||||
// glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR)
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, MAX_MIPMAP_LEVELS - 1)
|
||||
val textureId = OpenGLTextureUtil.createTextureArray()
|
||||
|
||||
for (level in 0 until MAX_MIPMAP_LEVELS) {
|
||||
for (level in 0 until OpenGLTextureUtil.MAX_MIPMAP_LEVELS) {
|
||||
glTexImage3D(GL_TEXTURE_2D_ARRAY, level, GL_RGBA, resolution shr level, resolution shr level, textures.size, 0, GL_RGBA, GL_UNSIGNED_BYTE, null as ByteBuffer?)
|
||||
}
|
||||
|
||||
@ -199,7 +192,7 @@ class OpenGLTextureArray(
|
||||
}
|
||||
|
||||
|
||||
override fun use(shader: Shader, arrayName: String) {
|
||||
override fun use(shader: Shader, name: String) {
|
||||
shader.use()
|
||||
|
||||
for ((index, textureId) in textureIds.withIndex()) {
|
||||
@ -208,7 +201,7 @@ class OpenGLTextureArray(
|
||||
}
|
||||
glActiveTexture(GL_TEXTURE0 + index)
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, textureId)
|
||||
shader.setTexture("$arrayName[$index]", index)
|
||||
shader.setTexture("$name[$index]", index)
|
||||
}
|
||||
}
|
||||
|
||||
@ -216,6 +209,5 @@ class OpenGLTextureArray(
|
||||
companion object {
|
||||
const val TEXTURE_MAX_RESOLUTION = 1024
|
||||
val TEXTURE_RESOLUTION_ID_MAP = intArrayOf(16, 32, 64, 128, 256, 512, TEXTURE_MAX_RESOLUTION) // A 12x12 texture will be saved in texture id 0 (in 0 are only 16x16 textures). Animated textures get split
|
||||
const val MAX_MIPMAP_LEVELS = 5
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,10 @@ package de.bixilon.minosoft.gui.rendering.system.opengl.texture
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.StaticTextureArray
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureManager
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.dynamic.DynamicTextureArray
|
||||
import de.bixilon.minosoft.gui.rendering.system.opengl.texture.dynamic.OpenGLDynamicTextureArray
|
||||
|
||||
class OpenGLTextureManager(val renderWindow: RenderWindow) : TextureManager() {
|
||||
override var staticTextures: StaticTextureArray = OpenGLTextureArray(renderWindow)
|
||||
override val staticTextures: StaticTextureArray = OpenGLTextureArray(renderWindow)
|
||||
override val dynamicTextures: DynamicTextureArray = OpenGLDynamicTextureArray(renderWindow, resolution = 64)
|
||||
}
|
||||
|
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.system.opengl.texture
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2i
|
||||
import de.matthiasmann.twl.utils.PNGDecoder
|
||||
import example.jonathan2520.SRGBAverager
|
||||
import org.lwjgl.BufferUtils
|
||||
import org.lwjgl.opengl.GL11.*
|
||||
import org.lwjgl.opengl.GL12.GL_TEXTURE_MAX_LEVEL
|
||||
import org.lwjgl.opengl.GL30.GL_TEXTURE_2D_ARRAY
|
||||
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 OpenGLTextureUtil {
|
||||
const val MAX_MIPMAP_LEVELS = 5
|
||||
|
||||
|
||||
fun createTextureArray(): Int {
|
||||
val textureId = glGenTextures()
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, textureId)
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT)
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT)
|
||||
// glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR)
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, MAX_MIPMAP_LEVELS - 1)
|
||||
|
||||
return textureId
|
||||
}
|
||||
|
||||
fun generateMipMaps(data: ByteBuffer, size: Vec2i): Array<ByteBuffer> {
|
||||
val images: MutableList<ByteBuffer> = mutableListOf()
|
||||
|
||||
images += data
|
||||
|
||||
var currentData = data
|
||||
for (i in 1 until MAX_MIPMAP_LEVELS) {
|
||||
val mipMapSize = Vec2i(size.x shr i, size.y shr i)
|
||||
if (mipMapSize.x <= 0 || mipMapSize.y <= 0) {
|
||||
break
|
||||
}
|
||||
currentData = generateMipmap(currentData, Vec2i(size.x shr (i - 1), size.y shr (i - 1)))
|
||||
images += currentData
|
||||
}
|
||||
|
||||
return images.toTypedArray()
|
||||
}
|
||||
|
||||
|
||||
private fun generateMipmap(origin: ByteBuffer, oldSize: Vec2i): ByteBuffer {
|
||||
// No Vec2i: performance reasons
|
||||
val oldSizeX = oldSize.x
|
||||
val newSizeX = oldSizeX shr 1
|
||||
|
||||
val buffer = BufferUtils.createByteBuffer(origin.capacity() shr 1)
|
||||
buffer.limit(buffer.capacity())
|
||||
|
||||
fun getRGB(x: Int, y: Int): Int {
|
||||
return origin.getInt((y * oldSizeX + x) * 4)
|
||||
}
|
||||
|
||||
fun setRGB(x: Int, y: Int, color: Int) {
|
||||
buffer.putInt((y * newSizeX + x) * 4, color)
|
||||
}
|
||||
|
||||
for (y in 0 until (oldSize.y shr 1)) {
|
||||
for (x in 0 until newSizeX) {
|
||||
val xOffset = x * 2
|
||||
val yOffset = y * 2
|
||||
|
||||
val output = SRGBAverager.average(
|
||||
getRGB(xOffset + 0, yOffset + 0),
|
||||
getRGB(xOffset + 1, yOffset + 0),
|
||||
getRGB(xOffset + 0, yOffset + 1),
|
||||
getRGB(xOffset + 1, yOffset + 1),
|
||||
)
|
||||
|
||||
setRGB(x, y, output)
|
||||
}
|
||||
}
|
||||
|
||||
buffer.rewind()
|
||||
return buffer
|
||||
}
|
||||
|
||||
private fun InputStream.readFallbackTexture(): Pair<Vec2i, ByteBuffer> {
|
||||
// ToDo: This somehow crashes with some resource packs
|
||||
val image: BufferedImage = ImageIO.read(this)
|
||||
val rgb = image.getRGB(0, 0, image.width, image.height, null, 0, image.width)
|
||||
|
||||
val byteOutput = ByteArrayOutputStream()
|
||||
val dataOutput = DataOutputStream(byteOutput)
|
||||
for (color in rgb) {
|
||||
dataOutput.writeInt(color shl 8)
|
||||
}
|
||||
|
||||
return Pair(Vec2i(image.width, image.height), ByteBuffer.wrap(byteOutput.toByteArray()))
|
||||
}
|
||||
|
||||
fun InputStream.readTexture(): Pair<Vec2i, ByteBuffer> {
|
||||
return 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)
|
||||
|
||||
Pair(Vec2i(decoder.width, decoder.height), data)
|
||||
} catch (exception: Throwable) {
|
||||
readFallbackTexture()
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.system.opengl.texture.dynamic
|
||||
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.dynamic.DynamicTexture
|
||||
import java.util.*
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
class OpenGLDynamicTexture(
|
||||
override val uuid: UUID,
|
||||
override val shaderId: Int,
|
||||
) : DynamicTexture {
|
||||
override val usages = AtomicInteger()
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.system.opengl.texture.dynamic
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2i
|
||||
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.opengl.texture.OpenGLTextureUtil
|
||||
import org.lwjgl.opengl.GL11.*
|
||||
import org.lwjgl.opengl.GL12
|
||||
import org.lwjgl.opengl.GL12.glTexImage3D
|
||||
import org.lwjgl.opengl.GL12.glTexSubImage3D
|
||||
import org.lwjgl.opengl.GL13.GL_TEXTURE0
|
||||
import org.lwjgl.opengl.GL13.glActiveTexture
|
||||
import org.lwjgl.opengl.GL30.GL_TEXTURE_2D_ARRAY
|
||||
import java.nio.ByteBuffer
|
||||
import java.util.*
|
||||
|
||||
class OpenGLDynamicTextureArray(
|
||||
val renderWindow: RenderWindow,
|
||||
val index: Int = 6,
|
||||
val resolution: Int,
|
||||
) : DynamicTextureArray {
|
||||
private val textures: Array<OpenGLDynamicTexture?> = arrayOfNulls(32)
|
||||
private var textureId = -1
|
||||
|
||||
override val size: Int
|
||||
get() = 2
|
||||
|
||||
override fun remove(uuid: UUID) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun remove(texture: DynamicTexture) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun push(identifier: UUID, data: () -> ByteBuffer): OpenGLDynamicTexture {
|
||||
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))
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, textureId)
|
||||
for ((level, mipmap) in mipmaps.withIndex()) {
|
||||
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, level, 0, 0, level, resolution, resolution, 1, GL_RGBA, GL_UNSIGNED_BYTE, mipmap)
|
||||
}
|
||||
|
||||
return OpenGLDynamicTexture(identifier, createShaderIdentifier(index = 0))
|
||||
}
|
||||
|
||||
private fun createShaderIdentifier(array: Int = this.index, index: Int): Int {
|
||||
return (array shl 28) or (index shl 12) or 0
|
||||
}
|
||||
|
||||
|
||||
override fun load(latch: CountUpAndDownLatch) {
|
||||
val textureId = OpenGLTextureUtil.createTextureArray()
|
||||
this.textureId = textureId
|
||||
|
||||
|
||||
for (level in 0 until OpenGLTextureUtil.MAX_MIPMAP_LEVELS) {
|
||||
glTexImage3D(GL_TEXTURE_2D_ARRAY, level, GL12.GL_RGBA, resolution shr level, resolution shr level, textures.size, 0, GL_RGBA, GL_UNSIGNED_BYTE, null as ByteBuffer?)
|
||||
}
|
||||
|
||||
|
||||
for (i in textures.indices) {
|
||||
for (level in 0 until OpenGLTextureUtil.MAX_MIPMAP_LEVELS) {
|
||||
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, level, 0, 0, i, resolution, resolution, 1, GL_RGBA, GL_UNSIGNED_BYTE, ByteBuffer.wrap(ByteArray(resolution * resolution * 4)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.textureId = textureId
|
||||
}
|
||||
|
||||
override fun use(shader: Shader, name: String) {
|
||||
shader.use()
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + index)
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, textureId)
|
||||
shader.setTexture("$name[$index]", index)
|
||||
}
|
||||
}
|
@ -18,6 +18,7 @@ import de.bixilon.kotlinglm.vec2.Vec2i
|
||||
import de.bixilon.minosoft.assets.AssetsManager
|
||||
import de.bixilon.minosoft.config.profile.delegate.watcher.SimpleProfileDelegateWatcher.Companion.profileWatchRendering
|
||||
import de.bixilon.minosoft.config.profile.profiles.rendering.RenderingProfile
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.terminal.RunConfiguration
|
||||
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
||||
import de.matthiasmann.twl.utils.PNGDecoder
|
||||
@ -92,5 +93,10 @@ interface BaseWindow {
|
||||
get() = Vec2i(300, 100)
|
||||
val DEFAULT_MAXIMUM_WINDOW_SIZE: Vec2i
|
||||
get() = Vec2i(-1, -1)
|
||||
|
||||
|
||||
fun createWindow(renderWindow: RenderWindow): BaseWindow {
|
||||
return GLFWWindow(renderWindow)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ import java.nio.ByteBuffer
|
||||
|
||||
class GLFWWindow(
|
||||
private val renderWindow: RenderWindow,
|
||||
private val eventMaster: AbstractEventMaster,
|
||||
private val eventMaster: AbstractEventMaster = renderWindow.connection,
|
||||
) : BaseWindow {
|
||||
private var mousePosition = Vec2d.EMPTY
|
||||
private var skipNextMouseEvent = true
|
||||
|
@ -12,9 +12,11 @@
|
||||
*/
|
||||
|
||||
|
||||
uniform sampler2DArray uTextures[7];
|
||||
uniform sampler2DArray uTextures[8];
|
||||
|
||||
vec4 getTexture(uint textureId, vec3 uv) { // ToDo: This method is just stupid and workarounds an opengl crash with mesa drivers
|
||||
// ToDo: Those methods are just stupid and workaround an opengl crash with mesa drivers
|
||||
|
||||
vec4 getTexture(uint textureId, vec3 uv) {
|
||||
#if defined __NVIDIA || defined __AMD
|
||||
return texture(uTextures[textureId], uv);
|
||||
#else
|
||||
@ -25,12 +27,13 @@ vec4 getTexture(uint textureId, vec3 uv) { // ToDo: This method is just stupid a
|
||||
case 4u: return texture(uTextures[4], uv);
|
||||
case 5u: return texture(uTextures[5], uv);
|
||||
case 6u: return texture(uTextures[6], uv);
|
||||
case 7u: return texture(uTextures[7], uv);
|
||||
}
|
||||
return texture(uTextures[0], uv);
|
||||
#endif
|
||||
}
|
||||
|
||||
vec4 getTexture(uint textureId, vec3 uv, float mipmapLevel) { // ToDo: This method is just stupid and workarounds an opengl crash with mesa drivers
|
||||
vec4 getTexture(uint textureId, vec3 uv, float mipmapLevel) {
|
||||
#if defined __NVIDIA || defined __AMD
|
||||
return textureLod(uTextures[textureId], uv, mipmapLevel);
|
||||
#else
|
||||
@ -41,6 +44,7 @@ vec4 getTexture(uint textureId, vec3 uv, float mipmapLevel) { // ToDo: This meth
|
||||
case 4u: return textureLod(uTextures[4], uv, mipmapLevel);
|
||||
case 5u: return textureLod(uTextures[5], uv, mipmapLevel);
|
||||
case 6u: return textureLod(uTextures[6], uv, mipmapLevel);
|
||||
case 7u: return textureLod(uTextures[7], uv, mipmapLevel);
|
||||
}
|
||||
return textureLod(uTextures[0], uv, mipmapLevel);
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user